(function() {
			function onCommand(e) {
				let el = e.target;
				if (el.getAttribute("cui-areatype") === "menu-panel") {
					try {
						let ownerWindow = el.ownerDocument.defaultView;
						let {area} = ownerWindow.CustomizableUI.getPlacementOfWidget(el.id);
						let view = el.getAttribute("panelview");
						onDTAViewShowing(el, $(view));
						ownerWindow.PanelUI.showSubView(view, el, area);
						e.preventDefault();
						return false;
					}
					catch (ex) {
						log(LOG_ERROR, "failed to show panel", ex);
					}
				}
				$(el.getAttribute("buttoncommand")).doCommand();
			}
			let dta_button = $t('dta-button');
			dta_button.addEventListener('popupshowing', onDTAShowing, true);
			unloadWindow(window, () => dta_button.removeEventListener('popupshowing', onDTAShowing, true));
			dta_button.addEventListener('command', onCommand, true);
			unloadWindow(window, () => dta_button.removeEventListener('command', onCommand, true));

			setupDrop(dta_button, function(url, ref) {
				DTA.saveSingleItem(window, false, {
					"url": url,
					"referrer": ref,
					"description": "",
					"isPrivate": isWindowPrivate(window)
				});
			});

			let dta_turbo_button = $t('dta-turbo-button');
			dta_turbo_button.addEventListener('popupshowing', onDTAShowing, true);
			unloadWindow(window, () => dta_turbo_button.removeEventListener('popupshowing', onDTAShowing, true));
			dta_turbo_button.addEventListener('command', onCommand, true);
			unloadWindow(window, () => dta_turbo_button.removeEventListener('command', onCommand, true));

			setupDrop(dta_turbo_button, function(url, ref) {
				let item = {
					"url": url,
					"referrer": ref,
					"description": "",
					"isPrivate": isWindowPrivate(window)
				};
				try {
					DTA.saveSingleItem(window, true, item);
				}
				catch (ex) {
					log(LOG_ERROR, "failed to turbo drop, retrying normal", ex);
					DTA.saveSingleItem(window, false, item);
				}
			});

			unloadWindow(window, () => detachOneClick());
		})();
	function setupDrop(elem, func) {
		function ondragover(event) {
			try {
				if (event.dataTransfer.types.contains("text/x-moz-url")) {
					event.dataTransfer.dropEffect = "link";
					event.preventDefault();
				}
			}
			catch (ex) {
				log(LOG_ERROR, "failed to process ondragover", ex);
			}
		}
		async function ondrop(event) {
			try {
				let url = event.dataTransfer.getData("URL");
				if (!url) {
					return;
				}
				url = Services.io.newURI(url, null, null);
				url = new DTA.URL(DTA.getLinkPrintMetalink(url) || url);
				let {ref, title} = await getFocusedDetails();
				ref = makeURI(ref);
				func(url, ref);
			}
			catch (ex) {
				log(LOG_ERROR, "failed to process ondrop", ex);
			}
		}
		elem.addEventListener("dragover", ondragover, true);
		elem.addEventListener("drop", ondrop, true);
		unloadWindow(window, function() {
			elem.removeEventListener("dragover", ondragover, true);
			elem.removeEventListener("drop", ondrop, true);
		});
	}
Example #3
0
	watchWindows("chrome://global/content/customizeToolbar.xul", function(window, document) {
		let ss = document.createProcessingInstruction(
			"xml-stylesheet",
			'href="chrome://dta/skin/integration/style.css" type="text/css"'
			);
		document.insertBefore(ss, document.documentElement);
		unloadWindow(window, () => ss.parentNode.removeChild(ss));
	});
Example #4
0
		window.setTimeout(function dta_firewalkswithme() {
			try {
				fire._unloaders = [];
				fire._runUnloaders = function() {
					for (let i = 0; i < fire._unloaders.length; ++i) {
						try {
							fire._unloaders[i]();
						}
						catch (ex) {
						}
					}
					fire._unloaders = [];
				};
				fire.addFireListener = function(elem, type) {
					if (!elem) {
						return;
					}
					fire._unloaders.push(() => elem.removeEventListener(type, fire, false));
					elem.addEventListener(type, fire, false);
				};
				fire.addFireListener($("dtaCtxCompact").parentNode, "popupshowing");
				fire.addFireListener($("dtaToolsMenu").parentNode, "popupshowing");
				let appmenu = $("dtaAppMenu");
				if (appmenu) {
					fire.addFireListener($("appmenu-popup"), "popupshowing");
				}
				let toolsmenu = $("menu_ToolsPopup") || $("taskPopup");
				if (toolsmenu) {
					fire.addFireListener(toolsmenu, "popupshowing");
				}
				let panelbutton = $("PanelUI-button");
				if (panelbutton) {
					fire.addFireListener(panelbutton, "command");
				}
				fire.addFireListener($("dta:regular"), "command");
				fire.addFireListener($("dta-button"), "command");
				fire.addFireListener($("dta-button"), "popupshowing");
				fire.addFireListener($("dta-button"), "dragover");
				fire.addFireListener($("dta:turbo"), "command");
				fire.addFireListener($("dta-turbo-button"), "command");
				fire.addFireListener($("dta-turbo-button"), "popupshowing");
				fire.addFireListener($("dta-turbo-button"), "dragover");
				fire.addFireListener($("dta:turboselect"), "command");
				fire.addFireListener($("dta:manager"), "command");
				fire.addFireListener($("cmd_CustomizeToolbars"), "command");
				unloadWindow(window, function() {
					fire._runUnloaders();
				});
			}
			catch (ex) {
				log(LOG_ERROR, "stub installer failed!", ex);
			}
		}, 100);
exports.load = function load(window, outerEvent) {
	let document = window.document;
	let setTimeoutOnlyFun = function(c, ...args) {
		if (typeof(c) !== "function") {
			throw new Error("do not call me with a string!");
		}
		return window.setTimeout.call(window, c, ...args);
	};
	let setIntervalOnlyFun = function(c, ...args) {
		if (typeof(c) !== "function") {
			throw new Error("do not call me with a string!");
		}
		return window.setInterval(c, ...args);
	};
	let clearInterval = window.clearInterval;
	let gBrowser = window.gBrowser;

	function $(...args) {
		if (args.length === 1) {
			return document.getElementById(args[0]);
		}
		let elements = [];
		for (let i = 0, e = args.length; i < e; ++i) {
			let id = args[i];
			let element = document.getElementById(id);
			if (element) {
				elements.push(element);
			}
			else {
				log(LOG_ERROR, "requested a non-existing element: " + id);
			}
		}
		return elements;
	}

	let _selector = null;

	let _notify = function (title, message, priority, mustAlert, timeout) {
		switch (Preferences.getExt("notification2", 1)) {
		/* jshint strict:true, globalstrict:true, -W086 */
		case 1:
			if ('PopupNotifications' in window) {
				try {
					timeout = timeout || 2500;
					let notification = window.PopupNotifications.show(
							gBrowser.selectedBrowser,
							'downthemall',
							message,
							'downthemall-notification-icon',
							null,
							null,
							{timeout: timeout}
							);
					setTimeoutOnlyFun(function() {
						window.PopupNotifications.remove(notification);
					}, timeout);
					return;
				}
				catch (ex) {
					// no op
				}
				return;
			}
			// fall through in case we got not doorhangers
		case 2:
		/* jshint strict:true, globalstrict:true, +W086 */
			require("support/alertservice")
				.show("DownThemAll!", message, null, "chrome://dtaicon/content/icon64.png");
			return;
		default:
			// no notification
			return;
		}
	};

	function notifyError(title, message) {
		return _notify(title, message, 'PRIORITY_CRITICAL_HIGH', true, 1500);
	}
	function notifyInfo(message) {
		if (!_selector) {
			_notify('', message, 'PRIORITY_INFO_MEDIUM', false);
		}
	}

	function selectButton() {
		return $('dta-turboselect-button') || {checked: false};
	}
	function getMethod(method, data, target, browser) {
		let b = browser || gBrowser.selectedBrowser;
		return new Promise((resolve, reject) => {
			let job = ++findLinksJob;
			let result = m => {
				b.messageManager.removeMessageListener(`DTA:${method}:${job}`, result);
				if (m.data.exception) {
					reject(m.data.exception);
				}
				else {
					resolve(m.data);
				}
			};
			b.messageManager.addMessageListener(`DTA:${method}:${job}`, result);
			if (!target) {
				b.messageManager.sendAsyncMessage(`DTA:${method}`, {job:job, args: data});
			}
			else {
				b.messageManager.sendAsyncMessage(`DTA:${method}`, {job:job, args: data}, {target:target});
			}
		});
	}
	function getCurrentLocations() {
		return getMethod("getLocations");
	}
	function getFocusedDetails() {
		return getMethod("getFocusedDetails");
	}
	function getFormData(target) {
		return getMethod("getFormData", null, target);
	}
	function findBrowsers(all) {
		let browsers = [];
		if (!all) {
			browsers.push(gBrowser.selectedBrowser);
			return browsers;
		}
		for (let e of gBrowser.browsers) {
			browsers.push(e);
		}
		return browsers;
	}

	async function findLinks(turbo, all) {
		try {
			if (!all && turbo && Preferences.getExt('rememberoneclick', false)) {
				all = Preferences.getExt('lastalltabs', false);
			}
			if (turbo && all) {
				Preferences.setExt('lastalltabs', all);
			}

			if (turbo) {
				log(LOG_INFO, "findLinks(): DtaOneClick request from the user");
			}
			else {
				log(LOG_INFO, "findLinks(): DtaStandard request from the user");
			}

			let collectedUrls = [];
			let collectedImages = [];
			let urlsLength = 0;
			let imagesLength = 0;

			// long running fetching may confuse users, hence give them a hint that
			// stuff is happening
			let intervalfunc;
			let _updateInterval = setIntervalOnlyFun(intervalfunc = (function(isStarter) {
				if (isStarter) {
					clearInterval(_updateInterval);
					_updateInterval = setIntervalOnlyFun(intervalfunc, 150, false);
				}
				if (urlsLength + imagesLength) {
					notifyProgress(bundle.getFormattedString('processing.label', [urlsLength, imagesLength]));
				}
				else {
					notifyProgress(bundle.getString('preparing.label'));
				}
			}), 1750, true);

			try {
				let promises = [];
				let job = findLinksJob++;
				for (let b of findBrowsers(all)) {
					let browser = b;
					promises.push(new Promise((resolve, reject) => {
						let progress = m => {
							urlsLength += m.data.urls;
							imagesLength += m.data.images;
						};
						let result = m => {
							browser.messageManager.removeMessageListener("DTA:findLinks:progress:" + job, progress);
							browser.messageManager.removeMessageListener("DTA:findLinks:" + job, result);
							resolve(m.data);
						};
						browser.messageManager.addMessageListener("DTA:findLinks:progress:" + job, progress);
						browser.messageManager.addMessageListener("DTA:findLinks:" + job, result);
						browser.messageManager.sendAsyncMessage("DTA:findLinks", {
							job: job,
							honorSelection: !all,
							recognizeTextLinks: recognizeTextLinks
						});
					}));
				}

				let nonnull = function(e) {
					return !!e;
				};
				let transposeURIs = function(e) {
					try {
						e.url = makeURI(e.url);
						if (!e.url) {
							return null;
						}
						e.referrer = makeURI(e.referrer);
						return e;
					}
					catch (ex) {
						return null;
					}
				};
				for (let p of promises) {
					let {urls, images, locations} = await p;
					if (!urls.length && !images.length && !locations.length) {
						continue;
					}
					collectedUrls = collectedUrls.concat(mapFilterInSitu(urls, transposeURIs, nonnull));
					collectedImages = collectedImages.concat(mapFilterInSitu(images, transposeURIs, nonnull));
					for (let l of locations) {
						let sniffed = getSniffedInfoFromLocation(l);
						for (let s of sniffed) {
							let o = {
								"url": new DTA.URL(s.url),
								"fileName": s.name,
								"referrer": s.ref,
								"description": bundle.getString('sniffedvideo')
							};
							collectedUrls.push(o);
							collectedImages.push(o);
						}
					}
				}
				unique(collectedUrls);
				for (let e of collectedUrls) {
					if (!e.description) {
						e.description = e.defaultDescription || "";
					}
					delete e.defaultDescription;
					e.description = identity(e.description);
				}

				unique(collectedImages);
				for (let e of collectedImages) {
					if (!e.description) {
						e.description = e.defaultDescription || "";
					}
					delete e.defaultDescription;
					e.description = identity(e.description);
				}

				// clean up the "hint" notification from above
				clearInterval(_updateInterval);
				notifyProgress();

				log(LOG_DEBUG, "findLinks(): finishing...");
				if (!collectedUrls.length && !collectedImages.length) {
					notifyError(bundle.getString('error'), bundle.getString('error.nolinks'));
					return;
				}

				DTA.setPrivateMode(window, collectedUrls);
				DTA.setPrivateMode(window, collectedImages);

				if (turbo) {
					DTA.turboSaveLinkArray(window, collectedUrls, collectedImages, function(queued) {
						if (!queued) {
							DTA.saveLinkArray(
								window,
								collectedUrls,
								collectedImages,
								bundle.getString('error.information')
							);
						}
						else if (typeof queued === 'number') {
							notifyInfo(bundle.getFormattedString('queuedn', [queued]));
						}
						else {
							notifyInfo(bundle.getFormattedString('queued', [queued.url]));
						}
					});
					return;
				}
				DTA.saveLinkArray(window, collectedUrls, collectedImages);
			}
			catch (ex) {
				log(LOG_ERROR, "findLinksTask", ex);
			}
		}
		catch(ex) {
			log(LOG_ERROR, 'findLinks', ex);
		}
	}

	function findSingleLink(turbo) {
		if (!window.gContextMenu.onSaveableLink) {
			return;
		}
		saveSingleLinkAsync(turbo, "a", window.gContextMenu.target);
	}

	function findSingleImg(turbo) {
		saveSingleLinkAsync(turbo, "img", window.gContextMenu.target);
	}

	function _findSingleMedia(turbo, tag) {
		saveSingleLinkAsync(turbo, tag, window.gContextMenu.target, ctx.mediaURL);
	}
	function findSingleVideo(turbo) {
		_findSingleMedia(turbo, 'video');
	}
	function findSingleAudio(turbo) {
		_findSingleMedia(turbo, 'audio');
	}

	function findSniff(event, turbo) {
		const target = event.explicitOriginalTarget;
		if (target.classList.contains("dta-sniff-element") && target.info) {
			DTA.saveSingleItem(window, turbo, target.info);
		}
	}

	async function saveSingleLinkAsync(turbo, what, target, linkhint) {
		try {
			let data = await getMethod("saveTarget", {what:what, linkhint: linkhint}, target);
			let url = makeURI(data, true);
			if (!url) {
				throw new Error("invalid URL");
			}
			let ref = makeURI(data.ref);

			const item = {
				url: url,
				description: data.desc || trimMore(data.title || ""),
				referrer: ref,
				isPrivate: isWindowPrivate(window)
			};
			if (data.download) {
				data.download = data.download.trim();
				if (data.download) {
					item.fileName = data.download;
				}
			}
			if (turbo) {
				try {
					DTA.saveSingleItem(window, true, item);
					notifyInfo(bundle.getFormattedString('queued', [url]));
					return;
				}
				catch (ex) {
					log(LOG_ERROR, 'saveSingleLink', ex);
					notifyError(bundle.getString('error'), bundle.getString('error.information'));
				}
			}
			DTA.saveSingleItem(window, false, item);
		}
		catch (ex) {
			log(LOG_ERROR, "Failed to process single link", ex);
			notifyError(bundle.getString('error'), bundle.getString('errorcannotdownload'));
		}
	}

	async function findForm(turbo) {
		try {
			let data = await getFormData(window.gContextMenu.target);

			let action = makeURI(data);
			if (!action) {
				throw new Error("Invalid Form URL");
			}

			if (data.method === 'post') {
				let ss = new Instances.StringInputStream(data.values, -1);
				let ms = new Instances.MimeInputStream();
				ms.addContentLength = true;
				ms.addHeader('Content-Type', 'application/x-www-form-urlencoded');
				ms.setData(ss);

				let sis = new Instances.ScriptableInputStream(ms);
				let postData = '';
				let avail = 0;
				while ((avail = sis.available())) {
					postData += sis.read(avail);
				}
				sis.close();
				ms.close();
				ss.close();

				action.postData = postData;
			}
			else {
				action.url.query = data.values;
				action.url.ref = '';
			}

			let ref = makeURI(data.ref);
			let defaultDescription = trimMore(data.title || "");
			let desc = data.desc || defaultDescription;

			let item = {
				"url": action,
				"referrer": ref,
				"description": desc,
				"isPrivate": isWindowPrivate(window)
			};

			if (turbo) {
				try {
					DTA.saveSingleItem(window, true, item);
					return;
				}
				catch (ex) {
					log(LOG_ERROR, 'findSingleLink', ex);
					notifyError(bundle.getString('error'), bundle.getString('error.information'));
				}
			}
			DTA.saveSingleItem(window, false, item);
		}
		catch (ex) {
			log(LOG_ERROR, 'findForm', ex);
		}
	}

	let notifyProgress = function(message) {
		try {
			let _n = null;
			if ('PopupNotifications' in window) {
				notifyProgress = function(message) {
					if (!Preferences.getExt("notification2", 1) !== 1) {
						return;
					}
					if (!message && _n) {
						window.PopupNotifications.remove(_n);
						_n = null;
						return;
					}
					if (!message) {
						return;
					}
					_n = window.PopupNotifications.show(
						gBrowser.selectedBrowser,
						'downthemall',
						message,
						'downthemall-notification-icon'
						);
				};
				return notifyProgress(message);
			}
			notifyProgress = function() {};;
			return notifyProgress();
		}
		catch (ex) {
			log(LOG_ERROR, "np", ex);
			notifyProgress = function() {};
		}
	};

	function saveSelected(m) {
		try {
			let data = m.data;
			let url = makeURI(data, true);
			if (!url) {
				throw new Error("Invalid selected URL");
			}

			let ref = makeURI(data.ref);
			const item = {
				url: url,
				description: data.desc || trimMore(data.title || ""),
				referrer: ref,
				isPrivate: isWindowPrivate(window)
			};
			if (data.download) {
				data.download = data.download.trim();
				if (data.download) {
					item.fileName = data.download;
				}
			}
			try {
				DTA.saveSingleItem(window, true, item);
				notifyInfo(bundle.getFormattedString('queued', [url]));
				return;
			}
			catch (ex) {
				log(LOG_ERROR, 'saveSingleLink', ex);
				notifyError(bundle.getString('error'), bundle.getString('error.information'));
			}
			DTA.saveSingleItem(window, false, item);
		}
		catch (ex) {
			log(LOG_ERROR, "Failed to process single link", ex);
			notifyError(bundle.getString('error'), bundle.getString('errorcannotdownload'));
		}
	}

	function newFrameScript(m) {
		if (selectButton().checked) {
			attachOneClick();
		}
	}

	window.messageManager.addMessageListener("DTA:selected", saveSelected);
	window.messageManager.addMessageListener("DTA:new", newFrameScript);
	unloadWindow(window, () => {
		window.messageManager.removeMessageListener("DTA:selected", saveSelected);
		window.messageManager.removeMessageListener("DTA:new", newFrameScript);
	});

	// these are only valid after the load event.
	let direct = {};
	let compact = {};
	let tools = {};

	let ctxBase = $('dtaCtxCompact');
	let toolsBase = $('dtaToolsMenu');
	let toolsMenu = $('dtaToolsPopup');
	let toolsSep = $('dtaToolsSep');

	let ctx = ctxBase.parentNode;
	let menu = toolsBase.parentNode;

	function onContextShowing(evt) {
		try {
			let ctx = window.gContextMenu;
			let ctxdata = window.gContextMenuContentData;
			// get settings
			let items = Preferences.getExt("ctxmenu", "1,1,0").split(",").map(e => parseInt(e, 10));
			let showCompact = Preferences.getExt("ctxcompact", false);

			let menu;
			if (showCompact) {
				ctxBase.hidden = false;
				menu = compact;
			}
			else {
				ctxBase.hidden = true;
				menu = direct;
			}

			// hide all
			for (let i in menu) {
				direct[i].hidden = true;
				compact[i].hidden = true;
			}
			// show nothing!
			if (items.indexOf(1) === -1) {
				ctxBase.hidden = true;
				return;
			}

			// setup menu items
			// show will hold those that will be shown
			let show = [];

			let sel = ctx && ctx.isContentSelected;
			if (sel) {
				if (items[0]) {
					show.push(menu.DTASel);
				}
				if (items[1]) {
					show.push(menu.TDTASel);
				}
			}

			// hovering an image or link
			if (ctx && (ctx.onLink || ctx.onImage || ctx.onVideo || ctx.onAudio)) {
				if (items[0]) {
					if (ctx.onLink) {
						show.push(menu.SaveLink);
					}
					if (ctx.onImage) {
						show.push(menu.SaveImg);
					}
					if (ctx.onVideo) {
						show.push(menu.SaveVideo);
					}
					if (ctx.onAudio) {
						show.push(menu.SaveAudio);
					}
				}
				if (items[1]) {
					if (ctx.onLink) {
						show.push(menu.SaveLinkT);
					}
					if (ctx.onImage) {
						show.push(menu.SaveImgT);
					}
					if (ctx.onVideo) {
						show.push(menu.SaveVideoT);
					}
					if (ctx.onAudio) {
						show.push(menu.SaveAudioT);
					}
				}
			}
			else if (ctxdata && ctxdata.addonInfo && ctxdata.addonInfo["DTA:onform"]) {
				if (items[0]) {
					show.push(menu.SaveForm);
				}
				if (items[1]) {
					show.push(menu.SaveFormT);
				}
			}
			// regular
			else if (!sel) {
				if (items[0]) {
					show.push(menu.DTA);
				}
				if (items[1]) {
					show.push(menu.TDTA);
				}
			}

			// prefs
			if (items[2]) {
				show.push(menu.Pref);
				if (compact && (items[0] || items[1])) {
					show.push(menu.SepPref);
				}
			}

			// show the seperators, if required.
			let n = menu.SepFront;
			while ((n = n.previousSibling)) {
				if (n.hidden) {
					continue;
				}
				if (n.nodeName !== 'menuseparator') {
					show.push(menu.SepFront);
				}
				break;
			}
			n = menu.SepBack;
			while ((n = n.nextSibling)) {
				if (n.hidden) {
					continue;
				}
				if (n.nodeName !== 'menuseparator') {
					show.push(menu.SepBack);
				}
				break;
			}
			for (let node of show) {
				node.hidden = false;
			}
		}
		catch(ex) {
			log(LOG_ERROR, "DTAContext(): ", ex);
		}
	}

	function onToolsShowing(evt) {
		try {

			// get settings
			let menu = Preferences.getExt("toolsmenu", "1,1,1").split(",").map(e => parseInt(e, 10));

			// all hidden...
			let hidden = Preferences.getExt("toolshidden", false);
			for (let i in tools) {
				tools[i].hidden = hidden;
			}
			toolsBase.hidden = hidden;
			if (hidden) {
				return;
			}

			let compact = menu.indexOf(0) !== -1;

			// setup menu items
			// show will hold those that will be shown
			let show = [];

			if (menu[0]) {
				show.push('DTA');
			}
			if (menu[1]) {
				show.push('TDTA');
			}
			// prefs
			if (menu[2]) {
				show.push('Manager');
			}
			toolsSep.hidden = menu.indexOf(0) === -1;
			toolsBase.setAttribute('label',
				bundle.getString(menu.indexOf(1) !== -1 ? 'moredtatools' : 'simpledtatools'));

			// show the items.
			for (let i in tools) {
				let cur = tools[i];
				if (show.indexOf(i) === -1) {
					toolsMenu.insertBefore(cur, toolsSep);
				}
				else {
					toolsBase.parentNode.insertBefore(cur, toolsBase);
				}
			}
		}
		catch(ex) {
			log(LOG_ERROR, "DTATools(): ", ex);
		}
	}

	async function onDTAShowing(evt) {
		let menu = evt.target;
		for (let n of menu.querySelectorAll(".dta-sniff-element")) {
			n.parentNode.removeChild(n);
		}
		if (!Preferences.getExt('listsniffedvideos', false)) {
			return;
		}
		const locations = await getCurrentLocations();
		let sniffed = [];
		for (let l of locations) {
			sniffed = sniffed.concat(getSniffedInfoFromLocation(l));
		}
		if (!sniffed.length) {
			return;
		}

		let sep = document.createElement("menuseparator");
		sep.className = "dta-sniff-element";
		menu.appendChild(sep);

		let cmd = menu.parentNode.getAttribute("buttoncommand") + "-sniff";
		for (let s of sniffed) {
			let o = {
				"url": new DTA.URL(s.url),
				"referrer": s.ref,
				"fileName": s.name,
				"description": bundle.getString("sniffedvideo"),
				"isPrivate": isWindowPrivate(window)
			};
			let mi = document.createElement("menuitem");
			mi.setAttribute("label", strfn.cropCenter(s.name, 60));
			mi.setAttribute("tooltiptext", o.url.spec);
			mi.setAttribute("image", getIcon(s.name));
			mi.setAttribute("command", cmd);
			mi.info = o;
			mi.className = "dta-sniff-element menuitem-iconic";
			menu.appendChild(mi);
		}
	}

	async function onDTAViewShowing(button, view) {
		for (let n of view.querySelectorAll(".dta-sniff-element")) {
			n.parentNode.removeChild(n);
		}
		if (!Preferences.getExt('listsniffedvideos', false)) {
			return;
		}
		const locations = await getCurrentLocations();
		let sniffed = [];
		for (let l of locations) {
			sniffed = sniffed.concat(getSniffedInfoFromLocation(l));
		}
		if (!sniffed.length) {
			return;
		}

		let menu = view.querySelector(".panel-subview-body");

		let sep = document.createElement("menuseparator");
		sep.className = "dta-sniff-element";
		menu.appendChild(sep);

		let cmd = button.getAttribute("buttoncommand") + "-sniff";
		for (let s of sniffed) {
			let o = {
				"url": new DTA.URL(s.url),
				"referrer": s.ref,
				"fileName": s.name,
				"description": bundle.getString("sniffedvideo"),
				"isPrivate": isWindowPrivate(window)
			};
			let mi = document.createElement("toolbarbutton");
			mi.setAttribute("label", strfn.cropCenter(s.name, 60));
			mi.setAttribute("tooltiptext", o.url.spec);
			mi.setAttribute("image", getIcon(s.name));
			mi.setAttribute("command", cmd);
			mi.info = o;
			mi.className = "dta-sniff-element subviewbutton cui-withicon";
			menu.appendChild(mi);
		}
	}

	function attachOneClick() {
		window.messageManager.broadcastAsyncMessage("DTA:selector", {
			enable: true,
			bgimgs: Preferences.getExt('selectbgimages', false)
		});
	}

	function detachOneClick() {
		window.messageManager.broadcastAsyncMessage("DTA:selector", {enable: false});
	}

	let _keyActive =  false;
	function onKeyDown(evt) {
		return; // XXX reenable when polished
		/*if (_keyActive) {
			return;
		}
		if (evt.shiftKey && evt.ctrlKey) {
			_keyActive = true;
			selectButton().checked = true;
			attachOneClick();
		}*/
	}
	function onKeyUp(evt) {
		return; // XXX reenable when polished
		/*if (!_keyActive) {
			return;
		}
		if (evt.shiftKey) {
			_keyActive = false;
			selectButton().checked = false;
			detachOneClick();
		}*/
	}
	function onToolbarInstall(event) {
		// white list good locations
		// note that this is only performed to keep the number of event listeners down
		// The remote site does not get special privileges!
		try {
			if (!/^about:downthemall/.test(event.target.location) &&
				event.target.location.host !== "about.downthemall.net") {
				return;
			}
		}
		catch (ex) {
			// might be another location where there is no .host
			return;
		}
		let tbinstall, tbunload, win = event.target;
		win.addEventListener("DTA:toolbarinstall", tbinstall = (function() {
			win.removeEventListener("DTA:toolbarinstall", tbinstall, true);
			win.removeEventListener("unload", tbunload, true);
			Mediator.showToolbarInstall(window);
		}), true);
		win.addEventListener("unload", tbunload = (function() {
			win.removeEventListener("DTA:toolbarinstall", tbinstall, true);
			win.removeEventListener("unload", tbunload, true);
		}), true);
	}

	function onBlur(evt) {
		return; // XXX reenable when polished
		/*// when the window loses focus the keyup might not be received.
		// better toggle back
		if (!_keyActive) {
			return;
		}
		_keyActive = false;
		selectButton().checked = false;
		detachOneClick();
		*/
	}

	function toggleOneClick() {
		if (selectButton().checked) {
			attachOneClick();
		}
		else {
			detachOneClick();
		}
	}


	function setupDrop(elem, func) {
		function ondragover(event) {
			try {
				if (event.dataTransfer.types.contains("text/x-moz-url")) {
					event.dataTransfer.dropEffect = "link";
					event.preventDefault();
				}
			}
			catch (ex) {
				log(LOG_ERROR, "failed to process ondragover", ex);
			}
		}
		async function ondrop(event) {
			try {
				let url = event.dataTransfer.getData("URL");
				if (!url) {
					return;
				}
				url = Services.io.newURI(url, null, null);
				url = new DTA.URL(DTA.getLinkPrintMetalink(url) || url);
				let {ref, title} = await getFocusedDetails();
				ref = makeURI(ref);
				func(url, ref);
			}
			catch (ex) {
				log(LOG_ERROR, "failed to process ondrop", ex);
			}
		}
		elem.addEventListener("dragover", ondragover, true);
		elem.addEventListener("drop", ondrop, true);
		unloadWindow(window, function() {
			elem.removeEventListener("dragover", ondragover, true);
			elem.removeEventListener("drop", ondrop, true);
		});
	}

	function $t(...args) {
		let rv = [];
		for (let i = 0, e = args.length; i < e; ++i) {
			let id = args[i];
			let element = document.getElementById(id);
			if (element) {
					rv.push(element);
					continue;
			}
			if (id in paletteItems) {
				rv.push(paletteItems[id]);
				continue;
			}
		}
		return rv.length === 1 ? rv[0] : rv;
	}

	(function initMenusAndCommands(evt) {
		function bindEvt(evt, fn) {
			return function (e) {
				e.addEventListener(evt, fn, true);
				unloadWindow(window, () => e.removeEventListener(evt, fn, true));
			};
		}

		try {
			let cont = $('dtaCtxSubmenu');

			for (let id of MENU_ITEMS) {
				compact[id] = $('dtaCtx' + id);
				let node = $('dtaCtx' + id).cloneNode(true);
				node.setAttribute('id', node.id + "-direct");
				ctx.insertBefore(node, ctxBase.nextSibling);
				direct[id] = node;
				unloadWindow(window, () => node.parentNode.removeChild(node));
			}

			// prepare tools
			for (let e of ['DTA', 'TDTA', 'Manager']) {
				tools[e] = $('dtaTools' + e);
			}

			let f = bindEvt("command", () => findLinks(false));
			f($("dta:regular"));
			f($("dta:regular-sel"));
			bindEvt("command", () => findLinks(false, true))($("dta:regular-all"));
			bindEvt("command", () => findSingleLink(false))($("dta:regular-link"));
			bindEvt("command", () => findSingleImg(false))($("dta:regular-img"));
			bindEvt("command", () => findSingleVideo(false))($("dta:regular-video"));
			bindEvt("command", () => findSingleAudio(false))($("dta:regular-audio"));
			bindEvt("command", () => findForm(false))($("dta:regular-form"));
			bindEvt("command", e => findSniff(e, false))($("dta:regular-sniff"));

			f = bindEvt("command", () => findLinks(true));
			f($("dta:turbo"));
			f($("dta:turbo-sel"));
			bindEvt("command", () => findLinks(true, true))($("dta:turbo-all"));
			bindEvt("command", () => findSingleLink(true))($("dta:turbo-link"));
			bindEvt("command", () => findSingleImg(true))($("dta:turbo-img"));
			bindEvt("command", () => findSingleVideo(true))($("dta:turbo-video"));
			bindEvt("command", () => findSingleAudio(true))($("dta:turbo-audio"));
			bindEvt("command", () => findForm(true))($("dta:turbo-form"));
			bindEvt("command", e => findSniff(e, true))($("dta:turbo-sniff"));

			bindEvt("command", () => toggleOneClick())($("dta:turboselect"));
			bindEvt("command", () => DTA.openManager(window))($("dta:manager"));
			bindEvt("command", () => Mediator.showPreferences(window))($("dta:prefs"));
			bindEvt("command", () => Mediator.showToolbarInstall(window))($("dta:tbinstall"));
			bindEvt("command", () => Mediator.showAbout(window))($("dta:about"));

			bindEvt("popupshowing", onContextShowing)(ctx);
			bindEvt("popupshowing", onToolsShowing)(menu);
		}
		catch (ex) {
			Components.utils.reportError(ex);
			log(LOG_ERROR, "DCO::init()", ex);
		}
	})();

	/*window.addEventListener("keydown", onKeyDown, false);
	unloadWindow(window, function() window.removeEventListener("keydown", onKeyDown, false));

	window.addEventListener("keyup", onKeyUp, false);
	unloadWindow(window, function() window.removeEventListener("keyup", onKeyUp, false));

	window.addEventListener("blur", onBlur, true);
	unloadWindow(window, function() window.removeEventListener("blur", onBlur, true));*/

	let appcontent = document.getElementById("appcontent");
	if (appcontent) {
		appcontent.addEventListener("DOMContentLoaded", onToolbarInstall, true);
		unloadWindow(window, () => appcontent.removeEventListener("DOMContentLoaded", onToolbarInstall, true));
	}

	/* Toolbar buttons */

	// Santas little helper, palette items + lookup
	let paletteItems = {};
	try {
		let palette = $('navigator-toolbox').palette;
		for (let c = palette.firstChild; c; c = c.nextSibling) {
			if (c.id) {
				paletteItems[c.id] = c;
			}
		}
	}
	catch (ex) {
		log(LOG_ERROR, "Failed to parse palette", ex);
	}

	try {
		(function() {
			function onCommand(e) {
				let el = e.target;
				if (el.getAttribute("cui-areatype") === "menu-panel") {
					try {
						let ownerWindow = el.ownerDocument.defaultView;
						let {area} = ownerWindow.CustomizableUI.getPlacementOfWidget(el.id);
						let view = el.getAttribute("panelview");
						onDTAViewShowing(el, $(view));
						ownerWindow.PanelUI.showSubView(view, el, area);
						e.preventDefault();
						return false;
					}
					catch (ex) {
						log(LOG_ERROR, "failed to show panel", ex);
					}
				}
				$(el.getAttribute("buttoncommand")).doCommand();
			}
			let dta_button = $t('dta-button');
			dta_button.addEventListener('popupshowing', onDTAShowing, true);
			unloadWindow(window, () => dta_button.removeEventListener('popupshowing', onDTAShowing, true));
			dta_button.addEventListener('command', onCommand, true);
			unloadWindow(window, () => dta_button.removeEventListener('command', onCommand, true));

			setupDrop(dta_button, function(url, ref) {
				DTA.saveSingleItem(window, false, {
					"url": url,
					"referrer": ref,
					"description": "",
					"isPrivate": isWindowPrivate(window)
				});
			});

			let dta_turbo_button = $t('dta-turbo-button');
			dta_turbo_button.addEventListener('popupshowing', onDTAShowing, true);
			unloadWindow(window, () => dta_turbo_button.removeEventListener('popupshowing', onDTAShowing, true));
			dta_turbo_button.addEventListener('command', onCommand, true);
			unloadWindow(window, () => dta_turbo_button.removeEventListener('command', onCommand, true));

			setupDrop(dta_turbo_button, function(url, ref) {
				let item = {
					"url": url,
					"referrer": ref,
					"description": "",
					"isPrivate": isWindowPrivate(window)
				};
				try {
					DTA.saveSingleItem(window, true, item);
				}
				catch (ex) {
					log(LOG_ERROR, "failed to turbo drop, retrying normal", ex);
					DTA.saveSingleItem(window, false, item);
				}
			});

			unloadWindow(window, () => detachOneClick());
		})();
	}
	catch (ex) {
		log(LOG_ERROR, "Init TBB failed", ex);
	}

	if (outerEvent) {
		log(LOG_DEBUG, "replaying event");
		let target = outerEvent.target;
		let type = outerEvent.type;
		if (type === "popupshowing") {
			switch(target.id) {
				case "menu_ToolsPopup":
					onToolsShowing(outerEvent);
					break;
				case "contentAreaContextMenu":
					onContextShowing(outerEvent);
					break;
				default:
					log(LOG_DEBUG, "dispatching new event");
					let replayEvent = document.createEvent("Events");
					replayEvent.initEvent(type, true, true);
					target.dispatchEvent(replayEvent);
					break;
			}
		}
		else if (type === "command" && target.id !== "cmd_CustomizeToolbars") {
			target.doCommand();
		}
	}
	log(LOG_DEBUG, "dTa integration done");
};
			return function (e) {
				e.addEventListener(evt, fn, true);
				unloadWindow(window, () => e.removeEventListener(evt, fn, true));
			};
	(function initMenusAndCommands(evt) {
		function bindEvt(evt, fn) {
			return function (e) {
				e.addEventListener(evt, fn, true);
				unloadWindow(window, () => e.removeEventListener(evt, fn, true));
			};
		}

		try {
			let cont = $('dtaCtxSubmenu');

			for (let id of MENU_ITEMS) {
				compact[id] = $('dtaCtx' + id);
				let node = $('dtaCtx' + id).cloneNode(true);
				node.setAttribute('id', node.id + "-direct");
				ctx.insertBefore(node, ctxBase.nextSibling);
				direct[id] = node;
				unloadWindow(window, () => node.parentNode.removeChild(node));
			}

			// prepare tools
			for (let e of ['DTA', 'TDTA', 'Manager']) {
				tools[e] = $('dtaTools' + e);
			}

			let f = bindEvt("command", () => findLinks(false));
			f($("dta:regular"));
			f($("dta:regular-sel"));
			bindEvt("command", () => findLinks(false, true))($("dta:regular-all"));
			bindEvt("command", () => findSingleLink(false))($("dta:regular-link"));
			bindEvt("command", () => findSingleImg(false))($("dta:regular-img"));
			bindEvt("command", () => findSingleVideo(false))($("dta:regular-video"));
			bindEvt("command", () => findSingleAudio(false))($("dta:regular-audio"));
			bindEvt("command", () => findForm(false))($("dta:regular-form"));
			bindEvt("command", e => findSniff(e, false))($("dta:regular-sniff"));

			f = bindEvt("command", () => findLinks(true));
			f($("dta:turbo"));
			f($("dta:turbo-sel"));
			bindEvt("command", () => findLinks(true, true))($("dta:turbo-all"));
			bindEvt("command", () => findSingleLink(true))($("dta:turbo-link"));
			bindEvt("command", () => findSingleImg(true))($("dta:turbo-img"));
			bindEvt("command", () => findSingleVideo(true))($("dta:turbo-video"));
			bindEvt("command", () => findSingleAudio(true))($("dta:turbo-audio"));
			bindEvt("command", () => findForm(true))($("dta:turbo-form"));
			bindEvt("command", e => findSniff(e, true))($("dta:turbo-sniff"));

			bindEvt("command", () => toggleOneClick())($("dta:turboselect"));
			bindEvt("command", () => DTA.openManager(window))($("dta:manager"));
			bindEvt("command", () => Mediator.showPreferences(window))($("dta:prefs"));
			bindEvt("command", () => Mediator.showToolbarInstall(window))($("dta:tbinstall"));
			bindEvt("command", () => Mediator.showAbout(window))($("dta:about"));

			bindEvt("popupshowing", onContextShowing)(ctx);
			bindEvt("popupshowing", onToolsShowing)(menu);
		}
		catch (ex) {
			Components.utils.reportError(ex);
			log(LOG_ERROR, "DCO::init()", ex);
		}
	})();
Example #8
0
			function processToolbar(tb) {
				unloadWindow(tb.ownerDocument.defaultView, function() {
					tb.setAttribute("downthemall-currentset", tb.currentSet);
					tb.ownerDocument.persist(tb.id, "downthemall-currentset");
				});
			}
Example #9
0
	function elementsStub(window, document) {
		function $(id) { return document.getElementById(id); }
		function fire(event) {
			log(LOG_DEBUG, "Fire!");
			fire._runUnloaders();

			require("loaders/integration").load(window, event);
		}
		function _maybeInsertButtons(ids, attr) {
			function persist(tb, attr) {
				tb.setAttribute(attr, tb.currentSet);
				tb.ownerDocument.persist(tb.id, attr);
				try {
					var evt = document.createEvent("Events");
					evt.initEvent("aftercustomization", true, true);
					tb.toolbox.dispatchEvent(evt);
					if ("BrowserToolboxCustomizeDone" in window) {
						window.BrowserToolboxCustomizeDone(true);
					}
				}
				catch(ex) {
					log(LOG_ERROR, "failed to fire customization event", ex);
				}
			}

			function processToolbar(tb) {
				let ci = tb.getAttribute(attr).split(",");
				let insertIds = ids.filter(id => ~ci.indexOf(id));
				Utils.filterInSitu(ids, id => !~insertIds.indexOf(id));
				if (!insertIds.length) {
					return;
				}
				let li = tb.currentSet.split(",");
				for (let id of insertIds) {
					let idx = ci.indexOf(id);
					if (!~idx) {
						log(LOG_ERROR, "didn't find item; appending for now; this shouldn't happen!");
						li.push(id);
						continue;
					}
					let adjusted = false;
					for (let i = idx, e = ci.length; i < e; ++i) {
						let before = ci[i];
						let lidx = li.indexOf(before);
						if (~lidx) {
							idx = lidx;
							adjusted = true;
							break;
						}
					}
					if (!adjusted) {
						for (let i = idx; ~(--i);) {
							let after = ci[i];
							let lidx = li.indexOf(after);
							if (~lidx) {
								idx = lidx + 1;
								adjusted = true;
								break;
							}
						}
					}
					log(LOG_DEBUG, "insert at " + (adjusted ? "adjusted" : "") + " idx " + idx + " " + id);
					li.splice(idx, 0, id);
				}
				tb.currentSet = li.join(",");
				persist(tb, "downthemall-currentset");
				log(LOG_DEBUG, insertIds + " buttons restored in " + tb.id);
			}

			// Simply need to get the currentset attribute, which will still contain
			// the id and reset it and tb.currentSet
			try {
				for (let tb of document.getElementsByTagName("toolbar")) {
					processToolbar(tb);
				}
			}
			catch (ex) {
				log(LOG_DEBUG, "maybeInsertButtons failed for " + ids, ex);
			}
		}
		function maybeInsertButtons(ids) {
			function processToolbar(tb) {
				unloadWindow(tb.ownerDocument.defaultView, function() {
					tb.setAttribute("downthemall-currentset", tb.currentSet);
					tb.ownerDocument.persist(tb.id, "downthemall-currentset");
				});
			}

			if (window.CustomizableUI) {
				for (let id of ids.reverse()) {
					try {
						log(LOG_DEBUG, "trying to place " + id);
						window.CustomizableUI.ensureWidgetPlacedInWindow(id, window);
						log(LOG_DEBUG, "placed " + id);
					}
					catch (ex) {
						log(LOG_ERROR, "Died placing " + id, ex);
					}
				}
				return;
			}
			log(LOG_DEBUG, "running old");
			for (let attr of ["currentset", "downthemall-currentset"]) {
				if (!ids.length) {
					return;
				}
				_maybeInsertButtons(ids, attr);
			}
			for (let tb of document.getElementsByTagName("toolbar")) {
				processToolbar(tb);
			}
		}

		window.setTimeout(function dta_firewalkswithme() {
			try {
				fire._unloaders = [];
				fire._runUnloaders = function() {
					for (let i = 0; i < fire._unloaders.length; ++i) {
						try {
							fire._unloaders[i]();
						}
						catch (ex) {
						}
					}
					fire._unloaders = [];
				};
				fire.addFireListener = function(elem, type) {
					if (!elem) {
						return;
					}
					fire._unloaders.push(() => elem.removeEventListener(type, fire, false));
					elem.addEventListener(type, fire, false);
				};
				fire.addFireListener($("dtaCtxCompact").parentNode, "popupshowing");
				fire.addFireListener($("dtaToolsMenu").parentNode, "popupshowing");
				let appmenu = $("dtaAppMenu");
				if (appmenu) {
					fire.addFireListener($("appmenu-popup"), "popupshowing");
				}
				let toolsmenu = $("menu_ToolsPopup") || $("taskPopup");
				if (toolsmenu) {
					fire.addFireListener(toolsmenu, "popupshowing");
				}
				let panelbutton = $("PanelUI-button");
				if (panelbutton) {
					fire.addFireListener(panelbutton, "command");
				}
				fire.addFireListener($("dta:regular"), "command");
				fire.addFireListener($("dta-button"), "command");
				fire.addFireListener($("dta-button"), "popupshowing");
				fire.addFireListener($("dta-button"), "dragover");
				fire.addFireListener($("dta:turbo"), "command");
				fire.addFireListener($("dta-turbo-button"), "command");
				fire.addFireListener($("dta-turbo-button"), "popupshowing");
				fire.addFireListener($("dta-turbo-button"), "dragover");
				fire.addFireListener($("dta:turboselect"), "command");
				fire.addFireListener($("dta:manager"), "command");
				fire.addFireListener($("cmd_CustomizeToolbars"), "command");
				unloadWindow(window, function() {
					fire._runUnloaders();
				});
			}
			catch (ex) {
				log(LOG_ERROR, "stub installer failed!", ex);
			}
		}, 100);

		window.setTimeout(function dta_showabout() {
			function dta_showabout_i() {
				function openAbout() {
					fire(null);
					Version.showAbout = false;
					window.setTimeout(() => require("support/mediator").showAbout(window), 0);
				}
				function registerObserver() {
					obs.add({
						observe: function(s,t,d) {
							obs.remove(this, Version.TOPIC_SHOWABOUT);
							if (Version.showAbout) {
								openAbout();
							}
						}
					}, Version.TOPIC_SHOWABOUT);
				}

				try {
					if (Version.showAbout === null) {
						registerObserver();
						return;
					}
					if (Version.showAbout) {
						openAbout();
						return;
					}
				}
				catch (ex) {
				}
			}
			dta_showabout_i();
		}, 2000);

		log(LOG_DEBUG, "running elementsStub");

		maybeInsertButtons(["dta-button", "dta-turbo-button", "dta-turboselect-button", "dta-manager-button"]);

		let frameToLog = m => log(m.data.level, m.data.message, m.data.exception);
		let fs = "chrome://dta-modules/content/loaders/integration-content.js?" + (+new Date());
		window.messageManager.addMessageListener("DTA:log", frameToLog);
		window.messageManager.loadFrameScript(fs, true);
		unloadWindow(window, () => {
			window.messageManager.broadcastAsyncMessage("DTA:shutdown");
			window.messageManager.removeMessageListener("DTA:log", frameToLog);
			window.messageManager.removeDelayedFrameScript(fs);
		});
	}