| 
									
										
										
										
											2018-05-16 14:16:14 +01:00
										 |  |  | (function() { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (window.jopext_hasRun) return; | 
					
						
							|  |  |  | 	window.jopext_hasRun = true; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	console.info('jopext: Loading content script'); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-05-24 18:32:30 +01:00
										 |  |  | 	let browser_ = null; | 
					
						
							|  |  |  | 	if (typeof browser !== 'undefined') { | 
					
						
							| 
									
										
										
										
											2019-07-30 09:35:42 +02:00
										 |  |  | 		// eslint-disable-next-line no-undef
 | 
					
						
							| 
									
										
										
										
											2018-05-24 18:32:30 +01:00
										 |  |  | 		browser_ = browser; | 
					
						
							| 
									
										
										
										
											2019-07-30 09:35:42 +02:00
										 |  |  | 		// eslint-disable-next-line no-undef
 | 
					
						
							| 
									
										
										
										
											2018-05-24 18:32:30 +01:00
										 |  |  | 		browserSupportsPromises_ = true; | 
					
						
							|  |  |  | 	} else if (typeof chrome !== 'undefined') { | 
					
						
							| 
									
										
										
										
											2019-07-30 09:35:42 +02:00
										 |  |  | 		// eslint-disable-next-line no-undef
 | 
					
						
							| 
									
										
										
										
											2018-05-24 18:32:30 +01:00
										 |  |  | 		browser_ = chrome; | 
					
						
							| 
									
										
										
										
											2019-07-30 09:35:42 +02:00
										 |  |  | 		// eslint-disable-next-line no-undef
 | 
					
						
							| 
									
										
										
										
											2018-05-24 18:32:30 +01:00
										 |  |  | 		browserSupportsPromises_ = false; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-05-11 11:13:13 +01:00
										 |  |  | 	function absoluteUrl(url) { | 
					
						
							|  |  |  | 		if (!url) return url; | 
					
						
							|  |  |  | 		const protocol = url.toLowerCase().split(':')[0]; | 
					
						
							| 
									
										
										
										
											2020-02-13 23:59:23 +00:00
										 |  |  | 		if (['http', 'https', 'file', 'data'].indexOf(protocol) >= 0) return url; | 
					
						
							| 
									
										
										
										
											2019-05-11 11:13:13 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-11 01:09:48 +01:00
										 |  |  | 		if (url.indexOf('//') === 0) { | 
					
						
							| 
									
										
										
										
											2019-05-11 11:13:13 +01:00
										 |  |  | 			return location.protocol + url; | 
					
						
							|  |  |  | 		} else if (url[0] === '/') { | 
					
						
							| 
									
										
										
										
											2019-09-19 22:51:18 +01:00
										 |  |  | 			return `${location.protocol}//${location.host}${url}`; | 
					
						
							| 
									
										
										
										
											2019-05-11 11:13:13 +01:00
										 |  |  | 		} else { | 
					
						
							| 
									
										
										
										
											2019-09-19 22:51:18 +01:00
										 |  |  | 			return `${baseUrl()}/${url}`; | 
					
						
							| 
									
										
										
										
											2019-05-11 11:13:13 +01:00
										 |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-05-16 14:16:14 +01:00
										 |  |  | 	function pageTitle() { | 
					
						
							| 
									
										
										
										
											2019-07-30 09:35:42 +02:00
										 |  |  | 		const titleElements = document.getElementsByTagName('title'); | 
					
						
							| 
									
										
										
										
											2018-05-16 14:16:14 +01:00
										 |  |  | 		if (titleElements.length) return titleElements[0].text.trim(); | 
					
						
							|  |  |  | 		return document.title.trim(); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-11 01:09:48 +01:00
										 |  |  | 	function pageLocationOrigin() { | 
					
						
							|  |  |  | 		// location.origin normally returns the protocol + domain + port (eg. https://example.com:8080)
 | 
					
						
							|  |  |  | 		// but for file:// protocol this is browser dependant and in particular Firefox returns "null"
 | 
					
						
							|  |  |  | 		// in this case.
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		if (location.protocol === 'file:') { | 
					
						
							|  |  |  | 			return 'file://'; | 
					
						
							|  |  |  | 		} else { | 
					
						
							|  |  |  | 			return location.origin; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-05-16 14:16:14 +01:00
										 |  |  | 	function baseUrl() { | 
					
						
							| 
									
										
										
										
											2019-06-11 01:09:48 +01:00
										 |  |  | 		let output = pageLocationOrigin() + location.pathname; | 
					
						
							| 
									
										
										
										
											2018-05-16 14:16:14 +01:00
										 |  |  | 		if (output[output.length - 1] !== '/') { | 
					
						
							|  |  |  | 			output = output.split('/'); | 
					
						
							|  |  |  | 			output.pop(); | 
					
						
							|  |  |  | 			output = output.join('/'); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		return output; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-02-12 18:15:16 +00:00
										 |  |  | 	function getJoplinClipperSvgClassName(svg) { | 
					
						
							|  |  |  | 		for (const className of svg.classList) { | 
					
						
							|  |  |  | 			if (className.indexOf('joplin-clipper-svg-') === 0) return className; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		return ''; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-05-11 11:13:13 +01:00
										 |  |  | 	function getImageSizes(element, forceAbsoluteUrls = false) { | 
					
						
							| 
									
										
										
										
											2019-01-20 15:26:43 +00:00
										 |  |  | 		const output = {}; | 
					
						
							| 
									
										
										
										
											2020-02-12 18:15:16 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		const images = element.getElementsByTagName('img'); | 
					
						
							| 
									
										
										
										
											2019-01-20 15:26:43 +00:00
										 |  |  | 		for (let i = 0; i < images.length; i++) { | 
					
						
							|  |  |  | 			const img = images[i]; | 
					
						
							| 
									
										
										
										
											2019-07-16 21:47:44 +01:00
										 |  |  | 			if (img.classList && img.classList.contains('joplin-clipper-hidden')) continue; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-07-14 19:52:57 +01:00
										 |  |  | 			let src = imageSrc(img); | 
					
						
							|  |  |  | 			src = forceAbsoluteUrls ? absoluteUrl(src) : src; | 
					
						
							| 
									
										
										
										
											2019-07-16 21:47:44 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | 			if (!output[src]) output[src] = []; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			output[src].push({ | 
					
						
							| 
									
										
										
										
											2019-01-20 15:26:43 +00:00
										 |  |  | 				width: img.width, | 
					
						
							|  |  |  | 				height: img.height, | 
					
						
							|  |  |  | 				naturalWidth: img.naturalWidth, | 
					
						
							|  |  |  | 				naturalHeight: img.naturalHeight, | 
					
						
							| 
									
										
										
										
											2019-07-16 21:47:44 +01:00
										 |  |  | 			}); | 
					
						
							| 
									
										
										
										
											2019-01-20 15:26:43 +00:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2020-02-12 18:15:16 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		const svgs = element.getElementsByTagName('svg'); | 
					
						
							|  |  |  | 		for (let i = 0; i < svgs.length; i++) { | 
					
						
							|  |  |  | 			const svg = svgs[i]; | 
					
						
							|  |  |  | 			if (svg.classList && svg.classList.contains('joplin-clipper-hidden')) continue; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			const className = getJoplinClipperSvgClassName(svg);// 'joplin-clipper-svg-' + i;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			if (!className) { | 
					
						
							|  |  |  | 				console.warn('SVG without a Joplin class:', svg); | 
					
						
							|  |  |  | 				continue; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			if (!svg.classList.contains(className)) { | 
					
						
							|  |  |  | 				svg.classList.add(className); | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			const rect = svg.getBoundingClientRect(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			if (!output[className]) output[className] = []; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			output[className].push({ | 
					
						
							|  |  |  | 				width: rect.width, | 
					
						
							|  |  |  | 				height: rect.height, | 
					
						
							|  |  |  | 			}); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-01-20 15:26:43 +00:00
										 |  |  | 		return output; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-13 00:26:09 +01:00
										 |  |  | 	function getAnchorNames(element) { | 
					
						
							|  |  |  | 		const output = []; | 
					
						
							| 
									
										
										
										
											2019-10-12 00:18:40 +02:00
										 |  |  | 		// Anchor names are normally in A tags but can be in SPAN too
 | 
					
						
							|  |  |  | 		// https://github.com/laurent22/joplin-turndown/commit/45f4ee6bf15b8804bdc2aa1d7ecb2f8cb594b8e5#diff-172b8b2bc3ba160589d3a7eeb4913687R232
 | 
					
						
							|  |  |  | 		for (const tagName of ['a', 'span']) { | 
					
						
							|  |  |  | 			const anchors = element.getElementsByTagName(tagName); | 
					
						
							|  |  |  | 			for (let i = 0; i < anchors.length; i++) { | 
					
						
							|  |  |  | 				const anchor = anchors[i]; | 
					
						
							|  |  |  | 				if (anchor.id) { | 
					
						
							|  |  |  | 					output.push(anchor.id); | 
					
						
							|  |  |  | 				} else if (anchor.name) { | 
					
						
							|  |  |  | 					output.push(anchor.name); | 
					
						
							|  |  |  | 				} | 
					
						
							| 
									
										
										
										
											2019-06-13 00:26:09 +01:00
										 |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		return output; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-07-14 19:52:57 +01:00
										 |  |  | 	// In general we should use currentSrc because that's the image that's currently displayed,
 | 
					
						
							|  |  |  | 	// especially within <picture> tags or with srcset. In these cases there can be multiple
 | 
					
						
							|  |  |  | 	// sources and the best one is probably the one being displayed, thus currentSrc.
 | 
					
						
							|  |  |  | 	function imageSrc(image) { | 
					
						
							|  |  |  | 		if (image.currentSrc) return image.currentSrc; | 
					
						
							|  |  |  | 		return image.src; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-05-16 14:16:14 +01:00
										 |  |  | 	// Cleans up element by removing all its invisible children (which we don't want to render as Markdown)
 | 
					
						
							| 
									
										
										
										
											2019-06-24 00:00:11 +01:00
										 |  |  | 	// And hard-code the image dimensions so that the information can be used by the clipper server to
 | 
					
						
							|  |  |  | 	// display them at the right sizes in the notes.
 | 
					
						
							| 
									
										
										
										
											2019-07-16 22:23:04 +01:00
										 |  |  | 	function cleanUpElement(convertToMarkup, element, imageSizes, imageIndexes) { | 
					
						
							| 
									
										
										
										
											2018-05-16 14:16:14 +01:00
										 |  |  | 		const childNodes = element.childNodes; | 
					
						
							| 
									
										
										
										
											2019-07-16 21:47:44 +01:00
										 |  |  | 		const hiddenNodes = []; | 
					
						
							| 
									
										
										
										
											2018-05-16 14:16:14 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-07-16 21:47:44 +01:00
										 |  |  | 		for (let i = 0; i < childNodes.length; i++) { | 
					
						
							| 
									
										
										
										
											2018-05-16 14:16:14 +01:00
										 |  |  | 			const node = childNodes[i]; | 
					
						
							| 
									
										
										
										
											2019-06-24 00:57:39 +01:00
										 |  |  | 			const nodeName = node.nodeName.toLowerCase(); | 
					
						
							| 
									
										
										
										
											2018-05-20 10:19:59 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-24 00:00:11 +01:00
										 |  |  | 			const isHidden = node && node.classList && node.classList.contains('joplin-clipper-hidden'); | 
					
						
							| 
									
										
										
										
											2018-05-20 10:19:59 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-24 00:00:11 +01:00
										 |  |  | 			if (isHidden) { | 
					
						
							| 
									
										
										
										
											2019-07-16 21:47:44 +01:00
										 |  |  | 				hiddenNodes.push(node); | 
					
						
							| 
									
										
										
										
											2018-05-16 14:16:14 +01:00
										 |  |  | 			} else { | 
					
						
							| 
									
										
										
										
											2019-05-11 11:13:13 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-24 00:57:39 +01:00
										 |  |  | 				// If the data-joplin-clipper-value has been set earlier, create a new DIV element
 | 
					
						
							|  |  |  | 				// to replace the input or text area, so that it can be exported.
 | 
					
						
							|  |  |  | 				if (node.getAttribute && node.getAttribute('data-joplin-clipper-value')) { | 
					
						
							|  |  |  | 					const div = document.createElement('div'); | 
					
						
							|  |  |  | 					div.innerText = node.getAttribute('data-joplin-clipper-value'); | 
					
						
							|  |  |  | 					node.parentNode.insertBefore(div, node.nextSibling); | 
					
						
							|  |  |  | 					element.removeChild(node); | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				if (nodeName === 'img') { | 
					
						
							| 
									
										
										
										
											2019-07-14 19:52:57 +01:00
										 |  |  | 					const src = absoluteUrl(imageSrc(node)); | 
					
						
							|  |  |  | 					node.setAttribute('src', src); | 
					
						
							| 
									
										
										
										
											2019-07-16 21:47:44 +01:00
										 |  |  | 					if (!(src in imageIndexes)) imageIndexes[src] = 0; | 
					
						
							| 
									
										
										
										
											2019-10-02 19:03:36 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | 					if (!imageSizes[src]) { | 
					
						
							|  |  |  | 						// This seems to concern dynamic images that don't really such as Gravatar, etc.
 | 
					
						
							|  |  |  | 						console.warn('Found an image for which the size had not been fetched:', src); | 
					
						
							|  |  |  | 					} else { | 
					
						
							|  |  |  | 						const imageSize = imageSizes[src][imageIndexes[src]]; | 
					
						
							|  |  |  | 						imageIndexes[src]++; | 
					
						
							|  |  |  | 						if (imageSize && convertToMarkup === 'markdown') { | 
					
						
							|  |  |  | 							node.width = imageSize.width; | 
					
						
							|  |  |  | 							node.height = imageSize.height; | 
					
						
							|  |  |  | 						} | 
					
						
							| 
									
										
										
										
											2019-05-11 11:13:13 +01:00
										 |  |  | 					} | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-02-12 18:15:16 +00:00
										 |  |  | 				if (nodeName === 'svg') { | 
					
						
							|  |  |  | 					const className = getJoplinClipperSvgClassName(node); | 
					
						
							|  |  |  | 					if (!(className in imageIndexes)) imageIndexes[className] = 0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 					if (!imageSizes[className]) { | 
					
						
							|  |  |  | 						// This seems to concern dynamic images that don't really such as Gravatar, etc.
 | 
					
						
							|  |  |  | 						console.warn('Found an SVG for which the size had not been fetched:', className); | 
					
						
							|  |  |  | 					} else { | 
					
						
							|  |  |  | 						const imageSize = imageSizes[className][imageIndexes[className]]; | 
					
						
							|  |  |  | 						imageIndexes[className]++; | 
					
						
							|  |  |  | 						if (imageSize) { | 
					
						
							|  |  |  | 							node.style.width = `${imageSize.width}px`; | 
					
						
							|  |  |  | 							node.style.height = `${imageSize.height}px`; | 
					
						
							|  |  |  | 						} | 
					
						
							|  |  |  | 					} | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-07-16 22:23:04 +01:00
										 |  |  | 				cleanUpElement(convertToMarkup, node, imageSizes, imageIndexes); | 
					
						
							| 
									
										
										
										
											2018-05-16 14:16:14 +01:00
										 |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2019-07-16 21:47:44 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		for (const hiddenNode of hiddenNodes) { | 
					
						
							|  |  |  | 			if (!hiddenNode.parentNode) continue; | 
					
						
							| 
									
										
										
										
											2019-07-16 22:23:04 +01:00
										 |  |  | 			hiddenNode.parentNode.removeChild(hiddenNode); | 
					
						
							| 
									
										
										
										
											2019-07-16 21:47:44 +01:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2018-05-16 14:16:14 +01:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-24 00:00:11 +01:00
										 |  |  | 	// When we clone the document before cleaning it, we lose some of the information that might have been set via CSS or
 | 
					
						
							|  |  |  | 	// JavaScript, in particular whether an element was hidden or not. This function pre-process the document by
 | 
					
						
							|  |  |  | 	// adding a "joplin-clipper-hidden" class to all currently hidden elements in the current document.
 | 
					
						
							|  |  |  | 	// This class is then used in cleanUpElement() on the cloned document to find an element should be visible or not.
 | 
					
						
							| 
									
										
										
										
											2019-06-24 00:57:39 +01:00
										 |  |  | 	function preProcessDocument(element) { | 
					
						
							| 
									
										
										
										
											2019-06-24 00:00:11 +01:00
										 |  |  | 		const childNodes = element.childNodes; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-07-14 19:52:57 +01:00
										 |  |  | 		for (let i = childNodes.length - 1; i >= 0; i--) { | 
					
						
							| 
									
										
										
										
											2019-06-24 00:00:11 +01:00
										 |  |  | 			const node = childNodes[i]; | 
					
						
							| 
									
										
										
										
											2019-06-24 00:57:39 +01:00
										 |  |  | 			const nodeName = node.nodeName.toLowerCase(); | 
					
						
							| 
									
										
										
										
											2019-07-14 16:00:02 +01:00
										 |  |  | 			const nodeParent = node.parentNode; | 
					
						
							|  |  |  | 			const nodeParentName = nodeParent ? nodeParent.nodeName.toLowerCase() : ''; | 
					
						
							| 
									
										
										
										
											2019-06-24 00:00:11 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | 			let isVisible = node.nodeType === 1 ? window.getComputedStyle(node).display !== 'none' : true; | 
					
						
							| 
									
										
										
										
											2019-06-24 00:57:39 +01:00
										 |  |  | 			if (isVisible && ['script', 'noscript', 'style', 'select', 'option', 'button'].indexOf(nodeName) >= 0) isVisible = false; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			// If it's a text input or a textarea and it has a value, save
 | 
					
						
							|  |  |  | 			// that value to data-joplin-clipper-value. This is then used
 | 
					
						
							|  |  |  | 			// when cleaning up the document to export the value.
 | 
					
						
							|  |  |  | 			if (['input', 'textarea'].indexOf(nodeName) >= 0) { | 
					
						
							|  |  |  | 				isVisible = !!node.value; | 
					
						
							|  |  |  | 				if (nodeName === 'input' && node.getAttribute('type') !== 'text') isVisible = false; | 
					
						
							|  |  |  | 				if (isVisible) node.setAttribute('data-joplin-clipper-value', node.value); | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2019-06-24 00:00:11 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-07-13 19:17:28 +01:00
										 |  |  | 			if (nodeName === 'script') { | 
					
						
							|  |  |  | 				const a = node.getAttribute('type'); | 
					
						
							|  |  |  | 				if (a && a.toLowerCase().indexOf('math/tex') >= 0) isVisible = true; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-07-14 16:00:02 +01:00
										 |  |  | 			if (nodeName === 'source' && nodeParentName === 'picture') { | 
					
						
							| 
									
										
										
										
											2019-07-30 09:35:42 +02:00
										 |  |  | 				isVisible = false; | 
					
						
							| 
									
										
										
										
											2019-07-14 16:00:02 +01:00
										 |  |  | 			} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-07-14 19:52:57 +01:00
										 |  |  | 			if (node.nodeType === 8) { // Comments are just removed since we can't add a class
 | 
					
						
							|  |  |  | 				node.parentNode.removeChild(node); | 
					
						
							|  |  |  | 			} else if (!isVisible) { | 
					
						
							| 
									
										
										
										
											2019-06-24 00:00:11 +01:00
										 |  |  | 				node.classList.add('joplin-clipper-hidden'); | 
					
						
							|  |  |  | 			} else { | 
					
						
							| 
									
										
										
										
											2019-06-24 00:57:39 +01:00
										 |  |  | 				preProcessDocument(node); | 
					
						
							| 
									
										
										
										
											2019-06-24 00:00:11 +01:00
										 |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-22 18:57:41 +01:00
										 |  |  | 	// This sets the PRE elements computed style to the style attribute, so that
 | 
					
						
							|  |  |  | 	// the info can be exported and later processed by the htmlToMd converter
 | 
					
						
							|  |  |  | 	// to detect code blocks.
 | 
					
						
							|  |  |  | 	function hardcodePreStyles(doc) { | 
					
						
							|  |  |  | 		const preElements = doc.getElementsByTagName('pre'); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		for (const preElement of preElements) { | 
					
						
							|  |  |  | 			const fontFamily = getComputedStyle(preElement).getPropertyValue('font-family'); | 
					
						
							|  |  |  | 			const fontFamilyArray = fontFamily.split(',').map(f => f.toLowerCase().trim()); | 
					
						
							|  |  |  | 			if (fontFamilyArray.indexOf('monospace') >= 0) { | 
					
						
							|  |  |  | 				preElement.style.fontFamily = fontFamily; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-02-12 18:15:16 +00:00
										 |  |  | 	function addSvgClass(doc) { | 
					
						
							|  |  |  | 		const svgs = doc.getElementsByTagName('svg'); | 
					
						
							|  |  |  | 		let svgId = 0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		for (const svg of svgs) { | 
					
						
							|  |  |  | 			if (!getJoplinClipperSvgClassName(svg)) { | 
					
						
							|  |  |  | 				svg.classList.add(`joplin-clipper-svg-${svgId}`); | 
					
						
							|  |  |  | 				svgId++; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-25 22:11:12 +01:00
										 |  |  | 	// Given a document, return a <style> tag that contains all the styles
 | 
					
						
							| 
									
										
										
										
											2019-07-30 09:35:42 +02:00
										 |  |  | 	// required to render the page. Not currently used but could be as an
 | 
					
						
							| 
									
										
										
										
											2019-06-25 22:11:12 +01:00
										 |  |  | 	// option to clip pages as HTML.
 | 
					
						
							| 
									
										
										
										
											2019-07-14 16:00:02 +01:00
										 |  |  | 	function getStyleSheets(doc) { | 
					
						
							|  |  |  | 		const output = []; | 
					
						
							| 
									
										
										
										
											2019-06-25 22:11:12 +01:00
										 |  |  | 		for (var i=0; i<doc.styleSheets.length; i++) { | 
					
						
							| 
									
										
										
										
											2019-07-14 16:00:02 +01:00
										 |  |  | 			var sheet = doc.styleSheets[i]; | 
					
						
							| 
									
										
										
										
											2019-06-25 22:11:12 +01:00
										 |  |  | 			try { | 
					
						
							|  |  |  | 				for (const cssRule of sheet.cssRules) { | 
					
						
							| 
									
										
										
										
											2019-07-14 16:00:02 +01:00
										 |  |  | 					output.push({ type: 'text', value: cssRule.cssText }); | 
					
						
							| 
									
										
										
										
											2019-06-25 22:11:12 +01:00
										 |  |  | 				} | 
					
						
							|  |  |  | 			} catch (error) { | 
					
						
							| 
									
										
										
										
											2019-07-14 16:00:02 +01:00
										 |  |  | 				// Calling sheet.cssRules will throw a CORS error on Chrome if the stylesheet is on a different domain.
 | 
					
						
							|  |  |  | 				// In that case, we skip it and add it to the list of stylesheet URLs. These URls will be downloaded
 | 
					
						
							|  |  |  | 				// by the desktop application, since it doesn't have CORS restrictions.
 | 
					
						
							|  |  |  | 				console.info('Could not retrieve stylesheet now:', sheet.href); | 
					
						
							|  |  |  | 				console.info('It will downloaded by the main application.'); | 
					
						
							|  |  |  | 				console.info(error); | 
					
						
							|  |  |  | 				output.push({ type: 'url', value: sheet.href }); | 
					
						
							| 
									
										
										
										
											2019-06-25 22:11:12 +01:00
										 |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2019-07-14 16:00:02 +01:00
										 |  |  | 		return output; | 
					
						
							| 
									
										
										
										
											2019-06-25 22:11:12 +01:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-05-09 23:41:52 +01:00
										 |  |  | 	function documentForReadability() { | 
					
						
							|  |  |  | 		// Readability directly change the passed document so clone it so as
 | 
					
						
							|  |  |  | 		// to preserve the original web page.
 | 
					
						
							|  |  |  | 		return document.cloneNode(true); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-05-16 14:16:14 +01:00
										 |  |  | 	function readabilityProcess() { | 
					
						
							| 
									
										
										
										
											2019-07-30 09:35:42 +02:00
										 |  |  | 		// eslint-disable-next-line no-undef
 | 
					
						
							| 
									
										
										
										
											2019-05-09 23:41:52 +01:00
										 |  |  | 		const readability = new Readability(documentForReadability()); | 
					
						
							| 
									
										
										
										
											2018-05-16 14:16:14 +01:00
										 |  |  | 		const article = readability.parse(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		if (!article) throw new Error('Could not parse HTML document with Readability'); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		return { | 
					
						
							|  |  |  | 			title: article.title, | 
					
						
							|  |  |  | 			body: article.content, | 
					
						
							| 
									
										
										
										
											2019-07-30 09:35:42 +02:00
										 |  |  | 		}; | 
					
						
							| 
									
										
										
										
											2018-05-16 14:16:14 +01:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	async function prepareCommandResponse(command) { | 
					
						
							| 
									
										
										
										
											2019-09-19 22:51:18 +01:00
										 |  |  | 		console.info(`Got command: ${command.name}`); | 
					
						
							| 
									
										
										
										
											2020-02-11 02:49:07 -08:00
										 |  |  | 		const shouldSendToJoplin = !!command.shouldSendToJoplin; | 
					
						
							| 
									
										
										
										
											2018-05-24 18:32:30 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-07-16 22:23:04 +01:00
										 |  |  | 		const convertToMarkup = command.preProcessFor ? command.preProcessFor : 'markdown'; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-07-14 16:00:02 +01:00
										 |  |  | 		const clippedContentResponse = (title, html, imageSizes, anchorNames, stylesheets) => { | 
					
						
							| 
									
										
										
										
											2018-06-28 22:01:55 +01:00
										 |  |  | 			return { | 
					
						
							| 
									
										
										
										
											2020-02-11 02:49:07 -08:00
										 |  |  | 				name: shouldSendToJoplin ? 'sendContentToJoplin' : 'clippedContent', | 
					
						
							| 
									
										
										
										
											2018-06-28 22:01:55 +01:00
										 |  |  | 				title: title, | 
					
						
							|  |  |  | 				html: html, | 
					
						
							|  |  |  | 				base_url: baseUrl(), | 
					
						
							| 
									
										
										
										
											2019-06-11 01:09:48 +01:00
										 |  |  | 				url: pageLocationOrigin() + location.pathname + location.search, | 
					
						
							| 
									
										
										
										
											2018-06-28 22:01:55 +01:00
										 |  |  | 				parent_id: command.parent_id, | 
					
						
							| 
									
										
										
										
											2018-09-23 18:03:11 +01:00
										 |  |  | 				tags: command.tags || '', | 
					
						
							| 
									
										
										
										
											2019-01-20 15:26:43 +00:00
										 |  |  | 				image_sizes: imageSizes, | 
					
						
							| 
									
										
										
										
											2019-06-13 00:26:09 +01:00
										 |  |  | 				anchor_names: anchorNames, | 
					
						
							| 
									
										
										
										
											2019-07-14 16:00:02 +01:00
										 |  |  | 				source_command: Object.assign({}, command), | 
					
						
							| 
									
										
										
										
											2019-07-16 22:23:04 +01:00
										 |  |  | 				convert_to: convertToMarkup, | 
					
						
							| 
									
										
										
										
											2019-07-14 16:00:02 +01:00
										 |  |  | 				stylesheets: stylesheets, | 
					
						
							| 
									
										
										
										
											2019-07-30 09:35:42 +02:00
										 |  |  | 			}; | 
					
						
							|  |  |  | 		}; | 
					
						
							| 
									
										
										
										
											2018-06-28 22:01:55 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-07-30 09:35:42 +02:00
										 |  |  | 		if (command.name === 'simplifiedPageHtml') { | 
					
						
							| 
									
										
										
										
											2018-05-16 14:16:14 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | 			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; | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2019-06-13 00:26:09 +01:00
										 |  |  | 			return clippedContentResponse(article.title, article.body, getImageSizes(document), getAnchorNames(document)); | 
					
						
							| 
									
										
										
										
											2018-05-16 14:16:14 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-07-30 09:35:42 +02:00
										 |  |  | 		} else if (command.name === 'isProbablyReaderable') { | 
					
						
							| 
									
										
										
										
											2019-05-09 23:41:52 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-07-30 09:35:42 +02:00
										 |  |  | 			// eslint-disable-next-line no-undef
 | 
					
						
							| 
									
										
										
										
											2019-05-09 23:41:52 +01:00
										 |  |  | 			const ok = isProbablyReaderable(documentForReadability()); | 
					
						
							|  |  |  | 			return { name: 'isProbablyReaderable', value: ok }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-07-30 09:35:42 +02:00
										 |  |  | 		} else if (command.name === 'completePageHtml') { | 
					
						
							| 
									
										
										
										
											2018-05-16 14:16:14 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-22 18:57:41 +01:00
										 |  |  | 			hardcodePreStyles(document); | 
					
						
							| 
									
										
										
										
											2020-02-12 18:15:16 +00:00
										 |  |  | 			addSvgClass(document); | 
					
						
							| 
									
										
										
										
											2019-06-24 00:57:39 +01:00
										 |  |  | 			preProcessDocument(document); | 
					
						
							| 
									
										
										
										
											2019-06-24 00:00:11 +01:00
										 |  |  | 			// Because cleanUpElement is going to modify the DOM and remove elements we don't want to work
 | 
					
						
							|  |  |  | 			// directly on the document, so we make a copy of it first.
 | 
					
						
							| 
									
										
										
										
											2018-05-16 14:16:14 +01:00
										 |  |  | 			const cleanDocument = document.body.cloneNode(true); | 
					
						
							| 
									
										
										
										
											2019-05-11 11:13:13 +01:00
										 |  |  | 			const imageSizes = getImageSizes(document, true); | 
					
						
							| 
									
										
										
										
											2019-07-16 21:47:44 +01:00
										 |  |  | 			const imageIndexes = {}; | 
					
						
							| 
									
										
										
										
											2019-07-16 22:23:04 +01:00
										 |  |  | 			cleanUpElement(convertToMarkup, cleanDocument, imageSizes, imageIndexes); | 
					
						
							| 
									
										
										
										
											2019-07-14 16:00:02 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-07-16 22:23:04 +01:00
										 |  |  | 			const stylesheets = convertToMarkup === 'html' ? getStyleSheets(document) : null; | 
					
						
							| 
									
										
										
										
											2019-07-14 16:00:02 +01:00
										 |  |  | 			return clippedContentResponse(pageTitle(), cleanDocument.innerHTML, imageSizes, getAnchorNames(document), stylesheets); | 
					
						
							| 
									
										
										
										
											2018-05-16 14:16:14 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-07-30 09:35:42 +02:00
										 |  |  | 		} else if (command.name === 'selectedHtml') { | 
					
						
							| 
									
										
										
										
											2018-06-28 22:01:55 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-22 18:57:41 +01:00
										 |  |  | 			hardcodePreStyles(document); | 
					
						
							| 
									
										
										
										
											2020-02-12 18:15:16 +00:00
										 |  |  | 			addSvgClass(document); | 
					
						
							| 
									
										
										
										
											2019-06-25 22:11:12 +01:00
										 |  |  | 			preProcessDocument(document); | 
					
						
							| 
									
										
										
										
											2020-02-08 12:16:49 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-25 22:11:12 +01:00
										 |  |  | 			const container = document.createElement('div'); | 
					
						
							| 
									
										
										
										
											2020-02-08 12:16:49 +00:00
										 |  |  | 			const rangeCount = window.getSelection().rangeCount; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			// Even when the user makes only one selection, Firefox might report multiple selections
 | 
					
						
							|  |  |  | 			// so we need to process them all.
 | 
					
						
							|  |  |  | 			// Fixes https://github.com/laurent22/joplin/issues/2294
 | 
					
						
							|  |  |  | 			for (let i = 0; i < rangeCount; i++) { | 
					
						
							|  |  |  | 				const range = window.getSelection().getRangeAt(i); | 
					
						
							|  |  |  | 				container.appendChild(range.cloneContents()); | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-25 22:11:12 +01:00
										 |  |  | 			const imageSizes = getImageSizes(document, true); | 
					
						
							| 
									
										
										
										
											2019-07-16 21:47:44 +01:00
										 |  |  | 			const imageIndexes = {}; | 
					
						
							| 
									
										
										
										
											2019-07-16 22:23:04 +01:00
										 |  |  | 			cleanUpElement(convertToMarkup, container, imageSizes, imageIndexes); | 
					
						
							| 
									
										
										
										
											2019-06-25 22:11:12 +01:00
										 |  |  | 			return clippedContentResponse(pageTitle(), container.innerHTML, getImageSizes(document), getAnchorNames(document)); | 
					
						
							| 
									
										
										
										
											2018-05-16 14:16:14 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-05-24 18:32:30 +01:00
										 |  |  | 		} else if (command.name === 'screenshot') { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			const overlay = document.createElement('div'); | 
					
						
							| 
									
										
										
										
											2018-05-26 15:53:50 +01:00
										 |  |  | 			overlay.style.opacity = '0.6'; | 
					
						
							| 
									
										
										
										
											2018-05-24 18:32:30 +01:00
										 |  |  | 			overlay.style.background = 'black'; | 
					
						
							|  |  |  | 			overlay.style.width = '100%'; | 
					
						
							|  |  |  | 			overlay.style.height = '100%'; | 
					
						
							|  |  |  | 			overlay.style.zIndex = 99999999; | 
					
						
							|  |  |  | 			overlay.style.top = 0; | 
					
						
							|  |  |  | 			overlay.style.left = 0; | 
					
						
							|  |  |  | 			overlay.style.position = 'fixed'; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			document.body.appendChild(overlay); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-05-25 08:51:54 +01:00
										 |  |  | 			const messageComp = document.createElement('div'); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			const messageCompWidth = 300; | 
					
						
							| 
									
										
										
										
											2019-07-30 09:35:42 +02:00
										 |  |  | 			messageComp.style.position = 'fixed'; | 
					
						
							|  |  |  | 			messageComp.style.opacity = '0.95'; | 
					
						
							| 
									
										
										
										
											2018-05-26 15:53:50 +01:00
										 |  |  | 			messageComp.style.fontSize = '14px'; | 
					
						
							| 
									
										
										
										
											2019-09-19 22:51:18 +01:00
										 |  |  | 			messageComp.style.width = `${messageCompWidth}px`; | 
					
						
							|  |  |  | 			messageComp.style.maxWidth = `${messageCompWidth}px`; | 
					
						
							| 
									
										
										
										
											2019-07-30 09:35:42 +02:00
										 |  |  | 			messageComp.style.border = '1px solid black'; | 
					
						
							|  |  |  | 			messageComp.style.background = 'white'; | 
					
						
							| 
									
										
										
										
											2018-09-29 12:53:16 +01:00
										 |  |  | 			messageComp.style.color = 'black'; | 
					
						
							| 
									
										
										
										
											2019-07-30 09:35:42 +02:00
										 |  |  | 			messageComp.style.top = '10px'; | 
					
						
							| 
									
										
										
										
											2018-05-25 08:51:54 +01:00
										 |  |  | 			messageComp.style.textAlign = 'center'; | 
					
						
							| 
									
										
										
										
											2019-07-30 09:35:42 +02:00
										 |  |  | 			messageComp.style.padding = '10px'; | 
					
						
							| 
									
										
										
										
											2019-09-19 22:51:18 +01:00
										 |  |  | 			messageComp.style.left = `${Math.round(document.body.clientWidth / 2 - messageCompWidth / 2)}px`; | 
					
						
							| 
									
										
										
										
											2019-07-30 09:35:42 +02:00
										 |  |  | 			messageComp.style.zIndex = overlay.style.zIndex + 1; | 
					
						
							| 
									
										
										
										
											2018-05-25 08:51:54 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | 			messageComp.textContent = 'Drag and release to capture a screenshot'; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			document.body.appendChild(messageComp); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-05-24 18:32:30 +01:00
										 |  |  | 			const selection = document.createElement('div'); | 
					
						
							| 
									
										
										
										
											2018-05-25 08:51:54 +01:00
										 |  |  | 			selection.style.opacity = '0.4'; | 
					
						
							|  |  |  | 			selection.style.border = '1px solid red'; | 
					
						
							|  |  |  | 			selection.style.background = 'white'; | 
					
						
							|  |  |  | 			selection.style.border = '2px solid black'; | 
					
						
							| 
									
										
										
										
											2018-05-24 18:32:30 +01:00
										 |  |  | 			selection.style.zIndex = overlay.style.zIndex - 1; | 
					
						
							|  |  |  | 			selection.style.top = 0; | 
					
						
							|  |  |  | 			selection.style.left = 0; | 
					
						
							|  |  |  | 			selection.style.position = 'fixed'; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			document.body.appendChild(selection); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			let isDragging = false; | 
					
						
							|  |  |  | 			let draggingStartPos = null; | 
					
						
							|  |  |  | 			let selectionArea = {}; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-07-30 09:35:42 +02:00
										 |  |  | 			const updateSelection = function() { | 
					
						
							| 
									
										
										
										
											2019-09-19 22:51:18 +01:00
										 |  |  | 				selection.style.left = `${selectionArea.x}px`; | 
					
						
							|  |  |  | 				selection.style.top = `${selectionArea.y}px`; | 
					
						
							|  |  |  | 				selection.style.width = `${selectionArea.width}px`; | 
					
						
							|  |  |  | 				selection.style.height = `${selectionArea.height}px`; | 
					
						
							| 
									
										
										
										
											2019-07-30 09:35:42 +02:00
										 |  |  | 			}; | 
					
						
							| 
									
										
										
										
											2018-05-24 18:32:30 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-07-30 09:35:42 +02:00
										 |  |  | 			const setSelectionSizeFromMouse = function(event) { | 
					
						
							| 
									
										
										
										
											2018-05-25 08:51:54 +01:00
										 |  |  | 				selectionArea.width = Math.max(1, event.clientX - draggingStartPos.x); | 
					
						
							|  |  |  | 				selectionArea.height = Math.max(1, event.clientY - draggingStartPos.y); | 
					
						
							| 
									
										
										
										
											2018-05-24 18:32:30 +01:00
										 |  |  | 				updateSelection(); | 
					
						
							| 
									
										
										
										
											2019-07-30 09:35:42 +02:00
										 |  |  | 			}; | 
					
						
							| 
									
										
										
										
											2018-05-24 18:32:30 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-07-30 09:35:42 +02:00
										 |  |  | 			const selection_mouseDown = function(event) { | 
					
						
							|  |  |  | 				selectionArea = { x: event.clientX, y: event.clientY, width: 0, height: 0 }; | 
					
						
							| 
									
										
										
										
											2018-05-25 08:51:54 +01:00
										 |  |  | 				draggingStartPos = { x: event.clientX, y: event.clientY }; | 
					
						
							| 
									
										
										
										
											2018-05-24 18:32:30 +01:00
										 |  |  | 				isDragging = true; | 
					
						
							|  |  |  | 				updateSelection(); | 
					
						
							| 
									
										
										
										
											2019-07-30 09:35:42 +02:00
										 |  |  | 			}; | 
					
						
							| 
									
										
										
										
											2018-05-24 18:32:30 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-07-30 09:35:42 +02:00
										 |  |  | 			const selection_mouseMove = function(event) { | 
					
						
							| 
									
										
										
										
											2018-05-24 18:32:30 +01:00
										 |  |  | 				if (!isDragging) return; | 
					
						
							|  |  |  | 				setSelectionSizeFromMouse(event); | 
					
						
							| 
									
										
										
										
											2019-07-30 09:35:42 +02:00
										 |  |  | 			}; | 
					
						
							| 
									
										
										
										
											2018-05-24 18:32:30 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-07-30 09:35:42 +02:00
										 |  |  | 			const selection_mouseUp = function(event) { | 
					
						
							| 
									
										
										
										
											2018-05-24 18:32:30 +01:00
										 |  |  | 				setSelectionSizeFromMouse(event); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				isDragging = false; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				overlay.removeEventListener('mousedown', selection_mouseDown); | 
					
						
							|  |  |  | 				overlay.removeEventListener('mousemove', selection_mouseMove); | 
					
						
							|  |  |  | 				overlay.removeEventListener('mouseup', selection_mouseUp); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				document.body.removeChild(overlay); | 
					
						
							|  |  |  | 				document.body.removeChild(selection); | 
					
						
							| 
									
										
										
										
											2018-05-25 08:51:54 +01:00
										 |  |  | 				document.body.removeChild(messageComp); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-06-01 16:12:49 +01:00
										 |  |  | 				console.info('jopext: selectionArea:', selectionArea); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-05-25 08:51:54 +01:00
										 |  |  | 				if (!selectionArea || !selectionArea.width || !selectionArea.height) return; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-05-26 15:53:50 +01:00
										 |  |  | 				// Need to wait a bit before taking the screenshot to make sure
 | 
					
						
							|  |  |  | 				// the overlays have been removed and don't appear in the
 | 
					
						
							|  |  |  | 				// screenshot. 10ms is not enough.
 | 
					
						
							| 
									
										
										
										
											2018-05-25 08:51:54 +01:00
										 |  |  | 				setTimeout(() => { | 
					
						
							|  |  |  | 					const content = { | 
					
						
							|  |  |  | 						title: pageTitle(), | 
					
						
							| 
									
										
										
										
											2018-06-01 15:50:11 +01:00
										 |  |  | 						crop_rect: selectionArea, | 
					
						
							| 
									
										
										
										
											2019-11-07 18:12:14 +00:00
										 |  |  | 						url: pageLocationOrigin() + location.pathname + location.search, | 
					
						
							| 
									
										
										
										
											2018-06-01 15:50:11 +01:00
										 |  |  | 						parent_id: command.parent_id, | 
					
						
							| 
									
										
										
										
											2018-09-23 18:03:11 +01:00
										 |  |  | 						tags: command.tags, | 
					
						
							| 
									
										
										
										
											2018-05-25 08:51:54 +01:00
										 |  |  | 					}; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 					browser_.runtime.sendMessage({ | 
					
						
							|  |  |  | 						name: 'screenshotArea', | 
					
						
							|  |  |  | 						content: content, | 
					
						
							| 
									
										
										
										
											2018-06-01 15:50:11 +01:00
										 |  |  | 						api_base_url: command.api_base_url, | 
					
						
							| 
									
										
										
										
											2018-05-25 08:51:54 +01:00
										 |  |  | 					}); | 
					
						
							| 
									
										
										
										
											2018-05-26 15:53:50 +01:00
										 |  |  | 				}, 100); | 
					
						
							| 
									
										
										
										
											2019-07-30 09:35:42 +02:00
										 |  |  | 			}; | 
					
						
							| 
									
										
										
										
											2018-05-24 18:32:30 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | 			overlay.addEventListener('mousedown', selection_mouseDown); | 
					
						
							|  |  |  | 			overlay.addEventListener('mousemove', selection_mouseMove); | 
					
						
							|  |  |  | 			overlay.addEventListener('mouseup', selection_mouseUp); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			return {}; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-07-30 09:35:42 +02:00
										 |  |  | 		} else if (command.name === 'pageUrl') { | 
					
						
							| 
									
										
										
										
											2019-05-09 23:41:52 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-11 01:09:48 +01:00
										 |  |  | 			let url = pageLocationOrigin() + location.pathname + location.search; | 
					
						
							| 
									
										
										
										
											2019-06-13 00:26:09 +01:00
										 |  |  | 			return clippedContentResponse(pageTitle(), url, getImageSizes(document), getAnchorNames(document)); | 
					
						
							| 
									
										
										
										
											2019-02-15 00:05:28 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-05-16 14:16:14 +01:00
										 |  |  | 		} else { | 
					
						
							| 
									
										
										
										
											2019-09-19 22:51:18 +01:00
										 |  |  | 			throw new Error(`Unknown command: ${JSON.stringify(command)}`); | 
					
						
							| 
									
										
										
										
											2018-05-16 14:16:14 +01:00
										 |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	async function execCommand(command) { | 
					
						
							|  |  |  | 		const response = await prepareCommandResponse(command); | 
					
						
							| 
									
										
										
										
											2018-05-24 18:32:30 +01:00
										 |  |  | 		browser_.runtime.sendMessage(response); | 
					
						
							| 
									
										
										
										
											2018-05-16 14:16:14 +01:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-05-24 18:32:30 +01:00
										 |  |  | 	browser_.runtime.onMessage.addListener((command) => { | 
					
						
							| 
									
										
										
										
											2018-05-16 14:16:14 +01:00
										 |  |  | 		console.info('jopext: Got command:', command); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		execCommand(command); | 
					
						
							|  |  |  | 	}); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-07-30 09:35:42 +02:00
										 |  |  | })(); |