You've already forked joplin
							
							
				mirror of
				https://github.com/laurent22/joplin.git
				synced 2025-10-31 00:07:48 +02:00 
			
		
		
		
	Clipper: Added first files
This commit is contained in:
		
							
								
								
									
										1
									
								
								Clipper/joplin-webclipper/content_scripts/.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								Clipper/joplin-webclipper/content_scripts/.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1 @@ | ||||
| *.bundle.js | ||||
							
								
								
									
										121
									
								
								Clipper/joplin-webclipper/content_scripts/index.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										121
									
								
								Clipper/joplin-webclipper/content_scripts/index.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,121 @@ | ||||
| (function() { | ||||
|  | ||||
| 	if (window.jopext_hasRun) return; | ||||
| 	window.jopext_hasRun = true; | ||||
|  | ||||
| 	console.info('jopext: Loading content script'); | ||||
|  | ||||
| 	function pageTitle() { | ||||
| 		const titleElements = document.getElementsByTagName("title"); | ||||
| 		if (titleElements.length) return titleElements[0].text.trim(); | ||||
| 		return document.title.trim(); | ||||
| 	} | ||||
|  | ||||
| 	function baseUrl() { | ||||
| 		let output = location.origin + location.pathname; | ||||
| 		if (output[output.length - 1] !== '/') { | ||||
| 			output = output.split('/'); | ||||
| 			output.pop(); | ||||
| 			output = output.join('/'); | ||||
| 		} | ||||
| 		return output; | ||||
| 	} | ||||
|  | ||||
| 	// Cleans up element by removing all its invisible children (which we don't want to render as Markdown) | ||||
| 	function cleanUpElement(element) { | ||||
| 		const childNodes = element.childNodes; | ||||
|  | ||||
| 		for (let i = 0; i < childNodes.length; i++) { | ||||
| 			const node = childNodes[i]; | ||||
| 			const isVisible = node.nodeType === 1 ? window.getComputedStyle(node).display !== 'none' : true; | ||||
| 			if (!isVisible) { | ||||
| 				element.removeChild(node); | ||||
| 			} else { | ||||
| 				cleanUpElement(node); | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	function readabilityProcess() { | ||||
| 		var uri = { | ||||
| 			spec: location.href, | ||||
| 			host: location.host, | ||||
| 			prePath: location.protocol + "//" + location.host, | ||||
| 			scheme: location.protocol.substr(0, location.protocol.indexOf(":")), | ||||
| 			pathBase: location.protocol + "//" + location.host + location.pathname.substr(0, location.pathname.lastIndexOf("/") + 1) | ||||
| 		}; | ||||
|  | ||||
| 		// Readability directly change the passed document so clone it so as | ||||
| 		// to preserve the original web page. | ||||
| 		const documentClone = document.cloneNode(true); | ||||
| 		const readability = new window.Readability(uri, documentClone); | ||||
| 		const article = readability.parse(); | ||||
|  | ||||
| 		if (!article) throw new Error('Could not parse HTML document with Readability'); | ||||
|  | ||||
| 		return { | ||||
| 			title: article.title, | ||||
| 			body: article.content, | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	async function prepareCommandResponse(command) { | ||||
| 		if (command.name === "simplifiedPageHtml") { | ||||
|  | ||||
| 			let article = null; | ||||
| 			try { | ||||
| 				article = readabilityProcess(); | ||||
| 			} catch (error) { | ||||
| 				console.warn(error); | ||||
| 				console.warn('Sending full page HTML instead'); | ||||
| 				const newCommand = Object.assign({}, command, { name: 'completePageHtml' }); | ||||
| 				const response = await prepareCommandResponse(newCommand); | ||||
| 				response.warning = 'Could not retrieve simplified version of page - full page has been saved instead.'; | ||||
| 				return response; | ||||
| 			} | ||||
|  | ||||
| 			return { | ||||
| 				name: 'clippedContent', | ||||
| 				html: article.body, | ||||
| 				title: article.title, | ||||
| 				baseUrl: baseUrl(), | ||||
| 				url: location.origin + location.pathname, | ||||
| 			}; | ||||
|  | ||||
| 		} else if (command.name === "completePageHtml") { | ||||
|  | ||||
| 			const cleanDocument = document.body.cloneNode(true); | ||||
| 			cleanUpElement(cleanDocument); | ||||
|  | ||||
| 			return { | ||||
| 				name: 'clippedContent', | ||||
| 				html: cleanDocument.innerHTML, | ||||
| 				title: pageTitle(), | ||||
| 				baseUrl: baseUrl(), | ||||
| 				url: location.origin + location.pathname, | ||||
| 			}; | ||||
|  | ||||
| 		} else if (command.name === "pageTitle") { | ||||
| 			 | ||||
| 			return { | ||||
| 				name: 'pageTitle', | ||||
| 				text: pageTitle(), | ||||
| 			}; | ||||
|  | ||||
| 		} else { | ||||
| 			throw new Error('Unknown command', command); | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	async function execCommand(command) { | ||||
| 		const response = await prepareCommandResponse(command); | ||||
| 		browser.runtime.sendMessage(response); | ||||
| 	} | ||||
|  | ||||
| 	browser.runtime.onMessage.addListener((command) => { | ||||
| 		console.info('jopext: Got command:', command); | ||||
|  | ||||
| 		execCommand(command); | ||||
| 	}); | ||||
|  | ||||
| })(); | ||||
							
								
								
									
										1
									
								
								Clipper/joplin-webclipper/content_scripts/vendor.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								Clipper/joplin-webclipper/content_scripts/vendor.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1 @@ | ||||
| const Readability = require('readability-node').Readability; | ||||
							
								
								
									
										
											BIN
										
									
								
								Clipper/joplin-webclipper/icons/32.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								Clipper/joplin-webclipper/icons/32.png
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| After Width: | Height: | Size: 1.2 KiB | 
							
								
								
									
										
											BIN
										
									
								
								Clipper/joplin-webclipper/icons/48.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								Clipper/joplin-webclipper/icons/48.png
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| After Width: | Height: | Size: 1.5 KiB | 
							
								
								
									
										
											BIN
										
									
								
								Clipper/joplin-webclipper/icons/96.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								Clipper/joplin-webclipper/icons/96.png
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| After Width: | Height: | Size: 3.3 KiB | 
							
								
								
									
										3
									
								
								Clipper/joplin-webclipper/main.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								Clipper/joplin-webclipper/main.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,3 @@ | ||||
| //document.body.style.border = "5px solid red"; | ||||
|  | ||||
| // const Readability = require('readability-node').Readability; | ||||
							
								
								
									
										39
									
								
								Clipper/joplin-webclipper/manifest.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										39
									
								
								Clipper/joplin-webclipper/manifest.json
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,39 @@ | ||||
| { | ||||
|  | ||||
|   "manifest_version": 2, | ||||
|   "name": "Joplin Web Clipper", | ||||
|   "version": "1.0", | ||||
|  | ||||
|   "description": "Gets and saves content from your browser to Joplin.", | ||||
|  | ||||
|   "homepage_url": "https://joplin.cozic.net", | ||||
|  | ||||
|   "icons": { | ||||
|     "48": "icons/48.png", | ||||
|     "96": "icons/96.png" | ||||
|   }, | ||||
|  | ||||
|   "permissions": [ | ||||
|     "activeTab" | ||||
|   ], | ||||
|  | ||||
|   "browser_action": { | ||||
|     "default_icon": "icons/32.png", | ||||
|     "default_title": "Joplin Web Clipper", | ||||
|     "default_popup": "popup/build/index.html" | ||||
|   }, | ||||
|  | ||||
|   "content_scripts": [ | ||||
|     { | ||||
|       "matches": ["*://*/"], | ||||
|       "js": ["main.js"] | ||||
|     } | ||||
|   ], | ||||
|  | ||||
|   "applications": { | ||||
|       "gecko": { | ||||
|          "id": "{8419486a-54e9-11e8-9401-ac9e17909436}" | ||||
|       } | ||||
|    } | ||||
|  | ||||
| } | ||||
							
								
								
									
										13
									
								
								Clipper/joplin-webclipper/package-lock.json
									
									
									
										generated
									
									
									
										Normal file
									
								
							
							
						
						
									
										13
									
								
								Clipper/joplin-webclipper/package-lock.json
									
									
									
										generated
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,13 @@ | ||||
| { | ||||
|   "name": "joplin-webclipper", | ||||
|   "version": "1.0.0", | ||||
|   "lockfileVersion": 1, | ||||
|   "requires": true, | ||||
|   "dependencies": { | ||||
|     "readability-node": { | ||||
|       "version": "0.1.0", | ||||
|       "resolved": "https://registry.npmjs.org/readability-node/-/readability-node-0.1.0.tgz", | ||||
|       "integrity": "sha1-DUBacMLCFZRKf0qbX3UGzQWpsao=" | ||||
|     } | ||||
|   } | ||||
| } | ||||
							
								
								
									
										14
									
								
								Clipper/joplin-webclipper/package.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										14
									
								
								Clipper/joplin-webclipper/package.json
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,14 @@ | ||||
| { | ||||
|   "name": "joplin-webclipper", | ||||
|   "version": "1.0.0", | ||||
|   "description": "", | ||||
|   "main": "main.js", | ||||
|   "scripts": { | ||||
|     "test": "echo \"Error: no test specified\" && exit 1" | ||||
|   }, | ||||
|   "author": "", | ||||
|   "license": "MIT", | ||||
|   "dependencies": { | ||||
|     "readability-node": "^0.1.0" | ||||
|   } | ||||
| } | ||||
							
								
								
									
										21
									
								
								Clipper/joplin-webclipper/popup/.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										21
									
								
								Clipper/joplin-webclipper/popup/.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,21 @@ | ||||
| # See https://help.github.com/ignore-files/ for more about ignoring files. | ||||
|  | ||||
| # dependencies | ||||
| node_modules | ||||
|  | ||||
| # testing | ||||
| coverage | ||||
|  | ||||
| # production | ||||
| build | ||||
|  | ||||
| # misc | ||||
| .DS_Store | ||||
| .env.local | ||||
| .env.development.local | ||||
| .env.test.local | ||||
| .env.production.local | ||||
|  | ||||
| npm-debug.log* | ||||
| yarn-debug.log* | ||||
| yarn-error.log* | ||||
							
								
								
									
										2444
									
								
								Clipper/joplin-webclipper/popup/README.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										2444
									
								
								Clipper/joplin-webclipper/popup/README.md
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										22
									
								
								Clipper/joplin-webclipper/popup/index.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										22
									
								
								Clipper/joplin-webclipper/popup/index.html
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,22 @@ | ||||
| <!DOCTYPE html> | ||||
|  | ||||
| <html> | ||||
|   <head> | ||||
|     <meta charset="utf-8"> | ||||
|     <link rel="stylesheet" href="style.css"/> | ||||
|   </head> | ||||
|  | ||||
| <body> | ||||
|   <div id="popup-content"> | ||||
|     <div class="button" data-action="getCompletePageHtml">Complete HTMLxx</div> | ||||
|     <div class="button beast">Turtle</div> | ||||
|     <div class="button beast">Snake</div> | ||||
|     <div class="button reset">Reset</div> | ||||
|   </div> | ||||
|   <div id="error-content" class="hidden"> | ||||
|     <p>Can't beastify this web page.</p><p>Try a different page.</p> | ||||
|   </div> | ||||
|   <script src="index.js"></script> | ||||
| </body> | ||||
|  | ||||
| </html> | ||||
							
								
								
									
										145
									
								
								Clipper/joplin-webclipper/popup/index.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										145
									
								
								Clipper/joplin-webclipper/popup/index.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,145 @@ | ||||
| /** | ||||
|  * CSS to hide everything on the page, | ||||
|  * except for elements that have the "beastify-image" class. | ||||
|  */ | ||||
| const hidePage = `body > :not(.beastify-image) { | ||||
| 										display: none; | ||||
| 									}`; | ||||
|  | ||||
| /** | ||||
|  * Listen for clicks on the buttons, and send the appropriate message to | ||||
|  * the content script in the page. | ||||
|  */ | ||||
| function listenForClicks() { | ||||
| 	document.addEventListener('click', async (event) => { | ||||
| 		const tabs = await browser.tabs.query({active: true, currentWindow: true}); | ||||
| 		const html = await browser.tabs.sendMessage(tabs[0].id, { | ||||
| 			command: "getCompletePageHtml", | ||||
| 		}); | ||||
|  | ||||
| 		console.info('RRRRRRRRR', html); | ||||
| 	}); | ||||
|  | ||||
| 	// console.info('Listin'); | ||||
|  | ||||
| 	// document.addEventListener("click", (event) => { | ||||
| 	//   /** | ||||
| 	//    * Insert the page-hiding CSS into the active tab, | ||||
| 	//    * then get the beast URL and | ||||
| 	//    * send a "beastify" message to the content script in the active tab. | ||||
| 	//    */ | ||||
| 	//   // function beastify(tabs) { | ||||
| 	//   //   browser.tabs.insertCSS({code: hidePage}).then(() => { | ||||
| 	//   //     let url = beastNameToURL(e.target.textContent); | ||||
| 	//   //     browser.tabs.sendMessage(tabs[0].id, { | ||||
| 	//   //       command: "beastify", | ||||
| 	//   //       beastURL: url | ||||
| 	//   //     }); | ||||
| 	//   //   }); | ||||
| 	//   // } | ||||
|  | ||||
| 	//   // * | ||||
| 	//   //  * Remove the page-hiding CSS from the active tab, | ||||
| 	//   //  * send a "reset" message to the content script in the active tab. | ||||
| 		  | ||||
| 	//   // function reset(tabs) { | ||||
| 	//   //   browser.tabs.removeCSS({code: hidePage}).then(() => { | ||||
| 	//   //     browser.tabs.sendMessage(tabs[0].id, { | ||||
| 	//   //       command: "reset", | ||||
| 	//   //     }); | ||||
| 	//   //   }); | ||||
| 	//   // } | ||||
|  | ||||
| 	//   /** | ||||
| 	//    * Just log the error to the console. | ||||
| 	//    */ | ||||
| 	//   function reportError(error) { | ||||
| 	//     console.error(`Could not beastify: ${error}`); | ||||
| 	//   } | ||||
|  | ||||
| 	//   // const action = event.currentTarget.getAttribute('data-action'); | ||||
|  | ||||
| 	//   console.info(event.currentTarget); | ||||
|  | ||||
|  | ||||
|  | ||||
| 	//   /** | ||||
| 	//    * Get the active tab, | ||||
| 	//    * then call "beastify()" or "reset()" as appropriate. | ||||
| 	//    */ | ||||
| 	//   // if (e.target.classList.contains("beast")) { | ||||
| 	//   //   browser.tabs.query({active: true, currentWindow: true}) | ||||
| 	//   //     .then(beastify) | ||||
| 	//   //     .catch(reportError); | ||||
| 	//   // } | ||||
| 	//   // else if (e.target.classList.contains("reset")) { | ||||
| 	//   //   browser.tabs.query({active: true, currentWindow: true}) | ||||
| 	//   //     .then(reset) | ||||
| 	//   //     .catch(reportError); | ||||
| 	//   // } | ||||
| 	// }); | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * There was an error executing the script. | ||||
|  * Display the popup's error message, and hide the normal UI. | ||||
|  */ | ||||
| function reportExecuteScriptError(error) { | ||||
| 	document.querySelector("#popup-content").classList.add("hidden"); | ||||
| 	document.querySelector("#error-content").classList.remove("hidden"); | ||||
| 	console.error(`Failed to execute beastify content script: ${error.message}`); | ||||
| } | ||||
|  | ||||
| browser.runtime.onMessage.addListener(notify); | ||||
|  | ||||
| function notify(message) { | ||||
| 	if (message.command === 'setCompletePageHtml') { | ||||
|  | ||||
| 		console.info('UUUUUUUUUUUUU', message.baseUrl); | ||||
|  | ||||
| 		fetch("http://127.0.0.1:9967/notes", { | ||||
| 			method: "POST", | ||||
| 			headers: { | ||||
| 				'Accept': 'application/json', | ||||
| 				'Content-Type': 'application/json' | ||||
| 			}, | ||||
|  | ||||
| 			//make sure to serialize your JSON body | ||||
| 			body: JSON.stringify({ | ||||
| 				title: message.title, | ||||
| 				baseUrl: message.baseUrl, | ||||
| 				bodyHtml: message.html, | ||||
| 				url: message.url, | ||||
| 			}) | ||||
| 		}) | ||||
| 		.then( async (response) => {  | ||||
| 			console.info('GOT RESPNSE', response); | ||||
| 			const json = await response.json(); | ||||
| 			console.info(json); | ||||
| 			 //do something awesome that makes the world a better place | ||||
| 		}); | ||||
| 		// console.info('aaaaaaaaaa', message.html); | ||||
| 	} | ||||
| 	//console.info('Popup: got message', message); | ||||
| 	// browser.notifications.create({ | ||||
| 	//   "type": "basic", | ||||
| 	//   "iconUrl": browser.extension.getURL("link.png"), | ||||
| 	//   "title": "You clicked a link!", | ||||
| 	//   "message": message.url | ||||
| 	// }); | ||||
| } | ||||
|  | ||||
|  | ||||
| /** | ||||
|  * When the popup loads, inject a content script into the active tab, | ||||
|  * and add a click handler. | ||||
|  * If we couldn't inject the script, handle the error. | ||||
|  */ | ||||
|  | ||||
| browser.tabs.executeScript({file: "/content_scripts/vendor.bundle.js"}) | ||||
| .then(() => { | ||||
| 	return browser.tabs.executeScript({file: "/content_scripts/index.js"}) | ||||
| }) | ||||
| .then(listenForClicks) | ||||
| .catch(reportExecuteScriptError); | ||||
|  | ||||
							
								
								
									
										11315
									
								
								Clipper/joplin-webclipper/popup/package-lock.json
									
									
									
										generated
									
									
									
										Normal file
									
								
							
							
						
						
									
										11315
									
								
								Clipper/joplin-webclipper/popup/package-lock.json
									
									
									
										generated
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										23
									
								
								Clipper/joplin-webclipper/popup/package.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										23
									
								
								Clipper/joplin-webclipper/popup/package.json
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,23 @@ | ||||
| { | ||||
|   "name": "joplin-webclipper-popup", | ||||
|   "version": "0.1.0", | ||||
|   "private": true, | ||||
|   "homepage": ".", | ||||
|   "dependencies": { | ||||
|     "react": "^16.3.2", | ||||
|     "react-dom": "^16.3.2", | ||||
|     "react-redux": "^5.0.7", | ||||
|     "react-scripts": "1.1.4", | ||||
|     "redux": "^4.0.0" | ||||
|   }, | ||||
|   "scripts": { | ||||
|     "start": "react-scripts start", | ||||
|     "build": "react-scripts build", | ||||
|     "test": "react-scripts test --env=jsdom", | ||||
|     "eject": "react-scripts eject", | ||||
|     "watch": "cra-build-watch" | ||||
|   }, | ||||
|   "devDependencies": { | ||||
|     "cra-build-watch": "^1.0.1" | ||||
|   } | ||||
| } | ||||
							
								
								
									
										
											BIN
										
									
								
								Clipper/joplin-webclipper/popup/public/favicon.ico
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								Clipper/joplin-webclipper/popup/public/favicon.ico
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| After Width: | Height: | Size: 3.8 KiB | 
							
								
								
									
										40
									
								
								Clipper/joplin-webclipper/popup/public/index.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										40
									
								
								Clipper/joplin-webclipper/popup/public/index.html
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,40 @@ | ||||
| <!DOCTYPE html> | ||||
| <html lang="en"> | ||||
|   <head> | ||||
|     <meta charset="utf-8"> | ||||
|     <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no"> | ||||
|     <meta name="theme-color" content="#000000"> | ||||
|     <!-- | ||||
|       manifest.json provides metadata used when your web app is added to the | ||||
|       homescreen on Android. See https://developers.google.com/web/fundamentals/engage-and-retain/web-app-manifest/ | ||||
|     --> | ||||
|     <link rel="manifest" href="%PUBLIC_URL%/manifest.json"> | ||||
|     <link rel="shortcut icon" href="%PUBLIC_URL%/favicon.ico"> | ||||
|     <!-- | ||||
|       Notice the use of %PUBLIC_URL% in the tags above. | ||||
|       It will be replaced with the URL of the `public` folder during the build. | ||||
|       Only files inside the `public` folder can be referenced from the HTML. | ||||
|  | ||||
|       Unlike "/favicon.ico" or "favicon.ico", "%PUBLIC_URL%/favicon.ico" will | ||||
|       work correctly both with client-side routing and a non-root public URL. | ||||
|       Learn how to configure a non-root public URL by running `npm run build`. | ||||
|     --> | ||||
|     <title>React App</title> | ||||
|   </head> | ||||
|   <body> | ||||
|     <noscript> | ||||
|       You need to enable JavaScript to run this app. | ||||
|     </noscript> | ||||
|     <div id="root"></div> | ||||
|     <!-- | ||||
|       This HTML file is a template. | ||||
|       If you open it directly in the browser, you will see an empty page. | ||||
|  | ||||
|       You can add webfonts, meta tags, or analytics to this file. | ||||
|       The build step will place the bundled scripts into the <body> tag. | ||||
|  | ||||
|       To begin the development, run `npm start` or `yarn start`. | ||||
|       To create a production bundle, use `npm run build` or `yarn build`. | ||||
|     --> | ||||
|   </body> | ||||
| </html> | ||||
							
								
								
									
										15
									
								
								Clipper/joplin-webclipper/popup/public/manifest.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										15
									
								
								Clipper/joplin-webclipper/popup/public/manifest.json
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,15 @@ | ||||
| { | ||||
|   "short_name": "React App", | ||||
|   "name": "Create React App Sample", | ||||
|   "icons": [ | ||||
|     { | ||||
|       "src": "favicon.ico", | ||||
|       "sizes": "64x64 32x32 24x24 16x16", | ||||
|       "type": "image/x-icon" | ||||
|     } | ||||
|   ], | ||||
|   "start_url": "./index.html", | ||||
|   "display": "standalone", | ||||
|   "theme_color": "#000000", | ||||
|   "background_color": "#ffffff" | ||||
| } | ||||
							
								
								
									
										30
									
								
								Clipper/joplin-webclipper/popup/src/App.css
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										30
									
								
								Clipper/joplin-webclipper/popup/src/App.css
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,30 @@ | ||||
| .App { | ||||
|   text-align: center; | ||||
|   width: 400px; | ||||
|   height: 400px; | ||||
| } | ||||
|  | ||||
| .App-logo { | ||||
|   animation: App-logo-spin infinite 20s linear; | ||||
|   height: 80px; | ||||
| } | ||||
|  | ||||
| .App-header { | ||||
|   background-color: #222; | ||||
|   height: 150px; | ||||
|   padding: 20px; | ||||
|   color: white; | ||||
| } | ||||
|  | ||||
| .App-title { | ||||
|   font-size: 1.5em; | ||||
| } | ||||
|  | ||||
| .App-intro { | ||||
|   font-size: large; | ||||
| } | ||||
|  | ||||
| @keyframes App-logo-spin { | ||||
|   from { transform: rotate(0deg); } | ||||
|   to { transform: rotate(360deg); } | ||||
| } | ||||
							
								
								
									
										74
									
								
								Clipper/joplin-webclipper/popup/src/App.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										74
									
								
								Clipper/joplin-webclipper/popup/src/App.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,74 @@ | ||||
| import React, { Component } from 'react'; | ||||
| import './App.css'; | ||||
|  | ||||
| const { connect } = require('react-redux'); | ||||
| const Global = require('./Global'); | ||||
| const { bridge } = require('./bridge'); | ||||
|  | ||||
| class AppComponent extends Component { | ||||
|  | ||||
| 	constructor() { | ||||
| 		super(); | ||||
|  | ||||
| 		this.state = ({ | ||||
| 			contentScriptLoaded: false, | ||||
| 		}); | ||||
| 	} | ||||
|  | ||||
| 	async clipSimplified_click() { | ||||
| 		bridge().sendCommandToActiveTab({ | ||||
| 			name: 'simplifiedPageHtml', | ||||
| 		}); | ||||
| 	} | ||||
|  | ||||
| 	clipComplete_click() { | ||||
| 		bridge().sendCommandToActiveTab({ | ||||
| 			name: 'completePageHtml', | ||||
| 		}); | ||||
| 	} | ||||
|  | ||||
| 	async loadContentScripts() { | ||||
| 		await Global.browser().tabs.executeScript({file: "/content_scripts/vendor.bundle.js"}); | ||||
| 		await Global.browser().tabs.executeScript({file: "/content_scripts/index.js"}); | ||||
| 	} | ||||
|  | ||||
| 	async componentDidMount() { | ||||
| 		await this.loadContentScripts(); | ||||
| 		this.setState({ | ||||
| 			contentScriptLoaded: true, | ||||
| 		}); | ||||
|  | ||||
| 		bridge().sendCommandToActiveTab({ | ||||
| 			name: 'pageTitle', | ||||
| 		}); | ||||
| 	} | ||||
|  | ||||
| 	render() { | ||||
| 		if (!this.state.contentScriptLoaded) return 'Loading...'; | ||||
|  | ||||
| 		const warningComponent = !this.props.warning ? null : <div>{ this.props.warning }</div> | ||||
|  | ||||
| 		return ( | ||||
| 			<div className="App"> | ||||
| 				<p>Title: { this.props.pageTitle }</p> | ||||
| 				<ul> | ||||
| 					<li><button onClick={this.clipSimplified_click}>Clip simplified page</button></li> | ||||
| 					<li><button onClick={this.clipComplete_click}>Clip complete page</button></li> | ||||
| 				</ul> | ||||
| 				{ warningComponent } | ||||
| 			</div> | ||||
| 		); | ||||
| 	} | ||||
|  | ||||
| } | ||||
|  | ||||
| const mapStateToProps = (state) => { | ||||
| 	return { | ||||
| 		warning: state.warning, | ||||
| 		pageTitle: state.pageTitle, | ||||
| 	}; | ||||
| }; | ||||
|  | ||||
| const App = connect(mapStateToProps)(AppComponent); | ||||
|  | ||||
| export default App; | ||||
							
								
								
									
										7
									
								
								Clipper/joplin-webclipper/popup/src/Global.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								Clipper/joplin-webclipper/popup/src/Global.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,7 @@ | ||||
| const Global = {} | ||||
|  | ||||
| Global.browser = function() { | ||||
| 	return window.browser; | ||||
| } | ||||
|  | ||||
| module.exports = Global; | ||||
							
								
								
									
										81
									
								
								Clipper/joplin-webclipper/popup/src/bridge.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										81
									
								
								Clipper/joplin-webclipper/popup/src/bridge.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,81 @@ | ||||
| class Bridge { | ||||
|  | ||||
| 	init(browser, dispatch) { | ||||
| 		console.info('Popup: Init bridge'); | ||||
|  | ||||
| 		this.browser_ = browser; | ||||
| 		this.dispatch_ = dispatch; | ||||
|  | ||||
| 		this.browser_notify = async (command) => { | ||||
| 			console.info('Popup: Got command: ' + command.name); | ||||
| 			 | ||||
| 			if (command.warning) { | ||||
| 				console.warn('Popup: Got warning: ' + command.warning); | ||||
| 				this.dispatch({ type: 'WARNING_SET', text: command.warning }); | ||||
| 			} else { | ||||
| 				this.dispatch({ type: 'WARNING_SET', text: '' }); | ||||
| 			} | ||||
|  | ||||
| 			if (command.name === 'clippedContent') { | ||||
| 				console.info('Popup: Sending to Joplin...'); | ||||
|  | ||||
| 				try { | ||||
| 					const response = await fetch("http://127.0.0.1:9967/notes", { | ||||
| 						method: "POST", | ||||
| 						headers: { | ||||
| 							'Accept': 'application/json', | ||||
| 							'Content-Type': 'application/json' | ||||
| 						}, | ||||
|  | ||||
| 						//make sure to serialize your JSON body | ||||
| 						body: JSON.stringify({ | ||||
| 							title: command.title, | ||||
| 							baseUrl: command.baseUrl, | ||||
| 							bodyHtml: command.html, | ||||
| 							url: command.url, | ||||
| 						}) | ||||
| 					}) | ||||
|  | ||||
| 					console.info('GOT RESPNSE', response); | ||||
| 					const json = await response.json(); | ||||
| 					console.info(json); | ||||
| 				} catch (error) { | ||||
| 					console.error('Popup: Cannot send to Joplin', error) | ||||
| 				} | ||||
| 			} else if (command.name === 'pageTitle') { | ||||
|  | ||||
| 				this.dispatch({ type: 'PAGE_TITLE_SET', text: command.text }); | ||||
|  | ||||
| 			} | ||||
| 		} | ||||
|  | ||||
| 		this.browser_.runtime.onMessage.addListener(this.browser_notify); | ||||
| 	} | ||||
|  | ||||
| 	browser() { | ||||
| 		return this.browser_; | ||||
| 	} | ||||
|  | ||||
| 	dispatch(action) { | ||||
| 		return this.dispatch_(action); | ||||
| 	} | ||||
|  | ||||
| 	async sendCommandToActiveTab(command) { | ||||
| 		const tabs = await this.browser().tabs.query({ active: true, currentWindow: true }); | ||||
| 		if (!tabs.length) { | ||||
| 			console.warn('No valid tab'); | ||||
| 			return; | ||||
| 		} | ||||
|  | ||||
| 		await this.browser().tabs.sendMessage(tabs[0].id, command); | ||||
| 	} | ||||
|  | ||||
| } | ||||
|  | ||||
| const bridge_ = new Bridge(); | ||||
|  | ||||
| const bridge = function() { | ||||
| 	return bridge_; | ||||
| } | ||||
|  | ||||
| export { bridge } | ||||
							
								
								
									
										5
									
								
								Clipper/joplin-webclipper/popup/src/index.css
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										5
									
								
								Clipper/joplin-webclipper/popup/src/index.css
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,5 @@ | ||||
| body { | ||||
|   margin: 0; | ||||
|   padding: 0; | ||||
|   font-family: sans-serif; | ||||
| } | ||||
							
								
								
									
										39
									
								
								Clipper/joplin-webclipper/popup/src/index.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										39
									
								
								Clipper/joplin-webclipper/popup/src/index.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,39 @@ | ||||
| import React from 'react'; | ||||
| import ReactDOM from 'react-dom'; | ||||
| import './index.css'; | ||||
| import App from './App'; | ||||
|  | ||||
| const { connect, Provider } = require('react-redux'); | ||||
| const { bridge } = require('./bridge'); | ||||
| const { createStore } = require('redux'); | ||||
|  | ||||
| const defaultState = { | ||||
| 	warning: '', | ||||
| 	pageTitle: '', | ||||
| }; | ||||
|  | ||||
| function reducer(state = defaultState, action) { | ||||
| 	let newState = state; | ||||
|  | ||||
| 	if (action.type === 'WARNING_SET') { | ||||
|  | ||||
| 		newState = Object.assign({}, state); | ||||
| 		newState.warning = action.text; | ||||
|  | ||||
| 	} else if (action.type === 'PAGE_TITLE_SET') { | ||||
|  | ||||
| 		newState = Object.assign({}, state); | ||||
| 		newState.pageTitle = action.text; | ||||
|  | ||||
| 	} | ||||
|  | ||||
| 	return newState; | ||||
| } | ||||
|  | ||||
| const store = createStore(reducer); | ||||
|  | ||||
| bridge().init(window.browser, store.dispatch); | ||||
|  | ||||
| console.info('Popup: Creating React app...'); | ||||
|  | ||||
| ReactDOM.render(<Provider store={store}><App /></Provider>, document.getElementById('root')); | ||||
							
								
								
									
										31
									
								
								Clipper/joplin-webclipper/popup/style.css
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										31
									
								
								Clipper/joplin-webclipper/popup/style.css
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,31 @@ | ||||
| html, body { | ||||
|   width: 100px; | ||||
| } | ||||
|  | ||||
| .hidden { | ||||
|   display: none; | ||||
| } | ||||
|  | ||||
| .button { | ||||
|   margin: 3% auto; | ||||
|   padding: 4px; | ||||
|   text-align: center; | ||||
|   font-size: 1.5em; | ||||
|   cursor: pointer; | ||||
| } | ||||
|  | ||||
| .beast:hover { | ||||
|   background-color: #CFF2F2; | ||||
| } | ||||
|  | ||||
| .beast { | ||||
|   background-color: #E5F2F2; | ||||
| } | ||||
|  | ||||
| .reset { | ||||
|   background-color: #FBFBC9; | ||||
| } | ||||
|  | ||||
| .reset:hover { | ||||
|   background-color: #EAEA9D; | ||||
| } | ||||
							
								
								
									
										7171
									
								
								Clipper/joplin-webclipper/popup/yarn.lock
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										7171
									
								
								Clipper/joplin-webclipper/popup/yarn.lock
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										534
									
								
								ElectronClient/app/package-lock.json
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										534
									
								
								ElectronClient/app/package-lock.json
									
									
									
										generated
									
									
									
								
							| @@ -48,6 +48,24 @@ | ||||
|       "integrity": "sha512-jjpyQsKGsOF/wUElNjfPULk+d8PKvJOIXk3IUeBYYmNCy5dMWfrI+JiixYNw8ppKOlcRwWTXFl0B+i5oGrf95Q==", | ||||
|       "dev": true | ||||
|     }, | ||||
|     "abab": { | ||||
|       "version": "1.0.4", | ||||
|       "resolved": "https://registry.npmjs.org/abab/-/abab-1.0.4.tgz", | ||||
|       "integrity": "sha1-X6rZwsB/YN12dw9xzwJbYqY8/U4=" | ||||
|     }, | ||||
|     "acorn": { | ||||
|       "version": "4.0.13", | ||||
|       "resolved": "https://registry.npmjs.org/acorn/-/acorn-4.0.13.tgz", | ||||
|       "integrity": "sha1-EFSVrlNh1pe9GVyCUZLhrX8lN4c=" | ||||
|     }, | ||||
|     "acorn-globals": { | ||||
|       "version": "3.1.0", | ||||
|       "resolved": "https://registry.npmjs.org/acorn-globals/-/acorn-globals-3.1.0.tgz", | ||||
|       "integrity": "sha1-/YJw9x+7SZawBPqIDuXUZXOnMb8=", | ||||
|       "requires": { | ||||
|         "acorn": "^4.0.4" | ||||
|       } | ||||
|     }, | ||||
|     "ajv": { | ||||
|       "version": "6.2.0", | ||||
|       "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.2.0.tgz", | ||||
| @@ -199,6 +217,11 @@ | ||||
|       "dev": true, | ||||
|       "optional": true | ||||
|     }, | ||||
|     "array-equal": { | ||||
|       "version": "1.0.0", | ||||
|       "resolved": "https://registry.npmjs.org/array-equal/-/array-equal-1.0.0.tgz", | ||||
|       "integrity": "sha1-jCpe8kcv2ep0KwTHenUJO6J1fJM=" | ||||
|     }, | ||||
|     "array-find-index": { | ||||
|       "version": "1.0.2", | ||||
|       "resolved": "https://registry.npmjs.org/array-find-index/-/array-find-index-1.0.2.tgz", | ||||
| @@ -220,14 +243,18 @@ | ||||
|     "asn1": { | ||||
|       "version": "0.2.3", | ||||
|       "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.3.tgz", | ||||
|       "integrity": "sha1-2sh4dxPJlmhJ/IGAd36+nB3fO4Y=", | ||||
|       "dev": true | ||||
|       "integrity": "sha1-2sh4dxPJlmhJ/IGAd36+nB3fO4Y=" | ||||
|     }, | ||||
|     "assert-plus": { | ||||
|       "version": "1.0.0", | ||||
|       "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", | ||||
|       "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=", | ||||
|       "dev": true | ||||
|       "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=" | ||||
|     }, | ||||
|     "async": { | ||||
|       "version": "0.9.2", | ||||
|       "resolved": "https://registry.npmjs.org/async/-/async-0.9.2.tgz", | ||||
|       "integrity": "sha1-rqdNXmHB+JlhO/ZL2mbUx48v0X0=", | ||||
|       "optional": true | ||||
|     }, | ||||
|     "async-each": { | ||||
|       "version": "1.0.1", | ||||
| @@ -255,14 +282,12 @@ | ||||
|     "aws-sign2": { | ||||
|       "version": "0.7.0", | ||||
|       "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", | ||||
|       "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=", | ||||
|       "dev": true | ||||
|       "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=" | ||||
|     }, | ||||
|     "aws4": { | ||||
|       "version": "1.6.0", | ||||
|       "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.6.0.tgz", | ||||
|       "integrity": "sha1-g+9cqGCysy5KDe7e6MdxudtXRx4=", | ||||
|       "dev": true | ||||
|       "integrity": "sha1-g+9cqGCysy5KDe7e6MdxudtXRx4=" | ||||
|     }, | ||||
|     "babel-cli": { | ||||
|       "version": "6.26.0", | ||||
| @@ -591,7 +616,6 @@ | ||||
|       "version": "1.0.1", | ||||
|       "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.1.tgz", | ||||
|       "integrity": "sha1-Y7xdy2EzG5K8Bf1SiVPDNGKgb40=", | ||||
|       "dev": true, | ||||
|       "optional": true, | ||||
|       "requires": { | ||||
|         "tweetnacl": "^0.14.3" | ||||
| @@ -623,7 +647,6 @@ | ||||
|       "version": "4.3.1", | ||||
|       "resolved": "https://registry.npmjs.org/boom/-/boom-4.3.1.tgz", | ||||
|       "integrity": "sha1-T4owBctKfjiJ90kDD9JbluAdLjE=", | ||||
|       "dev": true, | ||||
|       "requires": { | ||||
|         "hoek": "4.x.x" | ||||
|       } | ||||
| @@ -910,8 +933,7 @@ | ||||
|     "caseless": { | ||||
|       "version": "0.12.0", | ||||
|       "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", | ||||
|       "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=", | ||||
|       "dev": true | ||||
|       "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=" | ||||
|     }, | ||||
|     "chalk": { | ||||
|       "version": "1.1.3", | ||||
| @@ -1019,8 +1041,7 @@ | ||||
|     "co": { | ||||
|       "version": "4.6.0", | ||||
|       "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", | ||||
|       "integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ=", | ||||
|       "dev": true | ||||
|       "integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ=" | ||||
|     }, | ||||
|     "code-point-at": { | ||||
|       "version": "1.1.0", | ||||
| @@ -1098,6 +1119,11 @@ | ||||
|         "xdg-basedir": "^3.0.0" | ||||
|       } | ||||
|     }, | ||||
|     "content-type-parser": { | ||||
|       "version": "1.0.2", | ||||
|       "resolved": "https://registry.npmjs.org/content-type-parser/-/content-type-parser-1.0.2.tgz", | ||||
|       "integrity": "sha512-lM4l4CnMEwOLHAHr/P6MEZwZFPJFtAAKgL6pogbXmVZggIqXhdB6RbBtPOTsw2FcXwYhehRGERJmRrjOiIB8pQ==" | ||||
|     }, | ||||
|     "convert-source-map": { | ||||
|       "version": "1.5.0", | ||||
|       "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.5.0.tgz", | ||||
| @@ -1153,7 +1179,6 @@ | ||||
|       "version": "3.1.2", | ||||
|       "resolved": "https://registry.npmjs.org/cryptiles/-/cryptiles-3.1.2.tgz", | ||||
|       "integrity": "sha1-qJ+7Ig9c4l7FboxKqKT9e1sNKf4=", | ||||
|       "dev": true, | ||||
|       "requires": { | ||||
|         "boom": "5.x.x" | ||||
|       }, | ||||
| @@ -1162,7 +1187,6 @@ | ||||
|           "version": "5.2.0", | ||||
|           "resolved": "https://registry.npmjs.org/boom/-/boom-5.2.0.tgz", | ||||
|           "integrity": "sha512-Z5BTk6ZRe4tXXQlkqftmsAUANpXmuwlsF5Oov8ThoMbQRzdGTA1ngYRW160GexgOgjsFOKJz0LYhoNi+2AMBUw==", | ||||
|           "dev": true, | ||||
|           "requires": { | ||||
|             "hoek": "4.x.x" | ||||
|           } | ||||
| @@ -1175,6 +1199,25 @@ | ||||
|       "integrity": "sha1-ojD2T1aDEOFJgAmUB5DsmVRbyn4=", | ||||
|       "dev": true | ||||
|     }, | ||||
|     "cssom": { | ||||
|       "version": "0.3.2", | ||||
|       "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.3.2.tgz", | ||||
|       "integrity": "sha1-uANhcMefB6kP8vFuIihAJ6JDhIs=" | ||||
|     }, | ||||
|     "cssstyle": { | ||||
|       "version": "0.2.37", | ||||
|       "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-0.2.37.tgz", | ||||
|       "integrity": "sha1-VBCXI0yyUTyDzu06zdwn/yeYfVQ=", | ||||
|       "requires": { | ||||
|         "cssom": "0.3.x" | ||||
|       } | ||||
|     }, | ||||
|     "ctype": { | ||||
|       "version": "0.5.3", | ||||
|       "resolved": "https://registry.npmjs.org/ctype/-/ctype-0.5.3.tgz", | ||||
|       "integrity": "sha1-gsGMJGH3QRTvFsE1IkrQuRRMoS8=", | ||||
|       "optional": true | ||||
|     }, | ||||
|     "currently-unhandled": { | ||||
|       "version": "0.4.1", | ||||
|       "resolved": "https://registry.npmjs.org/currently-unhandled/-/currently-unhandled-0.4.1.tgz", | ||||
| @@ -1480,7 +1523,6 @@ | ||||
|       "version": "1.14.1", | ||||
|       "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", | ||||
|       "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=", | ||||
|       "dev": true, | ||||
|       "requires": { | ||||
|         "assert-plus": "^1.0.0" | ||||
|       } | ||||
| @@ -1745,7 +1787,6 @@ | ||||
|       "version": "0.1.1", | ||||
|       "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.1.tgz", | ||||
|       "integrity": "sha1-D8c6ntXw1Tw4GTOYUj735UN3dQU=", | ||||
|       "dev": true, | ||||
|       "optional": true, | ||||
|       "requires": { | ||||
|         "jsbn": "~0.1.0" | ||||
| @@ -2210,17 +2251,46 @@ | ||||
|       "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", | ||||
|       "dev": true | ||||
|     }, | ||||
|     "escodegen": { | ||||
|       "version": "1.9.1", | ||||
|       "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-1.9.1.tgz", | ||||
|       "integrity": "sha512-6hTjO1NAWkHnDk3OqQ4YrCuwwmGHL9S3nPlzBOUG/R44rda3wLNrfvQ5fkSGjyhHFKM7ALPKcKGrwvCLe0lC7Q==", | ||||
|       "requires": { | ||||
|         "esprima": "^3.1.3", | ||||
|         "estraverse": "^4.2.0", | ||||
|         "esutils": "^2.0.2", | ||||
|         "optionator": "^0.8.1", | ||||
|         "source-map": "~0.6.1" | ||||
|       }, | ||||
|       "dependencies": { | ||||
|         "esprima": { | ||||
|           "version": "3.1.3", | ||||
|           "resolved": "https://registry.npmjs.org/esprima/-/esprima-3.1.3.tgz", | ||||
|           "integrity": "sha1-/cpRzuYTOJXjyI1TXOSdv/YqRjM=" | ||||
|         }, | ||||
|         "source-map": { | ||||
|           "version": "0.6.1", | ||||
|           "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", | ||||
|           "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", | ||||
|           "optional": true | ||||
|         } | ||||
|       } | ||||
|     }, | ||||
|     "esprima": { | ||||
|       "version": "4.0.0", | ||||
|       "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.0.tgz", | ||||
|       "integrity": "sha512-oftTcaMu/EGrEIu904mWteKIv8vMuOgGYo7EhVJJN00R/EED9DCua/xxHRdYnKtcECzVg7xOWhflvJMnqcFZjw==", | ||||
|       "dev": true | ||||
|     }, | ||||
|     "estraverse": { | ||||
|       "version": "4.2.0", | ||||
|       "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.2.0.tgz", | ||||
|       "integrity": "sha1-De4/7TH81GlhjOc0IJn8GvoL2xM=" | ||||
|     }, | ||||
|     "esutils": { | ||||
|       "version": "2.0.2", | ||||
|       "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.2.tgz", | ||||
|       "integrity": "sha1-Cr9PHKpbyx96nYrMbepPqqBLrJs=", | ||||
|       "dev": true | ||||
|       "integrity": "sha1-Cr9PHKpbyx96nYrMbepPqqBLrJs=" | ||||
|     }, | ||||
|     "execa": { | ||||
|       "version": "0.7.0", | ||||
| @@ -2277,8 +2347,7 @@ | ||||
|     "extend": { | ||||
|       "version": "3.0.1", | ||||
|       "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.1.tgz", | ||||
|       "integrity": "sha1-p1Xqe8Gt/MWjHOfnYtuq3F5jZEQ=", | ||||
|       "dev": true | ||||
|       "integrity": "sha1-p1Xqe8Gt/MWjHOfnYtuq3F5jZEQ=" | ||||
|     }, | ||||
|     "extglob": { | ||||
|       "version": "0.3.2", | ||||
| @@ -2316,20 +2385,22 @@ | ||||
|     "extsprintf": { | ||||
|       "version": "1.3.0", | ||||
|       "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", | ||||
|       "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=", | ||||
|       "dev": true | ||||
|       "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=" | ||||
|     }, | ||||
|     "fast-deep-equal": { | ||||
|       "version": "1.0.0", | ||||
|       "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-1.0.0.tgz", | ||||
|       "integrity": "sha1-liVqO8l1WV6zbYLpkp0GDYk0Of8=", | ||||
|       "dev": true | ||||
|       "integrity": "sha1-liVqO8l1WV6zbYLpkp0GDYk0Of8=" | ||||
|     }, | ||||
|     "fast-json-stable-stringify": { | ||||
|       "version": "2.0.0", | ||||
|       "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz", | ||||
|       "integrity": "sha1-1RQsDK7msRifh9OnYREGT4bIu/I=", | ||||
|       "dev": true | ||||
|       "integrity": "sha1-1RQsDK7msRifh9OnYREGT4bIu/I=" | ||||
|     }, | ||||
|     "fast-levenshtein": { | ||||
|       "version": "2.0.6", | ||||
|       "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", | ||||
|       "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=" | ||||
|     }, | ||||
|     "fbjs": { | ||||
|       "version": "0.8.16", | ||||
| @@ -2434,8 +2505,7 @@ | ||||
|     "forever-agent": { | ||||
|       "version": "0.6.1", | ||||
|       "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", | ||||
|       "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=", | ||||
|       "dev": true | ||||
|       "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=" | ||||
|     }, | ||||
|     "form-data": { | ||||
|       "version": "2.3.1", | ||||
| @@ -2584,7 +2654,7 @@ | ||||
|           "bundled": true, | ||||
|           "dev": true, | ||||
|           "requires": { | ||||
|             "inherits": "2.0.3" | ||||
|             "inherits": "~2.0.0" | ||||
|           } | ||||
|         }, | ||||
|         "boom": { | ||||
| @@ -2592,7 +2662,7 @@ | ||||
|           "bundled": true, | ||||
|           "dev": true, | ||||
|           "requires": { | ||||
|             "hoek": "2.16.3" | ||||
|             "hoek": "2.x.x" | ||||
|           } | ||||
|         }, | ||||
|         "brace-expansion": { | ||||
| @@ -2600,14 +2670,15 @@ | ||||
|           "bundled": true, | ||||
|           "dev": true, | ||||
|           "requires": { | ||||
|             "balanced-match": "0.4.2", | ||||
|             "balanced-match": "^0.4.1", | ||||
|             "concat-map": "0.0.1" | ||||
|           } | ||||
|         }, | ||||
|         "buffer-shims": { | ||||
|           "version": "1.0.0", | ||||
|           "bundled": true, | ||||
|           "dev": true | ||||
|           "dev": true, | ||||
|           "optional": true | ||||
|         }, | ||||
|         "caseless": { | ||||
|           "version": "0.12.0", | ||||
| @@ -2624,14 +2695,16 @@ | ||||
|         "code-point-at": { | ||||
|           "version": "1.1.0", | ||||
|           "bundled": true, | ||||
|           "dev": true | ||||
|           "dev": true, | ||||
|           "optional": true | ||||
|         }, | ||||
|         "combined-stream": { | ||||
|           "version": "1.0.5", | ||||
|           "bundled": true, | ||||
|           "dev": true, | ||||
|           "optional": true, | ||||
|           "requires": { | ||||
|             "delayed-stream": "1.0.0" | ||||
|             "delayed-stream": "~1.0.0" | ||||
|           } | ||||
|         }, | ||||
|         "concat-map": { | ||||
| @@ -2642,19 +2715,21 @@ | ||||
|         "console-control-strings": { | ||||
|           "version": "1.1.0", | ||||
|           "bundled": true, | ||||
|           "dev": true | ||||
|           "dev": true, | ||||
|           "optional": true | ||||
|         }, | ||||
|         "core-util-is": { | ||||
|           "version": "1.0.2", | ||||
|           "bundled": true, | ||||
|           "dev": true | ||||
|           "dev": true, | ||||
|           "optional": true | ||||
|         }, | ||||
|         "cryptiles": { | ||||
|           "version": "2.0.5", | ||||
|           "bundled": true, | ||||
|           "dev": true, | ||||
|           "requires": { | ||||
|             "boom": "2.10.1" | ||||
|             "boom": "2.x.x" | ||||
|           } | ||||
|         }, | ||||
|         "dashdash": { | ||||
| @@ -2663,7 +2738,7 @@ | ||||
|           "dev": true, | ||||
|           "optional": true, | ||||
|           "requires": { | ||||
|             "assert-plus": "1.0.0" | ||||
|             "assert-plus": "^1.0.0" | ||||
|           }, | ||||
|           "dependencies": { | ||||
|             "assert-plus": { | ||||
| @@ -2692,7 +2767,8 @@ | ||||
|         "delayed-stream": { | ||||
|           "version": "1.0.0", | ||||
|           "bundled": true, | ||||
|           "dev": true | ||||
|           "dev": true, | ||||
|           "optional": true | ||||
|         }, | ||||
|         "delegates": { | ||||
|           "version": "1.0.0", | ||||
| @@ -2712,7 +2788,7 @@ | ||||
|           "dev": true, | ||||
|           "optional": true, | ||||
|           "requires": { | ||||
|             "jsbn": "0.1.1" | ||||
|             "jsbn": "~0.1.0" | ||||
|           } | ||||
|         }, | ||||
|         "extend": { | ||||
| @@ -2724,7 +2800,8 @@ | ||||
|         "extsprintf": { | ||||
|           "version": "1.0.2", | ||||
|           "bundled": true, | ||||
|           "dev": true | ||||
|           "dev": true, | ||||
|           "optional": true | ||||
|         }, | ||||
|         "forever-agent": { | ||||
|           "version": "0.6.1", | ||||
| @@ -2792,7 +2869,7 @@ | ||||
|           "dev": true, | ||||
|           "optional": true, | ||||
|           "requires": { | ||||
|             "assert-plus": "1.0.0" | ||||
|             "assert-plus": "^1.0.0" | ||||
|           }, | ||||
|           "dependencies": { | ||||
|             "assert-plus": { | ||||
| @@ -2907,7 +2984,8 @@ | ||||
|         "isarray": { | ||||
|           "version": "1.0.0", | ||||
|           "bundled": true, | ||||
|           "dev": true | ||||
|           "dev": true, | ||||
|           "optional": true | ||||
|         }, | ||||
|         "isstream": { | ||||
|           "version": "0.1.2", | ||||
| @@ -2921,7 +2999,7 @@ | ||||
|           "dev": true, | ||||
|           "optional": true, | ||||
|           "requires": { | ||||
|             "jsbn": "0.1.1" | ||||
|             "jsbn": "~0.1.0" | ||||
|           } | ||||
|         }, | ||||
|         "jsbn": { | ||||
| @@ -3418,7 +3496,6 @@ | ||||
|       "version": "0.1.7", | ||||
|       "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", | ||||
|       "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=", | ||||
|       "dev": true, | ||||
|       "requires": { | ||||
|         "assert-plus": "^1.0.0" | ||||
|       } | ||||
| @@ -3527,14 +3604,12 @@ | ||||
|     "har-schema": { | ||||
|       "version": "2.0.0", | ||||
|       "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", | ||||
|       "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=", | ||||
|       "dev": true | ||||
|       "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=" | ||||
|     }, | ||||
|     "har-validator": { | ||||
|       "version": "5.0.3", | ||||
|       "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.0.3.tgz", | ||||
|       "integrity": "sha1-ukAsJmGU8VlW7xXg/PJCmT9qff0=", | ||||
|       "dev": true, | ||||
|       "requires": { | ||||
|         "ajv": "^5.1.0", | ||||
|         "har-schema": "^2.0.0" | ||||
| @@ -3544,7 +3619,6 @@ | ||||
|           "version": "5.5.2", | ||||
|           "resolved": "https://registry.npmjs.org/ajv/-/ajv-5.5.2.tgz", | ||||
|           "integrity": "sha1-c7Xuyj+rZT49P5Qis0GtQiBdyWU=", | ||||
|           "dev": true, | ||||
|           "requires": { | ||||
|             "co": "^4.6.0", | ||||
|             "fast-deep-equal": "^1.0.0", | ||||
| @@ -3573,7 +3647,6 @@ | ||||
|       "version": "6.0.2", | ||||
|       "resolved": "https://registry.npmjs.org/hawk/-/hawk-6.0.2.tgz", | ||||
|       "integrity": "sha512-miowhl2+U7Qle4vdLqDdPt9m09K6yZhkLDTWGoUiUzrQCn+mHHSmfJgAyGaLRZbPmTqfFFjRV1QWCW0VWUJBbQ==", | ||||
|       "dev": true, | ||||
|       "requires": { | ||||
|         "boom": "4.x.x", | ||||
|         "cryptiles": "3.x.x", | ||||
| @@ -3594,8 +3667,7 @@ | ||||
|     "hoek": { | ||||
|       "version": "4.2.0", | ||||
|       "resolved": "https://registry.npmjs.org/hoek/-/hoek-4.2.0.tgz", | ||||
|       "integrity": "sha512-v0XCLxICi9nPfYrS9RL8HbYnXi9obYAeLbSP00BmnZwCK9+Ih9WOjoZ8YoHCoav2csqn4FOz4Orldsy2dmDwmQ==", | ||||
|       "dev": true | ||||
|       "integrity": "sha512-v0XCLxICi9nPfYrS9RL8HbYnXi9obYAeLbSP00BmnZwCK9+Ih9WOjoZ8YoHCoav2csqn4FOz4Orldsy2dmDwmQ==" | ||||
|     }, | ||||
|     "hoist-non-react-statics": { | ||||
|       "version": "2.3.1", | ||||
| @@ -3624,6 +3696,14 @@ | ||||
|       "integrity": "sha512-pNgbURSuab90KbTqvRPsseaTxOJCZBD0a7t+haSN33piP9cCM4l0CqdzAif2hUqm716UovKB2ROmiabGAKVXyg==", | ||||
|       "dev": true | ||||
|     }, | ||||
|     "html-encoding-sniffer": { | ||||
|       "version": "1.0.2", | ||||
|       "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-1.0.2.tgz", | ||||
|       "integrity": "sha512-71lZziiDnsuabfdYiUeWdCVyKuqwWi23L8YeIgV9jSSZHCtb6wB1BKWooH7L3tn4/FuZJMVWyNaIDr4RGmaSYw==", | ||||
|       "requires": { | ||||
|         "whatwg-encoding": "^1.0.1" | ||||
|       } | ||||
|     }, | ||||
|     "html-entities": { | ||||
|       "version": "1.2.1", | ||||
|       "resolved": "https://registry.npmjs.org/html-entities/-/html-entities-1.2.1.tgz", | ||||
| @@ -3633,7 +3713,6 @@ | ||||
|       "version": "1.2.0", | ||||
|       "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", | ||||
|       "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=", | ||||
|       "dev": true, | ||||
|       "requires": { | ||||
|         "assert-plus": "^1.0.0", | ||||
|         "jsprim": "^1.2.2", | ||||
| @@ -3871,8 +3950,7 @@ | ||||
|     "is-typedarray": { | ||||
|       "version": "1.0.0", | ||||
|       "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", | ||||
|       "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=", | ||||
|       "dev": true | ||||
|       "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=" | ||||
|     }, | ||||
|     "is-utf8": { | ||||
|       "version": "0.2.1", | ||||
| @@ -3926,8 +4004,7 @@ | ||||
|     "isstream": { | ||||
|       "version": "0.1.2", | ||||
|       "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", | ||||
|       "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=", | ||||
|       "dev": true | ||||
|       "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=" | ||||
|     }, | ||||
|     "js-tokens": { | ||||
|       "version": "3.0.2", | ||||
| @@ -3948,9 +4025,34 @@ | ||||
|       "version": "0.1.1", | ||||
|       "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", | ||||
|       "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=", | ||||
|       "dev": true, | ||||
|       "optional": true | ||||
|     }, | ||||
|     "jsdom": { | ||||
|       "version": "9.12.0", | ||||
|       "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-9.12.0.tgz", | ||||
|       "integrity": "sha1-6MVG//ywbADUgzyoRBD+1/igl9Q=", | ||||
|       "requires": { | ||||
|         "abab": "^1.0.3", | ||||
|         "acorn": "^4.0.4", | ||||
|         "acorn-globals": "^3.1.0", | ||||
|         "array-equal": "^1.0.0", | ||||
|         "content-type-parser": "^1.0.1", | ||||
|         "cssom": ">= 0.3.2 < 0.4.0", | ||||
|         "cssstyle": ">= 0.2.37 < 0.3.0", | ||||
|         "escodegen": "^1.6.1", | ||||
|         "html-encoding-sniffer": "^1.0.1", | ||||
|         "nwmatcher": ">= 1.3.9 < 2.0.0", | ||||
|         "parse5": "^1.5.1", | ||||
|         "request": "^2.79.0", | ||||
|         "sax": "^1.2.1", | ||||
|         "symbol-tree": "^3.2.1", | ||||
|         "tough-cookie": "^2.3.2", | ||||
|         "webidl-conversions": "^4.0.0", | ||||
|         "whatwg-encoding": "^1.0.1", | ||||
|         "whatwg-url": "^4.3.0", | ||||
|         "xml-name-validator": "^2.0.1" | ||||
|       } | ||||
|     }, | ||||
|     "jsesc": { | ||||
|       "version": "1.3.0", | ||||
|       "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-1.3.0.tgz", | ||||
| @@ -3960,20 +4062,17 @@ | ||||
|     "json-schema": { | ||||
|       "version": "0.2.3", | ||||
|       "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz", | ||||
|       "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=", | ||||
|       "dev": true | ||||
|       "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=" | ||||
|     }, | ||||
|     "json-schema-traverse": { | ||||
|       "version": "0.3.1", | ||||
|       "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.3.1.tgz", | ||||
|       "integrity": "sha1-NJptRMU6Ud6JtAgFxdXlm0F9M0A=", | ||||
|       "dev": true | ||||
|       "integrity": "sha1-NJptRMU6Ud6JtAgFxdXlm0F9M0A=" | ||||
|     }, | ||||
|     "json-stringify-safe": { | ||||
|       "version": "5.0.1", | ||||
|       "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", | ||||
|       "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=", | ||||
|       "dev": true | ||||
|       "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=" | ||||
|     }, | ||||
|     "json5": { | ||||
|       "version": "0.5.1", | ||||
| @@ -3993,7 +4092,6 @@ | ||||
|       "version": "1.4.1", | ||||
|       "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz", | ||||
|       "integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=", | ||||
|       "dev": true, | ||||
|       "requires": { | ||||
|         "assert-plus": "1.0.0", | ||||
|         "extsprintf": "1.3.0", | ||||
| @@ -4061,6 +4159,15 @@ | ||||
|       "resolved": "https://registry.npmjs.org/levenshtein/-/levenshtein-1.0.5.tgz", | ||||
|       "integrity": "sha1-ORFzepy1baNF0Aj1V4LG8TiXm6M=" | ||||
|     }, | ||||
|     "levn": { | ||||
|       "version": "0.3.0", | ||||
|       "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", | ||||
|       "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=", | ||||
|       "requires": { | ||||
|         "prelude-ls": "~1.1.2", | ||||
|         "type-check": "~0.3.2" | ||||
|       } | ||||
|     }, | ||||
|     "linkify-it": { | ||||
|       "version": "2.0.3", | ||||
|       "resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-2.0.3.tgz", | ||||
| @@ -4425,6 +4532,180 @@ | ||||
|         "which": "^1.2.12" | ||||
|       } | ||||
|     }, | ||||
|     "node-readability": { | ||||
|       "version": "3.0.0", | ||||
|       "resolved": "https://registry.npmjs.org/node-readability/-/node-readability-3.0.0.tgz", | ||||
|       "integrity": "sha512-PzvPq/AVWJB6gO3jzeL2X3unreALzIVQFnkdjrNjSFUdoUhnKn7EsZ+kkDlb2wV2Amwjx+a78mFWZwKQfrOreg==", | ||||
|       "requires": { | ||||
|         "encoding": "~0.1.7", | ||||
|         "jsdom": "^9.12.0", | ||||
|         "minimist": "^1.2.0", | ||||
|         "request": "~2.40.0" | ||||
|       }, | ||||
|       "dependencies": { | ||||
|         "asn1": { | ||||
|           "version": "0.1.11", | ||||
|           "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.1.11.tgz", | ||||
|           "integrity": "sha1-VZvhg3bQik7E2+gId9J4GGObLfc=", | ||||
|           "optional": true | ||||
|         }, | ||||
|         "assert-plus": { | ||||
|           "version": "0.1.5", | ||||
|           "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-0.1.5.tgz", | ||||
|           "integrity": "sha1-7nQAlBMALYTOxyGcasgRgS5yMWA=", | ||||
|           "optional": true | ||||
|         }, | ||||
|         "aws-sign2": { | ||||
|           "version": "0.5.0", | ||||
|           "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.5.0.tgz", | ||||
|           "integrity": "sha1-xXED96F/wDfwLXwuZLYC6iI/fWM=", | ||||
|           "optional": true | ||||
|         }, | ||||
|         "boom": { | ||||
|           "version": "0.4.2", | ||||
|           "resolved": "https://registry.npmjs.org/boom/-/boom-0.4.2.tgz", | ||||
|           "integrity": "sha1-emNune1O/O+xnO9JR6PGffrukRs=", | ||||
|           "requires": { | ||||
|             "hoek": "0.9.x" | ||||
|           } | ||||
|         }, | ||||
|         "combined-stream": { | ||||
|           "version": "0.0.7", | ||||
|           "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-0.0.7.tgz", | ||||
|           "integrity": "sha1-ATfmV7qlp1QcV6w3rF/AfXO03B8=", | ||||
|           "optional": true, | ||||
|           "requires": { | ||||
|             "delayed-stream": "0.0.5" | ||||
|           } | ||||
|         }, | ||||
|         "cryptiles": { | ||||
|           "version": "0.2.2", | ||||
|           "resolved": "https://registry.npmjs.org/cryptiles/-/cryptiles-0.2.2.tgz", | ||||
|           "integrity": "sha1-7ZH/HxetE9N0gohZT4pIoNJvMlw=", | ||||
|           "optional": true, | ||||
|           "requires": { | ||||
|             "boom": "0.4.x" | ||||
|           } | ||||
|         }, | ||||
|         "delayed-stream": { | ||||
|           "version": "0.0.5", | ||||
|           "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-0.0.5.tgz", | ||||
|           "integrity": "sha1-1LH0OpPoKW3+AmlPRoC8N6MTxz8=", | ||||
|           "optional": true | ||||
|         }, | ||||
|         "forever-agent": { | ||||
|           "version": "0.5.2", | ||||
|           "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.5.2.tgz", | ||||
|           "integrity": "sha1-bQ4JxJIflKJ/Y9O0nF/v8epMUTA=" | ||||
|         }, | ||||
|         "form-data": { | ||||
|           "version": "0.1.4", | ||||
|           "resolved": "https://registry.npmjs.org/form-data/-/form-data-0.1.4.tgz", | ||||
|           "integrity": "sha1-kavXiKupcCsaq/qLwBAxoqyeOxI=", | ||||
|           "optional": true, | ||||
|           "requires": { | ||||
|             "async": "~0.9.0", | ||||
|             "combined-stream": "~0.0.4", | ||||
|             "mime": "~1.2.11" | ||||
|           } | ||||
|         }, | ||||
|         "hawk": { | ||||
|           "version": "1.1.1", | ||||
|           "resolved": "https://registry.npmjs.org/hawk/-/hawk-1.1.1.tgz", | ||||
|           "integrity": "sha1-h81JH5tG5OKurKM1QWdmiF0tHtk=", | ||||
|           "optional": true, | ||||
|           "requires": { | ||||
|             "boom": "0.4.x", | ||||
|             "cryptiles": "0.2.x", | ||||
|             "hoek": "0.9.x", | ||||
|             "sntp": "0.2.x" | ||||
|           } | ||||
|         }, | ||||
|         "hoek": { | ||||
|           "version": "0.9.1", | ||||
|           "resolved": "https://registry.npmjs.org/hoek/-/hoek-0.9.1.tgz", | ||||
|           "integrity": "sha1-PTIkYrrfB3Fup+uFuviAec3c5QU=" | ||||
|         }, | ||||
|         "http-signature": { | ||||
|           "version": "0.10.1", | ||||
|           "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-0.10.1.tgz", | ||||
|           "integrity": "sha1-T72sEyVZqoMjEh5UB3nAoBKyfmY=", | ||||
|           "optional": true, | ||||
|           "requires": { | ||||
|             "asn1": "0.1.11", | ||||
|             "assert-plus": "^0.1.5", | ||||
|             "ctype": "0.5.3" | ||||
|           } | ||||
|         }, | ||||
|         "mime": { | ||||
|           "version": "1.2.11", | ||||
|           "resolved": "https://registry.npmjs.org/mime/-/mime-1.2.11.tgz", | ||||
|           "integrity": "sha1-WCA+7Ybjpe8XrtK32evUfwpg3RA=", | ||||
|           "optional": true | ||||
|         }, | ||||
|         "mime-types": { | ||||
|           "version": "1.0.2", | ||||
|           "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-1.0.2.tgz", | ||||
|           "integrity": "sha1-mVrhOSq4r/y/yyZB3QVOlDwNXc4=" | ||||
|         }, | ||||
|         "minimist": { | ||||
|           "version": "1.2.0", | ||||
|           "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", | ||||
|           "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=" | ||||
|         }, | ||||
|         "node-uuid": { | ||||
|           "version": "1.4.8", | ||||
|           "resolved": "https://registry.npmjs.org/node-uuid/-/node-uuid-1.4.8.tgz", | ||||
|           "integrity": "sha1-sEDrCSOWivq/jTL7HxfxFn/auQc=" | ||||
|         }, | ||||
|         "oauth-sign": { | ||||
|           "version": "0.3.0", | ||||
|           "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.3.0.tgz", | ||||
|           "integrity": "sha1-y1QPk7srIqfVlBaRoojWDo6pOG4=", | ||||
|           "optional": true | ||||
|         }, | ||||
|         "qs": { | ||||
|           "version": "1.0.2", | ||||
|           "resolved": "https://registry.npmjs.org/qs/-/qs-1.0.2.tgz", | ||||
|           "integrity": "sha1-UKk+K1r2aRwxvOpdrnjubqGQN2g=" | ||||
|         }, | ||||
|         "request": { | ||||
|           "version": "2.40.0", | ||||
|           "resolved": "https://registry.npmjs.org/request/-/request-2.40.0.tgz", | ||||
|           "integrity": "sha1-TdZw9pbx5uhC5mtLXoOTAaub62c=", | ||||
|           "requires": { | ||||
|             "aws-sign2": "~0.5.0", | ||||
|             "forever-agent": "~0.5.0", | ||||
|             "form-data": "~0.1.0", | ||||
|             "hawk": "1.1.1", | ||||
|             "http-signature": "~0.10.0", | ||||
|             "json-stringify-safe": "~5.0.0", | ||||
|             "mime-types": "~1.0.1", | ||||
|             "node-uuid": "~1.4.0", | ||||
|             "oauth-sign": "~0.3.0", | ||||
|             "qs": "~1.0.0", | ||||
|             "stringstream": "~0.0.4", | ||||
|             "tough-cookie": ">=0.12.0", | ||||
|             "tunnel-agent": "~0.4.0" | ||||
|           } | ||||
|         }, | ||||
|         "sntp": { | ||||
|           "version": "0.2.4", | ||||
|           "resolved": "https://registry.npmjs.org/sntp/-/sntp-0.2.4.tgz", | ||||
|           "integrity": "sha1-+4hfGLDzqtGJ+CSGJTa87ux1CQA=", | ||||
|           "optional": true, | ||||
|           "requires": { | ||||
|             "hoek": "0.9.x" | ||||
|           } | ||||
|         }, | ||||
|         "tunnel-agent": { | ||||
|           "version": "0.4.3", | ||||
|           "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.4.3.tgz", | ||||
|           "integrity": "sha1-Y3PbdpCf5XDgjXNYM2Xtgop07us=", | ||||
|           "optional": true | ||||
|         } | ||||
|       } | ||||
|     }, | ||||
|     "normalize-package-data": { | ||||
|       "version": "2.4.0", | ||||
|       "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.4.0.tgz", | ||||
| @@ -4484,11 +4765,15 @@ | ||||
|       "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=", | ||||
|       "dev": true | ||||
|     }, | ||||
|     "nwmatcher": { | ||||
|       "version": "1.4.4", | ||||
|       "resolved": "https://registry.npmjs.org/nwmatcher/-/nwmatcher-1.4.4.tgz", | ||||
|       "integrity": "sha512-3iuY4N5dhgMpCUrOVnuAdGrgxVqV2cJpM+XNccjR2DKOB1RUP0aA+wGXEiNziG/UKboFyGBIoKOaNlJxx8bciQ==" | ||||
|     }, | ||||
|     "oauth-sign": { | ||||
|       "version": "0.8.2", | ||||
|       "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.8.2.tgz", | ||||
|       "integrity": "sha1-Rqarfwrq2N6unsBWV4C31O/rnUM=", | ||||
|       "dev": true | ||||
|       "integrity": "sha1-Rqarfwrq2N6unsBWV4C31O/rnUM=" | ||||
|     }, | ||||
|     "object-assign": { | ||||
|       "version": "4.1.1", | ||||
| @@ -4521,6 +4806,26 @@ | ||||
|         "wrappy": "1" | ||||
|       } | ||||
|     }, | ||||
|     "optionator": { | ||||
|       "version": "0.8.2", | ||||
|       "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.2.tgz", | ||||
|       "integrity": "sha1-NkxeQJ0/TWMB1sC0wFu6UBgK62Q=", | ||||
|       "requires": { | ||||
|         "deep-is": "~0.1.3", | ||||
|         "fast-levenshtein": "~2.0.4", | ||||
|         "levn": "~0.3.0", | ||||
|         "prelude-ls": "~1.1.2", | ||||
|         "type-check": "~0.3.2", | ||||
|         "wordwrap": "~1.0.0" | ||||
|       }, | ||||
|       "dependencies": { | ||||
|         "deep-is": { | ||||
|           "version": "0.1.3", | ||||
|           "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz", | ||||
|           "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=" | ||||
|         } | ||||
|       } | ||||
|     }, | ||||
|     "os-homedir": { | ||||
|       "version": "1.0.2", | ||||
|       "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz", | ||||
| @@ -4636,6 +4941,11 @@ | ||||
|         "error-ex": "^1.2.0" | ||||
|       } | ||||
|     }, | ||||
|     "parse5": { | ||||
|       "version": "1.5.1", | ||||
|       "resolved": "https://registry.npmjs.org/parse5/-/parse5-1.5.1.tgz", | ||||
|       "integrity": "sha1-m387DeMr543CQBsXVzzK8Pb1nZQ=" | ||||
|     }, | ||||
|     "path-exists": { | ||||
|       "version": "3.0.0", | ||||
|       "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", | ||||
| @@ -4687,8 +4997,7 @@ | ||||
|     "performance-now": { | ||||
|       "version": "2.1.0", | ||||
|       "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", | ||||
|       "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=", | ||||
|       "dev": true | ||||
|       "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=" | ||||
|     }, | ||||
|     "pify": { | ||||
|       "version": "3.0.0", | ||||
| @@ -4736,6 +5045,11 @@ | ||||
|         } | ||||
|       } | ||||
|     }, | ||||
|     "prelude-ls": { | ||||
|       "version": "1.1.2", | ||||
|       "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", | ||||
|       "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=" | ||||
|     }, | ||||
|     "prepend-http": { | ||||
|       "version": "1.0.4", | ||||
|       "resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-1.0.4.tgz", | ||||
| @@ -4807,8 +5121,7 @@ | ||||
|     "punycode": { | ||||
|       "version": "1.4.1", | ||||
|       "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", | ||||
|       "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=", | ||||
|       "dev": true | ||||
|       "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=" | ||||
|     }, | ||||
|     "pupa": { | ||||
|       "version": "1.0.0", | ||||
| @@ -4823,8 +5136,7 @@ | ||||
|     "qs": { | ||||
|       "version": "6.5.1", | ||||
|       "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.1.tgz", | ||||
|       "integrity": "sha512-eRzhrN1WSINYCDCbrz796z37LOe3m5tmW7RQf6oBntukAG1nmovJvhnwHHRMAfeoItc1m2Hk02WER2aQ/iqs+A==", | ||||
|       "dev": true | ||||
|       "integrity": "sha512-eRzhrN1WSINYCDCbrz796z37LOe3m5tmW7RQf6oBntukAG1nmovJvhnwHHRMAfeoItc1m2Hk02WER2aQ/iqs+A==" | ||||
|     }, | ||||
|     "query-string": { | ||||
|       "version": "5.0.1", | ||||
| @@ -5013,6 +5325,11 @@ | ||||
|         "read-pkg": "^1.0.0" | ||||
|       } | ||||
|     }, | ||||
|     "readability-node": { | ||||
|       "version": "0.1.0", | ||||
|       "resolved": "https://registry.npmjs.org/readability-node/-/readability-node-0.1.0.tgz", | ||||
|       "integrity": "sha1-DUBacMLCFZRKf0qbX3UGzQWpsao=" | ||||
|     }, | ||||
|     "readable-stream": { | ||||
|       "version": "2.3.3", | ||||
|       "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.3.tgz", | ||||
| @@ -5128,7 +5445,6 @@ | ||||
|       "version": "2.83.0", | ||||
|       "resolved": "https://registry.npmjs.org/request/-/request-2.83.0.tgz", | ||||
|       "integrity": "sha512-lR3gD69osqm6EYLk9wB/G1W/laGWjzH90t1vEa2xuxHD5KUrSzp9pUSfTm+YC5Nxt2T8nMPEvKlhbQayU7bgFw==", | ||||
|       "dev": true, | ||||
|       "requires": { | ||||
|         "aws-sign2": "~0.7.0", | ||||
|         "aws4": "^1.6.0", | ||||
| @@ -5302,7 +5618,6 @@ | ||||
|       "version": "2.1.0", | ||||
|       "resolved": "https://registry.npmjs.org/sntp/-/sntp-2.1.0.tgz", | ||||
|       "integrity": "sha512-FL1b58BDrqS3A11lJ0zEdnJ3UOKqVxawAkF3k7F0CVN7VQ34aZrV+G8BZ1WC9ZL7NyrwsW0oviwsWDgRuVYtJg==", | ||||
|       "dev": true, | ||||
|       "requires": { | ||||
|         "hoek": "4.x.x" | ||||
|       } | ||||
| @@ -6086,7 +6401,6 @@ | ||||
|       "version": "1.13.1", | ||||
|       "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.13.1.tgz", | ||||
|       "integrity": "sha1-US322mKHFEMW3EwY/hzx2UBzm+M=", | ||||
|       "dev": true, | ||||
|       "requires": { | ||||
|         "asn1": "~0.2.3", | ||||
|         "assert-plus": "^1.0.0", | ||||
| @@ -6145,8 +6459,7 @@ | ||||
|     "stringstream": { | ||||
|       "version": "0.0.5", | ||||
|       "resolved": "https://registry.npmjs.org/stringstream/-/stringstream-0.0.5.tgz", | ||||
|       "integrity": "sha1-TkhM1N5aC7vuGORjB3EKioFiGHg=", | ||||
|       "dev": true | ||||
|       "integrity": "sha1-TkhM1N5aC7vuGORjB3EKioFiGHg=" | ||||
|     }, | ||||
|     "strip-ansi": { | ||||
|       "version": "3.0.1", | ||||
| @@ -6208,6 +6521,11 @@ | ||||
|       "resolved": "https://registry.npmjs.org/symbol-observable/-/symbol-observable-1.0.4.tgz", | ||||
|       "integrity": "sha1-Kb9hXUqnEhvdiYsi1LP5vE4qoD0=" | ||||
|     }, | ||||
|     "symbol-tree": { | ||||
|       "version": "3.2.2", | ||||
|       "resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.2.tgz", | ||||
|       "integrity": "sha1-rifbOPZgp64uHDt9G8KQgZuFGeY=" | ||||
|     }, | ||||
|     "tar": { | ||||
|       "version": "4.4.0", | ||||
|       "resolved": "https://registry.npmjs.org/tar/-/tar-4.4.0.tgz", | ||||
| @@ -6317,11 +6635,15 @@ | ||||
|       "version": "2.3.3", | ||||
|       "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.3.3.tgz", | ||||
|       "integrity": "sha1-C2GKVWW23qkL80JdBNVe3EdadWE=", | ||||
|       "dev": true, | ||||
|       "requires": { | ||||
|         "punycode": "^1.4.1" | ||||
|       } | ||||
|     }, | ||||
|     "tr46": { | ||||
|       "version": "0.0.3", | ||||
|       "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", | ||||
|       "integrity": "sha1-gYT9NH2snNwYWZLzpmIuFLnZq2o=" | ||||
|     }, | ||||
|     "trim-newlines": { | ||||
|       "version": "1.0.0", | ||||
|       "resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-1.0.0.tgz", | ||||
| @@ -6347,7 +6669,6 @@ | ||||
|       "version": "0.6.0", | ||||
|       "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", | ||||
|       "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", | ||||
|       "dev": true, | ||||
|       "requires": { | ||||
|         "safe-buffer": "^5.0.1" | ||||
|       } | ||||
| @@ -6356,9 +6677,16 @@ | ||||
|       "version": "0.14.5", | ||||
|       "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", | ||||
|       "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=", | ||||
|       "dev": true, | ||||
|       "optional": true | ||||
|     }, | ||||
|     "type-check": { | ||||
|       "version": "0.3.2", | ||||
|       "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", | ||||
|       "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=", | ||||
|       "requires": { | ||||
|         "prelude-ls": "~1.1.2" | ||||
|       } | ||||
|     }, | ||||
|     "typedarray": { | ||||
|       "version": "0.0.6", | ||||
|       "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", | ||||
| @@ -6515,7 +6843,6 @@ | ||||
|       "version": "1.10.0", | ||||
|       "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", | ||||
|       "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=", | ||||
|       "dev": true, | ||||
|       "requires": { | ||||
|         "assert-plus": "^1.0.0", | ||||
|         "core-util-is": "1.0.2", | ||||
| @@ -6527,11 +6854,40 @@ | ||||
|       "resolved": "https://registry.npmjs.org/w3c-blob/-/w3c-blob-0.0.1.tgz", | ||||
|       "integrity": "sha1-sM01KhpQ9RVWNCD/1YYflQ8dhbg=" | ||||
|     }, | ||||
|     "webidl-conversions": { | ||||
|       "version": "4.0.2", | ||||
|       "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-4.0.2.tgz", | ||||
|       "integrity": "sha512-YQ+BmxuTgd6UXZW3+ICGfyqRyHXVlD5GtQr5+qjiNW7bF0cqrzX500HVXPBOvgXb5YnzDd+h0zqyv61KUD7+Sg==" | ||||
|     }, | ||||
|     "whatwg-encoding": { | ||||
|       "version": "1.0.3", | ||||
|       "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-1.0.3.tgz", | ||||
|       "integrity": "sha512-jLBwwKUhi8WtBfsMQlL4bUUcT8sMkAtQinscJAe/M4KHCkHuUJAF6vuB0tueNIw4c8ziO6AkRmgY+jL3a0iiPw==", | ||||
|       "requires": { | ||||
|         "iconv-lite": "0.4.19" | ||||
|       } | ||||
|     }, | ||||
|     "whatwg-fetch": { | ||||
|       "version": "2.0.3", | ||||
|       "resolved": "https://registry.npmjs.org/whatwg-fetch/-/whatwg-fetch-2.0.3.tgz", | ||||
|       "integrity": "sha1-nITsLc9oGH/wC8ZOEnS0QhduHIQ=" | ||||
|     }, | ||||
|     "whatwg-url": { | ||||
|       "version": "4.8.0", | ||||
|       "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-4.8.0.tgz", | ||||
|       "integrity": "sha1-0pgaqRSMHgCkHFphMRZqtGg7vMA=", | ||||
|       "requires": { | ||||
|         "tr46": "~0.0.3", | ||||
|         "webidl-conversions": "^3.0.0" | ||||
|       }, | ||||
|       "dependencies": { | ||||
|         "webidl-conversions": { | ||||
|           "version": "3.0.1", | ||||
|           "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", | ||||
|           "integrity": "sha1-JFNCdeKnvGvnvIZhHMFq4KVlSHE=" | ||||
|         } | ||||
|       } | ||||
|     }, | ||||
|     "which": { | ||||
|       "version": "1.3.0", | ||||
|       "resolved": "https://registry.npmjs.org/which/-/which-1.3.0.tgz", | ||||
| @@ -6588,6 +6944,11 @@ | ||||
|         } | ||||
|       } | ||||
|     }, | ||||
|     "wordwrap": { | ||||
|       "version": "1.0.0", | ||||
|       "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", | ||||
|       "integrity": "sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus=" | ||||
|     }, | ||||
|     "wrap-ansi": { | ||||
|       "version": "2.1.0", | ||||
|       "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz", | ||||
| @@ -6621,6 +6982,11 @@ | ||||
|       "integrity": "sha1-SWsswQnsqNus/i3HK2A8F8WHCtQ=", | ||||
|       "dev": true | ||||
|     }, | ||||
|     "xml-name-validator": { | ||||
|       "version": "2.0.1", | ||||
|       "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-2.0.1.tgz", | ||||
|       "integrity": "sha1-TYuPHszTQZqjYgYb7O9RXh5VljU=" | ||||
|     }, | ||||
|     "xml2js": { | ||||
|       "version": "0.4.19", | ||||
|       "resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.4.19.tgz", | ||||
|   | ||||
| @@ -107,6 +107,7 @@ | ||||
|     "react-datetime": "^2.11.0", | ||||
|     "react-dom": "^16.0.0", | ||||
|     "react-redux": "^5.0.6", | ||||
|     "readability-node": "^0.1.0", | ||||
|     "redux": "^3.7.2", | ||||
|     "smalltalk": "^2.5.1", | ||||
|     "sprintf-js": "^1.1.1", | ||||
|   | ||||
| @@ -34,6 +34,7 @@ const SyncTargetDropbox = require('lib/SyncTargetDropbox.js'); | ||||
| const EncryptionService = require('lib/services/EncryptionService'); | ||||
| const DecryptionWorker = require('lib/services/DecryptionWorker'); | ||||
| const BaseService = require('lib/services/BaseService'); | ||||
| const ClipperServer = require('lib/ClipperServer'); | ||||
|  | ||||
| SyncTargetRegistry.addClass(SyncTargetFilesystem); | ||||
| SyncTargetRegistry.addClass(SyncTargetOneDrive); | ||||
| @@ -466,6 +467,9 @@ class BaseApplication { | ||||
| 		if (!currentFolder) currentFolder = await Folder.defaultFolder(); | ||||
| 		Setting.setValue('activeFolderId', currentFolder ? currentFolder.id : ''); | ||||
|  | ||||
| 		this.clipperServer_ = new ClipperServer(); | ||||
| 		this.clipperServer_.start(); | ||||
|  | ||||
| 		return argv; | ||||
| 	} | ||||
|  | ||||
|   | ||||
							
								
								
									
										178
									
								
								ReactNativeClient/lib/ClipperServer.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										178
									
								
								ReactNativeClient/lib/ClipperServer.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,178 @@ | ||||
| const { netUtils } = require('lib/net-utils'); | ||||
| const urlParser = require("url"); | ||||
| const Note = require('lib/models/Note'); | ||||
| const Folder = require('lib/models/Folder'); | ||||
| const HtmlToMd = require('lib/HtmlToMd'); | ||||
|  | ||||
| class ClipperServer { | ||||
|  | ||||
| 	htmlToMdParser() { | ||||
| 		if (this.htmlToMdParser_) return this.htmlToMdParser_; | ||||
| 		this.htmlToMdParser_ = new HtmlToMd(); | ||||
| 		return this.htmlToMdParser_; | ||||
| 	} | ||||
|  | ||||
| 	readabilityProcess(url) { | ||||
| 		return new Promise((resolve, reject) => { | ||||
| 			// const Readability = require('readability-node').Readability; | ||||
|  | ||||
| 			// var location = document.location; | ||||
| 			// var uri = { | ||||
| 			//   spec: location.href, | ||||
| 			//   host: location.host, | ||||
| 			//   prePath: location.protocol + "//" + location.host, | ||||
| 			//   scheme: location.protocol.substr(0, location.protocol.indexOf(":")), | ||||
| 			//   pathBase: location.protocol + "//" + location.host + location.pathname.substr(0, location.pathname.lastIndexOf("/") + 1) | ||||
| 			// }; | ||||
| 			// var article = new Readability(uri, document).parse(); | ||||
|  | ||||
| 			// const read = require('node-readability'); | ||||
|  | ||||
| 			// read(url, function(error, article, meta) { | ||||
| 			// 	if (error) { | ||||
| 			// 		reject(error); | ||||
| 			// 		return; | ||||
| 			// 	} | ||||
|  | ||||
| 			// 	const output = { | ||||
| 			// 		body: article.content, | ||||
| 			// 		title: article.title, | ||||
| 			// 	} | ||||
|  | ||||
| 			// 	article.close(); | ||||
| 			// 	resolve(output); | ||||
| 			// }); | ||||
|  | ||||
| 			// // Main Article | ||||
| 			// console.log(article.content); | ||||
| 			// // Title | ||||
| 			// console.log(article.title); | ||||
|  | ||||
| 			// // HTML Source Code | ||||
| 			// console.log(article.html); | ||||
| 			// // DOM | ||||
| 			// console.log(article.document); | ||||
|  | ||||
| 			// // Response Object from Request Lib | ||||
| 			// console.log(meta); | ||||
|  | ||||
| 			// // Close article to clean up jsdom and prevent leaks | ||||
| 			// article.close(); | ||||
| 		}); | ||||
| 	} | ||||
|  | ||||
| 	async requestNoteToNote(requestNote) { | ||||
| 		// if (requestNote.url) { | ||||
| 		// 	console.info('Clipper: Got URL: ' + requestNote.url); | ||||
| 		// 	const result = await this.readabilityProcess(requestNote.url); | ||||
| 			 | ||||
| 		// 	return { | ||||
| 		// 		title: result.title, | ||||
| 		// 		body: result.body, | ||||
| 		// 	} | ||||
| 		// } else { | ||||
| 			const output = { | ||||
| 				title: requestNote.title ? requestNote.title : '', | ||||
| 				body: requestNote.body ? requestNote.body : '', | ||||
| 			}; | ||||
|  | ||||
| 			if (requestNote.bodyHtml) { | ||||
| 				console.info(requestNote.bodyHtml); | ||||
| 				 | ||||
| 				// Parsing will not work if the HTML is not wrapped in a top level tag, which is not guaranteed | ||||
| 				// when getting the content from elsewhere. So here wrap it - it won't change anything to the final | ||||
| 				// rendering but it makes sure everything will be parsed. | ||||
| 				output.body = await this.htmlToMdParser().parse('<div>' + requestNote.bodyHtml + '</div>', { | ||||
| 					baseUrl: requestNote.baseUrl ? requestNote.baseUrl : '', | ||||
| 				}); | ||||
| 			} | ||||
|  | ||||
| 			if (requestNote.parent_id) { | ||||
| 				output.parent_id = requestNote.parent_id; | ||||
| 			} else { | ||||
| 				const folder = await Folder.defaultFolder(); | ||||
| 				if (!folder) throw new Error('Cannot find folder for note'); | ||||
| 				output.parent_id = folder.id; | ||||
| 			} | ||||
|  | ||||
| 			return output; | ||||
| 		// } | ||||
| 	} | ||||
|  | ||||
| 	async start() { | ||||
| 		const port = await netUtils.findAvailablePort([9967, 8967, 8867], 0); // TODO: Make it shared with OneDrive server | ||||
| 		if (!port) throw new Error('All potential ports are in use or not available.'); | ||||
|  | ||||
| 		const server = require('http').createServer(); | ||||
|  | ||||
| 		server.on('request', (request, response) => { | ||||
|  | ||||
| 			const writeCorsHeaders = (code) => { | ||||
| 				response.writeHead(code, { | ||||
| 					"Content-Type": "application/json", | ||||
| 					'Access-Control-Allow-Origin': '*', | ||||
| 					'Access-Control-Allow-Methods': 'GET, POST, OPTIONS, PUT, PATCH, DELETE', | ||||
| 					'Access-Control-Allow-Headers': 'X-Requested-With,content-type', | ||||
| 				}); | ||||
| 			} | ||||
|  | ||||
| 			const writeResponseJson = (code, object) => { | ||||
| 				writeCorsHeaders(code); | ||||
| 				// response.writeHead(code, { | ||||
| 				// 	"Content-Type": "application/json", | ||||
| 				// 	'Access-Control-Allow-Origin': '*', | ||||
| 				// 	'Access-Control-Allow-Methods': 'GET, POST, OPTIONS, PUT, PATCH, DELETE', | ||||
| 				// 	'Access-Control-Allow-Headers': 'X-Requested-With,content-type', | ||||
| 				// }); | ||||
| 				response.write(JSON.stringify(object)); | ||||
| 				response.end(); | ||||
| 			} | ||||
|  | ||||
| 			console.info('GOT REQUEST', request.method + ' ' + request.url); | ||||
|  | ||||
| 			if (request.method === 'POST') { | ||||
| 				const url = urlParser.parse(request.url, true); | ||||
|  | ||||
| 				if (url.pathname === '/notes') { | ||||
| 					let body = ''; | ||||
|  | ||||
| 					request.on('data', (data) => { | ||||
| 						body += data; | ||||
| 					}); | ||||
|  | ||||
| 					request.on('end', async () => { | ||||
| 						try { | ||||
| 							// console.info('GOT BODY', body); | ||||
| 							const requestNote = JSON.parse(body); | ||||
| 							// console.info('GOT REQUEST',  | ||||
| 							let note = await this.requestNoteToNote(requestNote); | ||||
| 							note = await Note.save(note); | ||||
| 							return writeResponseJson(200, note); | ||||
| 						} catch (error) { | ||||
| 							console.warn(error); | ||||
| 							return writeResponseJson(400, { errorCode: 'exception', errorMessage: error.message }); | ||||
| 						} | ||||
| 					}); | ||||
| 				} else { | ||||
| 					return writeResponseJson(404, { errorCode: 'not_found' }); | ||||
| 				} | ||||
| 			} else if (request.method === 'OPTIONS') { | ||||
| 				writeCorsHeaders(200); | ||||
| 				response.end(); | ||||
| 			} else { | ||||
| 				return writeResponseJson(405, { errorCode: 'method_not_allowed' }); | ||||
| 			} | ||||
| 		}); | ||||
|  | ||||
| 		server.on('close', () => { | ||||
|  | ||||
| 		}); | ||||
|  | ||||
| 		console.info('Starting Clipper server on port ' + port); | ||||
|  | ||||
| 		server.listen(port); | ||||
| 	} | ||||
|  | ||||
| } | ||||
|  | ||||
| module.exports = ClipperServer; | ||||
| @@ -1,14 +0,0 @@ | ||||
| const { enexXmlToMd } = require('lib/import-enex-md-gen.js'); | ||||
|  | ||||
| class HtmlToMarkdownParser { | ||||
|  | ||||
| 	async parse(html, options = {}) { | ||||
| 		if (!options.baseUrl) options.baseUrl = ''; | ||||
|  | ||||
| 		const markdown = await enexXmlToMd(html, [], options); | ||||
| 		return markdown; | ||||
| 	} | ||||
|  | ||||
| } | ||||
|  | ||||
| module.exports = HtmlToMarkdownParser; | ||||
							
								
								
									
										13
									
								
								ReactNativeClient/lib/HtmlToMd.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										13
									
								
								ReactNativeClient/lib/HtmlToMd.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,13 @@ | ||||
| const TurndownService = require('turndown') | ||||
|  | ||||
| class HtmlToMd { | ||||
|  | ||||
| 	parse(html) { | ||||
| 		const turndownService = new TurndownService() | ||||
| 		let markdown = turndownService.turndown(html) | ||||
| 		return markdown; | ||||
| 	} | ||||
|  | ||||
| } | ||||
|  | ||||
| module.exports = HtmlToMd; | ||||
		Reference in New Issue
	
	Block a user