/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this file, * You can obtain one at http://mozilla.org/MPL/2.0/. */ "use strict"; const {registerOverlay, unloadWindow} = require("sdk/windows"); const RUNNING = new Set(); const globalMM = Cc["@mozilla.org/globalmessagemanager;1"]. getService(Ci.nsIMessageListenerManager); function registerRunning(m) { RUNNING.add(m.data.id); log(LOG_DEBUG, `added ${m.data.id} to running`); } function unregisterRunning(m) { RUNNING.delete(m.data.id); log(LOG_DEBUG, `removed ${m.data.id} from running`); } globalMM.addMessageListener("repagination:register", registerRunning); globalMM.addMessageListener("repagination:unregister", unregisterRunning); unload(() => { globalMM.removeMessageListener("repagination:register", registerRunning); globalMM.removeMessageListener("repagination:unregister", unregisterRunning); }); /* globals _ */ lazy(this, "_", function() { let bundle = require("sdk/strings"). getBundle("chrome://repagination/locale/repagination.properties"); return function() { return bundle.getString.apply(bundle, arguments); }; }); function checkSameOrigin(principal, tryLoadUri) { try { if (!(tryLoadUri instanceof Ci.nsIURI)) { tryLoadUri = Services.io.newURI(tryLoadUri, null, null); } if (tryLoadUri.schemeIs("data")) { return true; } principal.checkMayLoad(tryLoadUri, false, true); return true; } catch (ex) { log(LOG_DEBUG, "denied load of " + (tryLoadUri.spec || tryLoadUri), ex); return false; } } function main(window, document) { const $ = id => document.getElementById(id); const $$$ = q => document.querySelectorAll(q); function repaginate(num, slideshow) { log(LOG_INFO, "repaginate: " + num + "/" + slideshow); try { let mm = window.gBrowser.selectedBrowser.messageManager; mm.sendAsyncMessage("repagination:normal", { num: num, slideshow: slideshow, allowScripts: prefs.get("allowscripts", true), yielding: prefs.yielding }); } catch (ex) { log(LOG_ERROR, "failed to run repaginate", ex); } } function repaginate_domain() { log(LOG_INFO, "repaginate_domain"); try { let mm = window.gBrowser.selectedBrowser.messageManager; let queried = m => { mm.removeMessageListener("repagination:query", queried); log(LOG_DEBUG, "recv query " + m.data); if (!m.data) { return; } const host = window.gBrowser.selectedBrowser.currentURI.host; for (let i = 0; i < window.gBrowser.browsers.length; ++i) { let browser = window.gBrowser.getBrowserAtIndex(i); if (!browser) { continue; } if (browser.currentURI.host != host) { continue; } browser.messageManager.sendAsyncMessage("repagination:normal", { num: 0, slideshow: false, allowScripts: prefs.get("allowscripts", true), yielding: prefs.yielding, query: m.data }); } }; mm.addMessageListener("repagination:query", queried); mm.sendAsyncMessage("repagination:query"); } catch (ex) { log(LOG_ERROR, "failed to run repaginate_domain", ex); } } function stop() { log(LOG_INFO, "stop"); let mm = window.gBrowser.selectedBrowser.messageManager; mm.sendAsyncMessage("repagination:stop"); } function onAll() { repaginate(); } function onAllDomain() { repaginate_domain(); } function onStop() { stop(); } function onLimitCommand(evt) { let t = evt.target; if (t.localName != "menuitem") { return; } repaginate(parseInt(t.getAttribute("value"), 10)); } function onSlideCommand(evt) { let t = evt.target; if (t.localName != "menuitem") { return; } repaginate(parseInt(t.getAttribute("value"), 10), true); } log(LOG_INFO, "main called!"); let frameToLog = m => log(m.data.level, m.data.message, m.data.exception); let frameL10N = m => { return _.apply(null, m.data.arguments); }; window.messageManager.addMessageListener("repagination:log", frameToLog); window.messageManager.addMessageListener("repagination:_", frameL10N); let fs = "chrome://repagination/content/content-script.js?" + (+new Date()); window.messageManager.loadFrameScript(fs, true); unloadWindow(window, () => { window.messageManager.broadcastAsyncMessage("repagination:shutdown"); window.messageManager.removeMessageListener("repagination:log", frameToLog); window.messageManager.removeMessageListener("repagination:_", frameL10N); window.messageManager.removeDelayedFrameScript(fs); }); // finish the localization let nodes = $$$(":-moz-any(#repagination_limit, " + "#repagination_menu_limit) menuitem"); for (let n of nodes) { n.setAttribute("label", _("pages.label", n.getAttribute("value"))); } nodes = $$$(":-moz-any(#repagination_slide, #repagination_menu_slide) " + "menuitem:not([label])"); for (let n of nodes) { let s = parseInt(n.getAttribute("value"), 10); if (s < 60) { n.setAttribute("label", _("seconds.label", s)); } else { n.setAttribute("label", _("minutes.label", parseInt(s / 60, 10))); } } let contextMenu = $("contentAreaContextMenu"); let menuCascaded = { menu: $("repagination_menu"), allMenu: $("repagination_menu_nolimit"), allDomainMenu: $("repagination_menu_nolimit_domain"), stopMenu: $("repagination_menu_stop"), limitMenu: $("repagination_menu_limit"), slideMenu: $("repagination_menu_slide") }; let menuPlain = { menu: {}, allMenu: $("repagination_nolimit"), allDomainMenu: $("repagination_nolimit_domain"), stopMenu: $("repagination_stop"), limitMenu: $("repagination_limit"), slideMenu: $("repagination_slide") }; let menuCurrent; prefs.observe("submenu", function(pref, value) { menuCurrent = value ? menuCascaded : menuPlain; let menuDisabled = value ? menuPlain : menuCascaded; for (let [,mi] in new Iterator(menuDisabled)) { mi.hidden = true; } }, true); let onContextMenu = function onContextMenu() { function setMenuHidden(hidden) { log(LOG_DEBUG, "set menu hidden = " + hidden); for (let [,mi] in new Iterator(menuCurrent)) { mi.hidden = hidden; } menuCurrent.slideMenu.hidden = menuCurrent.slideMenu.hidden || !prefs.showslideshow; menuCurrent.allDomainMenu.hidden = menuCurrent.allDomainMenu.hidden || !prefs.showalldomain; } let {gContextMenu} = window; log(LOG_DEBUG, `context menu showing for ${gContextMenu.frameOuterWindowID}!`); try { if (gContextMenu.onLink && /^https?$/.test(gContextMenu.linkURI.scheme)) { setMenuHidden(!checkSameOrigin(gContextMenu.principal, gContextMenu.linkURL)); if (!RUNNING.has(gContextMenu.frameOuterWindowID)) { menuCurrent.stopMenu.hidden = true; } return; } } catch (ex) { log(LOG_ERROR, "failed to setup menu (onLink)", ex); } try { setMenuHidden(true); if (RUNNING.has(gContextMenu.frameOuterWindowID)) { menuCurrent.menu.hidden = menuCurrent.stopMenu.hidden = false; } } catch (ex) { log(LOG_ERROR, "failed to setup menu (plain)", ex); } }; contextMenu.addEventListener("popupshowing", onContextMenu, true); menuCascaded.allMenu.addEventListener("command", onAll, true); menuPlain.allMenu.addEventListener("command", onAll, true); menuCascaded.allDomainMenu.addEventListener("command", onAllDomain, true); menuPlain.allDomainMenu.addEventListener("command", onAllDomain, true); menuCascaded.stopMenu.addEventListener("command", onStop, true); menuPlain.stopMenu.addEventListener("command", onStop, true); menuCascaded.limitMenu.addEventListener("command", onLimitCommand, true); menuPlain.limitMenu.addEventListener("command", onLimitCommand, true); menuCascaded.slideMenu.addEventListener("command", onSlideCommand, true); menuPlain.slideMenu.addEventListener("command", onSlideCommand, true); unloadWindow(window, function() { contextMenu.removeEventListener("popuphowing", onContextMenu, true); menuCascaded.allMenu.removeEventListener("command", onAll, true); menuPlain.allMenu.removeEventListener("command", onAll, true); menuCascaded.allDomainMenu.removeEventListener("command", onAllDomain, true); menuPlain.allDomainMenu.removeEventListener("command", onAllDomain, true); menuCascaded.stopMenu.removeEventListener("command", onStop, true); menuPlain.stopMenu.removeEventListener("command", onStop, true); menuCascaded.limitMenu.removeEventListener("command", onLimitCommand, true); menuPlain.limitMenu.removeEventListener("command", onLimitCommand, true); menuCascaded.slideMenu.removeEventListener("command", onSlideCommand, true); menuPlain.slideMenu.removeEventListener("command", onSlideCommand, true); contextMenu = menuPlain = menuCascaded = null; }); log(LOG_INFO, "all good!"); } registerOverlay( "repagination.xul", "chrome://browser/content/browser.xul", main ); registerOverlay( "repagination.xul", "chrome://navigator/content/navigator.xul", main ); /* vim: set et ts=2 sw=2 : */