diff options
136 files changed, 6993 insertions, 4413 deletions
diff --git a/application/palemoon/base/content/content.js b/application/palemoon/base/content/content.js index 19c8b0682..653dac3e3 100644 --- a/application/palemoon/base/content/content.js +++ b/application/palemoon/base/content/content.js @@ -60,6 +60,114 @@ addEventListener("blur", function(event) { LoginManagerContent.onUsernameInput(event); }); +// Provide gContextMenuContentData for 'sdk/context-menu' +var handleContentContextMenu = function (event) { + let defaultPrevented = event.defaultPrevented; + if (!Services.prefs.getBoolPref("dom.event.contextmenu.enabled")) { + let plugin = null; + try { + plugin = event.target.QueryInterface(Ci.nsIObjectLoadingContent); + } catch (e) {} + if (plugin && plugin.displayedType == Ci.nsIObjectLoadingContent.TYPE_PLUGIN) { + // Don't open a context menu for plugins. + return; + } + + defaultPrevented = false; + } + + if (defaultPrevented) + return; + + let addonInfo = {}; + let subject = { + event: event, + addonInfo: addonInfo, + }; + subject.wrappedJSObject = subject; + Services.obs.notifyObservers(subject, "content-contextmenu", null); + + let doc = event.target.ownerDocument; + let docLocation = doc.mozDocumentURIIfNotForErrorPages; + docLocation = docLocation && docLocation.spec; + let charSet = doc.characterSet; + let baseURI = doc.baseURI; + let referrer = doc.referrer; + let referrerPolicy = doc.referrerPolicy; + let frameOuterWindowID = doc.defaultView.QueryInterface(Ci.nsIInterfaceRequestor) + .getInterface(Ci.nsIDOMWindowUtils) + .outerWindowID; + let loginFillInfo = LoginManagerContent.getFieldContext(event.target); + + // The same-origin check will be done in nsContextMenu.openLinkInTab. + let parentAllowsMixedContent = !!docShell.mixedContentChannel; + + // get referrer attribute from clicked link and parse it + // if per element referrer is enabled, the element referrer overrules + // the document wide referrer + if (Services.prefs.getBoolPref("network.http.enablePerElementReferrer")) { + let referrerAttrValue = Services.netUtils.parseAttributePolicyString(event.target. + getAttribute("referrerpolicy")); + if (referrerAttrValue !== Ci.nsIHttpChannel.REFERRER_POLICY_UNSET) { + referrerPolicy = referrerAttrValue; + } + } + + // Media related cache info parent needs for saving + let contentType = null; + let contentDisposition = null; + if (event.target.nodeType == Ci.nsIDOMNode.ELEMENT_NODE && + event.target instanceof Ci.nsIImageLoadingContent && + event.target.currentURI) { + + try { + let imageCache = + Cc["@mozilla.org/image/tools;1"].getService(Ci.imgITools) + .getImgCacheForDocument(doc); + let props = + imageCache.findEntryProperties(event.target.currentURI, doc); + try { + contentType = props.get("type", Ci.nsISupportsCString).data; + } catch (e) {} + try { + contentDisposition = + props.get("content-disposition", Ci.nsISupportsCString).data; + } catch (e) {} + } catch (e) {} + } + + let selectionInfo = BrowserUtils.getSelectionDetails(content); + + let loadContext = docShell.QueryInterface(Ci.nsILoadContext); + let userContextId = loadContext.originAttributes.userContextId; + + let browser = docShell.chromeEventHandler; + let mainWin = browser.ownerGlobal; + + mainWin.gContextMenuContentData = { + isRemote: false, + event: event, + popupNode: event.target, + browser: browser, + addonInfo: addonInfo, + documentURIObject: doc.documentURIObject, + docLocation: docLocation, + charSet: charSet, + referrer: referrer, + referrerPolicy: referrerPolicy, + contentType: contentType, + contentDisposition: contentDisposition, + selectionInfo: selectionInfo, + loginFillInfo, + parentAllowsMixedContent, + userContextId, + }; +} + +Cc["@mozilla.org/eventlistenerservice;1"] + .getService(Ci.nsIEventListenerService) + .addSystemEventListener(global, "contextmenu", handleContentContextMenu, false); + // Lazily load the finder code addMessageListener("Finder:Initialize", function () { let {RemoteFinderListener} = Cu.import("resource://gre/modules/RemoteFinder.jsm", {}); diff --git a/application/palemoon/base/content/nsContextMenu.js b/application/palemoon/base/content/nsContextMenu.js index 1fe592b52..3d5d40e4c 100644 --- a/application/palemoon/base/content/nsContextMenu.js +++ b/application/palemoon/base/content/nsContextMenu.js @@ -4,6 +4,8 @@ Components.utils.import("resource://gre/modules/PrivateBrowsingUtils.jsm"); +var gContextMenuContentData = null; + function nsContextMenu(aXulMenu, aIsShift) { this.shouldDisplay = true; this.initMenu(aXulMenu, aIsShift); @@ -39,6 +41,7 @@ nsContextMenu.prototype = { }, hiding: function CM_hiding() { + gContextMenuContentData = null; InlineSpellCheckerUI.clearSuggestionsFromMenu(); InlineSpellCheckerUI.clearDictionaryListFromMenu(); InlineSpellCheckerUI.uninit(); diff --git a/application/palemoon/components/statusbar/Downloads.jsm b/application/palemoon/components/statusbar/Downloads.jsm index 74bc42144..091fdad2e 100644 --- a/application/palemoon/components/statusbar/Downloads.jsm +++ b/application/palemoon/components/statusbar/Downloads.jsm @@ -18,657 +18,657 @@ CU.import("resource://gre/modules/XPCOMUtils.jsm"); function S4EDownloadService(window, gBrowser, service, getters) { - this._window = window; - this._gBrowser = gBrowser; - this._service = service; - this._getters = getters; + this._window = window; + this._gBrowser = gBrowser; + this._service = service; + this._getters = getters; - this._handler = new JSTransferHandler(this._window, this); + this._handler = new JSTransferHandler(this._window, this); } S4EDownloadService.prototype = { - _window: null, - _gBrowser: null, - _service: null, - _getters: null, - - _handler: null, - _listening: false, - - _binding: false, - _customizing: false, - - _lastTime: Infinity, - - _dlActive: false, - _dlPaused: false, - _dlFinished: false, - - _dlCountStr: null, - _dlTimeStr: null, - - _dlProgressAvg: 0, - _dlProgressMax: 0, - _dlProgressMin: 0, - _dlProgressType: "active", - - _dlNotifyTimer: 0, - _dlNotifyGlowTimer: 0, - - init: function() - { - if(!this._getters.downloadButton) - { - this.uninit(); - return; - } - - if(this._listening) - { - return; - } - - this._handler.start(); - this._listening = true; - - this._lastTime = Infinity; - - this.updateBinding(); - this.updateStatus(); - }, - - uninit: function() - { - if(!this._listening) - { - return; - } - - this._listening = false; - this._handler.stop(); - - this.releaseBinding(); - }, - - destroy: function() - { - this.uninit(); - this._handler.destroy(); - - ["_window", "_gBrowser", "_service", "_getters", "_handler"].forEach(function(prop) - { - delete this[prop]; - }, this); - }, - - updateBinding: function() - { - if(!this._listening) - { - this.releaseBinding(); - return; - } - - switch(this._service.downloadButtonAction) - { - case 1: // Default - this.attachBinding(); - break; - default: - this.releaseBinding(); - break; - } - }, - - attachBinding: function() - { - if(this._binding) - { - return; - } - - let db = this._window.DownloadsButton; - - db._getAnchorS4EBackup = db.getAnchor; - db.getAnchor = this.getAnchor.bind(this); - - db._releaseAnchorS4EBackup = db.releaseAnchor; - db.releaseAnchor = function() {}; - - this._binding = true; - }, - - releaseBinding: function() - { - if(!this._binding) - { - return; - } - - let db = this._window.DownloadsButton; - - db.getAnchor = db._getAnchorS4EBackup; - db.releaseAnchor = db._releaseAnchorS4EBackup; - - this._binding = false; - }, - - customizing: function(val) - { - this._customizing = val; - }, - - updateStatus: function(lastFinished) - { - if(!this._getters.downloadButton) - { - this.uninit(); - return; - } - - let numActive = 0; - let numPaused = 0; - let activeTotalSize = 0; - let activeTransferred = 0; - let activeMaxProgress = -Infinity; - let activeMinProgress = Infinity; - let pausedTotalSize = 0; - let pausedTransferred = 0; - let pausedMaxProgress = -Infinity; - let pausedMinProgress = Infinity; - let maxTime = -Infinity; - - let dls = ((this.isPrivateWindow) ? this._handler.activePrivateEntries() : this._handler.activeEntries()); - for(let dl of dls) - { - if(dl.state == CI.nsIDownloadManager.DOWNLOAD_DOWNLOADING) - { - numActive++; - if(dl.size > 0) - { - if(dl.speed > 0) - { - maxTime = Math.max(maxTime, (dl.size - dl.transferred) / dl.speed); - } - - activeTotalSize += dl.size; - activeTransferred += dl.transferred; - - let currentProgress = ((dl.transferred * 100) / dl.size); - activeMaxProgress = Math.max(activeMaxProgress, currentProgress); - activeMinProgress = Math.min(activeMinProgress, currentProgress); - } - } - else if(dl.state == CI.nsIDownloadManager.DOWNLOAD_PAUSED) - { - numPaused++; - if(dl.size > 0) - { - pausedTotalSize += dl.size; - pausedTransferred += dl.transferred; - - let currentProgress = ((dl.transferred * 100) / dl.size); - pausedMaxProgress = Math.max(pausedMaxProgress, currentProgress); - pausedMinProgress = Math.min(pausedMinProgress, currentProgress); - } - } - } - - if((numActive + numPaused) == 0) - { - this._dlActive = false; - this._dlFinished = lastFinished; - this.updateButton(); - this._lastTime = Infinity; - return; - } - - let dlPaused = (numActive == 0); - let dlStatus = ((dlPaused) ? this._getters.strings.getString("pausedDownloads") - : this._getters.strings.getString("activeDownloads")); - let dlCount = ((dlPaused) ? numPaused : numActive); - let dlTotalSize = ((dlPaused) ? pausedTotalSize : activeTotalSize); - let dlTransferred = ((dlPaused) ? pausedTransferred : activeTransferred); - let dlMaxProgress = ((dlPaused) ? pausedMaxProgress : activeMaxProgress); - let dlMinProgress = ((dlPaused) ? pausedMinProgress : activeMinProgress); - let dlProgressType = ((dlPaused) ? "paused" : "active"); - - [this._dlTimeStr, this._lastTime] = DownloadUtils.getTimeLeft(maxTime, this._lastTime); - this._dlCountStr = PluralForm.get(dlCount, dlStatus).replace("#1", dlCount); - this._dlProgressAvg = ((dlTotalSize == 0) ? 100 : ((dlTransferred * 100) / dlTotalSize)); - this._dlProgressMax = ((dlTotalSize == 0) ? 100 : dlMaxProgress); - this._dlProgressMin = ((dlTotalSize == 0) ? 100 : dlMinProgress); - this._dlProgressType = dlProgressType + ((dlTotalSize == 0) ? "-unknown" : ""); - this._dlPaused = dlPaused; - this._dlActive = true; - this._dlFinished = false; - - this.updateButton(); - }, - - updateButton: function() - { - let download_button = this._getters.downloadButton; - let download_tooltip = this._getters.downloadButtonTooltip; - let download_progress = this._getters.downloadButtonProgress; - let download_label = this._getters.downloadButtonLabel; - if(!download_button) - { - return; - } - - if(!this._dlActive) - { - download_button.collapsed = true; - download_label.value = download_tooltip.label = this._getters.strings.getString("noDownloads"); - - download_progress.collapsed = true; - download_progress.value = 0; - - if(this._dlFinished && this._handler.hasPBAPI && !this.isUIShowing) - { - this.callAttention(download_button); - } - return; - } - - switch(this._service.downloadProgress) - { - case 2: - download_progress.value = this._dlProgressMax; - break; - case 3: - download_progress.value = this._dlProgressMin; - break; - default: - download_progress.value = this._dlProgressAvg; - break; - } - download_progress.setAttribute("pmType", this._dlProgressType); - download_progress.collapsed = (this._service.downloadProgress == 0); - - download_label.value = this.buildString(this._service.downloadLabel); - download_tooltip.label = this.buildString(this._service.downloadTooltip); - - this.clearAttention(download_button); - download_button.collapsed = false; - }, - - callAttention: function(download_button) - { - if(this._dlNotifyGlowTimer != 0) - { - this._window.clearTimeout(this._dlNotifyGlowTimer); - this._dlNotifyGlowTimer = 0; - } - - download_button.setAttribute("attention", "true"); - - if(this._service.downloadNotifyTimeout) - { - this._dlNotifyGlowTimer = this._window.setTimeout(function(self, button) - { - self._dlNotifyGlowTimer = 0; - button.removeAttribute("attention"); - }, this._service.downloadNotifyTimeout, this, download_button); - } - }, - - clearAttention: function(download_button) - { - if(this._dlNotifyGlowTimer != 0) - { - this._window.clearTimeout(this._dlNotifyGlowTimer); - this._dlNotifyGlowTimer = 0; - } - - download_button.removeAttribute("attention"); - }, - - notify: function() - { - if(this._dlNotifyTimer == 0 && this._service.downloadNotifyAnimate) - { - let download_button_anchor = this._getters.downloadButtonAnchor; - let download_notify_anchor = this._getters.downloadNotifyAnchor; - if(download_button_anchor) - { - if(!download_notify_anchor.style.transform) - { - let bAnchorRect = download_button_anchor.getBoundingClientRect(); - let nAnchorRect = download_notify_anchor.getBoundingClientRect(); - - let translateX = bAnchorRect.left - nAnchorRect.left; - translateX += .5 * (bAnchorRect.width - nAnchorRect.width); - - let translateY = bAnchorRect.top - nAnchorRect.top; - translateY += .5 * (bAnchorRect.height - nAnchorRect.height); - - download_notify_anchor.style.transform = "translate(" + translateX + "px, " + translateY + "px)"; - } - - download_notify_anchor.setAttribute("notification", "finish"); - this._dlNotifyTimer = this._window.setTimeout(function(self, anchor) - { - self._dlNotifyTimer = 0; - anchor.removeAttribute("notification"); - anchor.style.transform = ""; - }, 1000, this, download_notify_anchor); - } - } - }, - - clearFinished: function() - { - this._dlFinished = false; - let download_button = this._getters.downloadButton; - if(download_button) - { - this.clearAttention(download_button); - } - }, - - getAnchor: function(aCallback) - { - if(this._customizing) - { - aCallback(null); - return; - } - - aCallback(this._getters.downloadButtonAnchor); - }, - - openUI: function(aEvent) - { - this.clearFinished(); - - switch(this._service.downloadButtonAction) - { - case 1: // Firefox Default - this._handler.openUINative(); - break; - case 2: // Show Library - this._window.PlacesCommandHook.showPlacesOrganizer("Downloads"); - break; - case 3: // Show Tab - let found = this._gBrowser.browsers.some(function(browser, index) - { - if("about:downloads" == browser.currentURI.spec) - { - this._gBrowser.selectedTab = this._gBrowser.tabContainer.childNodes[index]; - return true; - } - }, this); - - if(!found) - { - this._window.openUILinkIn("about:downloads", "tab"); - } - break; - case 4: // External Command - let command = this._service.downloadButtonActionCommand; - if(commend) - { - this._window.goDoCommand(command); - } - break; - default: // Nothing - break; - } - - aEvent.stopPropagation(); - }, - - get isPrivateWindow() - { - return this._handler.hasPBAPI && PrivateBrowsingUtils.isWindowPrivate(this._window); - }, - - get isUIShowing() - { - switch(this._service.downloadButtonAction) - { - case 1: // Firefox Default - return this._handler.isUIShowingNative; - case 2: // Show Library - var organizer = Services.wm.getMostRecentWindow("Places:Organizer"); - if(organizer) - { - let selectedNode = organizer.PlacesOrganizer._places.selectedNode; - let downloadsItemId = organizer.PlacesUIUtils.leftPaneQueries["Downloads"]; - return selectedNode && selectedNode.itemId === downloadsItemId; - } - return false; - case 3: // Show tab - let currentURI = this._gBrowser.currentURI; - return currentURI && currentURI.spec == "about:downloads"; - default: // Nothing - return false; - } - }, - - buildString: function(mode) - { - switch(mode) - { - case 0: - return this._dlCountStr; - case 1: - return ((this._dlPaused) ? this._dlCountStr : this._dlTimeStr); - default: - let compStr = this._dlCountStr; - if(!this._dlPaused) - { - compStr += " (" + this._dlTimeStr + ")"; - } - return compStr; - } - } + _window: null, + _gBrowser: null, + _service: null, + _getters: null, + + _handler: null, + _listening: false, + + _binding: false, + _customizing: false, + + _lastTime: Infinity, + + _dlActive: false, + _dlPaused: false, + _dlFinished: false, + + _dlCountStr: null, + _dlTimeStr: null, + + _dlProgressAvg: 0, + _dlProgressMax: 0, + _dlProgressMin: 0, + _dlProgressType: "active", + + _dlNotifyTimer: 0, + _dlNotifyGlowTimer: 0, + + init: function() + { + if(!this._getters.downloadButton) + { + this.uninit(); + return; + } + + if(this._listening) + { + return; + } + + this._handler.start(); + this._listening = true; + + this._lastTime = Infinity; + + this.updateBinding(); + this.updateStatus(); + }, + + uninit: function() + { + if(!this._listening) + { + return; + } + + this._listening = false; + this._handler.stop(); + + this.releaseBinding(); + }, + + destroy: function() + { + this.uninit(); + this._handler.destroy(); + + ["_window", "_gBrowser", "_service", "_getters", "_handler"].forEach(function(prop) + { + delete this[prop]; + }, this); + }, + + updateBinding: function() + { + if(!this._listening) + { + this.releaseBinding(); + return; + } + + switch(this._service.downloadButtonAction) + { + case 1: // Default + this.attachBinding(); + break; + default: + this.releaseBinding(); + break; + } + }, + + attachBinding: function() + { + if(this._binding) + { + return; + } + + let db = this._window.DownloadsButton; + + db._getAnchorS4EBackup = db.getAnchor; + db.getAnchor = this.getAnchor.bind(this); + + db._releaseAnchorS4EBackup = db.releaseAnchor; + db.releaseAnchor = function() {}; + + this._binding = true; + }, + + releaseBinding: function() + { + if(!this._binding) + { + return; + } + + let db = this._window.DownloadsButton; + + db.getAnchor = db._getAnchorS4EBackup; + db.releaseAnchor = db._releaseAnchorS4EBackup; + + this._binding = false; + }, + + customizing: function(val) + { + this._customizing = val; + }, + + updateStatus: function(lastFinished) + { + if(!this._getters.downloadButton) + { + this.uninit(); + return; + } + + let numActive = 0; + let numPaused = 0; + let activeTotalSize = 0; + let activeTransferred = 0; + let activeMaxProgress = -Infinity; + let activeMinProgress = Infinity; + let pausedTotalSize = 0; + let pausedTransferred = 0; + let pausedMaxProgress = -Infinity; + let pausedMinProgress = Infinity; + let maxTime = -Infinity; + + let dls = ((this.isPrivateWindow) ? this._handler.activePrivateEntries() : this._handler.activeEntries()); + for(let dl of dls) + { + if(dl.state == CI.nsIDownloadManager.DOWNLOAD_DOWNLOADING) + { + numActive++; + if(dl.size > 0) + { + if(dl.speed > 0) + { + maxTime = Math.max(maxTime, (dl.size - dl.transferred) / dl.speed); + } + + activeTotalSize += dl.size; + activeTransferred += dl.transferred; + + let currentProgress = ((dl.transferred * 100) / dl.size); + activeMaxProgress = Math.max(activeMaxProgress, currentProgress); + activeMinProgress = Math.min(activeMinProgress, currentProgress); + } + } + else if(dl.state == CI.nsIDownloadManager.DOWNLOAD_PAUSED) + { + numPaused++; + if(dl.size > 0) + { + pausedTotalSize += dl.size; + pausedTransferred += dl.transferred; + + let currentProgress = ((dl.transferred * 100) / dl.size); + pausedMaxProgress = Math.max(pausedMaxProgress, currentProgress); + pausedMinProgress = Math.min(pausedMinProgress, currentProgress); + } + } + } + + if((numActive + numPaused) == 0) + { + this._dlActive = false; + this._dlFinished = lastFinished; + this.updateButton(); + this._lastTime = Infinity; + return; + } + + let dlPaused = (numActive == 0); + let dlStatus = ((dlPaused) ? this._getters.strings.getString("pausedDownloads") + : this._getters.strings.getString("activeDownloads")); + let dlCount = ((dlPaused) ? numPaused : numActive); + let dlTotalSize = ((dlPaused) ? pausedTotalSize : activeTotalSize); + let dlTransferred = ((dlPaused) ? pausedTransferred : activeTransferred); + let dlMaxProgress = ((dlPaused) ? pausedMaxProgress : activeMaxProgress); + let dlMinProgress = ((dlPaused) ? pausedMinProgress : activeMinProgress); + let dlProgressType = ((dlPaused) ? "paused" : "active"); + + [this._dlTimeStr, this._lastTime] = DownloadUtils.getTimeLeft(maxTime, this._lastTime); + this._dlCountStr = PluralForm.get(dlCount, dlStatus).replace("#1", dlCount); + this._dlProgressAvg = ((dlTotalSize == 0) ? 100 : ((dlTransferred * 100) / dlTotalSize)); + this._dlProgressMax = ((dlTotalSize == 0) ? 100 : dlMaxProgress); + this._dlProgressMin = ((dlTotalSize == 0) ? 100 : dlMinProgress); + this._dlProgressType = dlProgressType + ((dlTotalSize == 0) ? "-unknown" : ""); + this._dlPaused = dlPaused; + this._dlActive = true; + this._dlFinished = false; + + this.updateButton(); + }, + + updateButton: function() + { + let download_button = this._getters.downloadButton; + let download_tooltip = this._getters.downloadButtonTooltip; + let download_progress = this._getters.downloadButtonProgress; + let download_label = this._getters.downloadButtonLabel; + if(!download_button) + { + return; + } + + if(!this._dlActive) + { + download_button.collapsed = true; + download_label.value = download_tooltip.label = this._getters.strings.getString("noDownloads"); + + download_progress.collapsed = true; + download_progress.value = 0; + + if(this._dlFinished && this._handler.hasPBAPI && !this.isUIShowing) + { + this.callAttention(download_button); + } + return; + } + + switch(this._service.downloadProgress) + { + case 2: + download_progress.value = this._dlProgressMax; + break; + case 3: + download_progress.value = this._dlProgressMin; + break; + default: + download_progress.value = this._dlProgressAvg; + break; + } + download_progress.setAttribute("pmType", this._dlProgressType); + download_progress.collapsed = (this._service.downloadProgress == 0); + + download_label.value = this.buildString(this._service.downloadLabel); + download_tooltip.label = this.buildString(this._service.downloadTooltip); + + this.clearAttention(download_button); + download_button.collapsed = false; + }, + + callAttention: function(download_button) + { + if(this._dlNotifyGlowTimer != 0) + { + this._window.clearTimeout(this._dlNotifyGlowTimer); + this._dlNotifyGlowTimer = 0; + } + + download_button.setAttribute("attention", "true"); + + if(this._service.downloadNotifyTimeout) + { + this._dlNotifyGlowTimer = this._window.setTimeout(function(self, button) + { + self._dlNotifyGlowTimer = 0; + button.removeAttribute("attention"); + }, this._service.downloadNotifyTimeout, this, download_button); + } + }, + + clearAttention: function(download_button) + { + if(this._dlNotifyGlowTimer != 0) + { + this._window.clearTimeout(this._dlNotifyGlowTimer); + this._dlNotifyGlowTimer = 0; + } + + download_button.removeAttribute("attention"); + }, + + notify: function() + { + if(this._dlNotifyTimer == 0 && this._service.downloadNotifyAnimate) + { + let download_button_anchor = this._getters.downloadButtonAnchor; + let download_notify_anchor = this._getters.downloadNotifyAnchor; + if(download_button_anchor) + { + if(!download_notify_anchor.style.transform) + { + let bAnchorRect = download_button_anchor.getBoundingClientRect(); + let nAnchorRect = download_notify_anchor.getBoundingClientRect(); + + let translateX = bAnchorRect.left - nAnchorRect.left; + translateX += .5 * (bAnchorRect.width - nAnchorRect.width); + + let translateY = bAnchorRect.top - nAnchorRect.top; + translateY += .5 * (bAnchorRect.height - nAnchorRect.height); + + download_notify_anchor.style.transform = "translate(" + translateX + "px, " + translateY + "px)"; + } + + download_notify_anchor.setAttribute("notification", "finish"); + this._dlNotifyTimer = this._window.setTimeout(function(self, anchor) + { + self._dlNotifyTimer = 0; + anchor.removeAttribute("notification"); + anchor.style.transform = ""; + }, 1000, this, download_notify_anchor); + } + } + }, + + clearFinished: function() + { + this._dlFinished = false; + let download_button = this._getters.downloadButton; + if(download_button) + { + this.clearAttention(download_button); + } + }, + + getAnchor: function(aCallback) + { + if(this._customizing) + { + aCallback(null); + return; + } + + aCallback(this._getters.downloadButtonAnchor); + }, + + openUI: function(aEvent) + { + this.clearFinished(); + + switch(this._service.downloadButtonAction) + { + case 1: // Firefox Default + this._handler.openUINative(); + break; + case 2: // Show Library + this._window.PlacesCommandHook.showPlacesOrganizer("Downloads"); + break; + case 3: // Show Tab + let found = this._gBrowser.browsers.some(function(browser, index) + { + if("about:downloads" == browser.currentURI.spec) + { + this._gBrowser.selectedTab = this._gBrowser.tabContainer.childNodes[index]; + return true; + } + }, this); + + if(!found) + { + this._window.openUILinkIn("about:downloads", "tab"); + } + break; + case 4: // External Command + let command = this._service.downloadButtonActionCommand; + if(commend) + { + this._window.goDoCommand(command); + } + break; + default: // Nothing + break; + } + + aEvent.stopPropagation(); + }, + + get isPrivateWindow() + { + return this._handler.hasPBAPI && PrivateBrowsingUtils.isWindowPrivate(this._window); + }, + + get isUIShowing() + { + switch(this._service.downloadButtonAction) + { + case 1: // Firefox Default + return this._handler.isUIShowingNative; + case 2: // Show Library + var organizer = Services.wm.getMostRecentWindow("Places:Organizer"); + if(organizer) + { + let selectedNode = organizer.PlacesOrganizer._places.selectedNode; + let downloadsItemId = organizer.PlacesUIUtils.leftPaneQueries["Downloads"]; + return selectedNode && selectedNode.itemId === downloadsItemId; + } + return false; + case 3: // Show tab + let currentURI = this._gBrowser.currentURI; + return currentURI && currentURI.spec == "about:downloads"; + default: // Nothing + return false; + } + }, + + buildString: function(mode) + { + switch(mode) + { + case 0: + return this._dlCountStr; + case 1: + return ((this._dlPaused) ? this._dlCountStr : this._dlTimeStr); + default: + let compStr = this._dlCountStr; + if(!this._dlPaused) + { + compStr += " (" + this._dlTimeStr + ")"; + } + return compStr; + } + } }; function JSTransferHandler(window, downloadService) { - this._window = window; + this._window = window; - let api = CU.import("resource://gre/modules/Downloads.jsm", {}).Downloads; + let api = CU.import("resource://gre/modules/Downloads.jsm", {}).Downloads; - this._activePublic = new JSTransferListener(downloadService, api.getList(api.PUBLIC), false); - this._activePrivate = new JSTransferListener(downloadService, api.getList(api.PRIVATE), true); + this._activePublic = new JSTransferListener(downloadService, api.getList(api.PUBLIC), false); + this._activePrivate = new JSTransferListener(downloadService, api.getList(api.PRIVATE), true); } JSTransferHandler.prototype = { - _window: null, - _activePublic: null, - _activePrivate: null, - - destroy: function() - { - this._activePublic.destroy(); - this._activePrivate.destroy(); - - ["_window", "_activePublic", "_activePrivate"].forEach(function(prop) - { - delete this[prop]; - }, this); - }, - - start: function() - { - this._activePublic.start(); - this._activePrivate.start(); - }, - - stop: function() - { - this._activePublic.stop(); - this._activePrivate.stop(); - }, - - get hasPBAPI() - { - return true; - }, - - openUINative: function() - { - this._window.DownloadsPanel.showPanel(); - }, - - get isUIShowingNative() - { - return this._window.DownloadsPanel.isPanelShowing; - }, - - activeEntries: function() - { - return this._activePublic.downloads(); - }, - - activePrivateEntries: function() - { - return this._activePrivate.downloads(); - } + _window: null, + _activePublic: null, + _activePrivate: null, + + destroy: function() + { + this._activePublic.destroy(); + this._activePrivate.destroy(); + + ["_window", "_activePublic", "_activePrivate"].forEach(function(prop) + { + delete this[prop]; + }, this); + }, + + start: function() + { + this._activePublic.start(); + this._activePrivate.start(); + }, + + stop: function() + { + this._activePublic.stop(); + this._activePrivate.stop(); + }, + + get hasPBAPI() + { + return true; + }, + + openUINative: function() + { + this._window.DownloadsPanel.showPanel(); + }, + + get isUIShowingNative() + { + return this._window.DownloadsPanel.isPanelShowing; + }, + + activeEntries: function() + { + return this._activePublic.downloads(); + }, + + activePrivateEntries: function() + { + return this._activePrivate.downloads(); + } }; function JSTransferListener(downloadService, listPromise, isPrivate) { - this._downloadService = downloadService; - this._isPrivate = isPrivate; - this._downloads = new Map(); + this._downloadService = downloadService; + this._isPrivate = isPrivate; + this._downloads = new Map(); - listPromise.then(this.initList.bind(this)).then(null, CU.reportError); + listPromise.then(this.initList.bind(this)).then(null, CU.reportError); } JSTransferListener.prototype = { - _downloadService: null, - _list: null, - _downloads: null, - _isPrivate: false, - _wantsStart: false, - - initList: function(list) - { - this._list = list; - if(this._wantsStart) { - this.start(); - } - - this._list.getAll().then(this.initDownloads.bind(this)).then(null, CU.reportError); - }, - - initDownloads: function(downloads) - { - downloads.forEach(function(download) - { - this.onDownloadAdded(download); - }, this); - }, - - destroy: function() - { - this._downloads.clear(); - - ["_downloadService", "_list", "_downloads"].forEach(function(prop) - { - delete this[prop]; - }, this); - }, - - start: function() - { - if(!this._list) - { - this._wantsStart = true; - return; - } - - this._list.addView(this); - }, - - stop: function() - { - if(!this._list) - { - this._wantsStart = false; - return; - } - - this._list.removeView(this); - }, - - downloads: function() - { - return this._downloads.values(); - }, - - convertToState: function(dl) - { - if(dl.succeeded) - { - return CI.nsIDownloadManager.DOWNLOAD_FINISHED; - } - if(dl.error && dl.error.becauseBlockedByParentalControls) - { - return CI.nsIDownloadManager.DOWNLOAD_BLOCKED_PARENTAL; - } - if(dl.error) - { - return CI.nsIDownloadManager.DOWNLOAD_FAILED; - } - if(dl.canceled && dl.hasPartialData) - { - return CI.nsIDownloadManager.DOWNLOAD_PAUSED; - } - if(dl.canceled) - { - return CI.nsIDownloadManager.DOWNLOAD_CANCELED; - } - if(dl.stopped) - { - return CI.nsIDownloadManager.DOWNLOAD_NOTSTARTED; - } - return CI.nsIDownloadManager.DOWNLOAD_DOWNLOADING; - }, - - onDownloadAdded: function(aDownload) - { - let dl = this._downloads.get(aDownload); - if(!dl) - { - dl = {}; - this._downloads.set(aDownload, dl); - } - - dl.state = this.convertToState(aDownload); - dl.size = aDownload.totalBytes; - dl.speed = aDownload.speed; - dl.transferred = aDownload.currentBytes; - }, - - onDownloadChanged: function(aDownload) - { - this.onDownloadAdded(aDownload); - - if(this._isPrivate != this._downloadService.isPrivateWindow) - { - return; - } - - this._downloadService.updateStatus(aDownload.succeeded); - - if(aDownload.succeeded) - { - this._downloadService.notify() - } - }, - - onDownloadRemoved: function(aDownload) - { - this._downloads.delete(aDownload); - } + _downloadService: null, + _list: null, + _downloads: null, + _isPrivate: false, + _wantsStart: false, + + initList: function(list) + { + this._list = list; + if(this._wantsStart) { + this.start(); + } + + this._list.getAll().then(this.initDownloads.bind(this)).then(null, CU.reportError); + }, + + initDownloads: function(downloads) + { + downloads.forEach(function(download) + { + this.onDownloadAdded(download); + }, this); + }, + + destroy: function() + { + this._downloads.clear(); + + ["_downloadService", "_list", "_downloads"].forEach(function(prop) + { + delete this[prop]; + }, this); + }, + + start: function() + { + if(!this._list) + { + this._wantsStart = true; + return; + } + + this._list.addView(this); + }, + + stop: function() + { + if(!this._list) + { + this._wantsStart = false; + return; + } + + this._list.removeView(this); + }, + + downloads: function() + { + return this._downloads.values(); + }, + + convertToState: function(dl) + { + if(dl.succeeded) + { + return CI.nsIDownloadManager.DOWNLOAD_FINISHED; + } + if(dl.error && dl.error.becauseBlockedByParentalControls) + { + return CI.nsIDownloadManager.DOWNLOAD_BLOCKED_PARENTAL; + } + if(dl.error) + { + return CI.nsIDownloadManager.DOWNLOAD_FAILED; + } + if(dl.canceled && dl.hasPartialData) + { + return CI.nsIDownloadManager.DOWNLOAD_PAUSED; + } + if(dl.canceled) + { + return CI.nsIDownloadManager.DOWNLOAD_CANCELED; + } + if(dl.stopped) + { + return CI.nsIDownloadManager.DOWNLOAD_NOTSTARTED; + } + return CI.nsIDownloadManager.DOWNLOAD_DOWNLOADING; + }, + + onDownloadAdded: function(aDownload) + { + let dl = this._downloads.get(aDownload); + if(!dl) + { + dl = {}; + this._downloads.set(aDownload, dl); + } + + dl.state = this.convertToState(aDownload); + dl.size = aDownload.totalBytes; + dl.speed = aDownload.speed; + dl.transferred = aDownload.currentBytes; + }, + + onDownloadChanged: function(aDownload) + { + this.onDownloadAdded(aDownload); + + if(this._isPrivate != this._downloadService.isPrivateWindow) + { + return; + } + + this._downloadService.updateStatus(aDownload.succeeded); + + if(aDownload.succeeded) + { + this._downloadService.notify() + } + }, + + onDownloadRemoved: function(aDownload) + { + this._downloads.delete(aDownload); + } }; diff --git a/application/palemoon/components/statusbar/Progress.jsm b/application/palemoon/components/statusbar/Progress.jsm index c03a25450..69d55db49 100644 --- a/application/palemoon/components/statusbar/Progress.jsm +++ b/application/palemoon/components/statusbar/Progress.jsm @@ -12,172 +12,172 @@ const CU = Components.utils; CU.import("resource://gre/modules/XPCOMUtils.jsm"); function S4EProgressService(gBrowser, service, getters, statusService) { - this._gBrowser = gBrowser; - this._service = service; - this._getters = getters; - this._statusService = statusService; + this._gBrowser = gBrowser; + this._service = service; + this._getters = getters; + this._statusService = statusService; - this._gBrowser.addProgressListener(this); + this._gBrowser.addProgressListener(this); } S4EProgressService.prototype = { - _gBrowser: null, - _service: null, - _getters: null, - _statusService: null, - - _busyUI: false, - - set value(val) - { - let toolbar_progress = this._getters.toolbarProgress; - if(toolbar_progress) - { - toolbar_progress.value = val; - } - - let throbber_progress = this._getters.throbberProgress; - if(throbber_progress) - { - if(val) - { - throbber_progress.setAttribute("progress", val); - } - else - { - throbber_progress.removeAttribute("progress"); - } - } - }, - - set collapsed(val) - { - let toolbar_progress = this._getters.toolbarProgress; - if(toolbar_progress) - { - toolbar_progress.collapsed = val; - } - - let throbber_progress = this._getters.throbberProgress; - if(throbber_progress) - { - if(val) - { - throbber_progress.removeAttribute("busy"); - } - else - { - throbber_progress.setAttribute("busy", true); - } - } - }, - - destroy: function() - { - this._gBrowser.removeProgressListener(this); - - ["_gBrowser", "_service", "_getters", "_statusService"].forEach(function(prop) - { - delete this[prop]; - }, this); - }, - - onStatusChange: function(aWebProgress, aRequest, aStatus, aMessage) - { - this._statusService.setNetworkStatus(aMessage, this._busyUI); - }, - - onStateChange: function(aWebProgress, aRequest, aStateFlags, aStatus) - { - let nsIWPL = CI.nsIWebProgressListener; - - if(!this._busyUI - && aStateFlags & nsIWPL.STATE_START - && aStateFlags & nsIWPL.STATE_IS_NETWORK - && !(aStateFlags & nsIWPL.STATE_RESTORING)) - { - this._busyUI = true; - this.value = 0; - this.collapsed = false; - } - else if(aStateFlags & nsIWPL.STATE_STOP) - { - if(aRequest) - { - let msg = ""; - let location; - if(aRequest instanceof CI.nsIChannel || "URI" in aRequest) - { - location = aRequest.URI; - if(location.spec != "about:blank") - { - switch (aStatus) - { - case Components.results.NS_BINDING_ABORTED: - msg = this._getters.strings.getString("nv_stopped"); - break; - case Components.results.NS_ERROR_NET_TIMEOUT: - msg = this._getters.strings.getString("nv_timeout"); - break; - } - } - } - - if(!msg && (!location || location.spec != "about:blank")) - { - msg = this._getters.strings.getString("nv_done"); - } - - this._statusService.setDefaultStatus(msg); - this._statusService.setNetworkStatus("", this._busyUI); - } - - if(this._busyUI) - { - this._busyUI = false; - this.collapsed = true; - this.value = 0; - } - } - }, - - onUpdateCurrentBrowser: function(aStateFlags, aStatus, aMessage, aTotalProgress) - { - let nsIWPL = CI.nsIWebProgressListener; - let loadingDone = aStateFlags & nsIWPL.STATE_STOP; - - this.onStateChange( - this._gBrowser.webProgress, - { URI: this._gBrowser.currentURI }, - ((loadingDone ? nsIWPL.STATE_STOP : nsIWPL.STATE_START) | (aStateFlags & nsIWPL.STATE_IS_NETWORK)), - aStatus - ); - - if(!loadingDone) - { - this.onProgressChange(this._gBrowser.webProgress, null, 0, 0, aTotalProgress, 1); - this.onStatusChange(this._gBrowser.webProgress, null, 0, aMessage); - } - }, - - onProgressChange: function(aWebProgress, aRequest, aCurSelfProgress, aMaxSelfProgress, aCurTotalProgress, aMaxTotalProgress) - { - if (aMaxTotalProgress > 0 && this._busyUI) - { - // This is highly optimized. Don't touch this code unless - // you are intimately familiar with the cost of setting - // attrs on XUL elements. -- hyatt - let percentage = (aCurTotalProgress * 100) / aMaxTotalProgress; - this.value = percentage; - } - }, - - onProgressChange64: function(aWebProgress, aRequest, aCurSelfProgress, aMaxSelfProgress, aCurTotalProgress, aMaxTotalProgress) - { - return this.onProgressChange(aWebProgress, aRequest, aCurSelfProgress, aMaxSelfProgress, aCurTotalProgress, aMaxTotalProgress); - }, - - QueryInterface: XPCOMUtils.generateQI([ CI.nsIWebProgressListener, CI.nsIWebProgressListener2 ]) + _gBrowser: null, + _service: null, + _getters: null, + _statusService: null, + + _busyUI: false, + + set value(val) + { + let toolbar_progress = this._getters.toolbarProgress; + if(toolbar_progress) + { + toolbar_progress.value = val; + } + + let throbber_progress = this._getters.throbberProgress; + if(throbber_progress) + { + if(val) + { + throbber_progress.setAttribute("progress", val); + } + else + { + throbber_progress.removeAttribute("progress"); + } + } + }, + + set collapsed(val) + { + let toolbar_progress = this._getters.toolbarProgress; + if(toolbar_progress) + { + toolbar_progress.collapsed = val; + } + + let throbber_progress = this._getters.throbberProgress; + if(throbber_progress) + { + if(val) + { + throbber_progress.removeAttribute("busy"); + } + else + { + throbber_progress.setAttribute("busy", true); + } + } + }, + + destroy: function() + { + this._gBrowser.removeProgressListener(this); + + ["_gBrowser", "_service", "_getters", "_statusService"].forEach(function(prop) + { + delete this[prop]; + }, this); + }, + + onStatusChange: function(aWebProgress, aRequest, aStatus, aMessage) + { + this._statusService.setNetworkStatus(aMessage, this._busyUI); + }, + + onStateChange: function(aWebProgress, aRequest, aStateFlags, aStatus) + { + let nsIWPL = CI.nsIWebProgressListener; + + if(!this._busyUI + && aStateFlags & nsIWPL.STATE_START + && aStateFlags & nsIWPL.STATE_IS_NETWORK + && !(aStateFlags & nsIWPL.STATE_RESTORING)) + { + this._busyUI = true; + this.value = 0; + this.collapsed = false; + } + else if(aStateFlags & nsIWPL.STATE_STOP) + { + if(aRequest) + { + let msg = ""; + let location; + if(aRequest instanceof CI.nsIChannel || "URI" in aRequest) + { + location = aRequest.URI; + if(location.spec != "about:blank") + { + switch (aStatus) + { + case Components.results.NS_BINDING_ABORTED: + msg = this._getters.strings.getString("nv_stopped"); + break; + case Components.results.NS_ERROR_NET_TIMEOUT: + msg = this._getters.strings.getString("nv_timeout"); + break; + } + } + } + + if(!msg && (!location || location.spec != "about:blank")) + { + msg = this._getters.strings.getString("nv_done"); + } + + this._statusService.setDefaultStatus(msg); + this._statusService.setNetworkStatus("", this._busyUI); + } + + if(this._busyUI) + { + this._busyUI = false; + this.collapsed = true; + this.value = 0; + } + } + }, + + onUpdateCurrentBrowser: function(aStateFlags, aStatus, aMessage, aTotalProgress) + { + let nsIWPL = CI.nsIWebProgressListener; + let loadingDone = aStateFlags & nsIWPL.STATE_STOP; + + this.onStateChange( + this._gBrowser.webProgress, + { URI: this._gBrowser.currentURI }, + ((loadingDone ? nsIWPL.STATE_STOP : nsIWPL.STATE_START) | (aStateFlags & nsIWPL.STATE_IS_NETWORK)), + aStatus + ); + + if(!loadingDone) + { + this.onProgressChange(this._gBrowser.webProgress, null, 0, 0, aTotalProgress, 1); + this.onStatusChange(this._gBrowser.webProgress, null, 0, aMessage); + } + }, + + onProgressChange: function(aWebProgress, aRequest, aCurSelfProgress, aMaxSelfProgress, aCurTotalProgress, aMaxTotalProgress) + { + if (aMaxTotalProgress > 0 && this._busyUI) + { + // This is highly optimized. Don't touch this code unless + // you are intimately familiar with the cost of setting + // attrs on XUL elements. -- hyatt + let percentage = (aCurTotalProgress * 100) / aMaxTotalProgress; + this.value = percentage; + } + }, + + onProgressChange64: function(aWebProgress, aRequest, aCurSelfProgress, aMaxSelfProgress, aCurTotalProgress, aMaxTotalProgress) + { + return this.onProgressChange(aWebProgress, aRequest, aCurSelfProgress, aMaxSelfProgress, aCurTotalProgress, aMaxTotalProgress); + }, + + QueryInterface: XPCOMUtils.generateQI([ CI.nsIWebProgressListener, CI.nsIWebProgressListener2 ]) }; diff --git a/application/palemoon/components/statusbar/Status.jsm b/application/palemoon/components/statusbar/Status.jsm index 3795545a3..d888c7d94 100644 --- a/application/palemoon/components/statusbar/Status.jsm +++ b/application/palemoon/components/statusbar/Status.jsm @@ -13,452 +13,452 @@ CU.import("resource://gre/modules/XPCOMUtils.jsm"); function S4EStatusService(window, service, getters) { - this._window = window; - this._service = service; - this._getters = getters; + this._window = window; + this._service = service; + this._getters = getters; - this._overLinkService = new S4EOverlinkService(this._window, this._service, this); + this._overLinkService = new S4EOverlinkService(this._window, this._service, this); } S4EStatusService.prototype = { - _window: null, - _service: null, - _getters: null, - _overLinkService: null, - - _overLink: { val: "", type: "" }, - _network: { val: "", type: "" }, - _networkXHR: { val: "", type: "" }, - _status: { val: "", type: "" }, - _jsStatus: { val: "", type: "" }, - _defaultStatus: { val: "", type: "" }, - - _isFullScreen: false, - _isFullScreenVideo: false, - - _statusText: { val: "", type: "" }, - _noUpdate: false, - _statusChromeTimeoutID: 0, - _statusContentTimeoutID: 0, - - getCompositeStatusText: function() - { - return this._statusText.val; - }, - - getStatusText: function() - { - return this._status.val; - }, - - setNetworkStatus: function(status, busy) - { - if(busy) - { - this._network = { val: status, type: "network" }; - this._networkXHR = { val: "", type: "network xhr" }; - } - else - { - this._networkXHR = { val: status, type: "network xhr" }; - } - this.updateStatusField(); - }, - - setStatusText: function(status) - { - this._status = { val: status, type: "status chrome" }; - this.updateStatusField(); - }, - - setJSStatus: function(status) - { - this._jsStatus = { val: status, type: "status content" }; - this.updateStatusField(); - }, - - setJSDefaultStatus: function(status) - { - // This was removed from Firefox in Bug 862917 - }, - - setDefaultStatus: function(status) - { - this._defaultStatus = { val: status, type: "status chrome default" }; - this.updateStatusField(); - }, - - setOverLink: function(link, aAnchor) - { - this._overLinkService.update(link, aAnchor); - }, - - setOverLinkInternal: function(link, aAnchor) - { - let status = this._service.status; - let statusLinkOver = this._service.statusLinkOver; - - if(statusLinkOver) - { - link = link.replace(/[\u200e\u200f\u202a\u202b\u202c\u202d\u202e]/g, encodeURIComponent); - if(status == statusLinkOver) - { - this._overLink = { val: link, type: "overLink", anchor: aAnchor }; - this.updateStatusField(); - } - else - { - this.setStatusField(statusLinkOver, { val: link, type: "overLink", anchor: aAnchor }, true); - } - } - }, - - setNoUpdate: function(nu) - { - this._noUpdate = nu; - }, - - buildBinding: function() { - let XULBWPropHandler = function(prop, oldval, newval) { - CU.reportError("Attempt to modify XULBrowserWindow." + prop); - return oldval; - }; - - ["updateStatusField", "onStatusChange"].forEach(function(prop) - { - this._window.XULBrowserWindow.unwatch(prop); - this._window.XULBrowserWindow[prop] = function() {}; - this._window.XULBrowserWindow.watch(prop, XULBWPropHandler); - }, this); - - ["getCompositeStatusText", "getStatusText", "setStatusText", "setJSStatus", - "setJSDefaultStatus", "setDefaultStatus", "setOverLink"].forEach(function(prop) - { - this._window.XULBrowserWindow.unwatch(prop); - this._window.XULBrowserWindow[prop] = this[prop].bind(this); - this._window.XULBrowserWindow.watch(prop, XULBWPropHandler); - }, this); - - let XULBWHandler = function(prop, oldval, newval) { - if(!newval) - { - return newval; - } - CU.reportError("XULBrowserWindow changed. Updating S4E bindings."); - this._window.setTimeout(function(self) - { - self.buildBinding(); - }, 0, this); - return newval; - }; - - this._window.watch("XULBrowserWindow", XULBWHandler); - }, - - destroy: function() - { - // No need to unbind from the XULBrowserWindow, it's already null at this point - - this.clearTimer("_statusChromeTimeoutID"); - this.clearTimer("_statusContentTimeoutID"); - - this._overLinkService.destroy(); - - ["_overLink", "_network", "_networkXHR", "_status", "_jsStatus", "_defaultStatus", - "_statusText", "_window", "_service", "_getters", "_overLinkService"].forEach(function(prop) - { - delete this[prop]; - }, this); - }, - - buildTextOrder: function() - { - this.__defineGetter__("_textOrder", function() - { - let textOrder = ["_overLink"]; - if(this._service.statusNetwork) - { - textOrder.push("_network"); - if(this._service.statusNetworkXHR) - { - textOrder.push("_networkXHR"); - } - } - textOrder.push("_status", "_jsStatus"); - if(this._service.statusDefault) - { - textOrder.push("_defaultStatus"); - } - - delete this._textOrder; - return this._textOrder = textOrder; - }); - }, - - updateStatusField: function(force) - { - let text = { val: "", type: "" }; - for(let i = 0; !text.val && i < this._textOrder.length; i++) - { - text = this[this._textOrder[i]]; - } - - if(this._statusText.val != text.val || force) - { - if(this._noUpdate) - { - return; - } - - this._statusText = text; - - this.setStatusField(this._service.status, text, false); - - if(text.val && this._service.statusTimeout) - { - this.setTimer(text.type); - } - } - }, - - updateFullScreen: function() - { - this._isFullScreen = this._window.fullScreen; - this._isFullScreenVideo = false; - if(this._isFullScreen) - { - let fsEl = this._window.content.document.mozFullScreenElement; - if(fsEl && (fsEl.nodeName == "VIDEO" || fsEl.getElementsByTagName("VIDEO").length > 0)) - { - this._isFullScreenVideo = true; - } - } - - this.clearStatusField(); - this.updateStatusField(true); - }, - - setTimer: function(type) - { - let typeArgs = type.split(" ", 3); - - if(typeArgs.length < 2 || typeArgs[0] != "status") - { - return; - } - - if(typeArgs[1] == "chrome") - { - this.clearTimer("_statusChromeTimeoutID"); - this._statusChromeTimeoutID = this._window.setTimeout(function(self, isDefault) - { - self._statusChromeTimeoutID = 0; - if(isDefault) - { - self.setDefaultStatus(""); - } - else - { - self.setStatusText(""); - } - }, this._service.statusTimeout, this, (typeArgs.length == 3 && typeArgs[2] == "default")); - } - else - { - this.clearTimer("_statusContentTimeoutID"); - this._statusContentTimeoutID = this._window.setTimeout(function(self) - { - self._statusContentTimeoutID = 0; - self.setJSStatus(""); - }, this._service.statusTimeout, this); - } - }, - - clearTimer: function(timerName) - { - if(this[timerName] != 0) - { - this._window.clearTimeout(this[timerName]); - this[timerName] = 0; - } - }, - - clearStatusField: function() - { - this._getters.statusOverlay.value = ""; - - let status_label = this._getters.statusWidgetLabel; - if(status_label) - { - status_label.value = ""; - } - - }, - - setStatusField: function(location, text, allowTooltip) - { - if(!location) - { - return; - } - - let label = null; - - if(this._isFullScreen && this._service.advancedStatusDetectFullScreen) - { - switch(location) - { - case 1: // Toolbar - location = 3 - break; - case 2: // URL bar - if(Services.prefs.getBoolPref("browser.fullscreen.autohide")) - { - location = 3 - } - break; - } - } - - switch(location) - { - case 1: // Toolbar - label = this._getters.statusWidgetLabel; - break; - case 2: // URL Bar - break; - case 3: // Popup - default: - if(this._isFullScreenVideo && this._service.advancedStatusDetectVideo) - { - return; - } - label = this._getters.statusOverlay; - break; - } - - if(label) - { - label.setAttribute("previoustype", label.getAttribute("type")); - label.setAttribute("type", text.type); - label.value = text.val; - label.setAttribute("crop", text.type == "overLink" ? "center" : "end"); - } - } + _window: null, + _service: null, + _getters: null, + _overLinkService: null, + + _overLink: { val: "", type: "" }, + _network: { val: "", type: "" }, + _networkXHR: { val: "", type: "" }, + _status: { val: "", type: "" }, + _jsStatus: { val: "", type: "" }, + _defaultStatus: { val: "", type: "" }, + + _isFullScreen: false, + _isFullScreenVideo: false, + + _statusText: { val: "", type: "" }, + _noUpdate: false, + _statusChromeTimeoutID: 0, + _statusContentTimeoutID: 0, + + getCompositeStatusText: function() + { + return this._statusText.val; + }, + + getStatusText: function() + { + return this._status.val; + }, + + setNetworkStatus: function(status, busy) + { + if(busy) + { + this._network = { val: status, type: "network" }; + this._networkXHR = { val: "", type: "network xhr" }; + } + else + { + this._networkXHR = { val: status, type: "network xhr" }; + } + this.updateStatusField(); + }, + + setStatusText: function(status) + { + this._status = { val: status, type: "status chrome" }; + this.updateStatusField(); + }, + + setJSStatus: function(status) + { + this._jsStatus = { val: status, type: "status content" }; + this.updateStatusField(); + }, + + setJSDefaultStatus: function(status) + { + // This was removed from Firefox in Bug 862917 + }, + + setDefaultStatus: function(status) + { + this._defaultStatus = { val: status, type: "status chrome default" }; + this.updateStatusField(); + }, + + setOverLink: function(link, aAnchor) + { + this._overLinkService.update(link, aAnchor); + }, + + setOverLinkInternal: function(link, aAnchor) + { + let status = this._service.status; + let statusLinkOver = this._service.statusLinkOver; + + if(statusLinkOver) + { + link = link.replace(/[\u200e\u200f\u202a\u202b\u202c\u202d\u202e]/g, encodeURIComponent); + if(status == statusLinkOver) + { + this._overLink = { val: link, type: "overLink", anchor: aAnchor }; + this.updateStatusField(); + } + else + { + this.setStatusField(statusLinkOver, { val: link, type: "overLink", anchor: aAnchor }, true); + } + } + }, + + setNoUpdate: function(nu) + { + this._noUpdate = nu; + }, + + buildBinding: function() { + let XULBWPropHandler = function(prop, oldval, newval) { + CU.reportError("Attempt to modify XULBrowserWindow." + prop); + return oldval; + }; + + ["updateStatusField", "onStatusChange"].forEach(function(prop) + { + this._window.XULBrowserWindow.unwatch(prop); + this._window.XULBrowserWindow[prop] = function() {}; + this._window.XULBrowserWindow.watch(prop, XULBWPropHandler); + }, this); + + ["getCompositeStatusText", "getStatusText", "setStatusText", "setJSStatus", + "setJSDefaultStatus", "setDefaultStatus", "setOverLink"].forEach(function(prop) + { + this._window.XULBrowserWindow.unwatch(prop); + this._window.XULBrowserWindow[prop] = this[prop].bind(this); + this._window.XULBrowserWindow.watch(prop, XULBWPropHandler); + }, this); + + let XULBWHandler = function(prop, oldval, newval) { + if(!newval) + { + return newval; + } + CU.reportError("XULBrowserWindow changed. Updating S4E bindings."); + this._window.setTimeout(function(self) + { + self.buildBinding(); + }, 0, this); + return newval; + }; + + this._window.watch("XULBrowserWindow", XULBWHandler); + }, + + destroy: function() + { + // No need to unbind from the XULBrowserWindow, it's already null at this point + + this.clearTimer("_statusChromeTimeoutID"); + this.clearTimer("_statusContentTimeoutID"); + + this._overLinkService.destroy(); + + ["_overLink", "_network", "_networkXHR", "_status", "_jsStatus", "_defaultStatus", + "_statusText", "_window", "_service", "_getters", "_overLinkService"].forEach(function(prop) + { + delete this[prop]; + }, this); + }, + + buildTextOrder: function() + { + this.__defineGetter__("_textOrder", function() + { + let textOrder = ["_overLink"]; + if(this._service.statusNetwork) + { + textOrder.push("_network"); + if(this._service.statusNetworkXHR) + { + textOrder.push("_networkXHR"); + } + } + textOrder.push("_status", "_jsStatus"); + if(this._service.statusDefault) + { + textOrder.push("_defaultStatus"); + } + + delete this._textOrder; + return this._textOrder = textOrder; + }); + }, + + updateStatusField: function(force) + { + let text = { val: "", type: "" }; + for(let i = 0; !text.val && i < this._textOrder.length; i++) + { + text = this[this._textOrder[i]]; + } + + if(this._statusText.val != text.val || force) + { + if(this._noUpdate) + { + return; + } + + this._statusText = text; + + this.setStatusField(this._service.status, text, false); + + if(text.val && this._service.statusTimeout) + { + this.setTimer(text.type); + } + } + }, + + updateFullScreen: function() + { + this._isFullScreen = this._window.fullScreen; + this._isFullScreenVideo = false; + if(this._isFullScreen) + { + let fsEl = this._window.content.document.mozFullScreenElement; + if(fsEl && (fsEl.nodeName == "VIDEO" || fsEl.getElementsByTagName("VIDEO").length > 0)) + { + this._isFullScreenVideo = true; + } + } + + this.clearStatusField(); + this.updateStatusField(true); + }, + + setTimer: function(type) + { + let typeArgs = type.split(" ", 3); + + if(typeArgs.length < 2 || typeArgs[0] != "status") + { + return; + } + + if(typeArgs[1] == "chrome") + { + this.clearTimer("_statusChromeTimeoutID"); + this._statusChromeTimeoutID = this._window.setTimeout(function(self, isDefault) + { + self._statusChromeTimeoutID = 0; + if(isDefault) + { + self.setDefaultStatus(""); + } + else + { + self.setStatusText(""); + } + }, this._service.statusTimeout, this, (typeArgs.length == 3 && typeArgs[2] == "default")); + } + else + { + this.clearTimer("_statusContentTimeoutID"); + this._statusContentTimeoutID = this._window.setTimeout(function(self) + { + self._statusContentTimeoutID = 0; + self.setJSStatus(""); + }, this._service.statusTimeout, this); + } + }, + + clearTimer: function(timerName) + { + if(this[timerName] != 0) + { + this._window.clearTimeout(this[timerName]); + this[timerName] = 0; + } + }, + + clearStatusField: function() + { + this._getters.statusOverlay.value = ""; + + let status_label = this._getters.statusWidgetLabel; + if(status_label) + { + status_label.value = ""; + } + + }, + + setStatusField: function(location, text, allowTooltip) + { + if(!location) + { + return; + } + + let label = null; + + if(this._isFullScreen && this._service.advancedStatusDetectFullScreen) + { + switch(location) + { + case 1: // Toolbar + location = 3 + break; + case 2: // URL bar + if(Services.prefs.getBoolPref("browser.fullscreen.autohide")) + { + location = 3 + } + break; + } + } + + switch(location) + { + case 1: // Toolbar + label = this._getters.statusWidgetLabel; + break; + case 2: // URL Bar + break; + case 3: // Popup + default: + if(this._isFullScreenVideo && this._service.advancedStatusDetectVideo) + { + return; + } + label = this._getters.statusOverlay; + break; + } + + if(label) + { + label.setAttribute("previoustype", label.getAttribute("type")); + label.setAttribute("type", text.type); + label.value = text.val; + label.setAttribute("crop", text.type == "overLink" ? "center" : "end"); + } + } }; function S4EOverlinkService(window, service, statusService) { - this._window = window; - this._service = service; - this._statusService = statusService; + this._window = window; + this._service = service; + this._statusService = statusService; } S4EOverlinkService.prototype = { - _window: null, - _service: null, - _statusService: null, - - _timer: 0, - _currentLink: { link: "", anchor: null }, - _pendingLink: { link: "", anchor: null }, - _listening: false, - - update: function(aLink, aAnchor) - { - this.clearTimer(); - this.stopListen(); - this._pendingLink = { link: aLink, anchor: aAnchor }; - - if(!aLink) - { - if(this._window.XULBrowserWindow.hideOverLinkImmediately || !this._service.statusLinkOverDelayHide) - { - this._show(); - } - else - { - this._showDelayed(); - } - } - else if(this._currentLink.link || !this._service.statusLinkOverDelayShow) - { - this._show(); - } - else - { - this._showDelayed(); - this.startListen(); - } - }, - - destroy: function() - { - this.clearTimer(); - this.stopListen(); - - ["_currentLink", "_pendingLink", "_statusService", "_window"].forEach(function(prop) - { - delete this[prop]; - }, this); - }, - - startListen: function() - { - if(!this._listening) - { - this._window.addEventListener("mousemove", this, true); - this._listening = true; - } - }, - - stopListen: function() - { - if(this._listening) - { - this._window.removeEventListener("mousemove", this, true); - this._listening = false; - } - }, - - clearTimer: function() - { - if(this._timer != 0) - { - this._window.clearTimeout(this._timer); - this._timer = 0; - } - }, - - handleEvent: function(event) - { - switch(event.type) - { - case "mousemove": - this.clearTimer(); - this._showDelayed(); - } - }, - - _showDelayed: function() - { - let delay = ((this._pendingLink.link) - ? this._service.statusLinkOverDelayShow - : this._service.statusLinkOverDelayHide); - - this._timer = this._window.setTimeout(function(self) - { - self._timer = 0; - self._show(); - self.stopListen(); - }, delay, this); - }, - - _show: function() - { - this._currentLink = this._pendingLink; - this._statusService.setOverLinkInternal(this._currentLink.link, this._currentLink.anchor); - } + _window: null, + _service: null, + _statusService: null, + + _timer: 0, + _currentLink: { link: "", anchor: null }, + _pendingLink: { link: "", anchor: null }, + _listening: false, + + update: function(aLink, aAnchor) + { + this.clearTimer(); + this.stopListen(); + this._pendingLink = { link: aLink, anchor: aAnchor }; + + if(!aLink) + { + if(this._window.XULBrowserWindow.hideOverLinkImmediately || !this._service.statusLinkOverDelayHide) + { + this._show(); + } + else + { + this._showDelayed(); + } + } + else if(this._currentLink.link || !this._service.statusLinkOverDelayShow) + { + this._show(); + } + else + { + this._showDelayed(); + this.startListen(); + } + }, + + destroy: function() + { + this.clearTimer(); + this.stopListen(); + + ["_currentLink", "_pendingLink", "_statusService", "_window"].forEach(function(prop) + { + delete this[prop]; + }, this); + }, + + startListen: function() + { + if(!this._listening) + { + this._window.addEventListener("mousemove", this, true); + this._listening = true; + } + }, + + stopListen: function() + { + if(this._listening) + { + this._window.removeEventListener("mousemove", this, true); + this._listening = false; + } + }, + + clearTimer: function() + { + if(this._timer != 0) + { + this._window.clearTimeout(this._timer); + this._timer = 0; + } + }, + + handleEvent: function(event) + { + switch(event.type) + { + case "mousemove": + this.clearTimer(); + this._showDelayed(); + } + }, + + _showDelayed: function() + { + let delay = ((this._pendingLink.link) + ? this._service.statusLinkOverDelayShow + : this._service.statusLinkOverDelayHide); + + this._timer = this._window.setTimeout(function(self) + { + self._timer = 0; + self._show(); + self.stopListen(); + }, delay, this); + }, + + _show: function() + { + this._currentLink = this._pendingLink; + this._statusService.setOverLinkInternal(this._currentLink.link, this._currentLink.anchor); + } }; diff --git a/application/palemoon/components/statusbar/Status4Evar.jsm b/application/palemoon/components/statusbar/Status4Evar.jsm index 03e899afc..055306a88 100644 --- a/application/palemoon/components/statusbar/Status4Evar.jsm +++ b/application/palemoon/components/statusbar/Status4Evar.jsm @@ -23,257 +23,257 @@ CU.import("resource:///modules/statusbar/Toolbars.jsm"); function Status4Evar(window, gBrowser, toolbox) { - this._window = window; - this._toolbox = toolbox; + this._window = window; + this._toolbox = toolbox; - this.getters = new S4EWindowGetters(this._window); - this.toolbars = new S4EToolbars(this._window, gBrowser, this._toolbox, s4e_service, this.getters); - this.statusService = new S4EStatusService(this._window, s4e_service, this.getters); - this.progressMeter = new S4EProgressService(gBrowser, s4e_service, this.getters, this.statusService); - this.downloadStatus = new S4EDownloadService(this._window, gBrowser, s4e_service, this.getters); - this.sizeModeService = new SizeModeService(this._window, this); + this.getters = new S4EWindowGetters(this._window); + this.toolbars = new S4EToolbars(this._window, gBrowser, this._toolbox, s4e_service, this.getters); + this.statusService = new S4EStatusService(this._window, s4e_service, this.getters); + this.progressMeter = new S4EProgressService(gBrowser, s4e_service, this.getters, this.statusService); + this.downloadStatus = new S4EDownloadService(this._window, gBrowser, s4e_service, this.getters); + this.sizeModeService = new SizeModeService(this._window, this); - this._window.addEventListener("unload", this, false); + this._window.addEventListener("unload", this, false); } Status4Evar.prototype = { - _window: null, - _toolbox: null, - - getters: null, - toolbars: null, - statusService: null, - progressMeter: null, - downloadStatus: null, - sizeModeService: null, - - setup: function() - { - this._toolbox.addEventListener("beforecustomization", this, false); - this._toolbox.addEventListener("aftercustomization", this, false); - - this.toolbars.setup(); - this.updateWindow(); - - // OMFG HAX! If a page is already loading, fake a network start event - if(this._window.XULBrowserWindow._busyUI) - { - let nsIWPL = CI.nsIWebProgressListener; - this.progressMeter.onStateChange(0, null, nsIWPL.STATE_START | nsIWPL.STATE_IS_NETWORK, 0); - } - }, - - destroy: function() - { - this._window.removeEventListener("unload", this, false); - this._toolbox.removeEventListener("aftercustomization", this, false); - this._toolbox.removeEventListener("beforecustomization", this, false); - - this.getters.destroy(); - this.statusService.destroy(); - this.downloadStatus.destroy(); - this.progressMeter.destroy(); - this.toolbars.destroy(); - this.sizeModeService.destroy(); - - ["_window", "_toolbox", "getters", "statusService", "downloadStatus", - "progressMeter", "toolbars", "sizeModeService"].forEach(function(prop) - { - delete this[prop]; - }, this); - }, - - handleEvent: function(aEvent) - { - switch(aEvent.type) - { - case "unload": - this.destroy(); - break; - case "beforecustomization": - this.beforeCustomization(); - break; - case "aftercustomization": - this.updateWindow(); - break; - } - }, - - beforeCustomization: function() - { - this.toolbars.updateSplitters(false); - this.toolbars.updateWindowGripper(false); - - this.statusService.setNoUpdate(true); - let status_label = this.getters.statusWidgetLabel; - if(status_label) - { - status_label.value = this.getters.strings.getString("statusText"); - } - - this.downloadStatus.customizing(true); - }, - - updateWindow: function() - { - this.statusService.setNoUpdate(false); - this.getters.resetGetters(); - this.statusService.buildTextOrder(); - this.statusService.buildBinding(); - this.downloadStatus.init(); - this.downloadStatus.customizing(false); - this.toolbars.updateSplitters(true); - - s4e_service.updateWindow(this._window); - // This also handles the following: - // * buildTextOrder() - // * updateStatusField(true) - // * updateWindowGripper(true) - }, - - launchOptions: function(currentWindow) - { - let optionsURL = "chrome://browser/content/statusbar/prefs.xul"; - let windows = Services.wm.getEnumerator(null); - while (windows.hasMoreElements()) - { - let win = windows.getNext(); - if (win.document.documentURI == optionsURL) - { - win.focus(); - return; - } - } - - let features = "chrome,titlebar,toolbar,centerscreen"; - try - { - let instantApply = Services.prefs.getBoolPref("browser.preferences.instantApply"); - features += instantApply ? ",dialog=no" : ",modal"; - } - catch(e) - { - features += ",modal"; - } - currentWindow.openDialog(optionsURL, "", features); - } + _window: null, + _toolbox: null, + + getters: null, + toolbars: null, + statusService: null, + progressMeter: null, + downloadStatus: null, + sizeModeService: null, + + setup: function() + { + this._toolbox.addEventListener("beforecustomization", this, false); + this._toolbox.addEventListener("aftercustomization", this, false); + + this.toolbars.setup(); + this.updateWindow(); + + // OMFG HAX! If a page is already loading, fake a network start event + if(this._window.XULBrowserWindow._busyUI) + { + let nsIWPL = CI.nsIWebProgressListener; + this.progressMeter.onStateChange(0, null, nsIWPL.STATE_START | nsIWPL.STATE_IS_NETWORK, 0); + } + }, + + destroy: function() + { + this._window.removeEventListener("unload", this, false); + this._toolbox.removeEventListener("aftercustomization", this, false); + this._toolbox.removeEventListener("beforecustomization", this, false); + + this.getters.destroy(); + this.statusService.destroy(); + this.downloadStatus.destroy(); + this.progressMeter.destroy(); + this.toolbars.destroy(); + this.sizeModeService.destroy(); + + ["_window", "_toolbox", "getters", "statusService", "downloadStatus", + "progressMeter", "toolbars", "sizeModeService"].forEach(function(prop) + { + delete this[prop]; + }, this); + }, + + handleEvent: function(aEvent) + { + switch(aEvent.type) + { + case "unload": + this.destroy(); + break; + case "beforecustomization": + this.beforeCustomization(); + break; + case "aftercustomization": + this.updateWindow(); + break; + } + }, + + beforeCustomization: function() + { + this.toolbars.updateSplitters(false); + this.toolbars.updateWindowGripper(false); + + this.statusService.setNoUpdate(true); + let status_label = this.getters.statusWidgetLabel; + if(status_label) + { + status_label.value = this.getters.strings.getString("statusText"); + } + + this.downloadStatus.customizing(true); + }, + + updateWindow: function() + { + this.statusService.setNoUpdate(false); + this.getters.resetGetters(); + this.statusService.buildTextOrder(); + this.statusService.buildBinding(); + this.downloadStatus.init(); + this.downloadStatus.customizing(false); + this.toolbars.updateSplitters(true); + + s4e_service.updateWindow(this._window); + // This also handles the following: + // * buildTextOrder() + // * updateStatusField(true) + // * updateWindowGripper(true) + }, + + launchOptions: function(currentWindow) + { + let optionsURL = "chrome://browser/content/statusbar/prefs.xul"; + let windows = Services.wm.getEnumerator(null); + while (windows.hasMoreElements()) + { + let win = windows.getNext(); + if (win.document.documentURI == optionsURL) + { + win.focus(); + return; + } + } + + let features = "chrome,titlebar,toolbar,centerscreen"; + try + { + let instantApply = Services.prefs.getBoolPref("browser.preferences.instantApply"); + features += instantApply ? ",dialog=no" : ",modal"; + } + catch(e) + { + features += ",modal"; + } + currentWindow.openDialog(optionsURL, "", features); + } }; function S4EWindowGetters(window) { - this._window = window; + this._window = window; } S4EWindowGetters.prototype = { - _window: null, - _getterMap: - [ - ["addonbar", "addon-bar"], - ["addonbarCloseButton", "addonbar-closebutton"], - ["browserBottomBox", "browser-bottombox"], - ["downloadButton", "status4evar-download-button"], - ["downloadButtonTooltip", "status4evar-download-tooltip"], - ["downloadButtonProgress", "status4evar-download-progress-bar"], - ["downloadButtonLabel", "status4evar-download-label"], - ["downloadButtonAnchor", "status4evar-download-anchor"], - ["downloadNotifyAnchor", "status4evar-download-notification-anchor"], - ["statusBar", "status4evar-status-bar"], - ["statusWidget", "status4evar-status-widget"], - ["statusWidgetLabel", "status4evar-status-text"], - ["strings", "bundle_status4evar"], - ["throbberProgress", "status4evar-throbber-widget"], - ["toolbarProgress", "status4evar-progress-bar"] - ], - - resetGetters: function() - { - let document = this._window.document; - - this._getterMap.forEach(function(getter) - { - let [prop, id] = getter; - delete this[prop]; - this.__defineGetter__(prop, function() - { - delete this[prop]; - return this[prop] = document.getElementById(id); - }); - }, this); - - delete this.statusOverlay; - this.__defineGetter__("statusOverlay", function() - { - let so = this._window.XULBrowserWindow.statusTextField; - if(!so) - { - return null; - } - - delete this.statusOverlay; - return this.statusOverlay = so; - }); - }, - - destroy: function() - { - this._getterMap.forEach(function(getter) - { - let [prop, id] = getter; - delete this[prop]; - }, this); - - ["statusOverlay", "statusOverlay", "_window"].forEach(function(prop) - { - delete this[prop]; - }, this); - } + _window: null, + _getterMap: + [ + ["addonbar", "addon-bar"], + ["addonbarCloseButton", "addonbar-closebutton"], + ["browserBottomBox", "browser-bottombox"], + ["downloadButton", "status4evar-download-button"], + ["downloadButtonTooltip", "status4evar-download-tooltip"], + ["downloadButtonProgress", "status4evar-download-progress-bar"], + ["downloadButtonLabel", "status4evar-download-label"], + ["downloadButtonAnchor", "status4evar-download-anchor"], + ["downloadNotifyAnchor", "status4evar-download-notification-anchor"], + ["statusBar", "status4evar-status-bar"], + ["statusWidget", "status4evar-status-widget"], + ["statusWidgetLabel", "status4evar-status-text"], + ["strings", "bundle_status4evar"], + ["throbberProgress", "status4evar-throbber-widget"], + ["toolbarProgress", "status4evar-progress-bar"] + ], + + resetGetters: function() + { + let document = this._window.document; + + this._getterMap.forEach(function(getter) + { + let [prop, id] = getter; + delete this[prop]; + this.__defineGetter__(prop, function() + { + delete this[prop]; + return this[prop] = document.getElementById(id); + }); + }, this); + + delete this.statusOverlay; + this.__defineGetter__("statusOverlay", function() + { + let so = this._window.XULBrowserWindow.statusTextField; + if(!so) + { + return null; + } + + delete this.statusOverlay; + return this.statusOverlay = so; + }); + }, + + destroy: function() + { + this._getterMap.forEach(function(getter) + { + let [prop, id] = getter; + delete this[prop]; + }, this); + + ["statusOverlay", "statusOverlay", "_window"].forEach(function(prop) + { + delete this[prop]; + }, this); + } }; function SizeModeService(window, s4e) { - this._window = window; - this._s4e = s4e; + this._window = window; + this._s4e = s4e; - this.lastFullScreen = this._window.fullScreen; - this.lastwindowState = this._window.windowState; - this._window.addEventListener("sizemodechange", this, false); + this.lastFullScreen = this._window.fullScreen; + this.lastwindowState = this._window.windowState; + this._window.addEventListener("sizemodechange", this, false); } SizeModeService.prototype = { - _window: null, - _s4e: null, - - lastFullScreen: null, - lastwindowState: null, - - destroy: function() - { - this._window.removeEventListener("sizemodechange", this, false); - - ["_window", "_s4e"].forEach(function(prop) - { - delete this[prop]; - }, this); - }, - - handleEvent: function(e) - { - if(this._window.fullScreen != this.lastFullScreen) - { - this.lastFullScreen = this._window.fullScreen; - this._s4e.statusService.updateFullScreen(); - } - - if(this._window.windowState != this.lastwindowState) - { - this.lastwindowState = this._window.windowState; - this._s4e.toolbars.updateWindowGripper(true); - } - }, - - QueryInterface: XPCOMUtils.generateQI([ CI.nsIDOMEventListener ]) + _window: null, + _s4e: null, + + lastFullScreen: null, + lastwindowState: null, + + destroy: function() + { + this._window.removeEventListener("sizemodechange", this, false); + + ["_window", "_s4e"].forEach(function(prop) + { + delete this[prop]; + }, this); + }, + + handleEvent: function(e) + { + if(this._window.fullScreen != this.lastFullScreen) + { + this.lastFullScreen = this._window.fullScreen; + this._s4e.statusService.updateFullScreen(); + } + + if(this._window.windowState != this.lastwindowState) + { + this.lastwindowState = this._window.windowState; + this._s4e.toolbars.updateWindowGripper(true); + } + }, + + QueryInterface: XPCOMUtils.generateQI([ CI.nsIDOMEventListener ]) }; diff --git a/application/palemoon/components/statusbar/Toolbars.jsm b/application/palemoon/components/statusbar/Toolbars.jsm index dda8565fd..321efd092 100644 --- a/application/palemoon/components/statusbar/Toolbars.jsm +++ b/application/palemoon/components/statusbar/Toolbars.jsm @@ -13,209 +13,209 @@ CU.import("resource://gre/modules/Services.jsm"); function S4EToolbars(window, gBrowser, toolbox, service, getters) { - this._window = window; - this._toolbox = toolbox; - this._service = service; - this._getters = getters; - this._handler = new ClassicS4EToolbars(this._window, this._toolbox); + this._window = window; + this._toolbox = toolbox; + this._service = service; + this._getters = getters; + this._handler = new ClassicS4EToolbars(this._window, this._toolbox); } S4EToolbars.prototype = { - _window: null, - _toolbox: null, - _service: null, - _getters: null, - - _handler: null, - - setup: function() - { - this.updateSplitters(false); - this.updateWindowGripper(false); - this._handler.setup(this._service.firstRun); - }, - - destroy: function() - { - this._handler.destroy(); - - ["_window", "_toolbox", "_service", "_getters", "_handler"].forEach(function(prop) - { - delete this[prop]; - }, this); - }, - - updateSplitters: function(action) - { - let document = this._window.document; - - let splitter_before = document.getElementById("status4evar-status-splitter-before"); - if(splitter_before) - { - splitter_before.parentNode.removeChild(splitter_before); - } - - let splitter_after = document.getElementById("status4evar-status-splitter-after"); - if(splitter_after) - { - splitter_after.parentNode.removeChild(splitter_after); - } - - let status = this._getters.statusWidget; - if(!action || !status) - { - return; - } - - let urlbar = document.getElementById("urlbar-container"); - let stop = document.getElementById("stop-button"); - let fullscreenflex = document.getElementById("fullscreenflex"); - - let nextSibling = status.nextSibling; - let previousSibling = status.previousSibling; - - function getSplitter(splitter, suffix) - { - if(!splitter) - { - splitter = document.createElement("splitter"); - splitter.id = "status4evar-status-splitter-" + suffix; - splitter.setAttribute("resizebefore", "flex"); - splitter.setAttribute("resizeafter", "flex"); - splitter.className = "chromeclass-toolbar-additional status4evar-status-splitter"; - } - return splitter; - } - - if((previousSibling && previousSibling.flex > 0) - || (urlbar && stop && urlbar.getAttribute("combined") && stop == previousSibling)) - { - status.parentNode.insertBefore(getSplitter(splitter_before, "before"), status); - } - - if(nextSibling && nextSibling.flex > 0 && nextSibling != fullscreenflex) - { - status.parentNode.insertBefore(getSplitter(splitter_after, "after"), nextSibling); - } - }, - - updateWindowGripper: function(action) - { - let document = this._window.document; - - let gripper = document.getElementById("status4evar-window-gripper"); - let toolbar = this._getters.statusBar || this._getters.addonbar; - - if(!action || !toolbar || !this._service.addonbarWindowGripper - || this._window.windowState != CI.nsIDOMChromeWindow.STATE_NORMAL || toolbar.toolbox.customizing) - { - if(gripper) - { - gripper.parentNode.removeChild(gripper); - } - return; - } - - gripper = this._handler.buildGripper(toolbar, gripper, "status4evar-window-gripper"); - - toolbar.appendChild(gripper); - } + _window: null, + _toolbox: null, + _service: null, + _getters: null, + + _handler: null, + + setup: function() + { + this.updateSplitters(false); + this.updateWindowGripper(false); + this._handler.setup(this._service.firstRun); + }, + + destroy: function() + { + this._handler.destroy(); + + ["_window", "_toolbox", "_service", "_getters", "_handler"].forEach(function(prop) + { + delete this[prop]; + }, this); + }, + + updateSplitters: function(action) + { + let document = this._window.document; + + let splitter_before = document.getElementById("status4evar-status-splitter-before"); + if(splitter_before) + { + splitter_before.parentNode.removeChild(splitter_before); + } + + let splitter_after = document.getElementById("status4evar-status-splitter-after"); + if(splitter_after) + { + splitter_after.parentNode.removeChild(splitter_after); + } + + let status = this._getters.statusWidget; + if(!action || !status) + { + return; + } + + let urlbar = document.getElementById("urlbar-container"); + let stop = document.getElementById("stop-button"); + let fullscreenflex = document.getElementById("fullscreenflex"); + + let nextSibling = status.nextSibling; + let previousSibling = status.previousSibling; + + function getSplitter(splitter, suffix) + { + if(!splitter) + { + splitter = document.createElement("splitter"); + splitter.id = "status4evar-status-splitter-" + suffix; + splitter.setAttribute("resizebefore", "flex"); + splitter.setAttribute("resizeafter", "flex"); + splitter.className = "chromeclass-toolbar-additional status4evar-status-splitter"; + } + return splitter; + } + + if((previousSibling && previousSibling.flex > 0) + || (urlbar && stop && urlbar.getAttribute("combined") && stop == previousSibling)) + { + status.parentNode.insertBefore(getSplitter(splitter_before, "before"), status); + } + + if(nextSibling && nextSibling.flex > 0 && nextSibling != fullscreenflex) + { + status.parentNode.insertBefore(getSplitter(splitter_after, "after"), nextSibling); + } + }, + + updateWindowGripper: function(action) + { + let document = this._window.document; + + let gripper = document.getElementById("status4evar-window-gripper"); + let toolbar = this._getters.statusBar || this._getters.addonbar; + + if(!action || !toolbar || !this._service.addonbarWindowGripper + || this._window.windowState != CI.nsIDOMChromeWindow.STATE_NORMAL || toolbar.toolbox.customizing) + { + if(gripper) + { + gripper.parentNode.removeChild(gripper); + } + return; + } + + gripper = this._handler.buildGripper(toolbar, gripper, "status4evar-window-gripper"); + + toolbar.appendChild(gripper); + } }; function ClassicS4EToolbars(window, toolbox) { - this._window = window; - this._toolbox = toolbox; + this._window = window; + this._toolbox = toolbox; } ClassicS4EToolbars.prototype = { - _window: null, - _toolbox: null, - - setup: function(firstRun) - { - let document = this._window.document; - - let addon_bar = document.getElementById("addon-bar"); - if(addon_bar) - { - let baseSet = "addonbar-closebutton" - + ",status4evar-status-widget" - + ",status4evar-progress-widget"; - - // Update the defaultSet - let defaultSet = baseSet; - let defaultSetIgnore = ["addonbar-closebutton", "spring", "status-bar"]; - addon_bar.getAttribute("defaultset").split(",").forEach(function(item) - { - if(defaultSetIgnore.indexOf(item) == -1) - { - defaultSet += "," + item; - } - }); - defaultSet += ",status-bar" - addon_bar.setAttribute("defaultset", defaultSet); - - // Update the currentSet - if(firstRun) - { - let isCustomizableToolbar = function(aElt) - { - return aElt.localName == "toolbar" && aElt.getAttribute("customizable") == "true"; - } - - let isCustomizedAlready = false; - let toolbars = Array.filter(this._toolbox.childNodes, isCustomizableToolbar).concat( - Array.filter(this._toolbox.externalToolbars, isCustomizableToolbar)); - toolbars.forEach(function(toolbar) - { - if(toolbar.currentSet.indexOf("status4evar") > -1) - { - isCustomizedAlready = true; - } - }); - - if(!isCustomizedAlready) - { - let currentSet = baseSet; - let currentSetIgnore = ["addonbar-closebutton", "spring"]; - addon_bar.currentSet.split(",").forEach(function(item) - { - if(currentSetIgnore.indexOf(item) == -1) - { - currentSet += "," + item; - } - }); - addon_bar.currentSet = currentSet; - addon_bar.setAttribute("currentset", currentSet); - document.persist(addon_bar.id, "currentset"); - this._window.setToolbarVisibility(addon_bar, true); - } - } - } - }, - - destroy: function() - { - ["_window", "_toolbox"].forEach(function(prop) - { - delete this[prop]; - }, this); - }, - - buildGripper: function(toolbar, gripper, id) - { - if(!gripper) - { - let document = this._window.document; - - gripper = document.createElement("resizer"); - gripper.id = id; - gripper.dir = "bottomend"; - } - - return gripper; - } + _window: null, + _toolbox: null, + + setup: function(firstRun) + { + let document = this._window.document; + + let addon_bar = document.getElementById("addon-bar"); + if(addon_bar) + { + let baseSet = "addonbar-closebutton" + + ",status4evar-status-widget" + + ",status4evar-progress-widget"; + + // Update the defaultSet + let defaultSet = baseSet; + let defaultSetIgnore = ["addonbar-closebutton", "spring", "status-bar"]; + addon_bar.getAttribute("defaultset").split(",").forEach(function(item) + { + if(defaultSetIgnore.indexOf(item) == -1) + { + defaultSet += "," + item; + } + }); + defaultSet += ",status-bar" + addon_bar.setAttribute("defaultset", defaultSet); + + // Update the currentSet + if(firstRun) + { + let isCustomizableToolbar = function(aElt) + { + return aElt.localName == "toolbar" && aElt.getAttribute("customizable") == "true"; + } + + let isCustomizedAlready = false; + let toolbars = Array.filter(this._toolbox.childNodes, isCustomizableToolbar).concat( + Array.filter(this._toolbox.externalToolbars, isCustomizableToolbar)); + toolbars.forEach(function(toolbar) + { + if(toolbar.currentSet.indexOf("status4evar") > -1) + { + isCustomizedAlready = true; + } + }); + + if(!isCustomizedAlready) + { + let currentSet = baseSet; + let currentSetIgnore = ["addonbar-closebutton", "spring"]; + addon_bar.currentSet.split(",").forEach(function(item) + { + if(currentSetIgnore.indexOf(item) == -1) + { + currentSet += "," + item; + } + }); + addon_bar.currentSet = currentSet; + addon_bar.setAttribute("currentset", currentSet); + document.persist(addon_bar.id, "currentset"); + this._window.setToolbarVisibility(addon_bar, true); + } + } + } + }, + + destroy: function() + { + ["_window", "_toolbox"].forEach(function(prop) + { + delete this[prop]; + }, this); + }, + + buildGripper: function(toolbar, gripper, id) + { + if(!gripper) + { + let document = this._window.document; + + gripper = document.createElement("resizer"); + gripper.id = id; + gripper.dir = "bottomend"; + } + + return gripper; + } }; diff --git a/application/palemoon/components/statusbar/content/overlay.css b/application/palemoon/components/statusbar/content/overlay.css index 6375b8ef8..fd3452119 100644 --- a/application/palemoon/components/statusbar/content/overlay.css +++ b/application/palemoon/components/statusbar/content/overlay.css @@ -8,8 +8,7 @@ * Status Popup */ -statuspanel -{ - -moz-binding: url("chrome://browser/content/statusbar/tabbrowser.xml#statuspanel"); +statuspanel { + -moz-binding: url("chrome://browser/content/statusbar/tabbrowser.xml#statuspanel"); } diff --git a/application/palemoon/components/statusbar/content/overlay.js b/application/palemoon/components/statusbar/content/overlay.js index cf6cfe296..b868aaf0e 100644 --- a/application/palemoon/components/statusbar/content/overlay.js +++ b/application/palemoon/components/statusbar/content/overlay.js @@ -6,11 +6,11 @@ if(!caligon) var caligon = {}; window.addEventListener("load", function buildS4E() { - window.removeEventListener("load", buildS4E, false); + window.removeEventListener("load", buildS4E, false); - Components.utils.import("resource:///modules/statusbar/Status4Evar.jsm"); + Components.utils.import("resource:///modules/statusbar/Status4Evar.jsm"); - caligon.status4evar = new Status4Evar(window, gBrowser, gNavToolbox); - caligon.status4evar.setup(); + caligon.status4evar = new Status4Evar(window, gBrowser, gNavToolbox); + caligon.status4evar.setup(); }, false); diff --git a/application/palemoon/components/statusbar/content/overlay.xul b/application/palemoon/components/statusbar/content/overlay.xul index f9a61a92e..b9934ee65 100644 --- a/application/palemoon/components/statusbar/content/overlay.xul +++ b/application/palemoon/components/statusbar/content/overlay.xul @@ -13,23 +13,23 @@ <overlay id="status4evar-overlay" xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"> - <stringbundleset id="stringbundleset"> - <stringbundle id="bundle_status4evar" src="chrome://browser/locale/statusbar/overlay.properties" /> - </stringbundleset> + <stringbundleset id="stringbundleset"> + <stringbundle id="bundle_status4evar" src="chrome://browser/locale/statusbar/overlay.properties" /> + </stringbundleset> - <script type="application/javascript" src="chrome://browser/content/statusbar/overlay.js" /> + <script type="application/javascript" src="chrome://browser/content/statusbar/overlay.js" /> - <commandset> - <command id="S4E:Options" oncommand="caligon.status4evar.launchOptions(window);"/> - </commandset> + <commandset> + <command id="S4E:Options" oncommand="caligon.status4evar.launchOptions(window);"/> + </commandset> - <popupset id="mainPopupSet"> - <hbox id="status4evar-download-notification-container" mousethrough="always"> - <vbox id="status4evar-download-notification-anchor"> - <vbox id="status4evar-download-notification-icon" /> - </vbox> - </hbox> - </popupset> + <popupset id="mainPopupSet"> + <hbox id="status4evar-download-notification-container" mousethrough="always"> + <vbox id="status4evar-download-notification-anchor"> + <vbox id="status4evar-download-notification-icon" /> + </vbox> + </hbox> + </popupset> <menupopup id="menu_ToolsPopup"> <menuitem id="statusbar-options-fx" command="S4E:Options" @@ -41,41 +41,41 @@ label="&status4evar.menu.options.label;"/> </menupopup> - <toolbarpalette id="BrowserToolbarPalette"> - <toolbaritem id="status4evar-status-widget" - title="&status4evar.status.widget.title;" - removable="true" flex="1" persist="width" width="100"> - <label id="status4evar-status-text" flex="1" crop="end" value="&status4evar.status.widget.title;" /> - </toolbaritem> + <toolbarpalette id="BrowserToolbarPalette"> + <toolbaritem id="status4evar-status-widget" + title="&status4evar.status.widget.title;" + removable="true" flex="1" persist="width" width="100"> + <label id="status4evar-status-text" flex="1" crop="end" value="&status4evar.status.widget.title;" /> + </toolbaritem> - <toolbarbutton id="status4evar-download-button" - title="&status4evar.download.widget.title;" - class="toolbarbutton-1 chromeclass-toolbar-additional" - removable="true" collapsed="true" tooltip="_child" - oncommand="caligon.status4evar.downloadStatus.openUI(event)"> - <stack id="status4evar-download-anchor" class="toolbarbutton-icon"> - <vbox id="status4evar-download-icon" /> - <vbox pack="end"> - <progressmeter id="status4evar-download-progress-bar" mode="normal" value="0" collapsed="true" min="0" max="100" /> - </vbox> - </stack> - <tooltip id="status4evar-download-tooltip" /> - <label id="status4evar-download-label" value="&status4evar.download.widget.title;" class="toolbarbutton-text" crop="right" flex="1" /> - </toolbarbutton> + <toolbarbutton id="status4evar-download-button" + title="&status4evar.download.widget.title;" + class="toolbarbutton-1 chromeclass-toolbar-additional" + removable="true" collapsed="true" tooltip="_child" + oncommand="caligon.status4evar.downloadStatus.openUI(event)"> + <stack id="status4evar-download-anchor" class="toolbarbutton-icon"> + <vbox id="status4evar-download-icon" /> + <vbox pack="end"> + <progressmeter id="status4evar-download-progress-bar" mode="normal" value="0" collapsed="true" min="0" max="100" /> + </vbox> + </stack> + <tooltip id="status4evar-download-tooltip" /> + <label id="status4evar-download-label" value="&status4evar.download.widget.title;" class="toolbarbutton-text" crop="right" flex="1" /> + </toolbarbutton> - <toolbaritem id="status4evar-progress-widget" - title="&status4evar.progress.widget.title;" - removable="true"> - <progressmeter id="status4evar-progress-bar" class="progressmeter-statusbar" - mode="normal" value="0" collapsed="true" min="0" max="100" /> - </toolbaritem> + <toolbaritem id="status4evar-progress-widget" + title="&status4evar.progress.widget.title;" + removable="true"> + <progressmeter id="status4evar-progress-bar" class="progressmeter-statusbar" + mode="normal" value="0" collapsed="true" min="0" max="100" /> + </toolbaritem> - <toolbarbutton id="status4evar-options-button" - title="&status4evar.options.widget.title;" - class="toolbarbutton-1 chromeclass-toolbar-additional" - label="&status4evar.options.widget.label;" - removable="true" command="S4E:Options" tooltiptext="&status4evar.options.widget.title;" /> - </toolbarpalette> + <toolbarbutton id="status4evar-options-button" + title="&status4evar.options.widget.title;" + class="toolbarbutton-1 chromeclass-toolbar-additional" + label="&status4evar.options.widget.label;" + removable="true" command="S4E:Options" tooltiptext="&status4evar.options.widget.title;" /> + </toolbarpalette> <statusbar id="status-bar" ordinal="1" /> </overlay> diff --git a/application/palemoon/components/statusbar/content/prefs.css b/application/palemoon/components/statusbar/content/prefs.css index c627f78fb..bafaa6129 100644 --- a/application/palemoon/components/statusbar/content/prefs.css +++ b/application/palemoon/components/statusbar/content/prefs.css @@ -4,8 +4,7 @@ @namespace url("http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"); -.css-bg-editor -{ - -moz-binding: url("chrome://browser/content/statusbar/prefs.xml#css-bg-editor"); +.css-bg-editor { + -moz-binding: url("chrome://browser/content/statusbar/prefs.xml#css-bg-editor"); } diff --git a/application/palemoon/components/statusbar/content/prefs.js b/application/palemoon/components/statusbar/content/prefs.js index ed81fb271..47fd4b63d 100644 --- a/application/palemoon/components/statusbar/content/prefs.js +++ b/application/palemoon/components/statusbar/content/prefs.js @@ -6,267 +6,267 @@ Components.utils.import("resource://gre/modules/Services.jsm"); var status4evarPrefs = { - get dynamicProgressStyle() - { - let styleSheets = window.document.styleSheets; - for(let i = 0; i < styleSheets.length; i++) - { - let styleSheet = styleSheets[i]; - if(styleSheet.href == "chrome://browser/skin/statusbar/dynamic.css") - { - delete this.dynamicProgressStyle; - return this.dynamicProgressStyle = styleSheet; - } - } - - return null; - }, + get dynamicProgressStyle() + { + let styleSheets = window.document.styleSheets; + for(let i = 0; i < styleSheets.length; i++) + { + let styleSheet = styleSheets[i]; + if(styleSheet.href == "chrome://browser/skin/statusbar/dynamic.css") + { + delete this.dynamicProgressStyle; + return this.dynamicProgressStyle = styleSheet; + } + } + + return null; + }, // // Status timeout management // - get statusTimeoutPref() - { - delete this.statusTimeoutPref; - return this.statusTimeoutPref = document.getElementById("status4evar-pref-status-timeout"); - }, - - get statusTimeoutCheckbox() - { - delete this.statusTimeoutCheckbox; - return this.statusTimeoutCheckbox = document.getElementById("status4evar-status-timeout-check"); - }, - - statusTimeoutChanged: function() - { - if(this.statusTimeoutPref.value > 0) - { - this.statusTimeoutPref.disabled = false; - this.statusTimeoutCheckbox.checked = true; - } - else - { - this.statusTimeoutPref.disabled = true; - this.statusTimeoutCheckbox.checked = false; - } - }, - - statusTimeoutSync: function() - { - this.statusTimeoutChanged(); - return undefined; - }, - - statusTimeoutToggle: function() - { - if(this.statusTimeoutPref.disabled == this.statusTimeoutCheckbox.checked) - { - if(this.statusTimeoutCheckbox.checked) - { - this.statusTimeoutPref.value = 10; - } - else - { - this.statusTimeoutPref.value = 0; - } - } - }, + get statusTimeoutPref() + { + delete this.statusTimeoutPref; + return this.statusTimeoutPref = document.getElementById("status4evar-pref-status-timeout"); + }, + + get statusTimeoutCheckbox() + { + delete this.statusTimeoutCheckbox; + return this.statusTimeoutCheckbox = document.getElementById("status4evar-status-timeout-check"); + }, + + statusTimeoutChanged: function() + { + if(this.statusTimeoutPref.value > 0) + { + this.statusTimeoutPref.disabled = false; + this.statusTimeoutCheckbox.checked = true; + } + else + { + this.statusTimeoutPref.disabled = true; + this.statusTimeoutCheckbox.checked = false; + } + }, + + statusTimeoutSync: function() + { + this.statusTimeoutChanged(); + return undefined; + }, + + statusTimeoutToggle: function() + { + if(this.statusTimeoutPref.disabled == this.statusTimeoutCheckbox.checked) + { + if(this.statusTimeoutCheckbox.checked) + { + this.statusTimeoutPref.value = 10; + } + else + { + this.statusTimeoutPref.value = 0; + } + } + }, // // Status network management // - get statusNetworkPref() - { - delete this.statusNetworkPref; - return this.statusNetworkPref = document.getElementById("status4evar-pref-status-network"); - }, - - get statusNetworkXHRPref() - { - delete this.statusNetworkXHRPref; - return this.statusNetworkXHRPref = document.getElementById("status4evar-pref-status-network-xhr"); - }, - - statusNetworkChanged: function() - { - this.statusNetworkXHRPref.disabled = ! this.statusNetworkPref.value; - }, - - statusNetworkSync: function() - { - this.statusNetworkChanged(); - return undefined; - }, + get statusNetworkPref() + { + delete this.statusNetworkPref; + return this.statusNetworkPref = document.getElementById("status4evar-pref-status-network"); + }, + + get statusNetworkXHRPref() + { + delete this.statusNetworkXHRPref; + return this.statusNetworkXHRPref = document.getElementById("status4evar-pref-status-network-xhr"); + }, + + statusNetworkChanged: function() + { + this.statusNetworkXHRPref.disabled = ! this.statusNetworkPref.value; + }, + + statusNetworkSync: function() + { + this.statusNetworkChanged(); + return undefined; + }, // // Status Text langth managment // - get textMaxLengthPref() - { - delete this.textMaxLengthPref; - return this.textMaxLengthPref = document.getElementById("status4evar-pref-status-toolbar-maxLength"); - }, - - get textMaxLengthCheckbox() - { - delete this.textMaxLengthCheckbox; - return this.textMaxLengthCheckbox = document.getElementById("status4evar-status-toolbar-maxLength-check"); - }, - - textLengthChanged: function() - { - if(this.textMaxLengthPref.value > 0) - { - this.textMaxLengthPref.disabled = false; - this.textMaxLengthCheckbox.checked = true; - } - else - { - this.textMaxLengthPref.disabled = true; - this.textMaxLengthCheckbox.checked = false; - } - }, - - textLengthSync: function() - { - this.textLengthChanged(); - return undefined; - }, - - textLengthToggle: function() - { - if(this.textMaxLengthPref.disabled == this.textMaxLengthCheckbox.checked) - { - if(this.textMaxLengthCheckbox.checked) - { - this.textMaxLengthPref.value = 800; - } - else - { - this.textMaxLengthPref.value = 0; - } - } - }, + get textMaxLengthPref() + { + delete this.textMaxLengthPref; + return this.textMaxLengthPref = document.getElementById("status4evar-pref-status-toolbar-maxLength"); + }, + + get textMaxLengthCheckbox() + { + delete this.textMaxLengthCheckbox; + return this.textMaxLengthCheckbox = document.getElementById("status4evar-status-toolbar-maxLength-check"); + }, + + textLengthChanged: function() + { + if(this.textMaxLengthPref.value > 0) + { + this.textMaxLengthPref.disabled = false; + this.textMaxLengthCheckbox.checked = true; + } + else + { + this.textMaxLengthPref.disabled = true; + this.textMaxLengthCheckbox.checked = false; + } + }, + + textLengthSync: function() + { + this.textLengthChanged(); + return undefined; + }, + + textLengthToggle: function() + { + if(this.textMaxLengthPref.disabled == this.textMaxLengthCheckbox.checked) + { + if(this.textMaxLengthCheckbox.checked) + { + this.textMaxLengthPref.value = 800; + } + else + { + this.textMaxLengthPref.value = 0; + } + } + }, // // Toolbar progress style management // - get progressToolbarStylePref() - { - delete this.progressToolbarStylePref; - return this.progressToolbarStylePref = document.getElementById("status4evar-pref-progress-toolbar-style"); - }, - - get progressToolbarCSSPref() - { - delete this.progressToolbarCSSPref; - return this.progressToolbarCSSPref = document.getElementById("status4evar-pref-progress-toolbar-css"); - }, - - get progressToolbarProgress() - { - delete this.progressToolbarProgress; - return this.progressToolbarProgress = document.getElementById("status4evar-progress-bar"); - }, - - progressToolbarCSSChanged: function() - { - if(!this.progressToolbarCSSPref.value) - { - this.progressToolbarCSSPref.value = "#33FF33"; - } - this.dynamicProgressStyle.cssRules[1].style.background = this.progressToolbarCSSPref.value; - }, - - progressToolbarStyleChanged: function() - { - this.progressToolbarCSSChanged(); - this.progressToolbarCSSPref.disabled = !this.progressToolbarStylePref.value; - if(this.progressToolbarStylePref.value) - { - this.progressToolbarProgress.setAttribute("s4estyle", true); - } - else - { - this.progressToolbarProgress.removeAttribute("s4estyle"); - } - }, - - progressToolbarStyleSync: function() - { - this.progressToolbarStyleChanged(); - return undefined; - }, + get progressToolbarStylePref() + { + delete this.progressToolbarStylePref; + return this.progressToolbarStylePref = document.getElementById("status4evar-pref-progress-toolbar-style"); + }, + + get progressToolbarCSSPref() + { + delete this.progressToolbarCSSPref; + return this.progressToolbarCSSPref = document.getElementById("status4evar-pref-progress-toolbar-css"); + }, + + get progressToolbarProgress() + { + delete this.progressToolbarProgress; + return this.progressToolbarProgress = document.getElementById("status4evar-progress-bar"); + }, + + progressToolbarCSSChanged: function() + { + if(!this.progressToolbarCSSPref.value) + { + this.progressToolbarCSSPref.value = "#33FF33"; + } + this.dynamicProgressStyle.cssRules[1].style.background = this.progressToolbarCSSPref.value; + }, + + progressToolbarStyleChanged: function() + { + this.progressToolbarCSSChanged(); + this.progressToolbarCSSPref.disabled = !this.progressToolbarStylePref.value; + if(this.progressToolbarStylePref.value) + { + this.progressToolbarProgress.setAttribute("s4estyle", true); + } + else + { + this.progressToolbarProgress.removeAttribute("s4estyle"); + } + }, + + progressToolbarStyleSync: function() + { + this.progressToolbarStyleChanged(); + return undefined; + }, // // Download progress management // - get downloadProgressCheck() - { - delete this.downloadProgressCheck; - return this.downloadProgressCheck = document.getElementById("status4evar-download-progress-check"); - }, - - get downloadProgressPref() - { - delete this.downloadProgressPref; - return this.downloadProgressPref = document.getElementById("status4evar-pref-download-progress"); - }, - - get downloadProgressColorActivePref() - { - delete this.downloadProgressActiveColorPref; - return this.downloadProgressActiveColorPref = document.getElementById("status4evar-pref-download-color-active"); - }, - - get downloadProgressColorPausedPref() - { - delete this.downloadProgressPausedColorPref; - return this.downloadProgressPausedColorPref = document.getElementById("status4evar-pref-download-color-paused"); - }, - - downloadProgressSync: function() - { - let val = this.downloadProgressPref.value; - this.downloadProgressColorActivePref.disabled = (val == 0); - this.downloadProgressColorPausedPref.disabled = (val == 0); - this.downloadProgressPref.disabled = (val == 0); - this.downloadProgressCheck.checked = (val != 0); - return ((val == 0) ? 1 : val); - }, - - downloadProgressToggle: function() - { - let enabled = this.downloadProgressCheck.checked; - this.downloadProgressPref.value = ((enabled) ? 1 : 0); - }, + get downloadProgressCheck() + { + delete this.downloadProgressCheck; + return this.downloadProgressCheck = document.getElementById("status4evar-download-progress-check"); + }, + + get downloadProgressPref() + { + delete this.downloadProgressPref; + return this.downloadProgressPref = document.getElementById("status4evar-pref-download-progress"); + }, + + get downloadProgressColorActivePref() + { + delete this.downloadProgressActiveColorPref; + return this.downloadProgressActiveColorPref = document.getElementById("status4evar-pref-download-color-active"); + }, + + get downloadProgressColorPausedPref() + { + delete this.downloadProgressPausedColorPref; + return this.downloadProgressPausedColorPref = document.getElementById("status4evar-pref-download-color-paused"); + }, + + downloadProgressSync: function() + { + let val = this.downloadProgressPref.value; + this.downloadProgressColorActivePref.disabled = (val == 0); + this.downloadProgressColorPausedPref.disabled = (val == 0); + this.downloadProgressPref.disabled = (val == 0); + this.downloadProgressCheck.checked = (val != 0); + return ((val == 0) ? 1 : val); + }, + + downloadProgressToggle: function() + { + let enabled = this.downloadProgressCheck.checked; + this.downloadProgressPref.value = ((enabled) ? 1 : 0); + }, // // Pref Window load // - get downloadButtonActionCommandPref() - { - delete this.downloadButtonActionCommandPref; - return this.downloadButtonActionCommandPref = document.getElementById("status4evar-pref-download-button-action-command"); - }, - - get downloadButtonActionThirdPartyItem() - { - delete this.downloadButtonActionThirdPartyItem; - return this.downloadButtonActionThirdPartyItem = document.getElementById("status4evar-download-button-action-menu-thirdparty"); - }, - - onPrefWindowLoad: function() - { - if(!this.downloadButtonActionCommandPref.value) - { - this.downloadButtonActionThirdPartyItem.disabled = true; - } - }, - - onPrefWindowUnLoad: function() - { - } + get downloadButtonActionCommandPref() + { + delete this.downloadButtonActionCommandPref; + return this.downloadButtonActionCommandPref = document.getElementById("status4evar-pref-download-button-action-command"); + }, + + get downloadButtonActionThirdPartyItem() + { + delete this.downloadButtonActionThirdPartyItem; + return this.downloadButtonActionThirdPartyItem = document.getElementById("status4evar-download-button-action-menu-thirdparty"); + }, + + onPrefWindowLoad: function() + { + if(!this.downloadButtonActionCommandPref.value) + { + this.downloadButtonActionThirdPartyItem.disabled = true; + } + }, + + onPrefWindowUnLoad: function() + { + } } var XULBrowserWindow = { diff --git a/application/palemoon/components/statusbar/content/prefs.xml b/application/palemoon/components/statusbar/content/prefs.xml index cf4a00bb8..44baab18d 100644 --- a/application/palemoon/components/statusbar/content/prefs.xml +++ b/application/palemoon/components/statusbar/content/prefs.xml @@ -11,694 +11,694 @@ xmlns:xul="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" xmlns:xbl="http://www.mozilla.org/xbl"> - <binding id="css-bg-editor"> - <content sizetopopup="pref"> - <xul:vbox flex="1"> - <xul:deck anonid="css-bg-editor-deck" flex="1"> - <xul:vbox> - <xul:hbox align="center"> - <xul:label xbl:inherits="disabled">&status4evar.editor.css.color.label;</xul:label> - <xul:colorpicker anonid="css-bg-editor-color" type="button" onchange="this._editor._buildCSS();" xbl:inherits="disabled" /> - </xul:hbox> - - <xul:hbox align="center"> - <xul:label xbl:inherits="disabled">&status4evar.editor.css.image.label;</xul:label> - <xul:textbox anonid="css-bg-editor-image" readonly="true" flex="1" xbl:inherits="disabled" /> - <xul:button anonid="css-bg-editor-image-browse" label="&status4evar.option.browse;" oncommand="this._editor._imageBrowse();" xbl:inherits="disabled" /> - </xul:hbox> - <xul:hbox align="center" pack="end"> - <xul:button anonid="css-bg-editor-image-clear" label="&status4evar.option.clear;" oncommand="this._editor._imageClear();" xbl:inherits="disabled=no-image" /> - </xul:hbox> - - <xul:hbox> - <xul:groupbox pack="center"> - <xul:caption label="" /> - <xul:hbox flex="1" align="center"> - <xul:label>X</xul:label> - </xul:hbox> - <xul:separator class="groove" orient="horizontal" /> - <xul:hbox flex="1" align="center"> - <xul:label>Y</xul:label> - </xul:hbox> - </xul:groupbox> - - <xul:groupbox> - <xul:caption label="&status4evar.editor.css.image.repeat;" xbl:inherits="disabled=no-image" /> - <xul:menulist anonid="css-bg-editor-image-repeat-x" sizetopopup="always" onselect="this._editor._buildCSS();" xbl:inherits="disabled=no-image"> - <xul:menupopup> - <xul:menuitem label="&status4evar.option.no-repeat;" value="no-repeat" /> - <xul:menuitem label="&status4evar.option.repeat;" value="repeat" /> + <binding id="css-bg-editor"> + <content sizetopopup="pref"> + <xul:vbox flex="1"> + <xul:deck anonid="css-bg-editor-deck" flex="1"> + <xul:vbox> + <xul:hbox align="center"> + <xul:label xbl:inherits="disabled">&status4evar.editor.css.color.label;</xul:label> + <xul:colorpicker anonid="css-bg-editor-color" type="button" onchange="this._editor._buildCSS();" xbl:inherits="disabled" /> + </xul:hbox> + + <xul:hbox align="center"> + <xul:label xbl:inherits="disabled">&status4evar.editor.css.image.label;</xul:label> + <xul:textbox anonid="css-bg-editor-image" readonly="true" flex="1" xbl:inherits="disabled" /> + <xul:button anonid="css-bg-editor-image-browse" label="&status4evar.option.browse;" oncommand="this._editor._imageBrowse();" xbl:inherits="disabled" /> + </xul:hbox> + <xul:hbox align="center" pack="end"> + <xul:button anonid="css-bg-editor-image-clear" label="&status4evar.option.clear;" oncommand="this._editor._imageClear();" xbl:inherits="disabled=no-image" /> + </xul:hbox> + + <xul:hbox> + <xul:groupbox pack="center"> + <xul:caption label="" /> + <xul:hbox flex="1" align="center"> + <xul:label>X</xul:label> + </xul:hbox> + <xul:separator class="groove" orient="horizontal" /> + <xul:hbox flex="1" align="center"> + <xul:label>Y</xul:label> + </xul:hbox> + </xul:groupbox> + + <xul:groupbox> + <xul:caption label="&status4evar.editor.css.image.repeat;" xbl:inherits="disabled=no-image" /> + <xul:menulist anonid="css-bg-editor-image-repeat-x" sizetopopup="always" onselect="this._editor._buildCSS();" xbl:inherits="disabled=no-image"> + <xul:menupopup> + <xul:menuitem label="&status4evar.option.no-repeat;" value="no-repeat" /> + <xul:menuitem label="&status4evar.option.repeat;" value="repeat" /> <!-- - <xul:menuitem label="&status4evar.option.space;" value="space" /> - <xul:menuitem label="&status4evar.option.round;" value="round" /> + <xul:menuitem label="&status4evar.option.space;" value="space" /> + <xul:menuitem label="&status4evar.option.round;" value="round" /> --> - </xul:menupopup> - </xul:menulist> - <xul:separator class="groove" orient="horizontal" /> - <xul:menulist anonid="css-bg-editor-image-repeat-y" sizetopopup="always" onselect="this._editor._buildCSS();" xbl:inherits="disabled=no-image"> - <xul:menupopup> - <xul:menuitem label="&status4evar.option.no-repeat;" value="no-repeat" /> - <xul:menuitem label="&status4evar.option.repeat;" value="repeat" /> + </xul:menupopup> + </xul:menulist> + <xul:separator class="groove" orient="horizontal" /> + <xul:menulist anonid="css-bg-editor-image-repeat-y" sizetopopup="always" onselect="this._editor._buildCSS();" xbl:inherits="disabled=no-image"> + <xul:menupopup> + <xul:menuitem label="&status4evar.option.no-repeat;" value="no-repeat" /> + <xul:menuitem label="&status4evar.option.repeat;" value="repeat" /> <!-- - <xul:menuitem label="&status4evar.option.space;" value="space" /> - <xul:menuitem label="&status4evar.option.round;" value="round" /> + <xul:menuitem label="&status4evar.option.space;" value="space" /> + <xul:menuitem label="&status4evar.option.round;" value="round" /> --> - </xul:menupopup> - </xul:menulist> - </xul:groupbox> - - <xul:groupbox> - <xul:caption label="&status4evar.editor.css.image.position;" xbl:inherits="disabled=no-image" /> - <xul:menulist anonid="css-bg-editor-image-position-x" sizetopopup="always" onselect="this._editor._updatePositionX();" xbl:inherits="disabled=no-image"> - <xul:menupopup> - <xul:menuitem label="&status4evar.option.left;" value="left" /> - <xul:menuitem label="&status4evar.option.center;" value="center" /> - <xul:menuitem label="&status4evar.option.right;" value="right" /> - <xul:menuitem label="&status4evar.option.offset;" value="offset" /> - </xul:menupopup> - </xul:menulist> - <xul:separator class="groove" orient="horizontal" /> - <xul:menulist anonid="css-bg-editor-image-position-y" sizetopopup="always" onselect="this._editor._updatePositionY();" xbl:inherits="disabled=no-image"> - <xul:menupopup> - <xul:menuitem label="&status4evar.option.top;" value="top" /> - <xul:menuitem label="&status4evar.option.center;" value="center" /> - <xul:menuitem label="&status4evar.option.bottom;" value="bottom" /> - <xul:menuitem label="&status4evar.option.offset;" value="offset" /> - </xul:menupopup> - </xul:menulist> - </xul:groupbox> - - <xul:groupbox> - <xul:caption label="&status4evar.editor.css.image.offset;" xbl:inherits="disabled=no-image" /> - <xul:hbox> - <xul:textbox anonid="css-bg-editor-image-offset-x" type="number" size="4" min="-65535" onchange="this._editor._buildCSS();" /> - <xul:menulist anonid="css-bg-editor-image-offset-unit-x" sizetopopup="always" onselect="this._editor._buildCSS();"> - <xul:menupopup> - <xul:menuitem label="%" value="%" /> - <xul:menuitem label="px" value="px" /> - <xul:menuitem label="em" value="em" /> - <xul:menuitem label="in" value="in" /> - <xul:menuitem label="cm" value="cm" /> - <xul:menuitem label="mm" value="mm" /> - <xul:menuitem label="pt" value="pt" /> - <xul:menuitem label="pc" value="pc" /> - </xul:menupopup> - </xul:menulist> - </xul:hbox> - <xul:separator class="groove" orient="horizontal" /> - <xul:hbox> - <xul:textbox anonid="css-bg-editor-image-offset-y" type="number" size="4" min="-65535" onchange="this._editor._buildCSS();" /> - <xul:menulist anonid="css-bg-editor-image-offset-unit-y" sizetopopup="always" onselect="this._editor._buildCSS();"> - <xul:menupopup> - <xul:menuitem label="%" value="%" /> - <xul:menuitem label="px" value="px" /> - <xul:menuitem label="em" value="em" /> - <xul:menuitem label="in" value="in" /> - <xul:menuitem label="cm" value="cm" /> - <xul:menuitem label="mm" value="mm" /> - <xul:menuitem label="pt" value="pt" /> - <xul:menuitem label="pc" value="pc" /> - </xul:menupopup> - </xul:menulist> - </xul:hbox> - </xul:groupbox> - </xul:hbox> - </xul:vbox> - - <xul:textbox anonid="css-bg-editor-css-text" multiline="true" rows="6" xbl:inherits="disabled" /> - </xul:deck> - </xul:vbox> - - <xul:hbox align="center" pack="end"> - <children includes="progressmeter|toolbox" /> - <xul:label xbl:inherits="disabled">&status4evar.editor.label;</xul:label> - <xul:menulist anonid="css-bg-editor-mode-menu" sizetopopup="always" onselect="this._editor._updateMode();" xbl:inherits="disabled"> - <xul:menupopup> - <xul:menuitem label="&status4evar.option.simple;" /> - <xul:menuitem label="&status4evar.option.advanced;" /> - </xul:menupopup> - </xul:menulist> - </xul:hbox> - </content> - - <implementation> - <constructor><![CDATA[ - [ - "_editorColor", - "_editorImageBrowse", - "_editorImageClear", - "_editorImageRepeatX", - "_editorImageRepeatY", - "_editorImagePositionX", - "_editorImagePositionY", - "_editorImageOffsetX", - "_editorImageOffsetY", - "_editorImageOffsetUnitX", - "_editorImageOffsetUnitY", - "_editorMode" - ].forEach(function(prop) - { - this[prop]._editor = this; - }, this); - - this.setAdvanced(true, false); - ]]></constructor> - - <destructor><![CDATA[ - ]]></destructor> - - <field name="_disableBuildCSS"><![CDATA[ - true - ]]></field> - - <field name="_editorColor" readonly="true"><![CDATA[ - document.getAnonymousElementByAttribute(this, "anonid", "css-bg-editor-color"); - ]]></field> - - <field name="_editorCSS" readonly="true"><![CDATA[ - document.getAnonymousElementByAttribute(this, "anonid", "css-bg-editor-css-text"); - ]]></field> - - <field name="_editorDeck" readonly="true"><![CDATA[ - document.getAnonymousElementByAttribute(this, "anonid", "css-bg-editor-deck"); - ]]></field> - - <field name="_editorImage" readonly="true"><![CDATA[ - document.getAnonymousElementByAttribute(this, "anonid", "css-bg-editor-image"); - ]]></field> - - <field name="_editorImageBrowse" readonly="true"><![CDATA[ - document.getAnonymousElementByAttribute(this, "anonid", "css-bg-editor-image-browse"); - ]]></field> - - <field name="_editorImageClear" readonly="true"><![CDATA[ - document.getAnonymousElementByAttribute(this, "anonid", "css-bg-editor-image-clear"); - ]]></field> - - <field name="_editorImageRepeatX" readonly="true"><![CDATA[ - document.getAnonymousElementByAttribute(this, "anonid", "css-bg-editor-image-repeat-x"); - ]]></field> - - <field name="_editorImageRepeatY" readonly="true"><![CDATA[ - document.getAnonymousElementByAttribute(this, "anonid", "css-bg-editor-image-repeat-y"); - ]]></field> - - <field name="_editorImagePositionX" readonly="true"><![CDATA[ - document.getAnonymousElementByAttribute(this, "anonid", "css-bg-editor-image-position-x"); - ]]></field> - - <field name="_editorImagePositionY" readonly="true"><![CDATA[ - document.getAnonymousElementByAttribute(this, "anonid", "css-bg-editor-image-position-y"); - ]]></field> - - <field name="_editorImageOffsetX" readonly="true"><![CDATA[ - document.getAnonymousElementByAttribute(this, "anonid", "css-bg-editor-image-offset-x"); - ]]></field> - - <field name="_editorImageOffsetY" readonly="true"><![CDATA[ - document.getAnonymousElementByAttribute(this, "anonid", "css-bg-editor-image-offset-y"); - ]]></field> - - <field name="_editorImageOffsetUnitX" readonly="true"><![CDATA[ - document.getAnonymousElementByAttribute(this, "anonid", "css-bg-editor-image-offset-unit-x"); - ]]></field> - - <field name="_editorImageOffsetUnitY" readonly="true"><![CDATA[ - document.getAnonymousElementByAttribute(this, "anonid", "css-bg-editor-image-offset-unit-y"); - ]]></field> - - <field name="_editorMode" readonly="true"><![CDATA[ - document.getAnonymousElementByAttribute(this, "anonid", "css-bg-editor-mode-menu"); - ]]></field> - - <field name="_initialized"><![CDATA[ - false - ]]></field> - - <field name="_reRGB" readonly="true"><![CDATA[ - /^rgb\((\d+), (\d+), (\d+)\)$/ - ]]></field> - - <field name="_reURL" readonly="true"><![CDATA[ - /^url\(\s*['"]?(.+?)['"]?\s*\)$/ - ]]></field> - - <field name="_reBgPosition" readonly="true"><![CDATA[ - /^(left|center|right)? ?(-?\d+[^\s\d]+)? ?(top|center|bottom)? ?(-?\d+[^\s\d]+)?$/ - ]]></field> - - <field name="_reCSSUnit" readonly="true"><![CDATA[ - /^(-?\d+)([^\s\d]+)$/ - ]]></field> - - <field name="_strings" readonly="true"><![CDATA[ - document.getElementById("bundle_status4evar"); - ]]></field> - - <property name="value"> - <getter><![CDATA[ - return this._editorCSS.value; - ]]></getter> - <setter><![CDATA[ - this._editorCSS.value = val; - - if(!this._initialized) - { - this.setAdvanced(false, false); - this._initialized = true; - } - - return val; - ]]></setter> - </property> - - <property name="disabled"> - <getter><![CDATA[ - return this.getAttribute("disabled") == "true"; - ]]></getter> - <setter><![CDATA[ - if(val) - { - this.setAttribute("disabled", "true"); - } - else - { - this.removeAttribute("disabled"); - } - - this._updateImageControllDisable(); - - return val; - ]]></setter> - </property> - - <method name="setAdvanced"> - <parameter name="aVal"/> - <parameter name="aPrompt"/> - <body><![CDATA[ - if(!aVal) - { - let success = this._parseCSS(); - if(!success) - { - let result = aPrompt && Services.prompt.confirm(window, - this._strings.getString("simpleEditorTitle"), - this._strings.getString("simpleEditorMessage")); - if(result) - { // Continue to simple mode - this._buildCSS(); - } - else - { // Stay on advanced mode - aVal = true; - } - } - } - - this._disableBuildCSS = aVal; - this._editorDeck.selectedIndex = ((aVal) ? 1 : 0); - this._editorMode.selectedIndex = ((aVal) ? 1 : 0); - ]]></body> - </method> - - <method name="_buildCSS"> - <body><![CDATA[ - if(this._disableBuildCSS) - { - return; - } - - let cssVal = this._editorColor.color; - let imgVal = this._editorImage.value; - if(imgVal) - { - cssVal += " url(\"" + imgVal + "\")"; - - // - // Print the background repeat - // - let bgRX = this._editorImageRepeatX.value; - let bgRY = this._editorImageRepeatY.value; - if(bgRX == "repeat" && bgRY == "no-repeat") - { - cssVal += " repeat-x"; - } - else if(bgRX == "no-repeat" && bgRY == "repeat") - { - cssVal += " repeat-y"; - } - else - { - cssVal += " " + bgRX; - if(bgRX != bgRY) - { - cssVal += " " + bgRY; - } - } - - // - // Print the background position - // - let bgPX = this._editorImagePositionX.value; - let bgPOX = this._editorImageOffsetX.value; - if(bgPX != "offset") - { - cssVal += " " + bgPX; - } - else - { - cssVal += " " + bgPOX + this._editorImageOffsetUnitX.value; - } - - let bgPY = this._editorImagePositionY.value; - let bgPOY = this._editorImageOffsetY.value; - if(bgPY != "offset") - { - cssVal += " " + bgPY; - } - else - { - cssVal += " " + bgPOY + this._editorImageOffsetUnitY.value; - } - } - - this._editorCSS.value = cssVal; - - let event = document.createEvent("Event"); - event.initEvent("change", true, true); - this._editorCSS.dispatchEvent(event); - ]]></body> - </method> - - <method name="_parseCSS"> - <body><![CDATA[ - let retVal = true; - - let cssParser = document.createElement("div"); - cssParser.style.background = this._editorCSS.value; - if(!cssParser.style.background) - { - Components.utils.reportError("Error parsing background CSS rule: " + this._editorCSS.value); - cssParser.style.background = "#33FF33"; - retVal = false; - } - - // - // Parse the background color - // - let bgC = cssParser.style.backgroundColor; - if(this._reRGB.test(bgC)) - { - let digits = this._reRGB.exec(bgC); - - let red = parseInt(digits[1]); - let green = parseInt(digits[2]); - let blue = parseInt(digits[3]); - - let rgb = blue | (green << 8) | (red << 16); - bgC = "#" + rgb.toString(16); - } - else - { - Components.utils.reportError("Error parsing background-color value: " + bgC); - bgC = "#33FF33"; - retVal = false; - } - - // - // Parse the background image - // - let bgI = cssParser.style.backgroundImage; - if(bgI != "none" && !this._reURL.test(bgI)) - { - Components.utils.reportError("Error parsing background-image value: " + bgI); - bgI = "none"; - retVal = false; - } - bgI = ((bgI != "none") ? this._reURL.exec(bgI)[1].trim() : ""); - - // - // Parse the background repeat - // - let bgR = cssParser.style.backgroundRepeat.split(" "); - let bgRX = bgR[0]; - if(bgRX == "repeat-x") - { - bgRX = "repeat"; - } - else if(bgRX == "repeat-y") - { - bgRX = "no-repeat"; - } - - let bgRY = bgR[bgR.length - 1]; - if(bgRY == "repeat-x") - { - bgRY = "no-repeat"; - } - else if(bgRY == "repeat-y") - { - bgRY = "repeat"; - } - - // - // Parse the background position - // - let bgP = cssParser.style.backgroundPosition; - let bgPParts = this._reBgPosition.exec(bgP); - let bgPValues = new Array(); - for(let i = 1; i <= 4; i++) - { - if(bgPParts[i]) - { - bgPValues.push({ - "value": bgPParts[i], - "group": i - }); - } - } - - if(bgPValues.length == 1) - { - bgPValues.splice(((bgPValues[0].group == 2) ? 0 : 1), 0, { - "value": "center", - "group": ((bgPValues[0].group == 2) ? 0 : 2) - }); - } - - if(bgPValues.length == 2 && bgPValues[1].group == 2) - { - bgPValues[1].group = 4; - } - - for(let i = 0; i < 4; i++) - { - let group = (i + 1); - if(bgPValues[i] != undefined && bgPValues[i].group == group) - { - continue; - } - - let tmp = "0px"; - switch(i) - { - case 0: - tmp = "offset"; - break; - case 2: - tmp = "offset"; - break; - } - - bgPValues.splice(i, 0, { - "value": tmp, - "group": group - }); - } - - let bgPOXParts = this._reCSSUnit.exec(bgPValues[1].value); - let bgPOYParts = this._reCSSUnit.exec(bgPValues[3].value); - - // - // Parse the background size - // - - // - // Initialize the UI - // - let disableBuildCSS = this._disableBuildCSS; - this._disableBuildCSS = true; - - this._editorColor.color = bgC; - this._editorImage.value = bgI; - this._editorImageOffsetX.value = bgPOXParts[1]; - this._editorImageOffsetY.value = bgPOYParts[1]; - - [ - [this._editorImageRepeatX, bgRX, "repeat", "repeat X"], - [this._editorImageRepeatY, bgRY, "repeat", "repeat Y"], - [this._editorImagePositionX, bgPValues[0].value, "left", "position X"], - [this._editorImagePositionY, bgPValues[2].value, "top", "position Y"], - [this._editorImageOffsetUnitX, bgPOXParts[2], "px", "offset X unit"], - [this._editorImageOffsetUnitY, bgPOYParts[2], "px", "offset Y unit"] - ].forEach(function(info) - { - if(!this._setSelectedItemSafe(info[0], info[1], info[2])) - { - Components.utils.reportError("Error setting " + info[3] + " to " + info[1]); - retVal = false; - } - }, this); - - this._updateImageControllDisable(); - - this._disableBuildCSS = disableBuildCSS; - - return retVal; - ]]></body> - </method> - - <method name="_imageBrowse"> - <body><![CDATA[ - let nsIFilePicker = Components.interfaces.nsIFilePicker; - let filePicker = Components.classes["@mozilla.org/filepicker;1"].createInstance(nsIFilePicker); - filePicker.init(window, this._strings.getString("imageSelectTitle"), nsIFilePicker.modeOpen); - filePicker.appendFilters(nsIFilePicker.filterImages); - - let res = filePicker.show(); - if(res == nsIFilePicker.returnOK) - { - this._editorImage.value = Services.io.newFileURI(filePicker.file).spec; - this._updateImageControllDisable(); - this._buildCSS(); - } - ]]></body> - </method> - - <method name="_imageClear"> - <body><![CDATA[ - this._editorImage.value = ""; - this._editorImageRepeatX.value = "repeat"; - this._editorImageRepeatY.value = "repeat"; - this._editorImagePositionX.value = "left"; - this._editorImagePositionY.value = "top"; - this._editorImageOffsetX.value = 0; - this._editorImageOffsetY.value = 0; - this._editorImageOffsetUnitX.value = "px"; - this._editorImageOffsetUnitY.value = "px"; - this._updateImageControllDisable(); - this._buildCSS(); - ]]></body> - </method> - - <method name="_processEvent"> - <parameter name="event"/> - <body><![CDATA[ - if(!("css-bg-editor-css-text" == event.originalTarget.getAttribute("anonid") - || "css-bg-editor-css-text" == document.getBindingParent(event.originalTarget).getAttribute("anonid"))) - { - event.stopPropagation(); - } - - //Components.utils.reportError("Editor event " + event.type + " on " + event.originalTarget.tagName + "::" + event.originalTarget.getAttribute("anonid")); - ]]></body> - </method> - - <method name="_setSelectedItemSafe"> - <parameter name="aElement"/> - <parameter name="aValue"/> - <parameter name="aDefault"/> - <body><![CDATA[ - aElement.value = aValue; - if(!aElement.selectedItem || aElement.selectedItem.value != aValue) - { - aElement.value = aDefault; - return false; - } - return true; - ]]></body> - </method> - - <method name="_updateImageControllDisable"> - <body><![CDATA[ - if(this.disabled || !this._editorImage.value) - { - this.setAttribute("no-image", "true"); - this._updatePositionOffsetXDisabled(true); - this._updatePositionOffsetYDisabled(true); - } - else - { - this.removeAttribute("no-image"); - this._updatePositionOffsetXDisabled(false); - this._updatePositionOffsetYDisabled(false); - } - ]]></body> - </method> - - <method name="_updateMode"> - <body><![CDATA[ - if(this._editorMode.selectedIndex == this._editorDeck.selectedIndex) - { - return; - } - - this.setAdvanced(((this._editorMode.selectedIndex == 1) ? true : false), true); - ]]></body> - </method> - - <method name="_updatePositionOffsetXDisabled"> - <parameter name="aVal"/> - <body><![CDATA[ - let bgPX = this._editorImagePositionX.value; - let disableOffsetX = aVal || (bgPX != "offset");// || bgPX == "center"); - this._editorImageOffsetX.disabled = disableOffsetX; - this._editorImageOffsetUnitX.disabled = disableOffsetX; - ]]></body> - </method> - - <method name="_updatePositionOffsetYDisabled"> - <parameter name="aVal"/> - <body><![CDATA[ - let bgPY = this._editorImagePositionY.value; - var disableOffsetY = aVal || (bgPY != "offset");// || bgPY == "center"); - this._editorImageOffsetY.disabled = disableOffsetY; - this._editorImageOffsetUnitY.disabled = disableOffsetY; - ]]></body> - </method> - - <method name="_updatePositionX"> - <body><![CDATA[ - this._updatePositionOffsetXDisabled(false); - this._buildCSS(); - ]]></body> - </method> - - <method name="_updatePositionY"> - <body><![CDATA[ - this._updatePositionOffsetYDisabled(false); - this._buildCSS(); - ]]></body> - </method> - </implementation> - - <handlers> - <handler event="command"><![CDATA[ - this._processEvent(event); - ]]></handler> - - <handler event="change"><![CDATA[ - this._processEvent(event); - ]]></handler> - - <handler event="input"><![CDATA[ - this._processEvent(event); - ]]></handler> - - <handler event="select"><![CDATA[ - this._processEvent(event); - ]]></handler> - </handlers> - </binding> + </xul:menupopup> + </xul:menulist> + </xul:groupbox> + + <xul:groupbox> + <xul:caption label="&status4evar.editor.css.image.position;" xbl:inherits="disabled=no-image" /> + <xul:menulist anonid="css-bg-editor-image-position-x" sizetopopup="always" onselect="this._editor._updatePositionX();" xbl:inherits="disabled=no-image"> + <xul:menupopup> + <xul:menuitem label="&status4evar.option.left;" value="left" /> + <xul:menuitem label="&status4evar.option.center;" value="center" /> + <xul:menuitem label="&status4evar.option.right;" value="right" /> + <xul:menuitem label="&status4evar.option.offset;" value="offset" /> + </xul:menupopup> + </xul:menulist> + <xul:separator class="groove" orient="horizontal" /> + <xul:menulist anonid="css-bg-editor-image-position-y" sizetopopup="always" onselect="this._editor._updatePositionY();" xbl:inherits="disabled=no-image"> + <xul:menupopup> + <xul:menuitem label="&status4evar.option.top;" value="top" /> + <xul:menuitem label="&status4evar.option.center;" value="center" /> + <xul:menuitem label="&status4evar.option.bottom;" value="bottom" /> + <xul:menuitem label="&status4evar.option.offset;" value="offset" /> + </xul:menupopup> + </xul:menulist> + </xul:groupbox> + + <xul:groupbox> + <xul:caption label="&status4evar.editor.css.image.offset;" xbl:inherits="disabled=no-image" /> + <xul:hbox> + <xul:textbox anonid="css-bg-editor-image-offset-x" type="number" size="4" min="-65535" onchange="this._editor._buildCSS();" /> + <xul:menulist anonid="css-bg-editor-image-offset-unit-x" sizetopopup="always" onselect="this._editor._buildCSS();"> + <xul:menupopup> + <xul:menuitem label="%" value="%" /> + <xul:menuitem label="px" value="px" /> + <xul:menuitem label="em" value="em" /> + <xul:menuitem label="in" value="in" /> + <xul:menuitem label="cm" value="cm" /> + <xul:menuitem label="mm" value="mm" /> + <xul:menuitem label="pt" value="pt" /> + <xul:menuitem label="pc" value="pc" /> + </xul:menupopup> + </xul:menulist> + </xul:hbox> + <xul:separator class="groove" orient="horizontal" /> + <xul:hbox> + <xul:textbox anonid="css-bg-editor-image-offset-y" type="number" size="4" min="-65535" onchange="this._editor._buildCSS();" /> + <xul:menulist anonid="css-bg-editor-image-offset-unit-y" sizetopopup="always" onselect="this._editor._buildCSS();"> + <xul:menupopup> + <xul:menuitem label="%" value="%" /> + <xul:menuitem label="px" value="px" /> + <xul:menuitem label="em" value="em" /> + <xul:menuitem label="in" value="in" /> + <xul:menuitem label="cm" value="cm" /> + <xul:menuitem label="mm" value="mm" /> + <xul:menuitem label="pt" value="pt" /> + <xul:menuitem label="pc" value="pc" /> + </xul:menupopup> + </xul:menulist> + </xul:hbox> + </xul:groupbox> + </xul:hbox> + </xul:vbox> + + <xul:textbox anonid="css-bg-editor-css-text" multiline="true" rows="6" xbl:inherits="disabled" /> + </xul:deck> + </xul:vbox> + + <xul:hbox align="center" pack="end"> + <children includes="progressmeter|toolbox" /> + <xul:label xbl:inherits="disabled">&status4evar.editor.label;</xul:label> + <xul:menulist anonid="css-bg-editor-mode-menu" sizetopopup="always" onselect="this._editor._updateMode();" xbl:inherits="disabled"> + <xul:menupopup> + <xul:menuitem label="&status4evar.option.simple;" /> + <xul:menuitem label="&status4evar.option.advanced;" /> + </xul:menupopup> + </xul:menulist> + </xul:hbox> + </content> + + <implementation> + <constructor><![CDATA[ + [ + "_editorColor", + "_editorImageBrowse", + "_editorImageClear", + "_editorImageRepeatX", + "_editorImageRepeatY", + "_editorImagePositionX", + "_editorImagePositionY", + "_editorImageOffsetX", + "_editorImageOffsetY", + "_editorImageOffsetUnitX", + "_editorImageOffsetUnitY", + "_editorMode" + ].forEach(function(prop) + { + this[prop]._editor = this; + }, this); + + this.setAdvanced(true, false); + ]]></constructor> + + <destructor><![CDATA[ + ]]></destructor> + + <field name="_disableBuildCSS"><![CDATA[ + true + ]]></field> + + <field name="_editorColor" readonly="true"><![CDATA[ + document.getAnonymousElementByAttribute(this, "anonid", "css-bg-editor-color"); + ]]></field> + + <field name="_editorCSS" readonly="true"><![CDATA[ + document.getAnonymousElementByAttribute(this, "anonid", "css-bg-editor-css-text"); + ]]></field> + + <field name="_editorDeck" readonly="true"><![CDATA[ + document.getAnonymousElementByAttribute(this, "anonid", "css-bg-editor-deck"); + ]]></field> + + <field name="_editorImage" readonly="true"><![CDATA[ + document.getAnonymousElementByAttribute(this, "anonid", "css-bg-editor-image"); + ]]></field> + + <field name="_editorImageBrowse" readonly="true"><![CDATA[ + document.getAnonymousElementByAttribute(this, "anonid", "css-bg-editor-image-browse"); + ]]></field> + + <field name="_editorImageClear" readonly="true"><![CDATA[ + document.getAnonymousElementByAttribute(this, "anonid", "css-bg-editor-image-clear"); + ]]></field> + + <field name="_editorImageRepeatX" readonly="true"><![CDATA[ + document.getAnonymousElementByAttribute(this, "anonid", "css-bg-editor-image-repeat-x"); + ]]></field> + + <field name="_editorImageRepeatY" readonly="true"><![CDATA[ + document.getAnonymousElementByAttribute(this, "anonid", "css-bg-editor-image-repeat-y"); + ]]></field> + + <field name="_editorImagePositionX" readonly="true"><![CDATA[ + document.getAnonymousElementByAttribute(this, "anonid", "css-bg-editor-image-position-x"); + ]]></field> + + <field name="_editorImagePositionY" readonly="true"><![CDATA[ + document.getAnonymousElementByAttribute(this, "anonid", "css-bg-editor-image-position-y"); + ]]></field> + + <field name="_editorImageOffsetX" readonly="true"><![CDATA[ + document.getAnonymousElementByAttribute(this, "anonid", "css-bg-editor-image-offset-x"); + ]]></field> + + <field name="_editorImageOffsetY" readonly="true"><![CDATA[ + document.getAnonymousElementByAttribute(this, "anonid", "css-bg-editor-image-offset-y"); + ]]></field> + + <field name="_editorImageOffsetUnitX" readonly="true"><![CDATA[ + document.getAnonymousElementByAttribute(this, "anonid", "css-bg-editor-image-offset-unit-x"); + ]]></field> + + <field name="_editorImageOffsetUnitY" readonly="true"><![CDATA[ + document.getAnonymousElementByAttribute(this, "anonid", "css-bg-editor-image-offset-unit-y"); + ]]></field> + + <field name="_editorMode" readonly="true"><![CDATA[ + document.getAnonymousElementByAttribute(this, "anonid", "css-bg-editor-mode-menu"); + ]]></field> + + <field name="_initialized"><![CDATA[ + false + ]]></field> + + <field name="_reRGB" readonly="true"><![CDATA[ + /^rgb\((\d+), (\d+), (\d+)\)$/ + ]]></field> + + <field name="_reURL" readonly="true"><![CDATA[ + /^url\(\s*['"]?(.+?)['"]?\s*\)$/ + ]]></field> + + <field name="_reBgPosition" readonly="true"><![CDATA[ + /^(left|center|right)? ?(-?\d+[^\s\d]+)? ?(top|center|bottom)? ?(-?\d+[^\s\d]+)?$/ + ]]></field> + + <field name="_reCSSUnit" readonly="true"><![CDATA[ + /^(-?\d+)([^\s\d]+)$/ + ]]></field> + + <field name="_strings" readonly="true"><![CDATA[ + document.getElementById("bundle_status4evar"); + ]]></field> + + <property name="value"> + <getter><![CDATA[ + return this._editorCSS.value; + ]]></getter> + <setter><![CDATA[ + this._editorCSS.value = val; + + if(!this._initialized) + { + this.setAdvanced(false, false); + this._initialized = true; + } + + return val; + ]]></setter> + </property> + + <property name="disabled"> + <getter><![CDATA[ + return this.getAttribute("disabled") == "true"; + ]]></getter> + <setter><![CDATA[ + if(val) + { + this.setAttribute("disabled", "true"); + } + else + { + this.removeAttribute("disabled"); + } + + this._updateImageControllDisable(); + + return val; + ]]></setter> + </property> + + <method name="setAdvanced"> + <parameter name="aVal"/> + <parameter name="aPrompt"/> + <body><![CDATA[ + if(!aVal) + { + let success = this._parseCSS(); + if(!success) + { + let result = aPrompt && Services.prompt.confirm(window, + this._strings.getString("simpleEditorTitle"), + this._strings.getString("simpleEditorMessage")); + if(result) + { // Continue to simple mode + this._buildCSS(); + } + else + { // Stay on advanced mode + aVal = true; + } + } + } + + this._disableBuildCSS = aVal; + this._editorDeck.selectedIndex = ((aVal) ? 1 : 0); + this._editorMode.selectedIndex = ((aVal) ? 1 : 0); + ]]></body> + </method> + + <method name="_buildCSS"> + <body><![CDATA[ + if(this._disableBuildCSS) + { + return; + } + + let cssVal = this._editorColor.color; + let imgVal = this._editorImage.value; + if(imgVal) + { + cssVal += " url(\"" + imgVal + "\")"; + + // + // Print the background repeat + // + let bgRX = this._editorImageRepeatX.value; + let bgRY = this._editorImageRepeatY.value; + if(bgRX == "repeat" && bgRY == "no-repeat") + { + cssVal += " repeat-x"; + } + else if(bgRX == "no-repeat" && bgRY == "repeat") + { + cssVal += " repeat-y"; + } + else + { + cssVal += " " + bgRX; + if(bgRX != bgRY) + { + cssVal += " " + bgRY; + } + } + + // + // Print the background position + // + let bgPX = this._editorImagePositionX.value; + let bgPOX = this._editorImageOffsetX.value; + if(bgPX != "offset") + { + cssVal += " " + bgPX; + } + else + { + cssVal += " " + bgPOX + this._editorImageOffsetUnitX.value; + } + + let bgPY = this._editorImagePositionY.value; + let bgPOY = this._editorImageOffsetY.value; + if(bgPY != "offset") + { + cssVal += " " + bgPY; + } + else + { + cssVal += " " + bgPOY + this._editorImageOffsetUnitY.value; + } + } + + this._editorCSS.value = cssVal; + + let event = document.createEvent("Event"); + event.initEvent("change", true, true); + this._editorCSS.dispatchEvent(event); + ]]></body> + </method> + + <method name="_parseCSS"> + <body><![CDATA[ + let retVal = true; + + let cssParser = document.createElement("div"); + cssParser.style.background = this._editorCSS.value; + if(!cssParser.style.background) + { + Components.utils.reportError("Error parsing background CSS rule: " + this._editorCSS.value); + cssParser.style.background = "#33FF33"; + retVal = false; + } + + // + // Parse the background color + // + let bgC = cssParser.style.backgroundColor; + if(this._reRGB.test(bgC)) + { + let digits = this._reRGB.exec(bgC); + + let red = parseInt(digits[1]); + let green = parseInt(digits[2]); + let blue = parseInt(digits[3]); + + let rgb = blue | (green << 8) | (red << 16); + bgC = "#" + rgb.toString(16); + } + else + { + Components.utils.reportError("Error parsing background-color value: " + bgC); + bgC = "#33FF33"; + retVal = false; + } + + // + // Parse the background image + // + let bgI = cssParser.style.backgroundImage; + if(bgI != "none" && !this._reURL.test(bgI)) + { + Components.utils.reportError("Error parsing background-image value: " + bgI); + bgI = "none"; + retVal = false; + } + bgI = ((bgI != "none") ? this._reURL.exec(bgI)[1].trim() : ""); + + // + // Parse the background repeat + // + let bgR = cssParser.style.backgroundRepeat.split(" "); + let bgRX = bgR[0]; + if(bgRX == "repeat-x") + { + bgRX = "repeat"; + } + else if(bgRX == "repeat-y") + { + bgRX = "no-repeat"; + } + + let bgRY = bgR[bgR.length - 1]; + if(bgRY == "repeat-x") + { + bgRY = "no-repeat"; + } + else if(bgRY == "repeat-y") + { + bgRY = "repeat"; + } + + // + // Parse the background position + // + let bgP = cssParser.style.backgroundPosition; + let bgPParts = this._reBgPosition.exec(bgP); + let bgPValues = new Array(); + for(let i = 1; i <= 4; i++) + { + if(bgPParts[i]) + { + bgPValues.push({ + "value": bgPParts[i], + "group": i + }); + } + } + + if(bgPValues.length == 1) + { + bgPValues.splice(((bgPValues[0].group == 2) ? 0 : 1), 0, { + "value": "center", + "group": ((bgPValues[0].group == 2) ? 0 : 2) + }); + } + + if(bgPValues.length == 2 && bgPValues[1].group == 2) + { + bgPValues[1].group = 4; + } + + for(let i = 0; i < 4; i++) + { + let group = (i + 1); + if(bgPValues[i] != undefined && bgPValues[i].group == group) + { + continue; + } + + let tmp = "0px"; + switch(i) + { + case 0: + tmp = "offset"; + break; + case 2: + tmp = "offset"; + break; + } + + bgPValues.splice(i, 0, { + "value": tmp, + "group": group + }); + } + + let bgPOXParts = this._reCSSUnit.exec(bgPValues[1].value); + let bgPOYParts = this._reCSSUnit.exec(bgPValues[3].value); + + // + // Parse the background size + // + + // + // Initialize the UI + // + let disableBuildCSS = this._disableBuildCSS; + this._disableBuildCSS = true; + + this._editorColor.color = bgC; + this._editorImage.value = bgI; + this._editorImageOffsetX.value = bgPOXParts[1]; + this._editorImageOffsetY.value = bgPOYParts[1]; + + [ + [this._editorImageRepeatX, bgRX, "repeat", "repeat X"], + [this._editorImageRepeatY, bgRY, "repeat", "repeat Y"], + [this._editorImagePositionX, bgPValues[0].value, "left", "position X"], + [this._editorImagePositionY, bgPValues[2].value, "top", "position Y"], + [this._editorImageOffsetUnitX, bgPOXParts[2], "px", "offset X unit"], + [this._editorImageOffsetUnitY, bgPOYParts[2], "px", "offset Y unit"] + ].forEach(function(info) + { + if(!this._setSelectedItemSafe(info[0], info[1], info[2])) + { + Components.utils.reportError("Error setting " + info[3] + " to " + info[1]); + retVal = false; + } + }, this); + + this._updateImageControllDisable(); + + this._disableBuildCSS = disableBuildCSS; + + return retVal; + ]]></body> + </method> + + <method name="_imageBrowse"> + <body><![CDATA[ + let nsIFilePicker = Components.interfaces.nsIFilePicker; + let filePicker = Components.classes["@mozilla.org/filepicker;1"].createInstance(nsIFilePicker); + filePicker.init(window, this._strings.getString("imageSelectTitle"), nsIFilePicker.modeOpen); + filePicker.appendFilters(nsIFilePicker.filterImages); + + let res = filePicker.show(); + if(res == nsIFilePicker.returnOK) + { + this._editorImage.value = Services.io.newFileURI(filePicker.file).spec; + this._updateImageControllDisable(); + this._buildCSS(); + } + ]]></body> + </method> + + <method name="_imageClear"> + <body><![CDATA[ + this._editorImage.value = ""; + this._editorImageRepeatX.value = "repeat"; + this._editorImageRepeatY.value = "repeat"; + this._editorImagePositionX.value = "left"; + this._editorImagePositionY.value = "top"; + this._editorImageOffsetX.value = 0; + this._editorImageOffsetY.value = 0; + this._editorImageOffsetUnitX.value = "px"; + this._editorImageOffsetUnitY.value = "px"; + this._updateImageControllDisable(); + this._buildCSS(); + ]]></body> + </method> + + <method name="_processEvent"> + <parameter name="event"/> + <body><![CDATA[ + if(!("css-bg-editor-css-text" == event.originalTarget.getAttribute("anonid") + || "css-bg-editor-css-text" == document.getBindingParent(event.originalTarget).getAttribute("anonid"))) + { + event.stopPropagation(); + } + + //Components.utils.reportError("Editor event " + event.type + " on " + event.originalTarget.tagName + "::" + event.originalTarget.getAttribute("anonid")); + ]]></body> + </method> + + <method name="_setSelectedItemSafe"> + <parameter name="aElement"/> + <parameter name="aValue"/> + <parameter name="aDefault"/> + <body><![CDATA[ + aElement.value = aValue; + if(!aElement.selectedItem || aElement.selectedItem.value != aValue) + { + aElement.value = aDefault; + return false; + } + return true; + ]]></body> + </method> + + <method name="_updateImageControllDisable"> + <body><![CDATA[ + if(this.disabled || !this._editorImage.value) + { + this.setAttribute("no-image", "true"); + this._updatePositionOffsetXDisabled(true); + this._updatePositionOffsetYDisabled(true); + } + else + { + this.removeAttribute("no-image"); + this._updatePositionOffsetXDisabled(false); + this._updatePositionOffsetYDisabled(false); + } + ]]></body> + </method> + + <method name="_updateMode"> + <body><![CDATA[ + if(this._editorMode.selectedIndex == this._editorDeck.selectedIndex) + { + return; + } + + this.setAdvanced(((this._editorMode.selectedIndex == 1) ? true : false), true); + ]]></body> + </method> + + <method name="_updatePositionOffsetXDisabled"> + <parameter name="aVal"/> + <body><![CDATA[ + let bgPX = this._editorImagePositionX.value; + let disableOffsetX = aVal || (bgPX != "offset");// || bgPX == "center"); + this._editorImageOffsetX.disabled = disableOffsetX; + this._editorImageOffsetUnitX.disabled = disableOffsetX; + ]]></body> + </method> + + <method name="_updatePositionOffsetYDisabled"> + <parameter name="aVal"/> + <body><![CDATA[ + let bgPY = this._editorImagePositionY.value; + var disableOffsetY = aVal || (bgPY != "offset");// || bgPY == "center"); + this._editorImageOffsetY.disabled = disableOffsetY; + this._editorImageOffsetUnitY.disabled = disableOffsetY; + ]]></body> + </method> + + <method name="_updatePositionX"> + <body><![CDATA[ + this._updatePositionOffsetXDisabled(false); + this._buildCSS(); + ]]></body> + </method> + + <method name="_updatePositionY"> + <body><![CDATA[ + this._updatePositionOffsetYDisabled(false); + this._buildCSS(); + ]]></body> + </method> + </implementation> + + <handlers> + <handler event="command"><![CDATA[ + this._processEvent(event); + ]]></handler> + + <handler event="change"><![CDATA[ + this._processEvent(event); + ]]></handler> + + <handler event="input"><![CDATA[ + this._processEvent(event); + ]]></handler> + + <handler event="select"><![CDATA[ + this._processEvent(event); + ]]></handler> + </handlers> + </binding> </bindings> diff --git a/application/palemoon/components/statusbar/content/prefs.xul b/application/palemoon/components/statusbar/content/prefs.xul index d10dc006a..dd4158246 100644 --- a/application/palemoon/components/statusbar/content/prefs.xul +++ b/application/palemoon/components/statusbar/content/prefs.xul @@ -5,8 +5,8 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. --> <!DOCTYPE prefwindow [ - <!ENTITY % prefsDTD SYSTEM "chrome://browser/locale/statusbar/statusbar-prefs.dtd"> - %prefsDTD; + <!ENTITY % prefsDTD SYSTEM "chrome://browser/locale/statusbar/statusbar-prefs.dtd"> + %prefsDTD; ]> <?xml-stylesheet href="chrome://global/skin/config.css" type="text/css" ?> @@ -23,275 +23,275 @@ xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" onload="status4evarPrefs.onPrefWindowLoad();" onunload="status4evarPrefs.onPrefWindowUnLoad();"> - <stringbundleset id="stringbundleset"> - <stringbundle id="bundle_status4evar" src="chrome://browser/locale/statusbar/prefs.properties" /> - </stringbundleset> - <script type="application/javascript" src="chrome://browser/content/statusbar/prefs.js" /> + <stringbundleset id="stringbundleset"> + <stringbundle id="bundle_status4evar" src="chrome://browser/locale/statusbar/prefs.properties" /> + </stringbundleset> + <script type="application/javascript" src="chrome://browser/content/statusbar/prefs.js" /> - <prefpane id="status4evar-pane-status" label="&status4evar.pane.status;"> - <preferences> - <preference id="status4evar-pref-status" name="status4evar.status" type="int" /> - <preference id="status4evar-pref-status-default" name="status4evar.status.default" type="bool" /> - <preference id="status4evar-pref-status-network" name="status4evar.status.network" type="bool" - onchange="status4evarPrefs.statusNetworkChanged();" /> - <preference id="status4evar-pref-status-network-xhr" name="status4evar.status.network.xhr" type="bool" /> - <preference id="status4evar-pref-status-timeout" name="status4evar.status.timeout" type="int" - onchange="status4evarPrefs.statusTimeoutChanged();" /> - <preference id="status4evar-pref-status-linkOver" name="status4evar.status.linkOver" type="int" /> - <preference id="status4evar-pref-status-linkOver-delay-show" name="status4evar.status.linkOver.delay.show" type="int" /> - <preference id="status4evar-pref-status-linkOver-delay-hide" name="status4evar.status.linkOver.delay.hide" type="int" /> - <preference id="status4evar-pref-status-toolbar-maxLength" name="status4evar.status.toolbar.maxLength" type="int" - onchange="status4evarPrefs.textLengthChanged();" /> - <preference id="status4evar-pref-status-popup-invertMirror" name="status4evar.status.popup.invertMirror" type="bool" /> - <preference id="status4evar-pref-status-popup-mouseMirror" name="status4evar.status.popup.mouseMirror" type="bool" /> - <preference id="toolkit-pref-dom-status-change" name="dom.disable_window_status_change" type="bool" inverted="true" /> - </preferences> - - <commandset id="status4evar-commandset-status"> - <command id="status4evar-command-status-timeout" oncommand="status4evarPrefs.statusTimeoutToggle();" /> - <command id="status4evar-command-status-toolbar-maxLength" oncommand="status4evarPrefs.textLengthToggle();" /> - </commandset> - - <tabbox id="status4evar-tabbox-status" flex="1"> - <tabs id="status4evar-tabs-status"> - <tab id="status4evar-tab-status-general" label="&status4evar.tab.general;" /> - <tab id="status4evar-tab-status-toolbar" label="&status4evar.tab.toolbar;" /> - <tab id="status4evar-tab-status-popup" label="&status4evar.tab.popup;" /> - </tabs> - - <tabpanels id="status4evar-tabpanels-status" flex="1"> - <tabpanel id="status4evar-tabpanel-status-general" orient="vertical"> - <groupbox id="status4evar-status-general-status"> - <caption label="&status4evar.status.general.status.caption;" /> - - <hbox align="center"> - <label id="status4evar-status-label" control="status4evar-status-menu">&status4evar.status.label;</label> - <menulist id="status4evar-status-menu" preference="status4evar-pref-status" sizetopopup="always"> - <menupopup> - <menuitem label="&status4evar.option.none;" value="0" /> - <menuitem label="&status4evar.option.toolbar;" value="1" /> - <menuitem label="&status4evar.option.popup;" value="3" /> - </menupopup> - </menulist> - </hbox> - - <hbox align="center"> - <checkbox id="status4evar-status-timeout-check" label="&status4evar.status.timeout.label;" - command="status4evar-command-status-timeout" /> - <textbox id="status4evar-status-timeout-value" preference="status4evar-pref-status-timeout" type="number" size="4" - onsyncfrompreference="return status4evarPrefs.statusTimeoutSync();" /> - <label id="status4evar-status-timeout-unit">&status4evar.unit.seconds;</label> - </hbox> - - <checkbox id="status4evar-status-default-check" preference="status4evar-pref-status-default" label="&status4evar.status.default.label;" /> - - <checkbox id="status4evar-status-network-check" preference="status4evar-pref-status-network" label="&status4evar.status.network.label;" - onsyncfrompreference="return status4evarPrefs.statusNetworkSync();" /> - - <hbox align="center" class="indent"> - <checkbox id="status4evar-status-network-xhr-check" preference="status4evar-pref-status-network-xhr" label="&status4evar.status.network.xhr.label;" /> - </hbox> - - <checkbox id="toolkit-dom-status-change-check" preference="toolkit-pref-dom-status-change" label="&toolkit.dom.status.change.label;" /> - </groupbox> - - <groupbox id="status4evar-status-general-linkOver"> - <caption label="&status4evar.status.general.linkOver.caption;" /> - - <hbox align="center"> - <label id="status4evar-status-linkOver-label" control="status4evar-status-linkOver-menu">&status4evar.status.linkOver.label;</label> - <menulist id="status4evar-status-linkOver-menu" preference="status4evar-pref-status-linkOver" sizetopopup="always"> - <menupopup> - <menuitem label="&status4evar.option.none;" value="0" /> - <menuitem label="&status4evar.option.toolbar;" value="1" /> - <menuitem label="&status4evar.option.popup;" value="3" /> - </menupopup> - </menulist> - </hbox> - - <hbox align="center"> - <label id="status4evar-status-linkOver-delay-show-label" control="status4evar-status-linkOver-delay-show-value">&status4evar.status.linkOver.delay.show.label;</label> - <textbox id="status4evar-status-linkOver-delay-show-value" preference="status4evar-pref-status-linkOver-delay-show" type="number" size="5" /> - <label id="status4evar-status-linkOver-delay-show-unit">&status4evar.unit.milliseconds;</label> - </hbox> - - <hbox align="center"> - <label id="status4evar-status-linkOver-delay-hide-label" control="status4evar-status-linkOver-delay-hide-value">&status4evar.status.linkOver.delay.hide.label;</label> - <textbox id="status4evar-status-linkOver-delay-hide-value" preference="status4evar-pref-status-linkOver-delay-hide" type="number" size="5" /> - <label id="status4evar-status-linkOver-delay-hide-unit">&status4evar.unit.milliseconds;</label> - </hbox> - </groupbox> - - </tabpanel> - - <tabpanel id="status4evar-tabpanel-status-toolbar" orient="vertical"> - <hbox align="center"> - <checkbox id="status4evar-status-toolbar-maxLength-check" label="&status4evar.status.toolbar.maxLength.label;" - command="status4evar-command-status-toolbar-maxLength" /> - <textbox id="status4evar-status-toolbar-maxLength-value" preference="status4evar-pref-status-toolbar-maxLength" type="number" size="4" - onsyncfrompreference="return status4evarPrefs.textLengthSync();" /> - <label id="status4evar-status-toolbar-maxLength-unit">&status4evar.unit.px;</label> - </hbox> - </tabpanel> - - <tabpanel id="status4evar-tabpanel-status-popup" orient="vertical"> - <checkbox id="status4evar-status-popup-invertMirror-check" preference="status4evar-pref-status-popup-invertMirror" label="&status4evar.status.popup.invertMirror.label;" /> - - <checkbox id="status4evar-status-popup-mouseMirror-check" preference="status4evar-pref-status-popup-mouseMirror" label="&status4evar.status.popup.mouseMirror.label;" /> - </tabpanel> - - </tabpanels> - </tabbox> - </prefpane> - - <prefpane id="status4evar-pane-progress" label="&status4evar.pane.progress;"> - <preferences> - <preference id="status4evar-pref-progress-toolbar-force" name="status4evar.progress.toolbar.force" type="bool" /> - <preference id="status4evar-pref-progress-toolbar-style" name="status4evar.progress.toolbar.style" type="bool" - onchange="status4evarPrefs.progressToolbarStyleChanged();" /> - <preference id="status4evar-pref-progress-toolbar-css" name="status4evar.progress.toolbar.css" type="string" - onchange="status4evarPrefs.progressToolbarCSSChanged();" /> - </preferences> - - <commandset id="status4evar-commandset-status"> - </commandset> - - <checkbox id="status4evar-progress-toolbar-force-check" preference="status4evar-pref-progress-toolbar-force" label="&status4evar.progress.toolbar.force.label;" /> - - <checkbox id="status4evar-progress-toolbar-style-check" preference="status4evar-pref-progress-toolbar-style" label="&status4evar.progress.style.label;" - onsyncfrompreference="return status4evarPrefs.progressToolbarStyleSync();" /> - - <vbox class="css-bg-editor" preference="status4evar-pref-progress-toolbar-css" preference-editable="true" flex="1"> - <progressmeter id="status4evar-progress-bar" value="75" flex="1" /> - </vbox> - </prefpane> - - <prefpane id="status4evar-pane-download" label="&status4evar.pane.download;"> - <preferences> - <preference id="status4evar-pref-download-button-action" name="status4evar.download.button.action" type="int" /> - <preference id="status4evar-pref-download-color-active" name="status4evar.download.color.active" type="string" /> - <preference id="status4evar-pref-download-color-paused" name="status4evar.download.color.paused" type="string" /> - <preference id="status4evar-pref-download-force" name="status4evar.download.force" type="bool" /> - <preference id="status4evar-pref-download-label" name="status4evar.download.label" type="int" /> - <preference id="status4evar-pref-download-label-force" name="status4evar.download.label.force" type="bool" /> - <preference id="status4evar-pref-download-notify-animate" name="status4evar.download.notify.animate" type="bool" /> - <preference id="status4evar-pref-download-notify-timeout" name="status4evar.download.notify.timeout" type="int" /> - <preference id="status4evar-pref-download-progress" name="status4evar.download.progress" type="int" /> - <preference id="status4evar-pref-download-tooltip" name="status4evar.download.tooltip" type="int" /> - - <preference id="status4evar-pref-download-button-action-command" name="status4evar.download.button.action.command" type="string"/> - </preferences> - - <commandset id="status4evar-commandset-download"> - <command id="status4evar-command-download-progress" oncommand="status4evarPrefs.downloadProgressToggle();" /> - </commandset> - - <checkbox id="status4evar-download-force-check" preference="status4evar-pref-download-force" label="&status4evar.download.force.label;" /> - - <checkbox id="status4evar-download-label-force-check" preference="status4evar-pref-download-label-force" label="&status4evar.download.label.force.label;" /> - - <hbox align="center"> - <label id="status4evar-download-label-label" control="status4evar-download-label-menu">&status4evar.download.label.label;</label> - <menulist id="status4evar-download-label-menu" preference="status4evar-pref-download-label" sizetopopup="always"> - <menupopup> - <menuitem value="0" label="&status4evar.option.dlcount;" /> - <menuitem value="1" label="&status4evar.option.dltime;" /> - <menuitem value="2" label="&status4evar.option.both;" /> - </menupopup> - </menulist> - </hbox> - - <hbox align="center"> - <label id="status4evar-download-tooltip-label" control="status4evar-download-tooltip-menu">&status4evar.download.tooltip.label;</label> - <menulist id="status4evar-download-tooltip-menu" preference="status4evar-pref-download-tooltip" sizetopopup="always"> - <menupopup> - <menuitem value="0" label="&status4evar.option.dlcount;" /> - <menuitem value="1" label="&status4evar.option.dltime;" /> - <menuitem value="2" label="&status4evar.option.both;" /> - </menupopup> - </menulist> - </hbox> - - <hbox align="center"> - <label id="status4evar-download-button-action-label" control="status4evar-download-button-action-menu">&status4evar.download.button.action.label;</label> - <menulist id="status4evar-download-button-action-menu" preference="status4evar-pref-download-button-action" sizetopopup="always"> - <menupopup> - <menuitem value="0" label="&status4evar.option.nothing;" /> - <menuitem value="1" label="&status4evar.option.firefoxdefault;" /> - <menuitem value="2" label="&status4evar.option.download.library;" /> - <menuitem value="3" label="&status4evar.option.download.tab;" /> - <menuitem value="4" label="&status4evar.option.download.thirdparty;" id="status4evar-download-button-action-menu-thirdparty" /> - </menupopup> - </menulist> - </hbox> - - <hbox align="center"> - <label id="status4evar-download-notify-timeout-label" control="status4evar-download-notify-timeout-value">&status4evar.download.notify.timeout.label;</label> - <textbox id="status4evar-download-notify-timeout-value" preference="status4evar-pref-download-notify-timeout" type="number" size="3" /> - <label id="status4evar-download-notify-timeout-unit">&status4evar.unit.seconds;</label> - </hbox> - - <checkbox id="status4evar-download-notify-animate-check" preference="status4evar-pref-download-notify-animate" label="&status4evar.download.notify.animate.label;" /> - - <checkbox id="status4evar-download-progress-check" command="status4evar-command-download-progress" label="&status4evar.download.progress.label;" /> - - <vbox class="indent"> - <hbox align="center"> - <radiogroup id="status4evar-download-progress-radiogroup" preference="status4evar-pref-download-progress" - onsyncfrompreference="return status4evarPrefs.downloadProgressSync();"> - <radio value="1" label="&status4evar.download.progress.average.label;" /> - <radio value="2" label="&status4evar.download.progress.max.label;" /> - <radio value="3" label="&status4evar.download.progress.min.label;" /> - </radiogroup> - </hbox> - - <hbox align="center"> - <label id="status4evar-download-color-active-label" control="status4evar-download-color-active-picker">&status4evar.download.color.active.label;</label> - <colorpicker id="status4evar-download-color-active-picker" preference="status4evar-pref-download-color-active" type="button" /> - </hbox> - - <hbox align="center"> - <label id="status4evar-download-color-paused-label" control="status4evar-download-color-paused-picker">&status4evar.download.color.paused.label;</label> - <colorpicker id="status4evar-download-color-paused-picker" preference="status4evar-pref-download-color-paused" type="button" /> - </hbox> - </vbox> - </prefpane> - - <prefpane id="status4evar-pane-addonbar" label="&status4evar.pane.statusbar;"> - <preferences> - <preference id="status4evar-pref-addonbar-borderStyle" name="status4evar.addonbar.borderStyle" type="bool" /> - <preference id="status4evar-pref-addonbar-closeButton" name="status4evar.addonbar.closeButton" type="bool" /> - <preference id="status4evar-pref-addonbar-windowGripper" name="status4evar.addonbar.windowGripper" type="bool" /> - </preferences> - - <checkbox id="status4evar-addonbar-borderStyle-check" preference="status4evar-pref-addonbar-borderStyle" label="&status4evar.addonbar.borderStyle;" /> - - <checkbox id="status4evar-addonbar-closeButton-check" preference="status4evar-pref-addonbar-closeButton" label="&status4evar.addonbar.closeButton;" /> - - <checkbox id="status4evar-addonbar-windowGripper-check" preference="status4evar-pref-addonbar-windowGripper" label="&status4evar.addonbar.windowGripper;" /> - </prefpane> - - <prefpane id="status4evar-pane-advanced" label="&status4evar.pane.advanced;"> - <preferences> - <preference id="status4evar-pref-advanced-status-detectFullScreen" name="status4evar.advanced.status.detectFullScreen" type="bool" /> - <preference id="status4evar-pref-advanced-status-detectVideo" name="status4evar.advanced.status.detectVideo" type="bool" /> - <preference id="browser-pref-urlbar-trimming-enabled" name="browser.urlbar.trimURLs" type="bool" /> - </preferences> - - <vbox flex="1"> - <groupbox id="status4evar-status-urlbar-builtin"> - <caption label="&status4evar.status.urlbar.firefox.builtin.caption;" /> - - <checkbox id="browser-urlbar-trimming-enabled-ckeck" preference="browser-pref-urlbar-trimming-enabled" label="&browser.urlbar.trimming.enabled.label;" /> - </groupbox> - - <groupbox id="status4evar-advanced-status"> - <caption label="&status4evar.pane.status;" /> - - <checkbox id="status4evar-advanced-status-detectFullScreen-check" preference="status4evar-pref-advanced-status-detectFullScreen" label="&status4evar.advanced.status.detectFullScreen;" /> - <checkbox id="status4evar-advanced-status-detectVideo-check" preference="status4evar-pref-advanced-status-detectVideo" label="&status4evar.advanced.status.detectVideo;" /> - </groupbox> - </vbox> - </prefpane> + <prefpane id="status4evar-pane-status" label="&status4evar.pane.status;"> + <preferences> + <preference id="status4evar-pref-status" name="status4evar.status" type="int" /> + <preference id="status4evar-pref-status-default" name="status4evar.status.default" type="bool" /> + <preference id="status4evar-pref-status-network" name="status4evar.status.network" type="bool" + onchange="status4evarPrefs.statusNetworkChanged();" /> + <preference id="status4evar-pref-status-network-xhr" name="status4evar.status.network.xhr" type="bool" /> + <preference id="status4evar-pref-status-timeout" name="status4evar.status.timeout" type="int" + onchange="status4evarPrefs.statusTimeoutChanged();" /> + <preference id="status4evar-pref-status-linkOver" name="status4evar.status.linkOver" type="int" /> + <preference id="status4evar-pref-status-linkOver-delay-show" name="status4evar.status.linkOver.delay.show" type="int" /> + <preference id="status4evar-pref-status-linkOver-delay-hide" name="status4evar.status.linkOver.delay.hide" type="int" /> + <preference id="status4evar-pref-status-toolbar-maxLength" name="status4evar.status.toolbar.maxLength" type="int" + onchange="status4evarPrefs.textLengthChanged();" /> + <preference id="status4evar-pref-status-popup-invertMirror" name="status4evar.status.popup.invertMirror" type="bool" /> + <preference id="status4evar-pref-status-popup-mouseMirror" name="status4evar.status.popup.mouseMirror" type="bool" /> + <preference id="toolkit-pref-dom-status-change" name="dom.disable_window_status_change" type="bool" inverted="true" /> + </preferences> + + <commandset id="status4evar-commandset-status"> + <command id="status4evar-command-status-timeout" oncommand="status4evarPrefs.statusTimeoutToggle();" /> + <command id="status4evar-command-status-toolbar-maxLength" oncommand="status4evarPrefs.textLengthToggle();" /> + </commandset> + + <tabbox id="status4evar-tabbox-status" flex="1"> + <tabs id="status4evar-tabs-status"> + <tab id="status4evar-tab-status-general" label="&status4evar.tab.general;" /> + <tab id="status4evar-tab-status-toolbar" label="&status4evar.tab.toolbar;" /> + <tab id="status4evar-tab-status-popup" label="&status4evar.tab.popup;" /> + </tabs> + + <tabpanels id="status4evar-tabpanels-status" flex="1"> + <tabpanel id="status4evar-tabpanel-status-general" orient="vertical"> + <groupbox id="status4evar-status-general-status"> + <caption label="&status4evar.status.general.status.caption;" /> + + <hbox align="center"> + <label id="status4evar-status-label" control="status4evar-status-menu">&status4evar.status.label;</label> + <menulist id="status4evar-status-menu" preference="status4evar-pref-status" sizetopopup="always"> + <menupopup> + <menuitem label="&status4evar.option.none;" value="0" /> + <menuitem label="&status4evar.option.toolbar;" value="1" /> + <menuitem label="&status4evar.option.popup;" value="3" /> + </menupopup> + </menulist> + </hbox> + + <hbox align="center"> + <checkbox id="status4evar-status-timeout-check" label="&status4evar.status.timeout.label;" + command="status4evar-command-status-timeout" /> + <textbox id="status4evar-status-timeout-value" preference="status4evar-pref-status-timeout" type="number" size="4" + onsyncfrompreference="return status4evarPrefs.statusTimeoutSync();" /> + <label id="status4evar-status-timeout-unit">&status4evar.unit.seconds;</label> + </hbox> + + <checkbox id="status4evar-status-default-check" preference="status4evar-pref-status-default" label="&status4evar.status.default.label;" /> + + <checkbox id="status4evar-status-network-check" preference="status4evar-pref-status-network" label="&status4evar.status.network.label;" + onsyncfrompreference="return status4evarPrefs.statusNetworkSync();" /> + + <hbox align="center" class="indent"> + <checkbox id="status4evar-status-network-xhr-check" preference="status4evar-pref-status-network-xhr" label="&status4evar.status.network.xhr.label;" /> + </hbox> + + <checkbox id="toolkit-dom-status-change-check" preference="toolkit-pref-dom-status-change" label="&toolkit.dom.status.change.label;" /> + </groupbox> + + <groupbox id="status4evar-status-general-linkOver"> + <caption label="&status4evar.status.general.linkOver.caption;" /> + + <hbox align="center"> + <label id="status4evar-status-linkOver-label" control="status4evar-status-linkOver-menu">&status4evar.status.linkOver.label;</label> + <menulist id="status4evar-status-linkOver-menu" preference="status4evar-pref-status-linkOver" sizetopopup="always"> + <menupopup> + <menuitem label="&status4evar.option.none;" value="0" /> + <menuitem label="&status4evar.option.toolbar;" value="1" /> + <menuitem label="&status4evar.option.popup;" value="3" /> + </menupopup> + </menulist> + </hbox> + + <hbox align="center"> + <label id="status4evar-status-linkOver-delay-show-label" control="status4evar-status-linkOver-delay-show-value">&status4evar.status.linkOver.delay.show.label;</label> + <textbox id="status4evar-status-linkOver-delay-show-value" preference="status4evar-pref-status-linkOver-delay-show" type="number" size="5" /> + <label id="status4evar-status-linkOver-delay-show-unit">&status4evar.unit.milliseconds;</label> + </hbox> + + <hbox align="center"> + <label id="status4evar-status-linkOver-delay-hide-label" control="status4evar-status-linkOver-delay-hide-value">&status4evar.status.linkOver.delay.hide.label;</label> + <textbox id="status4evar-status-linkOver-delay-hide-value" preference="status4evar-pref-status-linkOver-delay-hide" type="number" size="5" /> + <label id="status4evar-status-linkOver-delay-hide-unit">&status4evar.unit.milliseconds;</label> + </hbox> + </groupbox> + + </tabpanel> + + <tabpanel id="status4evar-tabpanel-status-toolbar" orient="vertical"> + <hbox align="center"> + <checkbox id="status4evar-status-toolbar-maxLength-check" label="&status4evar.status.toolbar.maxLength.label;" + command="status4evar-command-status-toolbar-maxLength" /> + <textbox id="status4evar-status-toolbar-maxLength-value" preference="status4evar-pref-status-toolbar-maxLength" type="number" size="4" + onsyncfrompreference="return status4evarPrefs.textLengthSync();" /> + <label id="status4evar-status-toolbar-maxLength-unit">&status4evar.unit.px;</label> + </hbox> + </tabpanel> + + <tabpanel id="status4evar-tabpanel-status-popup" orient="vertical"> + <checkbox id="status4evar-status-popup-invertMirror-check" preference="status4evar-pref-status-popup-invertMirror" label="&status4evar.status.popup.invertMirror.label;" /> + + <checkbox id="status4evar-status-popup-mouseMirror-check" preference="status4evar-pref-status-popup-mouseMirror" label="&status4evar.status.popup.mouseMirror.label;" /> + </tabpanel> + + </tabpanels> + </tabbox> + </prefpane> + + <prefpane id="status4evar-pane-progress" label="&status4evar.pane.progress;"> + <preferences> + <preference id="status4evar-pref-progress-toolbar-force" name="status4evar.progress.toolbar.force" type="bool" /> + <preference id="status4evar-pref-progress-toolbar-style" name="status4evar.progress.toolbar.style" type="bool" + onchange="status4evarPrefs.progressToolbarStyleChanged();" /> + <preference id="status4evar-pref-progress-toolbar-css" name="status4evar.progress.toolbar.css" type="string" + onchange="status4evarPrefs.progressToolbarCSSChanged();" /> + </preferences> + + <commandset id="status4evar-commandset-status"> + </commandset> + + <checkbox id="status4evar-progress-toolbar-force-check" preference="status4evar-pref-progress-toolbar-force" label="&status4evar.progress.toolbar.force.label;" /> + + <checkbox id="status4evar-progress-toolbar-style-check" preference="status4evar-pref-progress-toolbar-style" label="&status4evar.progress.style.label;" + onsyncfrompreference="return status4evarPrefs.progressToolbarStyleSync();" /> + + <vbox class="css-bg-editor" preference="status4evar-pref-progress-toolbar-css" preference-editable="true" flex="1"> + <progressmeter id="status4evar-progress-bar" value="75" flex="1" /> + </vbox> + </prefpane> + + <prefpane id="status4evar-pane-download" label="&status4evar.pane.download;"> + <preferences> + <preference id="status4evar-pref-download-button-action" name="status4evar.download.button.action" type="int" /> + <preference id="status4evar-pref-download-color-active" name="status4evar.download.color.active" type="string" /> + <preference id="status4evar-pref-download-color-paused" name="status4evar.download.color.paused" type="string" /> + <preference id="status4evar-pref-download-force" name="status4evar.download.force" type="bool" /> + <preference id="status4evar-pref-download-label" name="status4evar.download.label" type="int" /> + <preference id="status4evar-pref-download-label-force" name="status4evar.download.label.force" type="bool" /> + <preference id="status4evar-pref-download-notify-animate" name="status4evar.download.notify.animate" type="bool" /> + <preference id="status4evar-pref-download-notify-timeout" name="status4evar.download.notify.timeout" type="int" /> + <preference id="status4evar-pref-download-progress" name="status4evar.download.progress" type="int" /> + <preference id="status4evar-pref-download-tooltip" name="status4evar.download.tooltip" type="int" /> + + <preference id="status4evar-pref-download-button-action-command" name="status4evar.download.button.action.command" type="string"/> + </preferences> + + <commandset id="status4evar-commandset-download"> + <command id="status4evar-command-download-progress" oncommand="status4evarPrefs.downloadProgressToggle();" /> + </commandset> + + <checkbox id="status4evar-download-force-check" preference="status4evar-pref-download-force" label="&status4evar.download.force.label;" /> + + <checkbox id="status4evar-download-label-force-check" preference="status4evar-pref-download-label-force" label="&status4evar.download.label.force.label;" /> + + <hbox align="center"> + <label id="status4evar-download-label-label" control="status4evar-download-label-menu">&status4evar.download.label.label;</label> + <menulist id="status4evar-download-label-menu" preference="status4evar-pref-download-label" sizetopopup="always"> + <menupopup> + <menuitem value="0" label="&status4evar.option.dlcount;" /> + <menuitem value="1" label="&status4evar.option.dltime;" /> + <menuitem value="2" label="&status4evar.option.both;" /> + </menupopup> + </menulist> + </hbox> + + <hbox align="center"> + <label id="status4evar-download-tooltip-label" control="status4evar-download-tooltip-menu">&status4evar.download.tooltip.label;</label> + <menulist id="status4evar-download-tooltip-menu" preference="status4evar-pref-download-tooltip" sizetopopup="always"> + <menupopup> + <menuitem value="0" label="&status4evar.option.dlcount;" /> + <menuitem value="1" label="&status4evar.option.dltime;" /> + <menuitem value="2" label="&status4evar.option.both;" /> + </menupopup> + </menulist> + </hbox> + + <hbox align="center"> + <label id="status4evar-download-button-action-label" control="status4evar-download-button-action-menu">&status4evar.download.button.action.label;</label> + <menulist id="status4evar-download-button-action-menu" preference="status4evar-pref-download-button-action" sizetopopup="always"> + <menupopup> + <menuitem value="0" label="&status4evar.option.nothing;" /> + <menuitem value="1" label="&status4evar.option.firefoxdefault;" /> + <menuitem value="2" label="&status4evar.option.download.library;" /> + <menuitem value="3" label="&status4evar.option.download.tab;" /> + <menuitem value="4" label="&status4evar.option.download.thirdparty;" id="status4evar-download-button-action-menu-thirdparty" /> + </menupopup> + </menulist> + </hbox> + + <hbox align="center"> + <label id="status4evar-download-notify-timeout-label" control="status4evar-download-notify-timeout-value">&status4evar.download.notify.timeout.label;</label> + <textbox id="status4evar-download-notify-timeout-value" preference="status4evar-pref-download-notify-timeout" type="number" size="3" /> + <label id="status4evar-download-notify-timeout-unit">&status4evar.unit.seconds;</label> + </hbox> + + <checkbox id="status4evar-download-notify-animate-check" preference="status4evar-pref-download-notify-animate" label="&status4evar.download.notify.animate.label;" /> + + <checkbox id="status4evar-download-progress-check" command="status4evar-command-download-progress" label="&status4evar.download.progress.label;" /> + + <vbox class="indent"> + <hbox align="center"> + <radiogroup id="status4evar-download-progress-radiogroup" preference="status4evar-pref-download-progress" + onsyncfrompreference="return status4evarPrefs.downloadProgressSync();"> + <radio value="1" label="&status4evar.download.progress.average.label;" /> + <radio value="2" label="&status4evar.download.progress.max.label;" /> + <radio value="3" label="&status4evar.download.progress.min.label;" /> + </radiogroup> + </hbox> + + <hbox align="center"> + <label id="status4evar-download-color-active-label" control="status4evar-download-color-active-picker">&status4evar.download.color.active.label;</label> + <colorpicker id="status4evar-download-color-active-picker" preference="status4evar-pref-download-color-active" type="button" /> + </hbox> + + <hbox align="center"> + <label id="status4evar-download-color-paused-label" control="status4evar-download-color-paused-picker">&status4evar.download.color.paused.label;</label> + <colorpicker id="status4evar-download-color-paused-picker" preference="status4evar-pref-download-color-paused" type="button" /> + </hbox> + </vbox> + </prefpane> + + <prefpane id="status4evar-pane-addonbar" label="&status4evar.pane.statusbar;"> + <preferences> + <preference id="status4evar-pref-addonbar-borderStyle" name="status4evar.addonbar.borderStyle" type="bool" /> + <preference id="status4evar-pref-addonbar-closeButton" name="status4evar.addonbar.closeButton" type="bool" /> + <preference id="status4evar-pref-addonbar-windowGripper" name="status4evar.addonbar.windowGripper" type="bool" /> + </preferences> + + <checkbox id="status4evar-addonbar-borderStyle-check" preference="status4evar-pref-addonbar-borderStyle" label="&status4evar.addonbar.borderStyle;" /> + + <checkbox id="status4evar-addonbar-closeButton-check" preference="status4evar-pref-addonbar-closeButton" label="&status4evar.addonbar.closeButton;" /> + + <checkbox id="status4evar-addonbar-windowGripper-check" preference="status4evar-pref-addonbar-windowGripper" label="&status4evar.addonbar.windowGripper;" /> + </prefpane> + + <prefpane id="status4evar-pane-advanced" label="&status4evar.pane.advanced;"> + <preferences> + <preference id="status4evar-pref-advanced-status-detectFullScreen" name="status4evar.advanced.status.detectFullScreen" type="bool" /> + <preference id="status4evar-pref-advanced-status-detectVideo" name="status4evar.advanced.status.detectVideo" type="bool" /> + <preference id="browser-pref-urlbar-trimming-enabled" name="browser.urlbar.trimURLs" type="bool" /> + </preferences> + + <vbox flex="1"> + <groupbox id="status4evar-status-urlbar-builtin"> + <caption label="&status4evar.status.urlbar.firefox.builtin.caption;" /> + + <checkbox id="browser-urlbar-trimming-enabled-ckeck" preference="browser-pref-urlbar-trimming-enabled" label="&browser.urlbar.trimming.enabled.label;" /> + </groupbox> + + <groupbox id="status4evar-advanced-status"> + <caption label="&status4evar.pane.status;" /> + + <checkbox id="status4evar-advanced-status-detectFullScreen-check" preference="status4evar-pref-advanced-status-detectFullScreen" label="&status4evar.advanced.status.detectFullScreen;" /> + <checkbox id="status4evar-advanced-status-detectVideo-check" preference="status4evar-pref-advanced-status-detectVideo" label="&status4evar.advanced.status.detectVideo;" /> + </groupbox> + </vbox> + </prefpane> </prefwindow> diff --git a/application/palemoon/components/statusbar/content/tabbrowser.xml b/application/palemoon/components/statusbar/content/tabbrowser.xml index 5119fa58a..2f475771d 100644 --- a/application/palemoon/components/statusbar/content/tabbrowser.xml +++ b/application/palemoon/components/statusbar/content/tabbrowser.xml @@ -9,210 +9,210 @@ xmlns:xul="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" xmlns:xbl="http://www.mozilla.org/xbl"> - <binding id="statuspanel" display="xul:hbox" extends="chrome://browser/content/tabbrowser.xml#statuspanel"> - <implementation> - <!-- --> - <!-- Inverted mirror handling --> - <!-- --> - - <field name="_invertMirror"><![CDATA[ - false - ]]></field> - - <property name="invertMirror"> - <setter><![CDATA[ - this._invertMirror = val; - this.mirror = this._isMirrored; - return val; - ]]></setter> - <getter><![CDATA[ - return this._invertMirror; - ]]></getter> - </property> - - <!-- --> - <!-- Mouse mirror handling --> - <!-- --> - - <field name="_mouseMirror"><![CDATA[ - true - ]]></field> - - <field name="_mouseMirrorListen"><![CDATA[ - false - ]]></field> - - <property name="mouseMirror"> - <setter><![CDATA[ - this._mouseMirror = val; - this.setupMouseMirror(this.value); - return val; - ]]></setter> - <getter><![CDATA[ - return this._mouseMirror; - ]]></getter> - </property> - - <method name="setupMouseMirror"> - <parameter name="val"/> - <body><![CDATA[ - if(val && this._mouseMirror) - { - this._calcMouseTargetRect(); - if(!this._mouseMirrorListen) - { - MousePosTracker.addListener(this); - this._mouseMirrorListen = true; - } - } - else - { - this.mirror = false; - if(this._mouseMirrorListen) - { - MousePosTracker.removeListener(this); - this._mouseMirrorListen = false; - } - } - ]]></body> - </method> - - <method name="_calcMouseTargetRect"> - <body><![CDATA[ - let alignRight = false; - let isRTL = (getComputedStyle(document.documentElement).direction == "rtl"); - if((this._invertMirror && !isRTL) || (!this._invertMirror && isRTL)) - { - alignRight = true; - } - - let rect = this.getBoundingClientRect(); - this._mouseTargetRect = - { - top: rect.top, - bottom: rect.bottom, - left: ((alignRight) ? window.innerWidth - rect.width : 0), - right: ((alignRight) ? window.innerWidth : rect.width) - }; - ]]></body> - </method> - - <method name="onMouseEnter"> - <body><![CDATA[ - this.mirror = true; - ]]></body> - </method> - - <method name="onMouseLeave"> - <body><![CDATA[ - this.mirror = false; - ]]></body> - </method> - - <!-- --> - <!-- Mirror handling --> - <!-- --> - - <field name="_isMirrored"><![CDATA[ - false - ]]></field> - - <property name="mirror"> - <setter><![CDATA[ - this._isMirrored = val; - if(this._invertMirror) - { - val = !val; - } - - this.setBooleanAttr("mirror", val); - ]]></setter> - <getter><![CDATA[ - return this._isMirrored; - ]]></getter> - </property> - - <method name="_mirror"> - <body><![CDATA[ - this.mirror = !this._isMirrored; - ]]></body> - </method> - - <!-- --> - <!-- Value handling --> - <!-- --> - - <property name="label"> - <setter><![CDATA[ - if(window.caligon && window.caligon.status4evar) - { - window.caligon.status4evar.statusService.setStatusText(val); - } - return undefined; - ]]></setter> - <getter><![CDATA[ - if(window.caligon && window.caligon.status4evar) - { - return window.caligon.status4evar.statusService.getStatusText(); - } - return ""; - ]]></getter> - </property> - - <property name="value"> - <setter><![CDATA[ - this.setValue(val); - this.setupMouseMirror(val); - return val; - ]]></setter> - <getter><![CDATA[ - return ((this.hasAttribute("inactive")) ? "" : this.getAttribute("label")); - ]]></getter> - </property> - - <method name="setValue"> - <parameter name="val"/> - <body><![CDATA[ - if((this.getAttribute("type") || "").indexOf("network") > -1 && (this.getAttribute("previoustype") || "").indexOf("network") > -1) - { - this.style.minWidth = getComputedStyle(this).width; - } - else - { - this.style.minWidth = ""; - } - - if(val) - { - this.setAttribute("label", val); - this.setBooleanAttr("inactive", false); - } - else - { - this.setBooleanAttr("inactive", true); - } - ]]></body> - </method> - - <!-- --> - <!-- Helpers --> - <!-- --> - - <method name="setBooleanAttr"> - <parameter name="name"/> - <parameter name="val"/> - <body><![CDATA[ - if(val) - { - this.setAttribute(name, "true"); - } - else - { - this.removeAttribute(name); - } - ]]></body> - </method> - </implementation> - </binding> + <binding id="statuspanel" display="xul:hbox" extends="chrome://browser/content/tabbrowser.xml#statuspanel"> + <implementation> + <!-- --> + <!-- Inverted mirror handling --> + <!-- --> + + <field name="_invertMirror"><![CDATA[ + false + ]]></field> + + <property name="invertMirror"> + <setter><![CDATA[ + this._invertMirror = val; + this.mirror = this._isMirrored; + return val; + ]]></setter> + <getter><![CDATA[ + return this._invertMirror; + ]]></getter> + </property> + + <!-- --> + <!-- Mouse mirror handling --> + <!-- --> + + <field name="_mouseMirror"><![CDATA[ + true + ]]></field> + + <field name="_mouseMirrorListen"><![CDATA[ + false + ]]></field> + + <property name="mouseMirror"> + <setter><![CDATA[ + this._mouseMirror = val; + this.setupMouseMirror(this.value); + return val; + ]]></setter> + <getter><![CDATA[ + return this._mouseMirror; + ]]></getter> + </property> + + <method name="setupMouseMirror"> + <parameter name="val"/> + <body><![CDATA[ + if(val && this._mouseMirror) + { + this._calcMouseTargetRect(); + if(!this._mouseMirrorListen) + { + MousePosTracker.addListener(this); + this._mouseMirrorListen = true; + } + } + else + { + this.mirror = false; + if(this._mouseMirrorListen) + { + MousePosTracker.removeListener(this); + this._mouseMirrorListen = false; + } + } + ]]></body> + </method> + + <method name="_calcMouseTargetRect"> + <body><![CDATA[ + let alignRight = false; + let isRTL = (getComputedStyle(document.documentElement).direction == "rtl"); + if((this._invertMirror && !isRTL) || (!this._invertMirror && isRTL)) + { + alignRight = true; + } + + let rect = this.getBoundingClientRect(); + this._mouseTargetRect = + { + top: rect.top, + bottom: rect.bottom, + left: ((alignRight) ? window.innerWidth - rect.width : 0), + right: ((alignRight) ? window.innerWidth : rect.width) + }; + ]]></body> + </method> + + <method name="onMouseEnter"> + <body><![CDATA[ + this.mirror = true; + ]]></body> + </method> + + <method name="onMouseLeave"> + <body><![CDATA[ + this.mirror = false; + ]]></body> + </method> + + <!-- --> + <!-- Mirror handling --> + <!-- --> + + <field name="_isMirrored"><![CDATA[ + false + ]]></field> + + <property name="mirror"> + <setter><![CDATA[ + this._isMirrored = val; + if(this._invertMirror) + { + val = !val; + } + + this.setBooleanAttr("mirror", val); + ]]></setter> + <getter><![CDATA[ + return this._isMirrored; + ]]></getter> + </property> + + <method name="_mirror"> + <body><![CDATA[ + this.mirror = !this._isMirrored; + ]]></body> + </method> + + <!-- --> + <!-- Value handling --> + <!-- --> + + <property name="label"> + <setter><![CDATA[ + if(window.caligon && window.caligon.status4evar) + { + window.caligon.status4evar.statusService.setStatusText(val); + } + return undefined; + ]]></setter> + <getter><![CDATA[ + if(window.caligon && window.caligon.status4evar) + { + return window.caligon.status4evar.statusService.getStatusText(); + } + return ""; + ]]></getter> + </property> + + <property name="value"> + <setter><![CDATA[ + this.setValue(val); + this.setupMouseMirror(val); + return val; + ]]></setter> + <getter><![CDATA[ + return ((this.hasAttribute("inactive")) ? "" : this.getAttribute("label")); + ]]></getter> + </property> + + <method name="setValue"> + <parameter name="val"/> + <body><![CDATA[ + if((this.getAttribute("type") || "").indexOf("network") > -1 && (this.getAttribute("previoustype") || "").indexOf("network") > -1) + { + this.style.minWidth = getComputedStyle(this).width; + } + else + { + this.style.minWidth = ""; + } + + if(val) + { + this.setAttribute("label", val); + this.setBooleanAttr("inactive", false); + } + else + { + this.setBooleanAttr("inactive", true); + } + ]]></body> + </method> + + <!-- --> + <!-- Helpers --> + <!-- --> + + <method name="setBooleanAttr"> + <parameter name="name"/> + <parameter name="val"/> + <body><![CDATA[ + if(val) + { + this.setAttribute(name, "true"); + } + else + { + this.removeAttribute(name); + } + ]]></body> + </method> + </implementation> + </binding> </bindings> diff --git a/application/palemoon/components/statusbar/status4evar.idl b/application/palemoon/components/statusbar/status4evar.idl index d14fcbcd1..534dea31c 100644 --- a/application/palemoon/components/statusbar/status4evar.idl +++ b/application/palemoon/components/statusbar/status4evar.idl @@ -9,49 +9,49 @@ interface nsIDOMWindow; [scriptable, uuid(33d0433d-07be-4dc4-87fd-954057310efd)] interface nsIStatus4Evar : nsISupports { - readonly attribute boolean addonbarBorderStyle; - readonly attribute boolean addonbarCloseButton; - readonly attribute boolean addonbarLegacyShim; - readonly attribute boolean addonbarWindowGripper; - - readonly attribute boolean advancedStatusDetectFullScreen; - readonly attribute boolean advancedStatusDetectVideo; - - readonly attribute long downloadButtonAction; - readonly attribute ACString downloadButtonActionCommand; - readonly attribute ACString downloadColorActive; - readonly attribute ACString downloadColorPaused; - readonly attribute boolean downloadForce; - readonly attribute long downloadLabel; - readonly attribute boolean downloadLabelForce; - readonly attribute boolean downloadNotifyAnimate; - readonly attribute long downloadNotifyTimeout; - readonly attribute long downloadProgress; - readonly attribute long downloadTooltip; - - readonly attribute boolean firstRun; - readonly attribute boolean firstRunAustralis; - - readonly attribute ACString progressToolbarCSS; - readonly attribute boolean progressToolbarForce; - readonly attribute boolean progressToolbarStyle; - readonly attribute boolean progressToolbarStyleAdvanced; - - readonly attribute long status; - readonly attribute boolean statusDefault; - readonly attribute boolean statusNetwork; - readonly attribute boolean statusNetworkXHR; - readonly attribute long statusTimeout; - readonly attribute long statusLinkOver; - readonly attribute long statusLinkOverDelayShow; - readonly attribute long statusLinkOverDelayHide; - - readonly attribute long statusToolbarMaxLength; - - readonly attribute boolean statusToolbarInvertMirror; - readonly attribute boolean statusToolbarMouseMirror; - - void resetPrefs(); - void updateWindow(in nsIDOMWindow win); + readonly attribute boolean addonbarBorderStyle; + readonly attribute boolean addonbarCloseButton; + readonly attribute boolean addonbarLegacyShim; + readonly attribute boolean addonbarWindowGripper; + + readonly attribute boolean advancedStatusDetectFullScreen; + readonly attribute boolean advancedStatusDetectVideo; + + readonly attribute long downloadButtonAction; + readonly attribute ACString downloadButtonActionCommand; + readonly attribute ACString downloadColorActive; + readonly attribute ACString downloadColorPaused; + readonly attribute boolean downloadForce; + readonly attribute long downloadLabel; + readonly attribute boolean downloadLabelForce; + readonly attribute boolean downloadNotifyAnimate; + readonly attribute long downloadNotifyTimeout; + readonly attribute long downloadProgress; + readonly attribute long downloadTooltip; + + readonly attribute boolean firstRun; + readonly attribute boolean firstRunAustralis; + + readonly attribute ACString progressToolbarCSS; + readonly attribute boolean progressToolbarForce; + readonly attribute boolean progressToolbarStyle; + readonly attribute boolean progressToolbarStyleAdvanced; + + readonly attribute long status; + readonly attribute boolean statusDefault; + readonly attribute boolean statusNetwork; + readonly attribute boolean statusNetworkXHR; + readonly attribute long statusTimeout; + readonly attribute long statusLinkOver; + readonly attribute long statusLinkOverDelayShow; + readonly attribute long statusLinkOverDelayHide; + + readonly attribute long statusToolbarMaxLength; + + readonly attribute boolean statusToolbarInvertMirror; + readonly attribute boolean statusToolbarMouseMirror; + + void resetPrefs(); + void updateWindow(in nsIDOMWindow win); }; diff --git a/application/palemoon/components/statusbar/status4evar.js b/application/palemoon/components/statusbar/status4evar.js index abc6c9175..4aa2e3e78 100644 --- a/application/palemoon/components/statusbar/status4evar.js +++ b/application/palemoon/components/statusbar/status4evar.js @@ -18,677 +18,677 @@ function Status_4_Evar(){} Status_4_Evar.prototype = { - classID: Components.ID("{33d0433d-07be-4dc4-87fd-954057310efd}"), - QueryInterface: XPCOMUtils.generateQI([ - CI.nsISupportsWeakReference, - CI.nsIObserver, - CI.nsIStatus4Evar - ]), - - prefs: null, - - addonbarBorderStyle: false, - addonbarCloseButton: false, - addonbarWindowGripper: true, - - advancedStatusDetectFullScreen: true, - advancedStatusDetectVideo: true, - - downloadButtonAction: 1, - downloadButtonActionCommand: "", - downloadColorActive: null, - downloadColorPaused: null, - downloadForce: false, - downloadLabel: 0, - downloadLabelForce: true, - downloadNotifyAnimate: true, - downloadNotifyTimeout: 60000, - downloadProgress: 1, - downloadTooltip: 1, - - firstRun: true, - - progressToolbarCSS: null, - progressToolbarForce: false, - progressToolbarStyle: false, - - status: 1, - statusDefault: true, - statusNetwork: true, - statusTimeout: 10000, - statusLinkOver: 1, - statusLinkOverDelayShow: 70, - statusLinkOverDelayHide: 150, - - statusToolbarMaxLength: 0, - - statusToolbarInvertMirror: false, - statusToolbarMouseMirror: true, - - pref_registry: - { - "addonbar.borderStyle": - { - update: function() - { - this.addonbarBorderStyle = this.prefs.getBoolPref("addonbar.borderStyle"); - }, - updateWindow: function(win) - { - let browser_bottom_box = win.caligon.status4evar.getters.browserBottomBox; - if(browser_bottom_box) - { - this.setBoolElementAttribute(browser_bottom_box, "s4eboarder", this.addonbarBorderStyle); - } - } - }, - - "addonbar.closeButton": - { - update: function() - { - this.addonbarCloseButton = this.prefs.getBoolPref("addonbar.closeButton"); - }, - updateWindow: function(win) - { - let addonbar_close_button = win.caligon.status4evar.getters.addonbarCloseButton; - if(addonbar_close_button) - { - addonbar_close_button.hidden = !this.addonbarCloseButton; - } - } - }, - - "addonbar.windowGripper": - { - update: function() - { - this.addonbarWindowGripper = this.prefs.getBoolPref("addonbar.windowGripper"); - }, - updateWindow: function(win) - { - win.caligon.status4evar.toolbars.updateWindowGripper(true); - } - }, - - "advanced.status.detectFullScreen": - { - update: function() - { - this.advancedStatusDetectFullScreen = this.prefs.getBoolPref("advanced.status.detectFullScreen"); - } - }, - - "advanced.status.detectVideo": - { - update: function() - { - this.advancedStatusDetectVideo = this.prefs.getBoolPref("advanced.status.detectVideo"); - } - }, - - "download.button.action": - { - update: function() - { - this.downloadButtonAction = this.prefs.getIntPref("download.button.action"); - }, - updateWindow: function(win) - { - win.caligon.status4evar.downloadStatus.updateBinding(); - } - }, - - "download.button.action.command": - { - update: function() - { - this.downloadButtonActionCommand = this.prefs.getCharPref("download.button.action.command"); - } - }, - - "download.color.active": - { - update: function() - { - this.downloadColorActive = this.prefs.getCharPref("download.color.active"); - }, - updateDynamicStyle: function(sheet) - { - sheet.cssRules[2].style.backgroundColor = this.downloadColorActive; - } - }, - - "download.color.paused": - { - update: function() - { - this.downloadColorPaused = this.prefs.getCharPref("download.color.paused"); - }, - updateDynamicStyle: function(sheet) - { - sheet.cssRules[3].style.backgroundColor = this.downloadColorPaused; - } - }, - - "download.force": - { - update: function() - { - this.downloadForce = this.prefs.getBoolPref("download.force"); - }, - updateWindow: function(win) - { - let download_button = win.caligon.status4evar.getters.downloadButton; - if(download_button) - { - this.setBoolElementAttribute(download_button, "forcevisible", this.downloadForce); - } - - let download_notify_anchor = win.caligon.status4evar.getters.downloadNotifyAnchor; - this.setBoolElementAttribute(download_notify_anchor, "forcevisible", this.downloadForce); - } - }, - - "download.label": - { - update: function() - { - this.downloadLabel = this.prefs.getIntPref("download.label"); - }, - updateWindow: function(win) - { - win.caligon.status4evar.downloadStatus.updateButton(); - } - }, - - "download.label.force": - { - update: function() - { - this.downloadLabelForce = this.prefs.getBoolPref("download.label.force"); - }, - updateWindow: function(win) - { - let download_button = win.caligon.status4evar.getters.downloadButton; - if(download_button) - { - this.setBoolElementAttribute(download_button, "forcelabel", this.downloadLabelForce); - } - } - }, - - "download.notify.animate": - { - update: function() - { - this.downloadNotifyAnimate = this.prefs.getBoolPref("download.notify.animate"); - } - }, - - "download.notify.timeout": - { - update: function() - { - this.downloadNotifyTimeout = (this.prefs.getIntPref("download.notify.timeout") * 1000); - } - }, - - "download.progress": - { - update: function() - { - this.downloadProgress = this.prefs.getIntPref("download.progress"); - }, - updateWindow: function(win) - { - win.caligon.status4evar.downloadStatus.updateButton(); - } - }, - - "download.tooltip": - { - update: function() - { - this.downloadTooltip = this.prefs.getIntPref("download.tooltip"); - }, - updateWindow: function(win) - { - win.caligon.status4evar.downloadStatus.updateButton(); - } - }, - - "progress.toolbar.css": - { - update: function() - { - this.progressToolbarCSS = this.prefs.getCharPref("progress.toolbar.css"); - }, - updateDynamicStyle: function(sheet) - { - sheet.cssRules[1].style.background = this.progressToolbarCSS; - } - }, - - "progress.toolbar.force": - { - update: function() - { - this.progressToolbarForce = this.prefs.getBoolPref("progress.toolbar.force"); - }, - updateWindow: function(win) - { - let toolbar_progress = win.caligon.status4evar.getters.toolbarProgress; - if(toolbar_progress) - { - this.setBoolElementAttribute(toolbar_progress, "forcevisible", this.progressToolbarForce); - } - } - }, - - "progress.toolbar.style": - { - update: function() - { - this.progressToolbarStyle = this.prefs.getBoolPref("progress.toolbar.style"); - }, - updateWindow: function(win) - { - let toolbar_progress = win.caligon.status4evar.getters.toolbarProgress; - if(toolbar_progress) - { - this.setBoolElementAttribute(toolbar_progress, "s4estyle", this.progressToolbarStyle); - } - } - }, - - "status": - { - update: function() - { - this.status = this.prefs.getIntPref("status"); - }, - updateWindow: function(win) - { - win.caligon.status4evar.statusService.clearStatusField(); - win.caligon.status4evar.statusService.updateStatusField(true); - } - }, - - "status.default": - { - update: function() - { - this.statusDefault = this.prefs.getBoolPref("status.default"); - }, - updateWindow: function(win) - { - win.caligon.status4evar.statusService.buildTextOrder(); - win.caligon.status4evar.statusService.updateStatusField(true); - } - }, - - "status.linkOver": - { - update: function() - { - this.statusLinkOver = this.prefs.getIntPref("status.linkOver"); - } - }, - - "status.linkOver.delay.show": - { - update: function() - { - this.statusLinkOverDelayShow = this.prefs.getIntPref("status.linkOver.delay.show"); - } - }, - - "status.linkOver.delay.hide": - { - update: function() - { - this.statusLinkOverDelayHide = this.prefs.getIntPref("status.linkOver.delay.hide"); - } - }, - - "status.network": - { - update: function() - { - this.statusNetwork = this.prefs.getBoolPref("status.network"); - }, - updateWindow: function(win) - { - win.caligon.status4evar.statusService.buildTextOrder(); - } - }, - - "status.network.xhr": - { - update: function() - { - this.statusNetworkXHR = this.prefs.getBoolPref("status.network.xhr"); - }, - updateWindow: function(win) - { - win.caligon.status4evar.statusService.buildTextOrder(); - } - }, - - "status.timeout": - { - update: function() - { - this.statusTimeout = (this.prefs.getIntPref("status.timeout") * 1000); - }, - updateWindow: function(win) - { - win.caligon.status4evar.statusService.updateStatusField(true); - } - }, - - "status.toolbar.maxLength": - { - update: function() - { - this.statusToolbarMaxLength = this.prefs.getIntPref("status.toolbar.maxLength"); - }, - updateWindow: function(win) - { - let status_widget = win.caligon.status4evar.getters.statusWidget; - if(status_widget) - { - status_widget.maxWidth = (this.statusToolbarMaxLength || ""); - } - } - }, - - "status.popup.invertMirror": - { - update: function() - { - this.statusToolbarInvertMirror = this.prefs.getBoolPref("status.popup.invertMirror"); - }, - updateWindow: function(win) - { - let statusOverlay = win.caligon.status4evar.getters.statusOverlay; - if(statusOverlay) - { - statusOverlay.invertMirror = this.statusToolbarInvertMirror; - } - } - }, - - "status.popup.mouseMirror": - { - update: function() - { - this.statusToolbarMouseMirror = this.prefs.getBoolPref("status.popup.mouseMirror"); - }, - updateWindow: function(win) - { - let statusOverlay = win.caligon.status4evar.getters.statusOverlay; - if(statusOverlay) - { - statusOverlay.mouseMirror = this.statusToolbarMouseMirror; - } - } - } - - }, - - // nsIObserver - observe: function(subject, topic, data) - { - try - { - switch(topic) - { - case "profile-after-change": - this.startup(); - break; - case "quit-application": - this.shutdown(); - break; - case "nsPref:changed": - this.updatePref(data, true); - break; - } - } - catch(e) - { - CU.reportError(e); - } - }, - - startup: function() - { - this.prefs = Services.prefs.getBranch("status4evar.").QueryInterface(CI.nsIPrefBranch2); - - this.firstRun = this.prefs.getBoolPref("firstRun"); - if(this.firstRun) - { - this.prefs.setBoolPref("firstRun", false); - } - - this.migrate(); - - for(let pref in this.pref_registry) - { - let pro = this.pref_registry[pref]; - - pro.update = pro.update.bind(this); - if(pro.updateWindow) - { - pro.updateWindow = pro.updateWindow.bind(this); - } - if(pro.updateDynamicStyle) - { - pro.updateDynamicStyle = pro.updateDynamicStyle.bind(this); - } - - this.prefs.addObserver(pref, this, true); - - this.updatePref(pref, false); - } - - Services.obs.addObserver(this, "quit-application", true); - }, - - shutdown: function() - { - Services.obs.removeObserver(this, "quit-application"); - - for(let pref in this.pref_registry) - { - this.prefs.removeObserver(pref, this); - } - - this.prefs = null; - }, - - migrate: function() - { - if(!this.firstRun) - { - let migration = 0; - try - { - migration = this.prefs.getIntPref("migration"); - } - catch(e) {} - - switch(migration) - { - case 5: - this.migrateBoolPref("status.detectFullScreen", "advanced.status.detectFullScreen"); - case 6: - let oldDownloadAction = this.prefs.getIntPref("download.button.action"); - let newDownloadAction = 1; - switch(oldDownloadAction) - { - case 2: - newDownloadAction = 1; - break; - case 3: - newDownloadAction = 2; - break; - case 4: - newDownloadAction = 1; - break; - } - this.prefs.setIntPref("download.button.action", newDownloadAction); - case 7: - let progressLocation = this.prefs.getIntPref("status"); - if (progressLocation == 2) - this.prefs.setIntPref("status", 1); - let linkOverLocation = this.prefs.getIntPref("status.linkOver"); - if (linkOverLocation == 2) - this.prefs.setIntPref("status.linkOver", 1); - break; - case CURRENT_MIGRATION: - break; - } - } - - this.prefs.setIntPref("migration", CURRENT_MIGRATION); - }, - - migrateBoolPref: function(oldPref, newPref) - { - if(this.prefs.prefHasUserValue(oldPref)) - { - this.prefs.setBoolPref(newPref, this.prefs.getBoolPref(oldPref)); - this.prefs.clearUserPref(oldPref); - } - }, - - migrateIntPref: function(oldPref, newPref) - { - if(this.prefs.prefHasUserValue(oldPref)) - { - this.prefs.setIntPref(newPref, this.prefs.getIntPref(oldPref)); - this.prefs.clearUserPref(oldPref); - } - }, - - migrateCharPref: function(oldPref, newPref) - { - if(this.prefs.prefHasUserValue(oldPref)) - { - this.prefs.setCharPref(newPref, this.prefs.getCharPref(oldPref)); - this.prefs.clearUserPref(oldPref); - } - }, - - updatePref: function(pref, updateWindows) - { - if(!(pref in this.pref_registry)) - { - return; - } - let pro = this.pref_registry[pref]; - - pro.update(); - - if(updateWindows) - { - let windowsEnum = Services.wm.getEnumerator("navigator:browser"); - while(windowsEnum.hasMoreElements()) - { - this.updateWindow(windowsEnum.getNext(), pro); - } - } - - if(pro.alsoUpdate) - { - pro.alsoUpdate.forEach(function (alsoPref) - { - this.updatePref(alsoPref); - }, this); - } - }, - - // Updtate a browser window - updateWindow: function(win, pro) - { - if(!(win instanceof CI.nsIDOMWindow) - || !(win.document.documentElement.getAttribute("windowtype") == "navigator:browser")) - { - return; - } - - if(pro) - { - this.handlePro(win, pro); - } - else - { - for(let pref in this.pref_registry) - { - this.handlePro(win, this.pref_registry[pref]); - } - } - }, - - handlePro: function(win, pro) - { - if(pro.updateWindow) - { - pro.updateWindow(win); - } - - if(pro.updateDynamicStyle) - { - let styleSheets = win.document.styleSheets; - for(let i = 0; i < styleSheets.length; i++) - { - let styleSheet = styleSheets[i]; - if(styleSheet.href == "chrome://browser/skin/statusbar/dynamic.css") - { - pro.updateDynamicStyle(styleSheet); - break; - } - } - } - }, - - setBoolElementAttribute: function(elem, attr, val) - { - if(val) - { - elem.setAttribute(attr, "true"); - } - else - { - elem.removeAttribute(attr); - } - }, - - setStringElementAttribute: function(elem, attr, val) - { - if(val) - { - elem.setAttribute(attr, val); - } - else - { - elem.removeAttribute(attr); - } - }, - - resetPrefs: function() - { - let childPrefs = this.prefs.getChildList(""); - childPrefs.forEach(function(pref) - { - if(this.prefs.prefHasUserValue(pref)) - { - this.prefs.clearUserPref(pref); - } - }, this); - } + classID: Components.ID("{33d0433d-07be-4dc4-87fd-954057310efd}"), + QueryInterface: XPCOMUtils.generateQI([ + CI.nsISupportsWeakReference, + CI.nsIObserver, + CI.nsIStatus4Evar + ]), + + prefs: null, + + addonbarBorderStyle: false, + addonbarCloseButton: false, + addonbarWindowGripper: true, + + advancedStatusDetectFullScreen: true, + advancedStatusDetectVideo: true, + + downloadButtonAction: 1, + downloadButtonActionCommand: "", + downloadColorActive: null, + downloadColorPaused: null, + downloadForce: false, + downloadLabel: 0, + downloadLabelForce: true, + downloadNotifyAnimate: true, + downloadNotifyTimeout: 60000, + downloadProgress: 1, + downloadTooltip: 1, + + firstRun: true, + + progressToolbarCSS: null, + progressToolbarForce: false, + progressToolbarStyle: false, + + status: 1, + statusDefault: true, + statusNetwork: true, + statusTimeout: 10000, + statusLinkOver: 1, + statusLinkOverDelayShow: 70, + statusLinkOverDelayHide: 150, + + statusToolbarMaxLength: 0, + + statusToolbarInvertMirror: false, + statusToolbarMouseMirror: true, + + pref_registry: + { + "addonbar.borderStyle": + { + update: function() + { + this.addonbarBorderStyle = this.prefs.getBoolPref("addonbar.borderStyle"); + }, + updateWindow: function(win) + { + let browser_bottom_box = win.caligon.status4evar.getters.browserBottomBox; + if(browser_bottom_box) + { + this.setBoolElementAttribute(browser_bottom_box, "s4eboarder", this.addonbarBorderStyle); + } + } + }, + + "addonbar.closeButton": + { + update: function() + { + this.addonbarCloseButton = this.prefs.getBoolPref("addonbar.closeButton"); + }, + updateWindow: function(win) + { + let addonbar_close_button = win.caligon.status4evar.getters.addonbarCloseButton; + if(addonbar_close_button) + { + addonbar_close_button.hidden = !this.addonbarCloseButton; + } + } + }, + + "addonbar.windowGripper": + { + update: function() + { + this.addonbarWindowGripper = this.prefs.getBoolPref("addonbar.windowGripper"); + }, + updateWindow: function(win) + { + win.caligon.status4evar.toolbars.updateWindowGripper(true); + } + }, + + "advanced.status.detectFullScreen": + { + update: function() + { + this.advancedStatusDetectFullScreen = this.prefs.getBoolPref("advanced.status.detectFullScreen"); + } + }, + + "advanced.status.detectVideo": + { + update: function() + { + this.advancedStatusDetectVideo = this.prefs.getBoolPref("advanced.status.detectVideo"); + } + }, + + "download.button.action": + { + update: function() + { + this.downloadButtonAction = this.prefs.getIntPref("download.button.action"); + }, + updateWindow: function(win) + { + win.caligon.status4evar.downloadStatus.updateBinding(); + } + }, + + "download.button.action.command": + { + update: function() + { + this.downloadButtonActionCommand = this.prefs.getCharPref("download.button.action.command"); + } + }, + + "download.color.active": + { + update: function() + { + this.downloadColorActive = this.prefs.getCharPref("download.color.active"); + }, + updateDynamicStyle: function(sheet) + { + sheet.cssRules[2].style.backgroundColor = this.downloadColorActive; + } + }, + + "download.color.paused": + { + update: function() + { + this.downloadColorPaused = this.prefs.getCharPref("download.color.paused"); + }, + updateDynamicStyle: function(sheet) + { + sheet.cssRules[3].style.backgroundColor = this.downloadColorPaused; + } + }, + + "download.force": + { + update: function() + { + this.downloadForce = this.prefs.getBoolPref("download.force"); + }, + updateWindow: function(win) + { + let download_button = win.caligon.status4evar.getters.downloadButton; + if(download_button) + { + this.setBoolElementAttribute(download_button, "forcevisible", this.downloadForce); + } + + let download_notify_anchor = win.caligon.status4evar.getters.downloadNotifyAnchor; + this.setBoolElementAttribute(download_notify_anchor, "forcevisible", this.downloadForce); + } + }, + + "download.label": + { + update: function() + { + this.downloadLabel = this.prefs.getIntPref("download.label"); + }, + updateWindow: function(win) + { + win.caligon.status4evar.downloadStatus.updateButton(); + } + }, + + "download.label.force": + { + update: function() + { + this.downloadLabelForce = this.prefs.getBoolPref("download.label.force"); + }, + updateWindow: function(win) + { + let download_button = win.caligon.status4evar.getters.downloadButton; + if(download_button) + { + this.setBoolElementAttribute(download_button, "forcelabel", this.downloadLabelForce); + } + } + }, + + "download.notify.animate": + { + update: function() + { + this.downloadNotifyAnimate = this.prefs.getBoolPref("download.notify.animate"); + } + }, + + "download.notify.timeout": + { + update: function() + { + this.downloadNotifyTimeout = (this.prefs.getIntPref("download.notify.timeout") * 1000); + } + }, + + "download.progress": + { + update: function() + { + this.downloadProgress = this.prefs.getIntPref("download.progress"); + }, + updateWindow: function(win) + { + win.caligon.status4evar.downloadStatus.updateButton(); + } + }, + + "download.tooltip": + { + update: function() + { + this.downloadTooltip = this.prefs.getIntPref("download.tooltip"); + }, + updateWindow: function(win) + { + win.caligon.status4evar.downloadStatus.updateButton(); + } + }, + + "progress.toolbar.css": + { + update: function() + { + this.progressToolbarCSS = this.prefs.getCharPref("progress.toolbar.css"); + }, + updateDynamicStyle: function(sheet) + { + sheet.cssRules[1].style.background = this.progressToolbarCSS; + } + }, + + "progress.toolbar.force": + { + update: function() + { + this.progressToolbarForce = this.prefs.getBoolPref("progress.toolbar.force"); + }, + updateWindow: function(win) + { + let toolbar_progress = win.caligon.status4evar.getters.toolbarProgress; + if(toolbar_progress) + { + this.setBoolElementAttribute(toolbar_progress, "forcevisible", this.progressToolbarForce); + } + } + }, + + "progress.toolbar.style": + { + update: function() + { + this.progressToolbarStyle = this.prefs.getBoolPref("progress.toolbar.style"); + }, + updateWindow: function(win) + { + let toolbar_progress = win.caligon.status4evar.getters.toolbarProgress; + if(toolbar_progress) + { + this.setBoolElementAttribute(toolbar_progress, "s4estyle", this.progressToolbarStyle); + } + } + }, + + "status": + { + update: function() + { + this.status = this.prefs.getIntPref("status"); + }, + updateWindow: function(win) + { + win.caligon.status4evar.statusService.clearStatusField(); + win.caligon.status4evar.statusService.updateStatusField(true); + } + }, + + "status.default": + { + update: function() + { + this.statusDefault = this.prefs.getBoolPref("status.default"); + }, + updateWindow: function(win) + { + win.caligon.status4evar.statusService.buildTextOrder(); + win.caligon.status4evar.statusService.updateStatusField(true); + } + }, + + "status.linkOver": + { + update: function() + { + this.statusLinkOver = this.prefs.getIntPref("status.linkOver"); + } + }, + + "status.linkOver.delay.show": + { + update: function() + { + this.statusLinkOverDelayShow = this.prefs.getIntPref("status.linkOver.delay.show"); + } + }, + + "status.linkOver.delay.hide": + { + update: function() + { + this.statusLinkOverDelayHide = this.prefs.getIntPref("status.linkOver.delay.hide"); + } + }, + + "status.network": + { + update: function() + { + this.statusNetwork = this.prefs.getBoolPref("status.network"); + }, + updateWindow: function(win) + { + win.caligon.status4evar.statusService.buildTextOrder(); + } + }, + + "status.network.xhr": + { + update: function() + { + this.statusNetworkXHR = this.prefs.getBoolPref("status.network.xhr"); + }, + updateWindow: function(win) + { + win.caligon.status4evar.statusService.buildTextOrder(); + } + }, + + "status.timeout": + { + update: function() + { + this.statusTimeout = (this.prefs.getIntPref("status.timeout") * 1000); + }, + updateWindow: function(win) + { + win.caligon.status4evar.statusService.updateStatusField(true); + } + }, + + "status.toolbar.maxLength": + { + update: function() + { + this.statusToolbarMaxLength = this.prefs.getIntPref("status.toolbar.maxLength"); + }, + updateWindow: function(win) + { + let status_widget = win.caligon.status4evar.getters.statusWidget; + if(status_widget) + { + status_widget.maxWidth = (this.statusToolbarMaxLength || ""); + } + } + }, + + "status.popup.invertMirror": + { + update: function() + { + this.statusToolbarInvertMirror = this.prefs.getBoolPref("status.popup.invertMirror"); + }, + updateWindow: function(win) + { + let statusOverlay = win.caligon.status4evar.getters.statusOverlay; + if(statusOverlay) + { + statusOverlay.invertMirror = this.statusToolbarInvertMirror; + } + } + }, + + "status.popup.mouseMirror": + { + update: function() + { + this.statusToolbarMouseMirror = this.prefs.getBoolPref("status.popup.mouseMirror"); + }, + updateWindow: function(win) + { + let statusOverlay = win.caligon.status4evar.getters.statusOverlay; + if(statusOverlay) + { + statusOverlay.mouseMirror = this.statusToolbarMouseMirror; + } + } + } + + }, + + // nsIObserver + observe: function(subject, topic, data) + { + try + { + switch(topic) + { + case "profile-after-change": + this.startup(); + break; + case "quit-application": + this.shutdown(); + break; + case "nsPref:changed": + this.updatePref(data, true); + break; + } + } + catch(e) + { + CU.reportError(e); + } + }, + + startup: function() + { + this.prefs = Services.prefs.getBranch("status4evar.").QueryInterface(CI.nsIPrefBranch2); + + this.firstRun = this.prefs.getBoolPref("firstRun"); + if(this.firstRun) + { + this.prefs.setBoolPref("firstRun", false); + } + + this.migrate(); + + for(let pref in this.pref_registry) + { + let pro = this.pref_registry[pref]; + + pro.update = pro.update.bind(this); + if(pro.updateWindow) + { + pro.updateWindow = pro.updateWindow.bind(this); + } + if(pro.updateDynamicStyle) + { + pro.updateDynamicStyle = pro.updateDynamicStyle.bind(this); + } + + this.prefs.addObserver(pref, this, true); + + this.updatePref(pref, false); + } + + Services.obs.addObserver(this, "quit-application", true); + }, + + shutdown: function() + { + Services.obs.removeObserver(this, "quit-application"); + + for(let pref in this.pref_registry) + { + this.prefs.removeObserver(pref, this); + } + + this.prefs = null; + }, + + migrate: function() + { + if(!this.firstRun) + { + let migration = 0; + try + { + migration = this.prefs.getIntPref("migration"); + } + catch(e) {} + + switch(migration) + { + case 5: + this.migrateBoolPref("status.detectFullScreen", "advanced.status.detectFullScreen"); + case 6: + let oldDownloadAction = this.prefs.getIntPref("download.button.action"); + let newDownloadAction = 1; + switch(oldDownloadAction) + { + case 2: + newDownloadAction = 1; + break; + case 3: + newDownloadAction = 2; + break; + case 4: + newDownloadAction = 1; + break; + } + this.prefs.setIntPref("download.button.action", newDownloadAction); + case 7: + let progressLocation = this.prefs.getIntPref("status"); + if (progressLocation == 2) + this.prefs.setIntPref("status", 1); + let linkOverLocation = this.prefs.getIntPref("status.linkOver"); + if (linkOverLocation == 2) + this.prefs.setIntPref("status.linkOver", 1); + break; + case CURRENT_MIGRATION: + break; + } + } + + this.prefs.setIntPref("migration", CURRENT_MIGRATION); + }, + + migrateBoolPref: function(oldPref, newPref) + { + if(this.prefs.prefHasUserValue(oldPref)) + { + this.prefs.setBoolPref(newPref, this.prefs.getBoolPref(oldPref)); + this.prefs.clearUserPref(oldPref); + } + }, + + migrateIntPref: function(oldPref, newPref) + { + if(this.prefs.prefHasUserValue(oldPref)) + { + this.prefs.setIntPref(newPref, this.prefs.getIntPref(oldPref)); + this.prefs.clearUserPref(oldPref); + } + }, + + migrateCharPref: function(oldPref, newPref) + { + if(this.prefs.prefHasUserValue(oldPref)) + { + this.prefs.setCharPref(newPref, this.prefs.getCharPref(oldPref)); + this.prefs.clearUserPref(oldPref); + } + }, + + updatePref: function(pref, updateWindows) + { + if(!(pref in this.pref_registry)) + { + return; + } + let pro = this.pref_registry[pref]; + + pro.update(); + + if(updateWindows) + { + let windowsEnum = Services.wm.getEnumerator("navigator:browser"); + while(windowsEnum.hasMoreElements()) + { + this.updateWindow(windowsEnum.getNext(), pro); + } + } + + if(pro.alsoUpdate) + { + pro.alsoUpdate.forEach(function (alsoPref) + { + this.updatePref(alsoPref); + }, this); + } + }, + + // Updtate a browser window + updateWindow: function(win, pro) + { + if(!(win instanceof CI.nsIDOMWindow) + || !(win.document.documentElement.getAttribute("windowtype") == "navigator:browser")) + { + return; + } + + if(pro) + { + this.handlePro(win, pro); + } + else + { + for(let pref in this.pref_registry) + { + this.handlePro(win, this.pref_registry[pref]); + } + } + }, + + handlePro: function(win, pro) + { + if(pro.updateWindow) + { + pro.updateWindow(win); + } + + if(pro.updateDynamicStyle) + { + let styleSheets = win.document.styleSheets; + for(let i = 0; i < styleSheets.length; i++) + { + let styleSheet = styleSheets[i]; + if(styleSheet.href == "chrome://browser/skin/statusbar/dynamic.css") + { + pro.updateDynamicStyle(styleSheet); + break; + } + } + } + }, + + setBoolElementAttribute: function(elem, attr, val) + { + if(val) + { + elem.setAttribute(attr, "true"); + } + else + { + elem.removeAttribute(attr); + } + }, + + setStringElementAttribute: function(elem, attr, val) + { + if(val) + { + elem.setAttribute(attr, val); + } + else + { + elem.removeAttribute(attr); + } + }, + + resetPrefs: function() + { + let childPrefs = this.prefs.getChildList(""); + childPrefs.forEach(function(pref) + { + if(this.prefs.prefHasUserValue(pref)) + { + this.prefs.clearUserPref(pref); + } + }, this); + } }; const NSGetFactory = XPCOMUtils.generateNSGetFactory([Status_4_Evar]); diff --git a/application/xulrunner/README.xulrunner b/application/xulrunner/README.xulrunner new file mode 100644 index 000000000..424b7a615 --- /dev/null +++ b/application/xulrunner/README.xulrunner @@ -0,0 +1,13 @@ +XULRunner is a package which can be used to run applications written in HTML +or XUL. It can also be used to embed the gecko rendering engine into +binary applications. + +XULRunner is not a product; it is a tool which can be used to create products. +It is a byproduct of Firefox development and the Mozilla community does not +have a strong commitment to support XULRunner development apart from Firefox +development. + +For more information about using XULRunner or how to use this binary package, +see the Mozilla Developer Center article: + +https://developer.mozilla.org/en/XULRunner diff --git a/application/xulrunner/app.mozbuild b/application/xulrunner/app.mozbuild new file mode 100644 index 000000000..7b8316016 --- /dev/null +++ b/application/xulrunner/app.mozbuild @@ -0,0 +1,13 @@ +# vim: set filetype=python: +# 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/. + +include('/toolkit/toolkit.mozbuild') + +if CONFIG['MOZ_EXTENSIONS']: + DIRS += ['/extensions'] + +DIRS += [ + '/application/xulrunner', +] diff --git a/application/xulrunner/app/Makefile.in b/application/xulrunner/app/Makefile.in new file mode 100644 index 000000000..98e377d69 --- /dev/null +++ b/application/xulrunner/app/Makefile.in @@ -0,0 +1,75 @@ +# vim:set ts=8 sw=8 sts=8 et: +# 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/. + +GARBAGE += $(addprefix $(DIST)/bin/defaults/pref/,xulrunner.js) + +ifeq (cocoa,$(MOZ_WIDGET_TOOLKIT)) +TK_LIBS := -framework Cocoa $(TK_LIBS) +endif + +ifndef MOZ_WINCONSOLE +ifdef MOZ_DEBUG +MOZ_WINCONSOLE = 1 +else +MOZ_WINCONSOLE = 0 +endif +endif + +# This switches $(INSTALL) to copy mode, like $(SYSINSTALL), so things that +# shouldn't get 755 perms need $(IFLAGS1) for either way of calling nsinstall. +NSDISTMODE = copy + +include $(topsrcdir)/config/config.mk + +include $(topsrcdir)/config/rules.mk + +DEFINES += -DXULRUNNER_ICO='"$(DIST)/branding/xulrunner.ico"' -DDOCUMENT_ICO='"$(DIST)/branding/document.ico"' + +ifdef MOZ_WIDGET_GTK +libs:: + $(INSTALL) $(IFLAGS1) $(DIST)/branding/default16.png $(DIST)/bin/chrome/icons/default + $(INSTALL) $(IFLAGS1) $(DIST)/branding/default32.png $(DIST)/bin/chrome/icons/default + $(INSTALL) $(IFLAGS1) $(DIST)/branding/default48.png $(DIST)/bin/chrome/icons/default +endif + +# XXX applications would need to supply this file +#export:: brand.dtd.in +# $(call py_action,preprocessor,$(DEFINES) $(ACDEFINES) $^ -o brand.dtd) + +ifeq (cocoa,$(MOZ_WIDGET_TOOLKIT)) + +FRAMEWORK_NAME = XUL +FRAMEWORK_VERSION = $(MOZILLA_VERSION) + +FRAMEWORK_DIR = \ + $(DIST)/$(FRAMEWORK_NAME).framework/Versions/$(FRAMEWORK_VERSION) + +$(FRAMEWORK_DIR)/Resources: + $(NSINSTALL) -D $@ + +tools:: $(PROGRAM) $(FRAMEWORK_DIR)/Resources + $(NSINSTALL) $(srcdir)/macbuild/InfoPlist.strings $(FRAMEWORK_DIR)/Resources + sed -e 's/APP_VERSION/$(APP_VERSION)/' $(srcdir)/macbuild/Info.plist.in > $(FRAMEWORK_DIR)/Info.plist + rsync -av $(DIST)/bin/ $(FRAMEWORK_DIR) --exclude mangle --exclude shlibsign + rm -f $(DIST)/$(FRAMEWORK_NAME).framework/Versions/Current \ + $(DIST)/$(FRAMEWORK_NAME).framework/libxpcom.dylib \ + $(DIST)/$(FRAMEWORK_NAME).framework/XUL \ + $(DIST)/$(FRAMEWORK_NAME).framework/xulrunner + ln -s $(FRAMEWORK_VERSION) $(DIST)/$(FRAMEWORK_NAME).framework/Versions/Current + ln -s Versions/Current/libxpcom.dylib $(DIST)/$(FRAMEWORK_NAME).framework/libxpcom.dylib + ln -s Versions/Current/XUL $(DIST)/$(FRAMEWORK_NAME).framework/XUL + ln -s Versions/Current/xulrunner $(DIST)/$(FRAMEWORK_NAME).framework/xulrunner + +clean clobber:: + rm -rf $(DIST)/$(FRAMEWORK_NAME).framework +endif + +README_FILE = $(srcdir)/../README.xulrunner + +libs:: + $(INSTALL) $(IFLAGS1) $(README_FILE) $(DIST)/bin + $(INSTALL) $(IFLAGS1) $(topsrcdir)/LICENSE $(DIST)/bin + $(INSTALL) $(IFLAGS1) $(srcdir)/install_app.py $(DIST)/bin + diff --git a/application/xulrunner/app/default16.png b/application/xulrunner/app/default16.png Binary files differnew file mode 100644 index 000000000..e74f5cf2e --- /dev/null +++ b/application/xulrunner/app/default16.png diff --git a/application/xulrunner/app/default32.png b/application/xulrunner/app/default32.png Binary files differnew file mode 100644 index 000000000..914509054 --- /dev/null +++ b/application/xulrunner/app/default32.png diff --git a/application/xulrunner/app/default48.png b/application/xulrunner/app/default48.png Binary files differnew file mode 100644 index 000000000..5fd71e110 --- /dev/null +++ b/application/xulrunner/app/default48.png diff --git a/application/xulrunner/app/document.ico b/application/xulrunner/app/document.ico Binary files differnew file mode 100644 index 000000000..311116324 --- /dev/null +++ b/application/xulrunner/app/document.ico diff --git a/application/xulrunner/app/install_app.py b/application/xulrunner/app/install_app.py new file mode 100644 index 000000000..6be8c5ecb --- /dev/null +++ b/application/xulrunner/app/install_app.py @@ -0,0 +1,221 @@ +#!/usr/bin/env python + +# 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/. + +# Min version of python is 2.7 +import sys +if ((sys.version_info.major != 2) or (sys.version_info.minor < 7)): + raise Exception("You need to use Python version 2.7 or higher") + +import os, shutil, re, zipfile +from ConfigParser import SafeConfigParser + +# Platform-specific support +# see https://developer.mozilla.org/en/XULRunner/Deploying_XULRunner_1.8 +if sys.platform.startswith('linux') or sys.platform == "win32": + def installApp(appLocation, installDir, appName, greDir): + zipApp, iniParser, appName = validateArguments(appLocation, installDir, appName, greDir) + if (zipApp): + zipApp.extractAll(installDir) + else: + shutil.copytree(appLocation, installDir) + shutil.copy2(os.path.join(greDir, xulrunnerStubName), + os.path.join(installDir, appName)) + copyGRE(greDir, os.path.join(installDir, "xulrunner")) + +if sys.platform.startswith('linux'): + xulrunnerStubName = "xulrunner-stub" + + def makeAppName(leafName): + return leafName.lower() + +elif sys.platform == "win32": + xulrunnerStubName = "xulrunner-stub.exe" + + def makeAppName(leafName): + return leafName + ".exe" + +elif sys.platform == "darwin": + xulrunnerStubName = "xulrunner-stub" + + def installApp(appLocation, installDir, appName, greDir): + zipApp, iniparser, appName = validateArguments(appLocation, installDir, appName, greDir) + installDir += "/" + appName + ".app" + resourcesDir = os.path.join(installDir, "Contents/Resources") + if (zipApp): + zipApp.extractAll(resourcesDir) + else: + shutil.copytree(appLocation, resourcesDir) + MacOSDir = os.path.join(installDir, "Contents/MacOS") + os.makedirs(MacOSDir) + shutil.copy2(os.path.join(greDir, xulrunnerStubName), MacOSDir) + copyGRE(greDir, + os.path.join(installDir, "Contents/Frameworks/XUL.framework")) + + # Contents/Info.plist + contents = """<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> +<plist version="1.0"> +<dict> +<key>CFBundleInfoDictionaryVersion</key> +<string>6.0</string> +<key>CFBundlePackageType</key> +<string>APPL</string> +<key>CFBundleSignature</key> +<string>????</string> +<key>CFBundleExecutable</key> +<string>xulrunner</string> +<key>NSAppleScriptEnabled</key> +<true/> +<key>CFBundleGetInfoString</key> +<string>$infoString</string> +<key>CFBundleName</key> +<string>$appName</string> +<key>CFBundleShortVersionString</key> +<string>$version</string> +<key>CFBundleVersion</key> +<string>$version.$buildID</string> +<key>CFBundleIdentifier</key> +<string>$reverseVendor</string> +</dict> +</plist> +""" + version = iniparser.get("App", "Version") + buildID = iniparser.get("App", "BuildID") + infoString = appName + " " + version + reverseVendor = "com.vendor.unknown" + appID = iniparser.get("App", "ID") + colonIndex = appID.find("@") + 1 + if (colonIndex != 0): + vendor = appID[colonIndex:] + reverseVendor = ".".join(vendor.split(".")[::-1]) + contents = contents.replace("$infoString", infoString) + contents = contents.replace("$appName", appName) + contents = contents.replace("$version", version) + contents = contents.replace("$buildID", buildID) + contents = contents.replace("$reverseVendor", reverseVendor) + infoPList = open(os.path.join(installDir, "Contents/Info.plist"), "w+b") + infoPList.write(contents) + infoPList.close() + + def makeAppName(leafName): + return leafName + +else: + # Implement xulrunnerStubName, installApp and makeAppName as above. + raise Exception("This operating system isn't supported for install_app.py yet!") +# End platform-specific support + +def resolvePath(path): + return os.path.realpath(path) + +def requireINIOption(iniparser, section, option): + if not (iniparser.has_option(section, option)): + raise Exception("application.ini must have a " + option + " option under the " + section + " section") + +def checkAppINI(appLocation): + if (os.path.isdir(appLocation)): + zipApp = None + appINIPath = os.path.join(appLocation, "application.ini") + if not (os.path.isfile(appINIPath)): + raise Exception(appINIPath + " does not exist") + appINI = open(appINIPath) + elif (zipfile.is_zipfile(appLocation)): + zipApp = zipfile.ZipFile(appLocation) + if not ("application.ini" in zipApp.namelist()): + raise Exception("jar:" + appLocation + "!/application.ini does not exist") + appINI = zipApp.open("application.ini") + else: + raise Exception("appLocation must be a directory containing application.ini or a zip file with application.ini at its root") + + # application.ini verification + iniparser = SafeConfigParser() + iniparser.readfp(appINI) + if not (iniparser.has_section("App")): + raise Exception("application.ini must have an App section") + if not (iniparser.has_section("Gecko")): + raise Exception("application.ini must have a Gecko section") + requireINIOption(iniparser, "App", "Name") + requireINIOption(iniparser, "App", "Version") + requireINIOption(iniparser, "App", "BuildID") + requireINIOption(iniparser, "App", "ID") + requireINIOption(iniparser, "Gecko", "MinVersion") + + return zipApp, iniparser + pass + +def copyGRE(greDir, targetDir): + shutil.copytree(greDir, targetDir, symlinks=True) + +def validateArguments(appLocation, installDir, appName, greDir): + # application directory / zip verification + appLocation = resolvePath(appLocation) + + # target directory + installDir = resolvePath(installDir) + + if (os.path.exists(installDir)): + raise Exception("installDir must not exist: " + cmds.installDir) + + greDir = resolvePath(greDir) + xulrunnerStubPath = os.path.isfile(os.path.join(greDir, xulrunnerStubName)) + if not xulrunnerStubPath: + raise Exception("XULRunner stub executable not found: " + os.path.join(greDir, xulrunnerStubName)) + + # appName + zipApp, iniparser = checkAppINI(appLocation) + if not appName: + appName = iniparser.get("App", "Name") + appName = makeAppName(appName) + pattern = re.compile("[\\\/\:*?\"<>|\x00]") + if pattern.search(appName): + raise Exception("App name has illegal characters for at least one operating system") + return zipApp, iniparser, appName + +def handleCommandLine(): + import argparse + + # Argument parsing. + parser = argparse.ArgumentParser( + description="XULRunner application installer", + usage="""install_app.py appLocation installDir greDir [--appName APPNAME] + install_app.py -h + install_app.py --version + """ + ) + parser.add_argument( + "appLocation", + action="store", + help="The directory or ZIP file containing application.ini as a top-level child file" + ) + parser.add_argument( + "installDir", + action="store", + help="The directory to install the application to" + ) + parser.add_argument( + "--greDir", + action="store", + help="The directory containing the Gecko SDK (usually where this Python script lives)", + default=os.path.dirname(sys.argv[0]) + ) + parser.add_argument( + "--appName", + action="store", + help="The name of the application to install" + ) + parser.add_argument("--version", action="version", version="%(prog)s 1.0") + + # The command code. + cmds = parser.parse_args() + try: + installApp(cmds.appLocation, cmds.installDir, cmds.appName, cmds.greDir) + except exn: + shutil.rmtree(cmds.installDir) + raise exn + print cmds.appName + " application installed to " + cmds.installDir + +if __name__ == '__main__': + handleCommandLine() diff --git a/application/xulrunner/app/macbuild/Info.plist.in b/application/xulrunner/app/macbuild/Info.plist.in new file mode 100644 index 000000000..69676b80c --- /dev/null +++ b/application/xulrunner/app/macbuild/Info.plist.in @@ -0,0 +1,31 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> +<plist version="1.0"> +<dict> + <key>CFBundleDevelopmentRegion</key> + <string>English</string> + <key>CFBundleExecutable</key> + <string>xulrunner-bin</string> + <key>CFBundleIdentifier</key> + <string>org.mozilla.xulrunner</string> + <key>CFBundleInfoDictionaryVersion</key> + <string>6.0</string> + <key>CFBundleName</key> + <string>XULRunner</string> + <key>CFBundlePackageType</key> + <string>FMWK</string> + <key>CFBundleSignature</key> + <string>MOZB</string> + <key>CFBundleVersion</key> + <string>APP_VERSION</string> + <key>LSMinimumSystemVersion</key> + <string>10.5</string> + <key>LSMinimumSystemVersionByArchitecture</key> + <dict> + <key>i386</key> + <string>10.5.0</string> + <key>x86_64</key> + <string>10.6.0</string> + </dict> +</dict> +</plist> diff --git a/application/xulrunner/app/macbuild/InfoPlist.strings b/application/xulrunner/app/macbuild/InfoPlist.strings Binary files differnew file mode 100644 index 000000000..5d9eefd51 --- /dev/null +++ b/application/xulrunner/app/macbuild/InfoPlist.strings diff --git a/application/xulrunner/app/moz.build b/application/xulrunner/app/moz.build new file mode 100644 index 000000000..1c9cb117c --- /dev/null +++ b/application/xulrunner/app/moz.build @@ -0,0 +1,70 @@ +# -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*- +# vim: set filetype=python: +# 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/. + +GeckoProgram('xulrunner') + +SOURCES += [ + 'nsXULRunnerApp.cpp', +] + +DEFINES['XULRUNNER_PROGNAME'] = '"xulrunner"' +if CONFIG['MOZ_DEBUG']: + DEFINES['DEBUG'] = True + +LOCAL_INCLUDES += [ + '/toolkit/profile', + '/toolkit/xre', + '/xpcom/base', + '/xpcom/build', +] + +if CONFIG['_MSC_VER']: + # Always enter a Windows program through wmain, whether or not we're + # a console application. + WIN32_EXE_LDFLAGS += ['-ENTRY:wmainCRTStartup'] + +# Control the default heap size. +# This is the heap returned by GetProcessHeap(). +# As we use the CRT heap, the default size is too large and wastes VM. +# +# The default heap size is 1MB on Win32. +# The heap will grow if need be. +# +# Set it to 256k. See bug 127069. +if CONFIG['OS_ARCH'] == 'WINNT' and not CONFIG['GNU_CC']: + LDFLAGS += ['/HEAP:0x40000'] + +if CONFIG['OS_ARCH'] == 'WINNT': + RCINCLUDE = 'splash.rc' + OS_LIBS += [ + 'comctl32', + 'comdlg32', + 'uuid', + 'shell32', + 'ole32', + 'oleaut32', + 'version', + 'winspool', + ] + +DISABLE_STL_WRAPPING = True + +JS_PREFERENCE_PP_FILES += [ + 'xulrunner.js', +] + +if CONFIG['OS_ARCH'] == 'WINNT': + BRANDING_FILES += [ + 'document.ico', + 'xulrunner.ico', + ] + +if CONFIG['MOZ_WIDGET_GTK']: + BRANDING_FILES += [ + 'default16.png', + 'default32.png', + 'default48.png', + ] diff --git a/application/xulrunner/app/nsXULRunnerApp.cpp b/application/xulrunner/app/nsXULRunnerApp.cpp new file mode 100644 index 000000000..d86317a85 --- /dev/null +++ b/application/xulrunner/app/nsXULRunnerApp.cpp @@ -0,0 +1,294 @@ +/* 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/. */ + +#include "nsXULAppAPI.h" +#include "nsXPCOMGlue.h" +#include <stdio.h> +#include <stdlib.h> +#ifdef XP_WIN +#include <windows.h> +#if defined(_MSC_VER) && _MSC_VER < 1900 +#define snprintf _snprintf +#endif +#define strcasecmp _stricmp +#endif + +#include "nsAppRunner.h" +#include "nsIFile.h" +#include "nsCOMPtr.h" +#include "nsMemory.h" +#include "nsCRTGlue.h" +#include "nsStringAPI.h" +#include "nsServiceManagerUtils.h" +#include "plstr.h" +#include "prprf.h" +#include "prenv.h" +#include "nsINIParser.h" + +#ifdef XP_WIN +#define XRE_DONT_SUPPORT_XPSP2 // See https://bugzil.la/1023941#c32 +#include "nsWindowsWMain.cpp" +#endif + +#include "BinaryPath.h" + +#include "nsXPCOMPrivate.h" // for MAXPATHLEN and XPCOM_DLL + +using namespace mozilla; + +/** + * Output a string to the user. This method is really only meant to be used to + * output last-ditch error messages designed for developers NOT END USERS. + * + * @param isError + * Pass true to indicate severe errors. + * @param fmt + * printf-style format string followed by arguments. + */ +static void Output(bool isError, const char *fmt, ... ) +{ + va_list ap; + va_start(ap, fmt); + +#if (defined(XP_WIN) && !MOZ_WINCONSOLE) + wchar_t msg[2048]; + _vsnwprintf(msg, sizeof(msg)/sizeof(msg[0]), NS_ConvertUTF8toUTF16(fmt).get(), ap); + + UINT flags = MB_OK; + if (isError) + flags |= MB_ICONERROR; + else + flags |= MB_ICONINFORMATION; + + MessageBoxW(nullptr, msg, L"XULRunner", flags); +#else + vfprintf(stderr, fmt, ap); +#endif + + va_end(ap); +} + +/** + * Return true if |arg| matches the given argument name. + */ +static bool IsArg(const char* arg, const char* s) +{ + if (*arg == '-') + { + if (*++arg == '-') + ++arg; + return !strcasecmp(arg, s); + } + +#if defined(XP_WIN) + if (*arg == '/') + return !strcasecmp(++arg, s); +#endif + + return false; +} + +static nsresult +GetGREVersion(const char *argv0, + nsACString *aMilestone, + nsACString *aVersion) +{ + if (aMilestone) + aMilestone->AssignLiteral("<Error>"); + if (aVersion) + aVersion->AssignLiteral("<Error>"); + + nsCOMPtr<nsIFile> iniFile; + nsresult rv = BinaryPath::GetFile(argv0, getter_AddRefs(iniFile)); + if (NS_FAILED(rv)) + return rv; + + iniFile->SetNativeLeafName(NS_LITERAL_CSTRING("platform.ini")); + + nsINIParser parser; + rv = parser.Init(iniFile); + if (NS_FAILED(rv)) + return rv; + + if (aMilestone) { + rv = parser.GetString("Build", "Milestone", *aMilestone); + if (NS_FAILED(rv)) + return rv; + } + if (aVersion) { + rv = parser.GetString("Build", "BuildID", *aVersion); + if (NS_FAILED(rv)) + return rv; + } + return NS_OK; +} + +static void Usage(const char *argv0) +{ + nsAutoCString milestone; + GetGREVersion(argv0, &milestone, nullptr); + + // display additional information (XXX make localizable?) + Output(false, + "Mozilla XULRunner %s\n\n" + "Usage: " XULRUNNER_PROGNAME " [OPTIONS]\n" + " " XULRUNNER_PROGNAME " APP-FILE [APP-OPTIONS...]\n" + "\n" + "OPTIONS\n" + " --app specify APP-FILE (optional)\n" + " -h, --help show this message\n" + " -v, --version show version\n" + " --gre-version print the GRE version string on stdout\n" + "\n" + "APP-FILE\n" + " Application initialization file.\n" + "\n" + "APP-OPTIONS\n" + " Application specific options.\n", + milestone.get()); +} + +XRE_GetFileFromPathType XRE_GetFileFromPath; +XRE_CreateAppDataType XRE_CreateAppData; +XRE_FreeAppDataType XRE_FreeAppData; +XRE_mainType XRE_main; + +static const nsDynamicFunctionLoad kXULFuncs[] = { + { "XRE_GetFileFromPath", (NSFuncPtr*) &XRE_GetFileFromPath }, + { "XRE_CreateAppData", (NSFuncPtr*) &XRE_CreateAppData }, + { "XRE_FreeAppData", (NSFuncPtr*) &XRE_FreeAppData }, + { "XRE_main", (NSFuncPtr*) &XRE_main }, + { nullptr, nullptr } +}; + +class AutoAppData +{ +public: + AutoAppData(nsIFile* aINIFile) : mAppData(nullptr) { + nsresult rv = XRE_CreateAppData(aINIFile, &mAppData); + if (NS_FAILED(rv)) + mAppData = nullptr; + } + ~AutoAppData() { + if (mAppData) + XRE_FreeAppData(mAppData); + } + + operator nsXREAppData*() const { return mAppData; } + nsXREAppData* operator -> () const { return mAppData; } + +private: + nsXREAppData* mAppData; +}; + +int main(int argc, char* argv[]) +{ + char exePath[MAXPATHLEN]; + nsresult rv = mozilla::BinaryPath::Get(argv[0], exePath); + if (NS_FAILED(rv)) { + Output(true, "Couldn't calculate the application directory.\n"); + return 255; + } + + char *lastSlash = strrchr(exePath, XPCOM_FILE_PATH_SEPARATOR[0]); + if (!lastSlash || (size_t(lastSlash - exePath) > MAXPATHLEN - sizeof(XPCOM_DLL) - 1)) + return 255; + + strcpy(++lastSlash, XPCOM_DLL); + + rv = XPCOMGlueStartup(exePath); + if (NS_FAILED(rv)) { + Output(true, "Couldn't load XPCOM.\n"); + return 255; + } + + if (argc > 1 && (IsArg(argv[1], "h") || + IsArg(argv[1], "help") || + IsArg(argv[1], "?"))) + { + Usage(argv[0]); + return 0; + } + + if (argc == 2 && (IsArg(argv[1], "v") || IsArg(argv[1], "version"))) + { + nsAutoCString milestone; + nsAutoCString version; + GetGREVersion(argv[0], &milestone, &version); + Output(false, "Mozilla XULRunner %s - %s\n", + milestone.get(), version.get()); + return 0; + } + + rv = XPCOMGlueLoadXULFunctions(kXULFuncs); + if (NS_FAILED(rv)) { + Output(true, "Couldn't load XRE functions.\n"); + return 255; + } + + if (argc > 1) { + nsAutoCString milestone; + rv = GetGREVersion(argv[0], &milestone, nullptr); + if (NS_FAILED(rv)) + return 2; + + if (IsArg(argv[1], "gre-version")) { + if (argc != 2) { + Usage(argv[0]); + return 1; + } + + printf("%s\n", milestone.get()); + return 0; + } + + if (IsArg(argv[1], "install-app")) { + Output(true, "--install-app support has been removed. Use 'python install-app.py' instead.\n"); + return 1; + } + } + + const char *appDataFile = getenv("XUL_APP_FILE"); + + if (!(appDataFile && *appDataFile)) { + if (argc < 2) { + Usage(argv[0]); + return 1; + } + + if (IsArg(argv[1], "app")) { + if (argc == 2) { + Usage(argv[0]); + return 1; + } + argv[1] = argv[0]; + ++argv; + --argc; + } + + appDataFile = argv[1]; + argv[1] = argv[0]; + ++argv; + --argc; + + static char kAppEnv[MAXPATHLEN]; + snprintf(kAppEnv, MAXPATHLEN, "XUL_APP_FILE=%s", appDataFile); + putenv(kAppEnv); + } + + nsCOMPtr<nsIFile> appDataLF; + rv = XRE_GetFileFromPath(appDataFile, getter_AddRefs(appDataLF)); + if (NS_FAILED(rv)) { + Output(true, "Error: unrecognized application.ini path.\n"); + return 2; + } + + AutoAppData appData(appDataLF); + if (!appData) { + Output(true, "Error: couldn't parse application.ini.\n"); + return 2; + } + + return XRE_main(argc, argv, appData, 0); +} diff --git a/application/xulrunner/app/splash.rc b/application/xulrunner/app/splash.rc new file mode 100644 index 000000000..4374383ba --- /dev/null +++ b/application/xulrunner/app/splash.rc @@ -0,0 +1,22 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* 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/. */ + +#include <windows.h> +#include "nsNativeAppSupportWin.h" + +1 24 "xulrunner.exe.manifest" + +IDI_APPICON ICON XULRUNNER_ICO +IDI_DOCUMENT ICON DOCUMENT_ICO +IDI_APPLICATION ICON XULRUNNER_ICO + +STRINGTABLE DISCARDABLE +BEGIN +#ifdef DEBUG + IDS_STARTMENU_APPNAME, "Firefox Debug" +#else + IDS_STARTMENU_APPNAME, "Firefox" +#endif +END diff --git a/application/xulrunner/app/xulrunner.exe.manifest b/application/xulrunner/app/xulrunner.exe.manifest new file mode 100644 index 000000000..b08eea074 --- /dev/null +++ b/application/xulrunner/app/xulrunner.exe.manifest @@ -0,0 +1,38 @@ +<?xml version="1.0" encoding="UTF-8" standalone="yes"?> +<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0"> +<assemblyIdentity + version="1.0.0.0" + processorArchitecture="*" + name="Mozilla.XULRunner" + type="win32" +/> +<description>Mozilla XULRunner</description> +<dependency> + <dependentAssembly> + <assemblyIdentity + type="win32" + name="Microsoft.Windows.Common-Controls" + version="6.0.0.0" + processorArchitecture="*" + publicKeyToken="6595b64144ccf1df" + language="*" + /> + </dependentAssembly> +</dependency> +<ms_asmv3:trustInfo xmlns:ms_asmv3="urn:schemas-microsoft-com:asm.v3"> + <ms_asmv3:security> + <ms_asmv3:requestedPrivileges> + <ms_asmv3:requestedExecutionLevel level="asInvoker" uiAccess="false" /> + </ms_asmv3:requestedPrivileges> + </ms_asmv3:security> +</ms_asmv3:trustInfo> + <compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1"> + <application> + <supportedOS Id="{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}"/> + <supportedOS Id="{1f676c76-80e1-4239-95bb-83d0f6d0da78}"/> + <supportedOS Id="{4a2f28e3-53b9-4441-ba9c-d69d4a4a6e38}"/> + <supportedOS Id="{35138b9a-5d96-4fbd-8e2d-a2440225f93a}"/> + <supportedOS Id="{e2011457-1546-43c5-a5fe-008deee3d3f0}"/> + </application> + </compatibility> +</assembly> diff --git a/application/xulrunner/app/xulrunner.ico b/application/xulrunner/app/xulrunner.ico Binary files differnew file mode 100644 index 000000000..0518438a0 --- /dev/null +++ b/application/xulrunner/app/xulrunner.ico diff --git a/application/xulrunner/app/xulrunner.js b/application/xulrunner/app/xulrunner.js new file mode 100644 index 000000000..509bb48a5 --- /dev/null +++ b/application/xulrunner/app/xulrunner.js @@ -0,0 +1,26 @@ +/* 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/. */ + +#filter substitution + +// We need to override the default values of these preferences since all.js +// assumes these are in the navigator package, which for us is nonexistent. +// XXX(darin): perhaps all.js should not be seamonkey specific +pref("general.useragent.locale", "@AB_CD@"); +pref("xpinstall.dialog.confirm", "chrome://mozapps/content/xpinstall/xpinstallConfirm.xul"); +pref("xpinstall.dialog.progress.chrome", "chrome://mozapps/content/extensions/extensions.xul"); +pref("xpinstall.dialog.progress.skin", "chrome://mozapps/content/extensions/extensions.xul"); +pref("xpinstall.dialog.progress.type.chrome", "Extension:Manager"); +pref("xpinstall.dialog.progress.type.skin", "Extension:Manager"); +pref("xpinstall.enabled", true); +#ifdef XP_WIN +pref("browser.preferences.instantApply", false); +#else +pref("browser.preferences.instantApply", true); +#endif +#ifdef XP_MACOSX +pref("browser.preferences.animateFadeIn", true); +#else +pref("browser.preferences.animateFadeIn", false); +#endif diff --git a/application/xulrunner/config/mozconfig b/application/xulrunner/config/mozconfig new file mode 100644 index 000000000..9fa972cac --- /dev/null +++ b/application/xulrunner/config/mozconfig @@ -0,0 +1,9 @@ +# 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/. + +# This file specifies the build flags for XULRunner. You can use it by adding: +# . $topsrcdir/xulrunner/config/mozconfig +# to the top of your mozconfig file. + +ac_add_options --enable-application=xulrunner diff --git a/application/xulrunner/config/mozconfigs/common b/application/xulrunner/config/mozconfigs/common new file mode 100644 index 000000000..a6811c575 --- /dev/null +++ b/application/xulrunner/config/mozconfigs/common @@ -0,0 +1,7 @@ +# 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/. + +# This file is included at the top of all xulrunner mozconfigs + +. "$topsrcdir/build/mozconfig.common" diff --git a/application/xulrunner/config/mozconfigs/common.override b/application/xulrunner/config/mozconfigs/common.override new file mode 100644 index 000000000..8d719a5b5 --- /dev/null +++ b/application/xulrunner/config/mozconfigs/common.override @@ -0,0 +1,8 @@ +# 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/. + +# This file is included at the bottom of all xulrunner mozconfigs + +. "$topsrcdir/build/mozconfig.common.override" +. "$topsrcdir/build/mozconfig.cache" diff --git a/application/xulrunner/config/mozconfigs/linux32/xulrunner b/application/xulrunner/config/mozconfigs/linux32/xulrunner new file mode 100644 index 000000000..171674f8c --- /dev/null +++ b/application/xulrunner/config/mozconfigs/linux32/xulrunner @@ -0,0 +1,9 @@ +export MOZILLA_OFFICIAL=1 +export JAVA_HOME=/tools/jdk + +ac_add_options --enable-application=xulrunner +ac_add_options --disable-tests + +. $topsrcdir/build/unix/mozconfig.linux32 + +. "$topsrcdir/xulrunner/config/mozconfigs/common.override" diff --git a/application/xulrunner/config/mozconfigs/linux32/xulrunner-qt b/application/xulrunner/config/mozconfigs/linux32/xulrunner-qt new file mode 100644 index 000000000..54e4ecb8f --- /dev/null +++ b/application/xulrunner/config/mozconfigs/linux32/xulrunner-qt @@ -0,0 +1,15 @@ +export MOZILLA_OFFICIAL=1 +export JAVA_HOME=/tools/jdk + +ac_add_options --enable-application=xulrunner +ac_add_options --disable-tests + +. $topsrcdir/build/unix/mozconfig.linux32 + +# QT Options +export PKG_CONFIG_PATH=/tools/qt-4.6.3/qt/lib/pkgconfig +ac_add_options --with-qtdir=/tools/qt-4.6.3/qt +ac_add_options --enable-default-toolkit=cairo-qt +ac_add_options --disable-crashreporter + +. "$topsrcdir/xulrunner/config/mozconfigs/common.override" diff --git a/application/xulrunner/config/mozconfigs/linux64/xulrunner b/application/xulrunner/config/mozconfigs/linux64/xulrunner new file mode 100644 index 000000000..c18a12f67 --- /dev/null +++ b/application/xulrunner/config/mozconfigs/linux64/xulrunner @@ -0,0 +1,9 @@ +export MOZILLA_OFFICIAL=1 +export JAVA_HOME=/tools/jdk + +ac_add_options --enable-application=xulrunner +ac_add_options --disable-tests + +. $topsrcdir/build/unix/mozconfig.linux + +. "$topsrcdir/xulrunner/config/mozconfigs/common.override" diff --git a/application/xulrunner/config/mozconfigs/macosx-universal/xulrunner b/application/xulrunner/config/mozconfigs/macosx-universal/xulrunner new file mode 100644 index 000000000..ac7e24fe2 --- /dev/null +++ b/application/xulrunner/config/mozconfigs/macosx-universal/xulrunner @@ -0,0 +1,9 @@ +. $topsrcdir/build/macosx/universal/mozconfig + +export MOZILLA_OFFICIAL=1 + +ac_add_options --enable-application=xulrunner +ac_add_options --disable-tests +ac_add_options --with-xulrunner-stub-name=xulrunner-stub + +. "$topsrcdir/xulrunner/config/mozconfigs/common.override" diff --git a/application/xulrunner/config/mozconfigs/win32/xulrunner b/application/xulrunner/config/mozconfigs/win32/xulrunner new file mode 100644 index 000000000..4c8b596a5 --- /dev/null +++ b/application/xulrunner/config/mozconfigs/win32/xulrunner @@ -0,0 +1,16 @@ +. "$topsrcdir/xulrunner/config/mozconfigs/common" + +export MOZILLA_OFFICIAL=1 +export JAVA_HOME=/d/jdk1.6.0_14 + +ac_add_options --enable-application=xulrunner +ac_add_options --enable-jemalloc +ac_add_options --disable-tests + +if test "$PROCESSOR_ARCHITECTURE" = "AMD64" -o "$PROCESSOR_ARCHITEW6432" = "AMD64"; then + . $topsrcdir/build/win32/mozconfig.vs2013-win64 +else + . $topsrcdir/build/win32/mozconfig.vs2010 +fi + +. "$topsrcdir/xulrunner/config/mozconfigs/common.override" diff --git a/application/xulrunner/config/mozconfigs/win64/xulrunner b/application/xulrunner/config/mozconfigs/win64/xulrunner new file mode 100644 index 000000000..7dbade2bb --- /dev/null +++ b/application/xulrunner/config/mozconfigs/win64/xulrunner @@ -0,0 +1,15 @@ +. "$topsrcdir/xulrunner/config/mozconfigs/common" + +ac_add_options --target=x86_64-pc-mingw32 +ac_add_options --host=x86_64-pc-mingw32 + +export MOZILLA_OFFICIAL=1 +export JAVA_HOME=/d/jdk1.6.0_14 + +ac_add_options --enable-application=xulrunner +ac_add_options --enable-jemalloc +ac_add_options --disable-tests + +. $topsrcdir/build/win64/mozconfig.vs2013 + +. "$topsrcdir/xulrunner/config/mozconfigs/common.override" diff --git a/application/xulrunner/configure.in b/application/xulrunner/configure.in new file mode 100644 index 000000000..825faaddd --- /dev/null +++ b/application/xulrunner/configure.in @@ -0,0 +1,11 @@ +dnl -*- Mode: Autoconf; tab-width: 2; indent-tabs-mode: nil; -*- +dnl vi: set tabstop=2 shiftwidth=2 expandtab: +dnl This Source Code Form is subject to the terms of the Mozilla Public +dnl License, v. 2.0. If a copy of the MPL was not distributed with this +dnl file, You can obtain one at http://mozilla.org/MPL/2.0/. + +dnl Things we need to carry from confvars.sh +AC_SUBST(MOZ_XULRUNNER) +AC_DEFINE(MOZ_XULRUNNER) + +dnl Optional parts of the build. diff --git a/application/xulrunner/confvars.sh b/application/xulrunner/confvars.sh new file mode 100644 index 000000000..a317df2a6 --- /dev/null +++ b/application/xulrunner/confvars.sh @@ -0,0 +1,28 @@ +#! /bin/sh +# 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/. + +MOZ_XULRUNNER=1 +MC_OFFICIAL=1 + +MOZ_APP_NAME=xulrunner +MOZ_APP_DISPLAYNAME=XULRunner +MOZ_APP_VERSION=$MOZILLA_VERSION +MOZ_CHROME_FILE_FORMAT=omni + +MOZ_UPDATER=1 + +if test "$OS_ARCH" = "WINNT"; then + MOZ_MAINTENANCE_SERVICE= +fi + +MOZ_PLACES=1 +MOZ_WEBRTC=1 +MOZ_WEBGL_CONFORMANT=1 + +MOZ_EXTENSIONS_DEFAULT=" gio" + +MOZ_SERVICES_COMMON=1 +MOZ_SERVICES_SYNC=1 +MOZ_SERVICES_HEALTHREPORT= diff --git a/application/xulrunner/examples/moz.build b/application/xulrunner/examples/moz.build new file mode 100644 index 000000000..a1782b42f --- /dev/null +++ b/application/xulrunner/examples/moz.build @@ -0,0 +1,7 @@ +# -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*- +# vim: set filetype=python: +# 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/. + +DIRS += ['simple'] diff --git a/application/xulrunner/examples/simple/application.ini b/application/xulrunner/examples/simple/application.ini new file mode 100644 index 000000000..39c051422 --- /dev/null +++ b/application/xulrunner/examples/simple/application.ini @@ -0,0 +1,43 @@ +#filter substitution +[App] +; +; This field specifies your organization's name. This field is recommended, +; but optional. +Vendor=MozillaTest +; +; This field specifies your application's name. This field is required. +Name=Simple +; +; This field specifies your application's version. This field is required. +Version=0.1 +; +; This field specifies your application's build ID (timestamp). This field is +; required. +BuildID=20070625 +; +; This field specifies a compact copyright notice for your application. This +; field is optional. +Copyright=Copyright (c) 2004 Mozilla.org +; +; This ID is just an example. Every XUL app ought to have it's own unique ID. +; You can use the microsoft "guidgen" or "uuidgen" tools, or go on +; irc.mozilla.org and /msg botbot uuid. This field is optional. +ID={3aea3f07-ffe3-4060-bb03-bff3a5365e90} + +[Gecko] +; +; This field is required. It specifies the minimum Gecko version that this +; application requires. +MinVersion=@MOZILLA_VERSION_U@ +; +; This field is optional. It specifies the maximum Gecko version that this +; application requires. It should be specified if your application uses +; unfrozen interfaces. +MaxVersion=@MOZILLA_VERSION_U@ + +[Shell] +; +; This field specifies the location of your application's main icon with file +; extension excluded. NOTE: Unix style file separators are required. This +; field is optional. +Icon=chrome/icons/default/simple diff --git a/application/xulrunner/examples/simple/components/moz.build b/application/xulrunner/examples/simple/components/moz.build new file mode 100644 index 000000000..8ff468534 --- /dev/null +++ b/application/xulrunner/examples/simple/components/moz.build @@ -0,0 +1,7 @@ +# -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*- +# vim: set filetype=python: +# 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/. + +DIRS += ['public', 'src'] diff --git a/application/xulrunner/examples/simple/components/public/moz.build b/application/xulrunner/examples/simple/components/public/moz.build new file mode 100644 index 000000000..3a611f85a --- /dev/null +++ b/application/xulrunner/examples/simple/components/public/moz.build @@ -0,0 +1,13 @@ +# -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*- +# vim: set filetype=python: +# 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/. + +XPIDL_SOURCES += [ + 'nsISimpleTest.idl', +] + +XPIDL_MODULE = 'simple' + +XPI_NAME = 'simple' diff --git a/application/xulrunner/examples/simple/components/public/nsISimpleTest.idl b/application/xulrunner/examples/simple/components/public/nsISimpleTest.idl new file mode 100644 index 000000000..99b9b86af --- /dev/null +++ b/application/xulrunner/examples/simple/components/public/nsISimpleTest.idl @@ -0,0 +1,15 @@ +/* vim:set ts=2 sw=2 sts=2 et cin: */ +/* 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/. */ + +#include "nsISupports.idl" + +[scriptable, uuid(f2f71d91-0451-47ec-aaa0-166663a7711a)] +interface nsISimpleTest : nsISupports +{ + /** + * This interface adds two numbers together and returns the result. + */ + long add(in long a, in long b); +}; diff --git a/application/xulrunner/examples/simple/components/src/SimpleTest.cpp b/application/xulrunner/examples/simple/components/src/SimpleTest.cpp new file mode 100644 index 000000000..06249abdd --- /dev/null +++ b/application/xulrunner/examples/simple/components/src/SimpleTest.cpp @@ -0,0 +1,54 @@ +/* vim:set ts=2 sw=2 sts=2 et cin: */ +/* 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/. */ + +#include <stdio.h> +#include "nsISimpleTest.h" +#include "mozilla/ModuleUtils.h" + +class SimpleTest : public nsISimpleTest +{ + ~SimpleTest() {} +public: + NS_DECL_ISUPPORTS + NS_DECL_NSISIMPLETEST +}; + +NS_IMPL_ISUPPORTS(SimpleTest, nsISimpleTest) + +NS_IMETHODIMP +SimpleTest::Add(int32_t a, int32_t b, int32_t *r) +{ + printf("add(%d,%d) from C++\n", a, b); + + *r = a + b; + return NS_OK; +} + +NS_GENERIC_FACTORY_CONSTRUCTOR(SimpleTest) + +// 5e14b432-37b6-4377-923b-c987418d8429 +#define SIMPLETEST_CID \ + { 0x5e14b432, 0x37b6, 0x4377, \ + { 0x92, 0x3b, 0xc9, 0x87, 0x41, 0x8d, 0x84, 0x29 } } + +NS_DEFINE_NAMED_CID(SIMPLETEST_CID); + +static const mozilla::Module::CIDEntry kSimpleCIDs[] = { + { &kSIMPLETEST_CID, false, nullptr, SimpleTestConstructor }, + { nullptr } +}; + +static const mozilla::Module::ContractIDEntry kSimpleContracts[] = { + { "@test.mozilla.org/simple-test;1?impl=c++", &kSIMPLETEST_CID }, + { nullptr } +}; + +static const mozilla::Module kSimpleModule = { + mozilla::Module::kVersion, + kSimpleCIDs, + kSimpleContracts +}; + +NSMODULE_DEFN(SimpleTestModule) = &kSimpleModule; diff --git a/application/xulrunner/examples/simple/components/src/SimpleTest.js b/application/xulrunner/examples/simple/components/src/SimpleTest.js new file mode 100644 index 000000000..e6cf90660 --- /dev/null +++ b/application/xulrunner/examples/simple/components/src/SimpleTest.js @@ -0,0 +1,27 @@ +/* vim:set ts=2 sw=2 sts=2 et cin: */ +/* 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/. */ + +Components.utils.import("resource://gre/modules/XPCOMUtils.jsm"); + +function SimpleTest() { +} + +SimpleTest.prototype = { + classID: Components.ID("{4177e257-a0dc-49b9-a774-522a000a49fa}"), + + QueryInterface: function(iid) { + if (iid.equals(Components.interfaces.nsISimpleTest) || + iid.equals(Components.interfaces.nsISupports)) + return this; + throw Components.results.NS_ERROR_NO_INTERFACE; + }, + + add: function(a, b) { + dump("add(" + a + "," + b + ") from JS\n"); + return a + b; + } +}; + +this.NSGetFactory = XPCOMUtils.generateNSGetFactory([SimpleTest]); diff --git a/application/xulrunner/examples/simple/components/src/SimpleTest.manifest b/application/xulrunner/examples/simple/components/src/SimpleTest.manifest new file mode 100644 index 000000000..c7388b9d7 --- /dev/null +++ b/application/xulrunner/examples/simple/components/src/SimpleTest.manifest @@ -0,0 +1,2 @@ +component {4177e257-a0dc-49b9-a774-522a000a49fa} SimpleTest.js +contract @test.mozilla.org/simple-test;1?impl=js {4177e257-a0dc-49b9-a774-522a000a49fa} diff --git a/application/xulrunner/examples/simple/components/src/moz.build b/application/xulrunner/examples/simple/components/src/moz.build new file mode 100644 index 000000000..153bfdd0c --- /dev/null +++ b/application/xulrunner/examples/simple/components/src/moz.build @@ -0,0 +1,21 @@ +# -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*- +# vim: set filetype=python: +# 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/. + +SOURCES += [ + 'SimpleTest.cpp', +] + +XPCOMBinaryComponent('simpletest') + +EXTRA_COMPONENTS += [ + 'SimpleTest.js', + 'SimpleTest.manifest', +] + +XPI_NAME = 'simple' + +if CONFIG['GNU_CXX']: + CXXFLAGS += ['-Wshadow'] diff --git a/application/xulrunner/examples/simple/content/contents.rdf b/application/xulrunner/examples/simple/content/contents.rdf new file mode 100644 index 000000000..e69de29bb --- /dev/null +++ b/application/xulrunner/examples/simple/content/contents.rdf diff --git a/application/xulrunner/examples/simple/content/simple.js b/application/xulrunner/examples/simple/content/simple.js new file mode 100644 index 000000000..acf6f1029 --- /dev/null +++ b/application/xulrunner/examples/simple/content/simple.js @@ -0,0 +1,17 @@ +/* vim:set ts=2 sw=2 sts=2 et cin: */ +/* 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/. */ + +function onButtonClick() { + var textbox = document.getElementById("textbox"); + + var contractid = (textbox.value % 2 == 0) ? + "@test.mozilla.org/simple-test;1?impl=js" : + "@test.mozilla.org/simple-test;1?impl=c++"; + + var test = Components.classes[contractid]. + createInstance(Components.interfaces.nsISimpleTest); + + textbox.value = test.add(textbox.value, 1); +} diff --git a/application/xulrunner/examples/simple/content/simple.xul b/application/xulrunner/examples/simple/content/simple.xul new file mode 100644 index 000000000..6ff915d0c --- /dev/null +++ b/application/xulrunner/examples/simple/content/simple.xul @@ -0,0 +1,20 @@ +<?xml version="1.0"?> +# vim:set ts=8 sw=8 sts=8 noet: +# 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/. + +<?xml-stylesheet href="chrome://global/skin/" type="text/css"?> + +<!DOCTYPE window SYSTEM "chrome://simple/locale/simple.dtd"> + +<window + id = "simple" + title = "&simple.title;" + xmlns = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"> + <script src="chrome://simple/content/simple.js"/> + <vbox> + <textbox id="textbox" value="&simple.textValue;" flex="1"/> + <button id="button" label="&simple.buttonLabel;" oncommand="onButtonClick();"/> + </vbox> +</window> diff --git a/application/xulrunner/examples/simple/icons/simple.ico b/application/xulrunner/examples/simple/icons/simple.ico Binary files differnew file mode 100644 index 000000000..16bd7e9d1 --- /dev/null +++ b/application/xulrunner/examples/simple/icons/simple.ico diff --git a/application/xulrunner/examples/simple/jar.mn b/application/xulrunner/examples/simple/jar.mn new file mode 100644 index 000000000..7d141ad1d --- /dev/null +++ b/application/xulrunner/examples/simple/jar.mn @@ -0,0 +1,12 @@ +# 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/. + +simple.jar: +% content simple %content/ + content/simple.xul (content/simple.xul) + content/simple.js (content/simple.js) + +en-US.jar: +% locale simple en-US %locale/en-US/ + locale/en-US/simple.dtd (locale/simple.dtd) diff --git a/application/xulrunner/examples/simple/locale/simple.dtd b/application/xulrunner/examples/simple/locale/simple.dtd new file mode 100644 index 000000000..2fd1c9285 --- /dev/null +++ b/application/xulrunner/examples/simple/locale/simple.dtd @@ -0,0 +1,7 @@ +<!-- 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/. --> + +<!ENTITY simple.title "Simple App"> +<!ENTITY simple.textValue "0"> +<!ENTITY simple.buttonLabel "Increment"> diff --git a/application/xulrunner/examples/simple/moz.build b/application/xulrunner/examples/simple/moz.build new file mode 100644 index 000000000..c88c57a4b --- /dev/null +++ b/application/xulrunner/examples/simple/moz.build @@ -0,0 +1,22 @@ +# -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*- +# vim: set filetype=python: +# 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/. + +DIRS += ['components'] + +XPI_NAME = 'simple' + +JAR_MANIFESTS += ['jar.mn'] + +JS_PREFERENCE_FILES += [ + 'simple-prefs.js', +] + +FINAL_TARGET_PP_FILES += [ + 'application.ini', +] + +if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'windows': + FINAL_TARGET_FILES.chrome.icons.default += ['icons/simple.ico'] diff --git a/application/xulrunner/examples/simple/simple-prefs.js b/application/xulrunner/examples/simple/simple-prefs.js new file mode 100644 index 000000000..fc92e0df5 --- /dev/null +++ b/application/xulrunner/examples/simple/simple-prefs.js @@ -0,0 +1,6 @@ +/* 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/. */ + +pref("toolkit.defaultChromeURI", "chrome://simple/content/simple.xul"); +pref("general.useragent.extra.simple", "SimpleApp/0.1"); diff --git a/application/xulrunner/installer/Makefile.in b/application/xulrunner/installer/Makefile.in new file mode 100644 index 000000000..04803dddb --- /dev/null +++ b/application/xulrunner/installer/Makefile.in @@ -0,0 +1,148 @@ +# 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/. + +STANDALONE_MAKEFILE := 1 + +NO_PKG_FILES = \ + xulrunner-config \ + regchrome* \ + regxpcom* \ + $(NULL) + +# We want xpcshell, run-mozilla and install_app.py in the SDK but not in the binary package. +ifndef STAGE_SDK +NO_PKG_FILES += \ + xpcshell* \ + run-mozilla* \ + install_app.py \ + $(NULL) +endif + +# If we're on mac, we don't want an end-user-facing DMG, we want a .tar.bz2 +# which developers then use to package their application. + +ifeq (cocoa,$(MOZ_WIDGET_TOOLKIT)) +MOZ_PKG_FORMAT = BZ2 +_APPNAME = XUL.framework +_BINPATH = /$(_APPNAME)/Versions/Current +_RESPATH := $(_BINPATH) +endif + +include $(topsrcdir)/config/rules.mk + +INSTALL_SDK = 1 + +include $(topsrcdir)/toolkit/mozapps/installer/signing.mk +include $(topsrcdir)/toolkit/mozapps/installer/packager.mk + +# Add pkg-config files to the install:: target + +pkg_config_files = \ + libxul.pc \ + libxul-embedding.pc \ + mozilla-js.pc \ + mozilla-plugin.pc \ + $(NULL) + +ifdef MOZ_NATIVE_NSPR +NSPR_NAME=nspr +NSPR_VERSION=$(shell $(NSPR_CONFIG) --version) +else +pkg_config_files += mozilla-nspr.pc +NSPR_NAME=mozilla-nspr +FULL_NSPR_CFLAGS=-I\$${includedir} +FULL_NSPR_LIBS=$(subst $(prefix),\$${sdkdir},$(shell $(DEPTH)/nsprpub/config/nspr-config --libs)) +NSPR_VERSION=$(shell $(DEPTH)/nsprpub/config/nspr-config --version) +endif + +MOZ_XUL_LINK = -lxpcomglue_s -lxul +ifdef JS_SHARED_LIBRARY +MOZ_JS_LINK = -lmozjs +else +MOZ_JS_LINK = $(MOZ_XUL_LINK) +endif + +$(warning FULL_NSPR_CFLAGS=$(FULL_NSPR_CFLAGS)) + +ifndef MOZ_NATIVE_NSS +pkg_config_files += mozilla-nss.pc +endif + +%.pc: $(srcdir)/%.pc.in $(GLOBAL_DEPS) + cat $< | sed \ + -e "s|%prefix%|$(prefix)|" \ + -e "s|%includedir%|$(includedir)|" \ + -e "s|%idldir%|$(idldir)|" \ + -e "s|%sdkdir%|$(sdkdir)|" \ + -e "s|%MOZ_APP_NAME%|$(MOZ_APP_NAME)|" \ + -e "s|%MOZILLA_VERSION%|$(MOZ_APP_VERSION)|" \ + -e "s|%WCHAR_CFLAGS%|$(WCHAR_CFLAGS)|" \ + -e "s|%FULL_NSPR_LIBS%|$(FULL_NSPR_LIBS)|" \ + -e "s|%FULL_NSPR_CFLAGS%|$(FULL_NSPR_CFLAGS)|" \ + -e "s|%NSPR_NAME%|$(NSPR_NAME)|" \ + -e "s|%NSPR_VERSION%|$(NSPR_VERSION)|" \ + -e "s|%MOZ_XUL_LINK%|$(MOZ_XUL_LINK)|" \ + -e "s|%MOZ_JS_LINK%|$(MOZ_JS_LINK)|" > $@ + chmod 644 $@ + +install:: $(pkg_config_files) + @echo pkg_config_file: $(pkg_config_files) + $(SYSINSTALL) $(IFLAGS1) $^ $(DESTDIR)$(libdir)/pkgconfig + +GARBAGE += $(pkg_config_files) + +GARBAGE += debian/changelog + +DEBDESTDIR=debian/$(MOZ_BUILD_APP) + +GRE_BUILDID = $(shell $(PYTHON) $(topsrcdir)/config/printconfigsetting.py $(DIST)/bin/platform.ini Build BuildID) +MOZ_DEB_TIMESTAMP = "$(shell date +"%a, %d %b %Y %T %z" )" + +DEFINES += \ + -DGRE_MILESTONE=$(GRE_MILESTONE) \ + -DGRE_BUILDID=$(GRE_BUILDID) \ + -DMOZ_DEB_TIMESTAMP=$(MOZ_DEB_TIMESTAMP) \ + -DMOZ_APP_NAME=$(MOZ_APP_NAME) \ + -Dinstalldir=$(installdir) \ + $(NULL) + +ifeq ($(OS_TARGET),Linux) +debian/changelog: $(srcdir)/debian/changelog.in $(DIST)/bin/platform.ini + $(call py_action,preprocessor, \ + $(AUTOMATION_PPARGS) $(DEFINES) $(ACDEFINES) $^ -o $@) + +debian/xulrunner.links: $(srcdir)/debian/xulrunner.links.in + $(call py_action,preprocessor, \ + $(AUTOMATION_PPARGS) $(DEFINES) $(ACDEFINES) $^ -o $@) + +debian/xulrunner.service: $(srcdir)/debian/xulrunner.service.in + $(call py_action,preprocessor, \ + $(AUTOMATION_PPARGS) $(DEFINES) $(ACDEFINES) $^ -o $@) + +debian/prerm: $(srcdir)/debian/prerm.in + $(call py_action,preprocessor, \ + $(AUTOMATION_PPARGS) $(DEFINES) $(ACDEFINES) $^ -o $@) + +debian/postinst: $(srcdir)/debian/postinst.in + $(call py_action,preprocessor, \ + $(AUTOMATION_PPARGS) $(DEFINES) $(ACDEFINES) $^ -o $@) + +package: + $(MAKE) package -C $(DEPTH) + +deb: package debian/changelog debian/xulrunner.service debian/xulrunner.links + $(NSINSTALL) $(topsrcdir)/$(MOZ_BUILD_APP)/installer/debian . + rm -fr $(DEBDESTDIR) + $(NSINSTALL) -D $(DEBDESTDIR)/$(installdir) + cp -pRL $(DEPTH)/dist/$(MOZ_BUILD_APP)/* $(DEBDESTDIR)/$(installdir) + $(NSINSTALL) -D $(DEBDESTDIR)/usr/share/dbus-1/services/ + cp debian/$(MOZ_BUILD_APP).service $(DEBDESTDIR)/usr/share/dbus-1/services/org.mozilla.$(MOZ_BUILD_APP).service + dh_link; fakeroot dh_fixperms; fakeroot dh_installdeb; fakeroot dh_shlibdeps; fakeroot dh_gencontrol; fakeroot dh_md5sums; fakeroot dh_builddeb; +endif + +DEB_BUILD_ARCH = $(shell dpkg-architecture -qDEB_BUILD_ARCH) +# package name comes from xulrunner/installer/debian/changelog.in +DEB_PKG_NAME = $(MOZ_PKG_APPNAME)_$(GRE_MILESTONE)-$(GRE_BUILDID)_$(DEB_BUILD_ARCH).deb +# relative to $(DIST) +UPLOAD_EXTRA_FILES += ../xulrunner/$(DEB_PKG_NAME) diff --git a/application/xulrunner/installer/debian/changelog.in b/application/xulrunner/installer/debian/changelog.in new file mode 100644 index 000000000..1efd55a1d --- /dev/null +++ b/application/xulrunner/installer/debian/changelog.in @@ -0,0 +1,7 @@ +# if the naming changes please modify DEB_PKG_NAME in xulrunner/installer/Makefile.in as well +#filter substitution +xulrunner (@GRE_MILESTONE@-@GRE_BUILDID@) unstable; urgency=low + + * Mozilla Nightly (Closes: #nnnn) <nnnn is the bug number of your ITP> + + -- Mozilla Runtime <mobile-feedback@mozilla.com> @MOZ_DEB_TIMESTAMP@ diff --git a/application/xulrunner/installer/debian/compat b/application/xulrunner/installer/debian/compat new file mode 100644 index 000000000..b8626c4cf --- /dev/null +++ b/application/xulrunner/installer/debian/compat @@ -0,0 +1 @@ +4 diff --git a/application/xulrunner/installer/debian/control b/application/xulrunner/installer/debian/control new file mode 100644 index 000000000..da99aa8d4 --- /dev/null +++ b/application/xulrunner/installer/debian/control @@ -0,0 +1,48 @@ +Source: xulrunner +Section: user/network +Priority: extra +Maintainer: Mobile Feedback <mobile-feedback@mozilla.com> +Build-Depends: debhelper (>= 5) +Standards-Version: 3.7.2 + +Package: xulrunner +Architecture: any +Depends: ${shlibs:Depends} +Description: Web and JavaScript engine used by the Firefox Web browser + The Mozilla runtime is the modern browser engine, also known as "Gecko," that powers Firefox and can be embedded by other applications +XB-Maemo-Display-Name: Mozilla Runtime +XB-Maemo-Icon-26: + MB5!.1PT*&@H````-24A$4@```!H````:"`8```"I2DS.````"7!(67,```L3 + M```+$P$`FIP8```%;$E$051(B:667XQ4U1W'/_>>>V?NG=F9V3^S_W%9<'#! + M/Q1;NQ:EQH@:T2"EH>&A34R;]$U?Q%9-VH:41BUJFV"-B<8'^Z!-VP=E?37& + M5=18L"SACVMVH<M.9W>8V9G9N7-G[O_3AP6$LD"$;W*3<T_R^W[.]Y=S3@Z< + ME90H_)\DE\Y=J]3SHW_\1)6O#FV2NVD'D*\,W<T;JWK.0W>3OA[012N68]LW + MD1W^!8?W_XGANQ^C5?V$(V/_8L.VGU.:.JG\\M@[UPK2SD/V#=U,K=QDW;TF + M#S_[&HZC4,^O9_T6'84VWO[PI]>32/MFV.URZ^;G273UT7^7`3&)#%*!TM"U + MS]ZHTC?\B/SUD7\J>\E?,TC^'4%LA4?DS\O^V]<H<L!I.6`:,5S[:#B^T)?1 + M\MJZ>]YF8:GLB3@/WIQ!,U1F9AH<V]VX&DB1N]'HS6WFN]L>8>"V`6(=O;)S + M8]O<?"!E%/+ZFZ_R_'-[U;4CZTX6NA_8;VZX_X>IWO3W4\,]W;II4CE3MZJS + M9R9JIPICSOBQ,4Z_4+U<HH@H?H"W7CY`@,&NEUY1>M;?GFBC^=2NWR-434HU + M;OY@\]:'8OTW;3]N&@RM74ER1195Z!0S1E^QS5B3CZL[BHJ<L$_L^1T'?[O_ + MDD07_LCQQW]$;M-3M&JEL8EJ[M$?/QN"2*OI[-"JW(AX[&<[J:174NK(D<T- + M(F*"N>EYBJ<7*)VI4%EHL'!ZWG7R\[_AT)Z7+O06YR%_&>PBU;V#RLE]%/]S + M5/A6YK7WIP+1WCLJA"Z:C44*E1H=]SZ*TMF-D=31@?J9&E:Q@EVW<2IUM$Q" + M\U8/W1>MW9)GXMW#Y_R_.;!6(^+SO[VH;/[K%XN'QJ>/C7VR+]CVAY1^XRVJ + M%A?(9`IO=`MS'8-XAH[M!5B-%JUZ`]_U20UT0;-%Z_@I8J&OJ<.]S['QF=RR + MK;M(]^S=R<8-[PA148S\89*WW$GVUN^1T049324I)-;D?VG,E:F7+%+?N9'% + M:I7J=!&W+TLSE<;Y^."?>>^))R].=+%4#+&3,%1"LX?6Z`[\U`W87\]0*Y2H + MN1YU)\0UX]A^2*0+HJ2!.;*2MM4K$%T91,M%B2>VPM;LN5VWC+9T0>P.K!;, + M%8AL"RN10$G$"7K:(1G#C1N8G2F2=XP02/!5B=-R\<(63!>1PH!(K"*W)L<4 + MY>5!;4X/]<5V)AM0KX(J"!(F]722T/.(!KHQLYTT58FN0A!&1&Z(W_+P\B6\ + M`U_BZW%D6U805FX`/E\>%/D&MB/(SX,:@6&"ZQ`T&MC51?SV#*X21Q,0DZ`& + M+J$?X9>K^">F""HE@DH-?!>D;5R^=:%E4;-<'#N!],#WH!D#31`,KB!038)\ + M$5W5<%4)00"A@CST;[P3D_BVA73J$'J`6[\\R)THXVS,T[ZJ`]\#Q8;:/&@Z + M%(`C<;QL%X$O(!T#1<!"!8X>)5I<`,^&R`.$!<Q<83-0I5[X"*7S-M(IJ!6@ + M50-A@&-#N0"#JXFZ^J&B@YF&\@($$AP+\``)A!,P>Q(NN!DN;9_2Q._8CB\, + M(@]:<Q#Y$#H0^-!8A,(T%&?`5T#)0*B"-7T6I$CP_PBS!ZX,HEP@3/3C)D:) + MXA"5(*Q!%"Y]01-D"%*'P`17!3L`KP'2!J(/8'8/>,VK@(A@]CBH:PGM'+)\ + M=EH#G*55JQF(C8"O@]T`IP&1!()).+4+ZE^=,[L2"&`1YKZ$L!=J-X&B0AIH + M`C;(&O@.!&6(3H.<!N8_A9E?06W\*M[+:A!23T/J('2UH$TNG2!#0DI".H#, + M)&1>!-8M9_!MWFTQB*V&Q"AX(V`,@-3`*X*<`O\@^">6HEX?Z$*90/QLO<]2 + :+Z,K%?P/&D=O=_6]@+\`````245.1*Y"8((` + ` diff --git a/application/xulrunner/installer/debian/icon_base64 b/application/xulrunner/installer/debian/icon_base64 new file mode 100644 index 000000000..124fb4ccc --- /dev/null +++ b/application/xulrunner/installer/debian/icon_base64 @@ -0,0 +1,36 @@ +begin 644 -m +MB5!.1PT*&@H````-24A$4@```!H````:"`8```"I2DS.````"7!(67,```L3 +M```+$P$`FIP8```%;$E$051(B:667XQ4U1W'/_>>>V?NG=F9V3^S_W%9<'#! +M/Q1;NQ:EQH@:T2"EH>&A34R;]$U?Q%9-VH:41BUJFV"-B<8'^Z!-VP=E?37& +M5=18L"SACVMVH<M.9W>8V9G9N7-G[O_3AP6$LD"$;W*3<T_R^W[.]Y=S3@Z< +ME90H_)\DE\Y=J]3SHW_\1)6O#FV2NVD'D*\,W<T;JWK.0W>3OA[012N68]LW +MD1W^!8?W_XGANQ^C5?V$(V/_8L.VGU.:.JG\\M@[UPK2SD/V#=U,K=QDW;TF +M#S_[&HZC4,^O9_T6'84VWO[PI]>32/MFV.URZ^;G273UT7^7`3&)#%*!TM"U +MS]ZHTC?\B/SUD7\J>\E?,TC^'4%LA4?DS\O^V]<H<L!I.6`:,5S[:#B^T)?1 +M\MJZ>]YF8:GLB3@/WIQ!,U1F9AH<V]VX&DB1N]'HS6WFN]L>8>"V`6(=O;)S +M8]O<?"!E%/+ZFZ_R_'-[U;4CZTX6NA_8;VZX_X>IWO3W4\,]W;II4CE3MZJS +M9R9JIPICSOBQ,4Z_4+U<HH@H?H"W7CY`@,&NEUY1>M;?GFBC^=2NWR-434HU +M;OY@\]:'8OTW;3]N&@RM74ER1195Z!0S1E^QS5B3CZL[BHJ<L$_L^1T'?[O_ +MDD07_LCQQW]$;M-3M&JEL8EJ[M$?/QN"2*OI[-"JW(AX[&<[J:174NK(D<T- +M(F*"N>EYBJ<7*)VI4%EHL'!ZWG7R\[_AT)Z7+O06YR%_&>PBU;V#RLE]%/]S +M5/A6YK7WIP+1WCLJA"Z:C44*E1H=]SZ*TMF-D=31@?J9&E:Q@EVW<2IUM$Q" +M\U8/W1>MW9)GXMW#Y_R_.;!6(^+SO[VH;/[K%XN'QJ>/C7VR+]CVAY1^XRVJ +M%A?(9`IO=`MS'8-XAH[M!5B-%JUZ`]_U20UT0;-%Z_@I8J&OJ<.]S['QF=RR +MK;M(]^S=R<8-[PA148S\89*WW$GVUN^1T049324I)-;D?VG,E:F7+%+?N9'% +M:I7J=!&W+TLSE<;Y^."?>>^))R].=+%4#+&3,%1"LX?6Z`[\U`W87\]0*Y2H +MN1YU)\0UX]A^2*0+HJ2!.;*2MM4K$%T91,M%B2>VPM;LN5VWC+9T0>P.K!;, +M%8AL"RN10$G$"7K:(1G#C1N8G2F2=XP02/!5B=-R\<(63!>1PH!(K"*W)L<4 +MY>5!;4X/]<5V)AM0KX(J"!(F]722T/.(!KHQLYTT58FN0A!&1&Z(W_+P\B6\ +M`U_BZW%D6U805FX`/E\>%/D&MB/(SX,:@6&"ZQ`T&MC51?SV#*X21Q,0DZ`& +M+J$?X9>K^">F""HE@DH-?!>D;5R^=:%E4;-<'#N!],#WH!D#31`,KB!038)\ +M$5W5<%4)00"A@CST;[P3D_BVA73J$'J`6[\\R)THXVS,T[ZJ`]\#Q8;:/&@Z +M%(`C<;QL%X$O(!T#1<!"!8X>)5I<`,^&R`.$!<Q<83-0I5[X"*7S-M(IJ!6@ +M50-A@&-#N0"#JXFZ^J&B@YF&\@($$AP+\``)A!,P>Q(NN!DN;9_2Q._8CB\, +M(@]:<Q#Y$#H0^-!8A,(T%&?`5T#)0*B"-7T6I$CP_PBS!ZX,HEP@3/3C)D:) +MXA"5(*Q!%"Y]01-D"%*'P`17!3L`KP'2!J(/8'8/>,VK@(A@]CBH:PGM'+)\ +M=EH#G*55JQF(C8"O@]T`IP&1!()).+4+ZE^=,[L2"&`1YKZ$L!=J-X&B0AIH +M`C;(&O@.!&6(3H.<!N8_A9E?06W\*M[+:A!23T/J('2UH$TNG2!#0DI".H#, +M)&1>!-8M9_!MWFTQB*V&Q"AX(V`,@-3`*X*<`O\@^">6HEX?Z$*90/QLO<]2 +:+Z,K%?P/&D=O=_6]@+\`````245.1*Y"8((` +` +end diff --git a/application/xulrunner/installer/debian/menu b/application/xulrunner/installer/debian/menu new file mode 100644 index 000000000..e1ce52201 --- /dev/null +++ b/application/xulrunner/installer/debian/menu @@ -0,0 +1,2 @@ +?package(xulrunner):needs="X11|text|vc|wm" section="Apps/Internet"\ + title="xulrunner" command="/usr/bin/xulrunner" diff --git a/application/xulrunner/installer/debian/postinst.in b/application/xulrunner/installer/debian/postinst.in new file mode 100644 index 000000000..0f06640e2 --- /dev/null +++ b/application/xulrunner/installer/debian/postinst.in @@ -0,0 +1,42 @@ +#literal #! /bin/sh +#filter substitution +# postinst script for moz +# +# see: dh_installdeb(1) + +set -e + +# summary of how this script can be called: +# * <postinst> `configure' <most-recently-configured-version> +# * <old-postinst> `abort-upgrade' <new version> +# * <conflictor's-postinst> `abort-remove' `in-favour' <package> +# <new-version> +# * <postinst> `abort-remove' +# * <deconfigured's-postinst> `abort-deconfigure' `in-favour' +# <failed-install-package> <version> `removing' +# <conflicting-package> <version> +# for details, see http://www.debian.org/doc/debian-policy/ or +# the debian-policy package + + +case "$1" in + configure) + ;; + + abort-upgrade|abort-remove|abort-deconfigure) + ;; + + *) + echo "postinst called with unknown argument \`$1'" >&2 + exit 1 + ;; +esac + +#ifdef MOZ_WIDGET_GTK +gtk-update-icon-cache /usr/share/icons/hicolor +#endif + + +exit 0 + + diff --git a/application/xulrunner/installer/debian/prerm.in b/application/xulrunner/installer/debian/prerm.in new file mode 100644 index 000000000..1d46d382c --- /dev/null +++ b/application/xulrunner/installer/debian/prerm.in @@ -0,0 +1,29 @@ +#literal #! /bin/sh +#filter substitution +# prerm script for moz +# +# see: dh_installdeb(1) + +set -e + +case "$1" in + remove|upgrade|deconfigure) + ;; + + failed-upgrade) + ;; + + *) + echo "postinst called with unknown argument \`$1'" >&2 + exit 1 + ;; +esac + +#ifdef MOZ_WIDGET_GTK +gtk-update-icon-cache /usr/share/icons/hicolor +#endif + + +exit 0 + + diff --git a/application/xulrunner/installer/debian/xulrunner.links.in b/application/xulrunner/installer/debian/xulrunner.links.in new file mode 100644 index 000000000..eabac6f51 --- /dev/null +++ b/application/xulrunner/installer/debian/xulrunner.links.in @@ -0,0 +1,2 @@ +#filter substitution +@installdir@/xulrunner /usr/bin/xulrunner diff --git a/application/xulrunner/installer/debian/xulrunner.service.in b/application/xulrunner/installer/debian/xulrunner.service.in new file mode 100644 index 000000000..48d87a1b9 --- /dev/null +++ b/application/xulrunner/installer/debian/xulrunner.service.in @@ -0,0 +1,4 @@ +#filter substitution +[D-BUS Service] +Name=org.mozilla.@MOZ_APP_NAME@ +Exec=@installdir@/xulrunner diff --git a/application/xulrunner/installer/libxul-embedding.pc.in b/application/xulrunner/installer/libxul-embedding.pc.in new file mode 100644 index 000000000..100e0a763 --- /dev/null +++ b/application/xulrunner/installer/libxul-embedding.pc.in @@ -0,0 +1,10 @@ +prefix=%prefix% +sdkdir=%sdkdir% +includedir=%includedir% +idldir=%idldir% + +Name: libxul-embedding +Description: Static library for version-independent embedding of the Mozilla runtime +Version: %MOZILLA_VERSION% +Libs: -L${sdkdir}/lib -lxpcomglue -ldl +Cflags: -DXPCOM_GLUE -I${includedir} %WCHAR_CFLAGS% diff --git a/application/xulrunner/installer/libxul.pc.in b/application/xulrunner/installer/libxul.pc.in new file mode 100644 index 000000000..ccce9aa59 --- /dev/null +++ b/application/xulrunner/installer/libxul.pc.in @@ -0,0 +1,11 @@ +prefix=%prefix% +sdkdir=%sdkdir% +includedir=%includedir% +idldir=%idldir% + +Name: libxul +Description: The Mozilla Runtime and Embedding Engine +Version: %MOZILLA_VERSION% +Requires: %NSPR_NAME% >= %NSPR_VERSION% +Libs: -L${sdkdir}/lib %MOZ_XUL_LINK% +Cflags: -I${includedir} %WCHAR_CFLAGS% diff --git a/application/xulrunner/installer/moz.build b/application/xulrunner/installer/moz.build new file mode 100644 index 000000000..895d11993 --- /dev/null +++ b/application/xulrunner/installer/moz.build @@ -0,0 +1,6 @@ +# -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*- +# vim: set filetype=python: +# 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/. + diff --git a/application/xulrunner/installer/mozilla-js.pc.in b/application/xulrunner/installer/mozilla-js.pc.in new file mode 100644 index 000000000..55e84ca00 --- /dev/null +++ b/application/xulrunner/installer/mozilla-js.pc.in @@ -0,0 +1,10 @@ +prefix=%prefix% +sdkdir=%sdkdir% +includedir=%includedir% + +Name: JavaScript +Description: The Mozilla JavaScript Library +Version: %MOZILLA_VERSION% +Requires: %NSPR_NAME% >= %NSPR_VERSION% +Libs: -L${sdkdir}/lib %MOZ_JS_LINK% +Cflags: -I${includedir} -DXP_UNIX diff --git a/application/xulrunner/installer/mozilla-nspr.pc.in b/application/xulrunner/installer/mozilla-nspr.pc.in new file mode 100644 index 000000000..7ebd3421c --- /dev/null +++ b/application/xulrunner/installer/mozilla-nspr.pc.in @@ -0,0 +1,11 @@ +prefix=%prefix% +sdkdir=%sdkdir% +includedir=%includedir%/nspr + +Name: NSPR +Description: The Netscape Portable Runtime +Version: %NSPR_VERSION% +Libs: %FULL_NSPR_LIBS% +Cflags: %FULL_NSPR_CFLAGS% + + diff --git a/application/xulrunner/installer/mozilla-nss.pc.in b/application/xulrunner/installer/mozilla-nss.pc.in new file mode 100644 index 000000000..90f14c3ae --- /dev/null +++ b/application/xulrunner/installer/mozilla-nss.pc.in @@ -0,0 +1,10 @@ +prefix=%prefix% +sdkdir=%sdkdir% +includedir=%includedir%/nss + +Name: NSS +Description: Mozilla Network Security Services +Version: %MOZILLA_VERSION% +Requires: %NSPR_NAME% >= %NSPR_VERSION% +Libs: -L${sdkdir}/lib -lsmime3 -lssl3 -lnss3 -lnssutil3 +Cflags: -I${includedir} diff --git a/application/xulrunner/installer/mozilla-plugin.pc.in b/application/xulrunner/installer/mozilla-plugin.pc.in new file mode 100644 index 000000000..7080161b3 --- /dev/null +++ b/application/xulrunner/installer/mozilla-plugin.pc.in @@ -0,0 +1,8 @@ +prefix=%prefix% +sdkdir=%sdkdir% +includedir=%includedir% + +Name: Mozilla Plug-In API +Description: Mozilla Plug-In API +Version: %MOZILLA_VERSION% +Cflags: -I${includedir} -DXP_UNIX diff --git a/application/xulrunner/locales/all-locales b/application/xulrunner/locales/all-locales new file mode 100644 index 000000000..85ef789a6 --- /dev/null +++ b/application/xulrunner/locales/all-locales @@ -0,0 +1,39 @@ +ar +bg +ca +cs +da +de +el +en-GB +es-AR +es-ES +eu +fi +fr +ga-IE +gu-IN +he +hu +hy-AM +it +ja +ja-JP-mac +ko +nb-NO +nl +nn-NO +mk +mn +pa-IN +pl +pt-BR +ro +ru +sk +sl +sq +sv-SE +tr +zh-CN +zh-TW diff --git a/application/xulrunner/moz.build b/application/xulrunner/moz.build new file mode 100644 index 000000000..371f69f5e --- /dev/null +++ b/application/xulrunner/moz.build @@ -0,0 +1,11 @@ +# -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*- +# vim: set filetype=python: +# 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/. + +CONFIGURE_SUBST_FILES += ['installer/Makefile'] + +DIRS += [ + 'app', +] diff --git a/application/xulrunner/moz.configure b/application/xulrunner/moz.configure new file mode 100644 index 000000000..72236254f --- /dev/null +++ b/application/xulrunner/moz.configure @@ -0,0 +1,7 @@ +# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*- +# vim: set filetype=python: +# 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/. + +include('../../toolkit/moz.configure') diff --git a/application/xulrunner/stub/Makefile.in b/application/xulrunner/stub/Makefile.in new file mode 100644 index 000000000..0fa0cccf6 --- /dev/null +++ b/application/xulrunner/stub/Makefile.in @@ -0,0 +1,11 @@ +# 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/. + +ifndef MOZ_WINCONSOLE +ifdef MOZ_DEBUG +MOZ_WINCONSOLE = 1 +else +MOZ_WINCONSOLE = 0 +endif +endif diff --git a/application/xulrunner/stub/moz.build b/application/xulrunner/stub/moz.build new file mode 100644 index 000000000..4fd172f72 --- /dev/null +++ b/application/xulrunner/stub/moz.build @@ -0,0 +1,51 @@ +# -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*- +# vim: set filetype=python: +# 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/. + +# The value of XULRUNNER_STUB_NAME is generated by configure to allow XULRunner +# apps to override it using the --with-xulrunner-stub-name=<appname> argument. +# If this configure argument is not present then the default name is +# 'xulrunner-stub'. + +# We don't want to create a dependency on mozglue. +# Statically link against the RTL on windows +GeckoProgram(CONFIG['XULRUNNER_STUB_NAME'], mozglue=None, msvcrt='static') + +SOURCES += [ + 'nsXULStub.cpp', +] + +if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'cocoa': + FINAL_TARGET = 'dist/XUL.framework/Versions/%(MOZILLA_VERSION)s' % CONFIG + +DEFINES['XPCOM_GLUE'] = True + +LOCAL_INCLUDES += [ + '/xpcom/base', + '/xpcom/build', +] + +if CONFIG['OS_ARCH'] == 'WINNT': + LOCAL_INCLUDES += ['/toolkit/xre'] + # this is an awful workaround - glandium + USE_LIBS += ['mfbt_staticruntime'] + +if CONFIG['_MSC_VER']: + WIN32_EXE_LDFLAGS += ['-ENTRY:wmainCRTStartup'] + +if CONFIG['OS_ARCH'] == 'WINNT': + DEFINES['MOZ_XULRUNNER'] = True + RCINCLUDE = 'xulrunner-stub.rc' + +if CONFIG['OS_ARCH'] == 'WINNT': + OS_LIBS += [ + 'shell32', + ] + +DISABLE_STL_WRAPPING = True + +# Need to link with CoreFoundation on Mac +if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'cocoa': + OS_LIBS += CONFIG['TK_LIBS'] diff --git a/application/xulrunner/stub/nsXULStub.cpp b/application/xulrunner/stub/nsXULStub.cpp new file mode 100644 index 000000000..8638ae43e --- /dev/null +++ b/application/xulrunner/stub/nsXULStub.cpp @@ -0,0 +1,445 @@ +/* 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/. */ + +#include "nsXPCOMGlue.h" +#include "nsINIParser.h" +#include "nsXPCOMPrivate.h" // for XP MAXPATHLEN +#include "nsXULAppAPI.h" +#include "nsIFile.h" + +#include <stdarg.h> + +#ifdef XP_WIN +#include <windows.h> +#include <io.h> +#if defined(_MSC_VER) && _MSC_VER < 1900 +#define snprintf _snprintf +#define vsnprintf _vsnprintf +#endif +#define strcasecmp _stricmp +#define PATH_SEPARATOR_CHAR '\\' +#define R_OK 04 +#elif defined(XP_MACOSX) +#include <unistd.h> +#include <sys/stat.h> +#include <CoreFoundation/CoreFoundation.h> +#define PATH_SEPARATOR_CHAR '/' +#else +#include <unistd.h> +#include <sys/types.h> +#include <sys/stat.h> +#define PATH_SEPARATOR_CHAR '/' +#endif + +#ifdef XP_WIN +#define XRE_DONT_PROTECT_DLL_LOAD +#include "nsWindowsWMain.cpp" +#endif + +#define VERSION_MAXLEN 128 + +static void Output(bool isError, const char *fmt, ... ) +{ + va_list ap; + va_start(ap, fmt); + +#if (defined(XP_WIN) && !MOZ_WINCONSOLE) + char msg[2048]; + + vsnprintf(msg, sizeof(msg), fmt, ap); + + UINT flags = MB_OK; + if (isError) + flags |= MB_ICONERROR; + else + flags |= MB_ICONINFORMATION; + + wchar_t wide_msg[1024]; + MultiByteToWideChar(CP_ACP, + 0, + msg, + -1, + wide_msg, + sizeof(wide_msg) / sizeof(wchar_t)); + + MessageBoxW(nullptr, wide_msg, L"XULRunner", flags); +#else + vfprintf(stderr, fmt, ap); +#endif + + va_end(ap); +} + +/** + * Return true if |arg| matches the given argument name. + */ +static bool IsArg(const char* arg, const char* s) +{ + if (*arg == '-') + { + if (*++arg == '-') + ++arg; + return !strcasecmp(arg, s); + } + +#if defined(XP_WIN) + if (*arg == '/') + return !strcasecmp(++arg, s); +#endif + + return false; +} + +/** + * Return true if |aDir| is a valid file/directory. + */ +static bool FolderExists(const char* aDir) +{ +#ifdef XP_WIN + wchar_t wideDir[MAX_PATH]; + MultiByteToWideChar(CP_UTF8, 0, aDir, -1, wideDir, MAX_PATH); + DWORD fileAttrs = GetFileAttributesW(wideDir); + return fileAttrs != INVALID_FILE_ATTRIBUTES; +#else + return access(aDir, R_OK) == 0; +#endif +} + +static nsresult GetRealPath(const char* appDataFile, char* *aResult) +{ +#ifdef XP_WIN + wchar_t wAppDataFile[MAX_PATH]; + wchar_t wIniPath[MAX_PATH]; + MultiByteToWideChar(CP_UTF8, 0, appDataFile, -1, wAppDataFile, MAX_PATH); + _wfullpath(wIniPath, wAppDataFile, MAX_PATH); + WideCharToMultiByte(CP_UTF8, 0, wIniPath, -1, *aResult, MAX_PATH, 0, 0); +#else + struct stat fileStat; + if (!realpath(appDataFile, *aResult) || stat(*aResult, &fileStat)) + return NS_ERROR_FAILURE; +#endif + if (!*aResult || !**aResult) + return NS_ERROR_FAILURE; + + return NS_OK; +} + +class AutoAppData +{ +public: + AutoAppData(nsIFile* aINIFile) : mAppData(nullptr) { + nsresult rv = XRE_CreateAppData(aINIFile, &mAppData); + if (NS_FAILED(rv)) + mAppData = nullptr; + } + ~AutoAppData() { + if (mAppData) + XRE_FreeAppData(mAppData); + } + + operator nsXREAppData*() const { return mAppData; } + nsXREAppData* operator -> () const { return mAppData; } + +private: + nsXREAppData* mAppData; +}; + +XRE_CreateAppDataType XRE_CreateAppData; +XRE_FreeAppDataType XRE_FreeAppData; +XRE_mainType XRE_main; + +int +main(int argc, char **argv) +{ + nsresult rv; + char *lastSlash; + + char iniPath[MAXPATHLEN]; + char tmpPath[MAXPATHLEN]; + char greDir[MAXPATHLEN]; + bool greFound = false; + +#if defined(XP_MACOSX) + CFBundleRef appBundle = CFBundleGetMainBundle(); + if (!appBundle) + return 1; + + CFURLRef resourcesURL = CFBundleCopyResourcesDirectoryURL(appBundle); + if (!resourcesURL) + return 1; + + CFURLRef absResourcesURL = CFURLCopyAbsoluteURL(resourcesURL); + CFRelease(resourcesURL); + if (!absResourcesURL) + return 1; + + CFURLRef iniFileURL = + CFURLCreateCopyAppendingPathComponent(kCFAllocatorDefault, + absResourcesURL, + CFSTR("application.ini"), + false); + CFRelease(absResourcesURL); + if (!iniFileURL) + return 1; + + CFStringRef iniPathStr = + CFURLCopyFileSystemPath(iniFileURL, kCFURLPOSIXPathStyle); + CFRelease(iniFileURL); + if (!iniPathStr) + return 1; + + CFStringGetCString(iniPathStr, iniPath, sizeof(iniPath), + kCFStringEncodingUTF8); + CFRelease(iniPathStr); + +#else + +#ifdef XP_WIN + wchar_t wide_path[MAX_PATH]; + if (!::GetModuleFileNameW(nullptr, wide_path, MAX_PATH)) + return 1; + + WideCharToMultiByte(CP_UTF8, 0, wide_path,-1, + iniPath, MAX_PATH, nullptr, nullptr); + +#else + // on unix, there is no official way to get the path of the current binary. + // instead of using the MOZILLA_FIVE_HOME hack, which doesn't scale to + // multiple applications, we will try a series of techniques: + // + // 1) use realpath() on argv[0], which works unless we're loaded from the + // PATH + // 2) manually walk through the PATH and look for ourself + // 3) give up + + struct stat fileStat; + strncpy(tmpPath, argv[0], sizeof(tmpPath)); + lastSlash = strrchr(tmpPath, '/'); + if (lastSlash) { + *lastSlash = 0; + realpath(tmpPath, iniPath); + } else { + const char *path = getenv("PATH"); + if (!path) + return 1; + + char *pathdup = strdup(path); + if (!pathdup) + return 1; + + bool found = false; + char *token = strtok(pathdup, ":"); + while (token) { + sprintf(tmpPath, "%s/%s", token, argv[0]); + if (stat(tmpPath, &fileStat) == 0) { + found = true; + lastSlash = strrchr(tmpPath, '/'); + *lastSlash = 0; + realpath(tmpPath, iniPath); + break; + } + token = strtok(nullptr, ":"); + } + free (pathdup); + if (!found) + return 1; + } + lastSlash = iniPath + strlen(iniPath); + *lastSlash = '/'; +#endif + +#ifndef XP_UNIX + lastSlash = strrchr(iniPath, PATH_SEPARATOR_CHAR); + if (!lastSlash) + return 1; +#endif + + *(++lastSlash) = '\0'; + + // On Linux/Win, look for XULRunner in appdir/xulrunner + + snprintf(greDir, sizeof(greDir), + "%sxulrunner" XPCOM_FILE_PATH_SEPARATOR XPCOM_DLL, + iniPath); + + greFound = FolderExists(greDir); + +#ifdef XP_UNIX + if (greFound) { + char resolved_greDir[MAXPATHLEN] = ""; + if (realpath(greDir, resolved_greDir) && *resolved_greDir) { + strncpy(greDir, resolved_greDir, MAXPATHLEN); + } + } +#endif + + strncpy(lastSlash, "application.ini", sizeof(iniPath) - (lastSlash - iniPath)); + +#endif + + // If -app parameter was passed in, it is now time to take it under + // consideration. + const char *appDataFile; + appDataFile = getenv("XUL_APP_FILE"); + if (!appDataFile || !*appDataFile) + if (argc > 1 && IsArg(argv[1], "app")) { + if (argc == 2) { + Output(false, "specify APP-FILE (optional)\n"); + return 1; + } + argv[1] = argv[0]; + ++argv; + --argc; + + appDataFile = argv[1]; + argv[1] = argv[0]; + ++argv; + --argc; + + char kAppEnv[MAXPATHLEN]; + snprintf(kAppEnv, MAXPATHLEN, "XUL_APP_FILE=%s", appDataFile); + if (putenv(kAppEnv)) + Output(false, "Couldn't set %s.\n", kAppEnv); + + char *result = (char*) calloc(sizeof(char), MAXPATHLEN); + if (NS_FAILED(GetRealPath(appDataFile, &result))) { + Output(true, "Invalid application.ini path.\n"); + return 1; + } + + // We have a valid application.ini path passed in to the -app parameter + // but not yet a valid greDir, so lets look for it also on the same folder + // as the stub. + if (!greFound) { + lastSlash = strrchr(iniPath, PATH_SEPARATOR_CHAR); + if (!lastSlash) + return 1; + + *(++lastSlash) = '\0'; + + snprintf(greDir, sizeof(greDir), "%s" XPCOM_DLL, iniPath); + greFound = FolderExists(greDir); + } + + // copy it back. + strcpy(iniPath, result); + } + + nsINIParser parser; + rv = parser.Init(iniPath); + if (NS_FAILED(rv)) { + fprintf(stderr, "Could not read application.ini\n"); + return 1; + } + + if (!greFound) { +#ifdef XP_MACOSX + // The bundle can be found next to the executable, in the MacOS dir. + CFURLRef exurl = CFBundleCopyExecutableURL(appBundle); + CFURLRef absexurl = nullptr; + if (exurl) { + absexurl = CFURLCopyAbsoluteURL(exurl); + CFRelease(exurl); + } + + if (absexurl) { + char tbuffer[MAXPATHLEN]; + + if (CFURLGetFileSystemRepresentation(absexurl, true, + (UInt8*) tbuffer, + sizeof(tbuffer)) && + access(tbuffer, R_OK | X_OK) == 0) { + if (realpath(tbuffer, greDir)) { + greFound = true; + } + else { + greDir[0] = '\0'; + } + } + + CFRelease(absexurl); + } +#endif + if (!greFound) { + Output(false, "Could not find the Mozilla runtime.\n"); + return 1; + } + } + + rv = XPCOMGlueStartup(greDir); + if (NS_FAILED(rv)) { + if (rv == NS_ERROR_OUT_OF_MEMORY) { + char applicationName[2000] = "this application"; + parser.GetString("App", "Name", applicationName, sizeof(applicationName)); + Output(true, "Not enough memory available to start %s.\n", + applicationName); + } else { + Output(true, "Couldn't load XPCOM.\n"); + } + return 1; + } + + static const nsDynamicFunctionLoad kXULFuncs[] = { + { "XRE_CreateAppData", (NSFuncPtr*) &XRE_CreateAppData }, + { "XRE_FreeAppData", (NSFuncPtr*) &XRE_FreeAppData }, + { "XRE_main", (NSFuncPtr*) &XRE_main }, + { nullptr, nullptr } + }; + + rv = XPCOMGlueLoadXULFunctions(kXULFuncs); + if (NS_FAILED(rv)) { + Output(true, "Couldn't load XRE functions.\n"); + return 1; + } + + NS_LogInit(); + + int retval; + + { // Scope COMPtr and AutoAppData + nsCOMPtr<nsIFile> iniFile; +#ifdef XP_WIN + // On Windows iniPath is UTF-8 encoded so we need to convert it. + rv = NS_NewLocalFile(NS_ConvertUTF8toUTF16(iniPath), false, + getter_AddRefs(iniFile)); +#else + rv = NS_NewNativeLocalFile(nsDependentCString(iniPath), false, + getter_AddRefs(iniFile)); +#endif + if (NS_FAILED(rv)) { + Output(true, "Couldn't find application.ini file.\n"); + return 1; + } + + AutoAppData appData(iniFile); + if (!appData) { + Output(true, "Error: couldn't parse application.ini.\n"); + return 1; + } + + NS_ASSERTION(appData->directory, "Failed to get app directory."); + + if (!appData->xreDirectory) { + // chop "libxul.so" off the GRE path + lastSlash = strrchr(greDir, PATH_SEPARATOR_CHAR); + if (lastSlash) { + *lastSlash = '\0'; + } +#ifdef XP_WIN + // same as iniPath. + NS_NewLocalFile(NS_ConvertUTF8toUTF16(greDir), false, + &appData->xreDirectory); +#else + NS_NewNativeLocalFile(nsDependentCString(greDir), false, + &appData->xreDirectory); +#endif + } + + retval = XRE_main(argc, argv, appData, 0); + } + + NS_LogTerm(); + + return retval; +} diff --git a/application/xulrunner/stub/xulrunner-stub.exe.manifest b/application/xulrunner/stub/xulrunner-stub.exe.manifest new file mode 100644 index 000000000..57c2a7070 --- /dev/null +++ b/application/xulrunner/stub/xulrunner-stub.exe.manifest @@ -0,0 +1,38 @@ +<?xml version="1.0" encoding="UTF-8" standalone="yes"?> +<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0"> +<assemblyIdentity + version="1.0.0.0" + processorArchitecture="*" + name="Mozilla.XULRunner.Stub" + type="win32" +/> +<description>Mozilla XULRunner Stub</description> +<dependency> + <dependentAssembly> + <assemblyIdentity + type="win32" + name="Microsoft.Windows.Common-Controls" + version="6.0.0.0" + processorArchitecture="*" + publicKeyToken="6595b64144ccf1df" + language="*" + /> + </dependentAssembly> +</dependency> +<ms_asmv3:trustInfo xmlns:ms_asmv3="urn:schemas-microsoft-com:asm.v3"> + <ms_asmv3:security> + <ms_asmv3:requestedPrivileges> + <ms_asmv3:requestedExecutionLevel level="asInvoker" uiAccess="false" /> + </ms_asmv3:requestedPrivileges> + </ms_asmv3:security> +</ms_asmv3:trustInfo> + <compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1"> + <application> + <supportedOS Id="{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}"/> + <supportedOS Id="{1f676c76-80e1-4239-95bb-83d0f6d0da78}"/> + <supportedOS Id="{4a2f28e3-53b9-4441-ba9c-d69d4a4a6e38}"/> + <supportedOS Id="{35138b9a-5d96-4fbd-8e2d-a2440225f93a}"/> + <supportedOS Id="{e2011457-1546-43c5-a5fe-008deee3d3f0}"/> + </application> + </compatibility> +</assembly> diff --git a/application/xulrunner/stub/xulrunner-stub.rc b/application/xulrunner/stub/xulrunner-stub.rc new file mode 100644 index 000000000..84c3e47ed --- /dev/null +++ b/application/xulrunner/stub/xulrunner-stub.rc @@ -0,0 +1,6 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* 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/. */ + +1 24 "xulrunner-stub.exe.manifest" diff --git a/application/xulrunner/tools/redit/Makefile.in b/application/xulrunner/tools/redit/Makefile.in new file mode 100644 index 000000000..31c253be8 --- /dev/null +++ b/application/xulrunner/tools/redit/Makefile.in @@ -0,0 +1,11 @@ +# 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/. */ + +ifeq ($(OS_ARCH),WINNT) + +SDK_BINARY = \ + $(PROGRAM) \ + $(NULL) + +endif diff --git a/application/xulrunner/tools/redit/moz.build b/application/xulrunner/tools/redit/moz.build new file mode 100644 index 000000000..812a56578 --- /dev/null +++ b/application/xulrunner/tools/redit/moz.build @@ -0,0 +1,15 @@ +# -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*- +# vim: set filetype=python: +# 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/. + +if CONFIG['OS_ARCH'] == 'WINNT': + GeckoProgram('redit') + SOURCES += [ + 'redit.cpp', + ] + for var in ('WIN32_LEAN_AND_MEAN', 'UNICODE', '_UNICODE'): + DEFINES[var] = True + if CONFIG['GNU_CC']: + WIN32_EXE_LDFLAGS += ['-municode'] diff --git a/application/xulrunner/tools/redit/redit.cpp b/application/xulrunner/tools/redit/redit.cpp new file mode 100644 index 000000000..8a96358b2 --- /dev/null +++ b/application/xulrunner/tools/redit/redit.cpp @@ -0,0 +1,187 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ + +/* 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/. */ + +// System headers (alphabetical) +#include <fcntl.h> +#include <io.h> +#include <share.h> +#include <stdio.h> +#include <stdlib.h> +#include <sys/stat.h> +#include <windows.h> + +// Mozilla headers (alphabetical) +#include "mozilla/FileUtils.h" // ScopedClose +#include "mozilla/UniquePtrExtensions.h" + +/* +Icon files are made up of: + +IconHeader +IconDirEntry1 +IconDirEntry2 +... +IconDirEntryN +IconData1 +IconData2 +... +IconDataN + +Each IconData must be added as a new RT_ICON resource to the exe. Then +an RT_GROUP_ICON resource must be added that contains an equivalent +header: + +IconHeader +IconResEntry1 +IconResEntry2 +... +IconResEntryN +*/ + +#pragma pack(push, 2) +typedef struct +{ + WORD Reserved; + WORD ResourceType; + WORD ImageCount; +} IconHeader; + +typedef struct +{ + BYTE Width; + BYTE Height; + BYTE Colors; + BYTE Reserved; + WORD Planes; + WORD BitsPerPixel; + DWORD ImageSize; + DWORD ImageOffset; +} IconDirEntry; + +typedef struct +{ + BYTE Width; + BYTE Height; + BYTE Colors; + BYTE Reserved; + WORD Planes; + WORD BitsPerPixel; + DWORD ImageSize; + WORD ResourceID; // This field is the one difference to above +} IconResEntry; +#pragma pack(pop) + +namespace { + /** + * ScopedResourceUpdate is a RAII wrapper for Windows resource updating + * + * Instances |EndUpdateResourceW()| their handles when they go out of scope. + * They pass |TRUE| as the second argument to |EndUpdateResourceW()|, which + * causes the resource update to be aborted (changes are discarded). + */ + struct ScopedResourceUpdateTraits + { + typedef HANDLE type; + static type empty() { return nullptr; } + static void release(type handle) { + if(nullptr != handle) { + EndUpdateResourceW(handle, TRUE); // Discard changes + } + } + }; + + typedef mozilla::Scoped<ScopedResourceUpdateTraits> ScopedResourceUpdate; +}; + +#ifdef __MINGW32__ +extern "C" +#endif +int +wmain(int argc, wchar_t** argv) +{ + if (argc != 3) { + printf("Usage: redit <exe file> <icon file>\n"); + return 1; + } + + mozilla::ScopedClose file; + if (0 != _wsopen_s(&file.rwget(), + argv[2], + _O_BINARY | _O_RDONLY, + _SH_DENYWR, + _S_IREAD) + || (-1 == file)) { + fprintf(stderr, "Unable to open icon file.\n"); + return 1; + } + + // Load all the data from the icon file + long filesize = _filelength(file); + auto data = MakeUniqueFallible<BYTE[]>(filesize); + if(!data) { + fprintf(stderr, "Failed to allocate memory for icon file.\n"); + return 1; + } + _read(file, data.get(), filesize); + + IconHeader* header = reinterpret_cast<IconHeader*>(data.get()); + + // Open the target library for updating + ScopedResourceUpdate updateRes(BeginUpdateResourceW(argv[1], FALSE)); + if (nullptr == updateRes) { + fprintf(stderr, "Unable to open library for modification.\n"); + return 1; + } + + // Allocate the group resource entry + long groupSize = sizeof(IconHeader) + + header->ImageCount * sizeof(IconResEntry); + auto group = MakeUniqueFallible<BYTE[]>(groupSize); + if(!group) { + fprintf(stderr, "Failed to allocate memory for new images.\n"); + return 1; + } + memcpy(group.get(), data.get(), sizeof(IconHeader)); + + IconDirEntry* sourceIcon = + reinterpret_cast<IconDirEntry*>(data.get() + + sizeof(IconHeader)); + IconResEntry* targetIcon = + reinterpret_cast<IconResEntry*>(group.get() + + sizeof(IconHeader)); + + for (int id = 1; id <= header->ImageCount; id++) { + // Add the individual icon + if (!UpdateResourceW(updateRes, RT_ICON, MAKEINTRESOURCE(id), + MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL), + data + sourceIcon->ImageOffset, + sourceIcon->ImageSize)) { + fprintf(stderr, "Unable to update resource (RT_ICON).\n"); + return 1; + } + // Copy the data for this icon + // (note that the structs have different sizes) + memcpy(targetIcon, sourceIcon, sizeof(IconResEntry)); + targetIcon->ResourceID = id; + sourceIcon++; + targetIcon++; + } + + if (!UpdateResourceW(updateRes, RT_GROUP_ICON, L"MAINICON", + MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL), + group, groupSize)) { + fprintf(stderr, "Unable to update resource (RT_GROUP_ICON).\n"); + return 1; + } + + // Save the modifications + if(!EndUpdateResourceW(updateRes.forget(), FALSE)) { + fprintf(stderr, "Unable to write changes to library.\n"); + return 1; + } + + return 0; +} diff --git a/browser/branding/official/locales/en-US/brand.dtd b/browser/branding/official/locales/en-US/brand.dtd index 7bfa07f71..1d2ac791e 100644 --- a/browser/branding/official/locales/en-US/brand.dtd +++ b/browser/branding/official/locales/en-US/brand.dtd @@ -6,4 +6,5 @@ <!ENTITY brandShortName "Basilisk"> <!ENTITY brandFullName "Basilisk"> <!ENTITY vendorShortName "Moonchild"> +<!ENTITY vendorFullName "Moonchild Productions"> <!ENTITY trademarkInfo.part1 "Basilisk, Basilisk Browser and the Basilisk logos are trademarks of Moonchild Productions."> diff --git a/browser/components/webextensions/ext-commands.js b/browser/components/webextensions/ext-commands.js index 416544e86..3f0bf8d1a 100644 --- a/browser/components/webextensions/ext-commands.js +++ b/browser/components/webextensions/ext-commands.js @@ -74,15 +74,14 @@ CommandList.prototype = { // For Windows, chrome.runtime expects 'win' while chrome.commands // expects 'windows'. We can special case this for now. let os = PlatformInfo.os == "win" ? "windows" : PlatformInfo.os; - for (let name of Object.keys(manifest.commands)) { - let command = manifest.commands[name]; - let shortcut = command.suggested_key[os] || command.suggested_key.default; - if (shortcut) { - commands.set(name, { - description: command.description, - shortcut: shortcut.replace(/\s+/g, ""), - }); - } + for (let [name, command] of Object.entries(manifest.commands)) { + let suggested_key = command.suggested_key || {}; + let shortcut = suggested_key[os] || suggested_key.default; + shortcut = shortcut ? shortcut.replace(/\s+/g, "") : null; + commands.set(name, { + description: command.description, + shortcut, + }); } return commands; }, @@ -96,8 +95,10 @@ CommandList.prototype = { let keyset = doc.createElementNS(XUL_NS, "keyset"); keyset.id = `ext-keyset-id-${this.id}`; this.commands.forEach((command, name) => { - let keyElement = this.buildKey(doc, name, command.shortcut); - keyset.appendChild(keyElement); + if (command.shortcut) { + let keyElement = this.buildKey(doc, name, command.shortcut); + keyset.appendChild(keyElement); + } }); doc.documentElement.appendChild(keyset); this.keysetsMap.set(window, keyset); diff --git a/browser/locales/en-US/firefox-l10n.js b/browser/locales/en-US/firefox-l10n.js index c1e5510f3..642ad6534 100644 --- a/browser/locales/en-US/firefox-l10n.js +++ b/browser/locales/en-US/firefox-l10n.js @@ -4,8 +4,4 @@ #filter substitution -# LOCALIZATION NOTE: this preference is set to true for en-US specifically, -# locales without this line have the setting set to false by default. -pref("browser.search.geoSpecificDefaults", true); - pref("general.useragent.locale", "@AB_CD@"); diff --git a/browser/locales/search/list.json b/browser/locales/search/list.json index 9f7d82b4e..722f3186f 100644 --- a/browser/locales/search/list.json +++ b/browser/locales/search/list.json @@ -5,36 +5,6 @@ ] }, "regionOverrides": { - "US": { - "google": "google-nocodes" - }, - "CA": { - "google": "google-nocodes" - }, - "KZ": { - "google": "google-nocodes" - }, - "BY": { - "google": "google-nocodes" - }, - "RU": { - "google": "google-nocodes" - }, - "TR": { - "google": "google-nocodes" - }, - "UA": { - "google": "google-nocodes" - }, - "CN": { - "google": "google-nocodes" - }, - "TW": { - "google": "google-nocodes" - }, - "HK": { - "google": "google-nocodes" - } }, "locales": { "en-US": { diff --git a/build/autoconf/compiler-opts.m4 b/build/autoconf/compiler-opts.m4 index 57a974435..c47d792f4 100644 --- a/build/autoconf/compiler-opts.m4 +++ b/build/autoconf/compiler-opts.m4 @@ -181,18 +181,15 @@ if test "$GNU_CC"; then if test -z "$CLANG_CC"; then case "$CC_VERSION" in - 4.*) + 4.* | 5.*) ;; *) # Lifetime Dead Store Elimination level 2 (default in GCC6+) breaks Gecko. - # Ideally, we'd use -flifetime-dse=1, but that means we'd forcefully - # enable it on optimization levels where it would otherwise not be enabled. - # So we disable it entirely. But since that would mean inconsistency with - # GCC5, which has level 1 depending on optimization level, disable it on - # GCC5 as well, because better safe than sorry. + # Instead of completely disabling this optimization on newer GCC's, + # we'll force them to use level 1 optimization with -flifetime-dse=1. # Add it first so that a mozconfig can override by setting CFLAGS/CXXFLAGS. - CFLAGS="-fno-lifetime-dse $CFLAGS" - CXXFLAGS="-fno-lifetime-dse $CXXFLAGS" + CFLAGS="-flifetime-dse=1 $CFLAGS" + CXXFLAGS="-flifetime-dse=1 $CXXFLAGS" ;; esac fi diff --git a/dom/events/EventStateManager.cpp b/dom/events/EventStateManager.cpp index c23cdb575..c6b304183 100644 --- a/dom/events/EventStateManager.cpp +++ b/dom/events/EventStateManager.cpp @@ -731,6 +731,9 @@ EventStateManager::PreHandleEvent(nsPresContext* aPresContext, FlushPendingEvents(aPresContext); break; } + case ePointerGotCapture: + GenerateMouseEnterExit(mouseEvent); + break; case eDragStart: if (Prefs::ClickHoldContextMenu()) { // an external drag gesture event came in, not generated internally @@ -3890,10 +3893,7 @@ CreateMouseOrPointerWidgetEvent(WidgetMouseEvent* aMouseEvent, newPointerEvent->mWidth = sourcePointer->mWidth; newPointerEvent->mHeight = sourcePointer->mHeight; newPointerEvent->inputSource = sourcePointer->inputSource; - newPointerEvent->relatedTarget = - nsIPresShell::GetPointerCapturingContent(sourcePointer->pointerId) - ? nullptr - : aRelatedContent; + newPointerEvent->relatedTarget = aRelatedContent; aNewEvent = newPointerEvent.forget(); } else { aNewEvent = @@ -4034,7 +4034,7 @@ public: } } - ~EnterLeaveDispatcher() + void Dispatch() { if (mEventMessage == eMouseEnter || mEventMessage == ePointerEnter) { for (int32_t i = mTargets.Count() - 1; i >= 0; --i) { @@ -4106,19 +4106,14 @@ EventStateManager::NotifyMouseOut(WidgetMouseEvent* aMouseEvent, SetContentState(nullptr, NS_EVENT_STATE_HOVER); } - // In case we go out from capturing element (retargetedByPointerCapture is true) - // we should dispatch ePointerLeave event and only for capturing element. - RefPtr<nsIContent> movingInto = aMouseEvent->retargetedByPointerCapture - ? wrapper->mLastOverElement->GetParent() - : aMovingInto; - EnterLeaveDispatcher leaveDispatcher(this, wrapper->mLastOverElement, - movingInto, aMouseEvent, + aMovingInto, aMouseEvent, isPointer ? ePointerLeave : eMouseLeave); // Fire mouseout DispatchMouseOrPointerEvent(aMouseEvent, isPointer ? ePointerOut : eMouseOut, wrapper->mLastOverElement, aMovingInto); + leaveDispatcher.Dispatch(); wrapper->mLastOverFrame = nullptr; wrapper->mLastOverElement = nullptr; @@ -4133,13 +4128,9 @@ EventStateManager::NotifyMouseOver(WidgetMouseEvent* aMouseEvent, { NS_ASSERTION(aContent, "Mouse must be over something"); - // If pointer capture is set, we should suppress pointerover/pointerenter events - // for all elements except element which have pointer capture. - bool dispatch = !aMouseEvent->retargetedByPointerCapture; - OverOutElementsWrapper* wrapper = GetWrapperByEventID(aMouseEvent); - if (wrapper->mLastOverElement == aContent && dispatch) + if (wrapper->mLastOverElement == aContent) return; // Before firing mouseover, check for recursion @@ -4162,7 +4153,7 @@ EventStateManager::NotifyMouseOver(WidgetMouseEvent* aMouseEvent, } // Firing the DOM event in the parent document could cause all kinds // of havoc. Reverify and take care. - if (wrapper->mLastOverElement == aContent && dispatch) + if (wrapper->mLastOverElement == aContent) return; // Remember mLastOverElement as the related content for the @@ -4171,11 +4162,9 @@ EventStateManager::NotifyMouseOver(WidgetMouseEvent* aMouseEvent, bool isPointer = aMouseEvent->mClass == ePointerEventClass; - Maybe<EnterLeaveDispatcher> enterDispatcher; - if (dispatch) { - enterDispatcher.emplace(this, aContent, lastOverElement, aMouseEvent, - isPointer ? ePointerEnter : eMouseEnter); - } + EnterLeaveDispatcher enterDispatcher(this, aContent, lastOverElement, + aMouseEvent, + isPointer ? ePointerEnter : eMouseEnter); NotifyMouseOut(aMouseEvent, aContent); @@ -4187,17 +4176,13 @@ EventStateManager::NotifyMouseOver(WidgetMouseEvent* aMouseEvent, SetContentState(aContent, NS_EVENT_STATE_HOVER); } - if (dispatch) { - // Fire mouseover - wrapper->mLastOverFrame = - DispatchMouseOrPointerEvent(aMouseEvent, - isPointer ? ePointerOver : eMouseOver, - aContent, lastOverElement); - wrapper->mLastOverElement = aContent; - } else { - wrapper->mLastOverFrame = nullptr; - wrapper->mLastOverElement = nullptr; - } + // Fire mouseover + wrapper->mLastOverFrame = + DispatchMouseOrPointerEvent(aMouseEvent, + isPointer ? ePointerOver : eMouseOver, + aContent, lastOverElement); + enterDispatcher.Dispatch(); + wrapper->mLastOverElement = aContent; // Turn recursion protection back off wrapper->mFirstOverEventElement = nullptr; @@ -4290,6 +4275,7 @@ EventStateManager::GenerateMouseEnterExit(WidgetMouseEvent* aMouseEvent) MOZ_FALLTHROUGH; case ePointerMove: case ePointerDown: + case ePointerGotCapture: { // Get the target content target (mousemove target == mouseover target) nsCOMPtr<nsIContent> targetElement = GetEventTargetContent(aMouseEvent); diff --git a/dom/events/PointerEvent.cpp b/dom/events/PointerEvent.cpp index f53739863..fbaa0f737 100644 --- a/dom/events/PointerEvent.cpp +++ b/dom/events/PointerEvent.cpp @@ -93,8 +93,10 @@ PointerEvent::Constructor(EventTarget* aOwner, widgetEvent->mWidth = aParam.mWidth; widgetEvent->mHeight = aParam.mHeight; widgetEvent->pressure = aParam.mPressure; + widgetEvent->tangentialPressure = aParam.mTangentialPressure; widgetEvent->tiltX = aParam.mTiltX; widgetEvent->tiltY = aParam.mTiltY; + widgetEvent->twist = aParam.mTwist; widgetEvent->inputSource = ConvertStringToPointerType(aParam.mPointerType); widgetEvent->mIsPrimary = aParam.mIsPrimary; widgetEvent->buttons = aParam.mButtons; @@ -145,6 +147,12 @@ PointerEvent::Pressure() return mEvent->AsPointerEvent()->pressure; } +float +PointerEvent::TangentialPressure() +{ + return mEvent->AsPointerEvent()->tangentialPressure; +} + int32_t PointerEvent::TiltX() { @@ -157,6 +165,12 @@ PointerEvent::TiltY() return mEvent->AsPointerEvent()->tiltY; } +int32_t +PointerEvent::Twist() +{ + return mEvent->AsPointerEvent()->twist; +} + bool PointerEvent::IsPrimary() { diff --git a/dom/events/PointerEvent.h b/dom/events/PointerEvent.h index 62c5a0c36..12d4941dc 100644 --- a/dom/events/PointerEvent.h +++ b/dom/events/PointerEvent.h @@ -44,8 +44,10 @@ public: int32_t Width(); int32_t Height(); float Pressure(); + float TangentialPressure(); int32_t TiltX(); int32_t TiltY(); + int32_t Twist(); bool IsPrimary(); void GetPointerType(nsAString& aPointerType); }; diff --git a/dom/events/test/pointerevents/mochitest.ini b/dom/events/test/pointerevents/mochitest.ini index 58eae12fe..5de7f27ea 100644 --- a/dom/events/test/pointerevents/mochitest.ini +++ b/dom/events/test/pointerevents/mochitest.ini @@ -148,5 +148,6 @@ support-files = support-files = bug1293174_implicit_pointer_capture_for_touch_1.html [test_bug1293174_implicit_pointer_capture_for_touch_2.html] support-files = bug1293174_implicit_pointer_capture_for_touch_2.html +[test_bug1323158.html] [test_empty_file.html] disabled = disabled # Bug 1150091 - Issue with support-files diff --git a/dom/events/test/pointerevents/pointerevent_releasepointercapture_events_to_original_target-manual.html b/dom/events/test/pointerevents/pointerevent_releasepointercapture_events_to_original_target-manual.html index f4d5573ed..2614790f3 100644 --- a/dom/events/test/pointerevents/pointerevent_releasepointercapture_events_to_original_target-manual.html +++ b/dom/events/test/pointerevents/pointerevent_releasepointercapture_events_to_original_target-manual.html @@ -1,4 +1,4 @@ -<!doctype html> +<!doctype html> <html> <head> <title>Pointer Event: releasePointerCapture() - subsequent events follow normal hitting testing mechanisms</title> @@ -12,19 +12,27 @@ <script type="text/javascript" src="pointerevent_support.js"></script> <script type="text/javascript" src="mochitest_support_internal.js"></script> <script type="text/javascript"> + var test_pointerEvent; var detected_pointertypes = {}; - var test_pointerEvent = async_test("lostpointercapture: subsequent events to target."); // set up test harness - var suppressedEventsFail = false; - // showPointerTypes is defined in pointerevent_support.js - // Requirements: the callback function will reference the test_pointerEvent object and - // will fail unless the async_test is created with the var name "test_pointerEvent". - add_completion_callback(showPointerTypes); - - var captured_event; + var captured_event = null; + var test_done = false; + var overEnterEventsFail = false; + var outLeaveEventsFail = false; var f_gotPointerCapture = false; var f_lostPointerCapture = false; + function resetTestState() { + captured_event = null; + test_done = false; + overEnterEventsFail = false; + outLeaveEventsFail = false; + f_gotPointerCapture = false; + f_lostPointerCapture = false; + } + function listenerEventHandler(event) { + if (test_done) + return; detected_pointertypes[event.pointerType] = true; if (event.type == "gotpointercapture") { f_gotPointerCapture = true; @@ -35,12 +43,20 @@ f_gotPointerCapture = false; check_PointerEvent(event); } - else if(event.type == "pointerover" || event.type == "pointerenter" || event.type == "pointerout" || event.type == "pointerleave") { - if(!suppressedEventsFail) { + else if(event.type == "pointerover" || event.type == "pointerenter") { + if(captured_event && !overEnterEventsFail) { + test(function() { + assert_false(f_gotPointerCapture, "pointerover/enter should be received before the target receives gotpointercapture even when the pointer is not over it."); + }, expectedPointerType + " pointerover/enter should be received before the target receives gotpointercapture even when the pointer is not over it."); + overEnterEventsFail = true; + } + } + else if(event.type == "pointerout" || event.type == "pointerleave") { + if(!outLeaveEventsFail) { test(function() { - assert_true(false, "Suppressed events were received"); - }, "Suppressed events were received"); - suppressedEventsFail = true; + assert_true(f_lostPointerCapture, "pointerout/leave should not be received unless the target just lost the capture."); + }, expectedPointerType + " pointerout/leave should not be received unless the target just lost the capture."); + outLeaveEventsFail = true; } } else if (event.pointerId == captured_event.pointerId) { @@ -50,19 +66,21 @@ } else { // if any other events are received after releaseCapture, then the test fails - test_pointerEvent.step(function () { - assert_true(false, event.target.id + "-" + event.type + " should be handled by target element handler"); - }); + test(function () { + assert_unreached(event.target.id + "-" + event.type + " should be handled by target element handler"); + }, expectedPointerType + " No other events should be recieved by capturing node after release"); } } } function targetEventHandler(event) { + if (test_done) + return; if (f_gotPointerCapture) { if(event.type != "pointerout" && event.type != "pointerleave") { - test_pointerEvent.step(function () { - assert_true(false, "The Target element should not have received any events while capture is active. Event recieved:" + event.type + ". "); - }); + test(function () { + assert_unreached("The Target element should not have received any events while capture is active. Event recieved:" + event.type + ". "); + }, expectedPointerType + " The target element should not receive any events while capture is active"); } } @@ -77,12 +95,14 @@ assert_equals(event.pointerId, captured_event.pointerId, "pointerID is same for event captured and after release"); }); if (event.type == "pointerup") { + test_done = true; test_pointerEvent.done(); // complete test } } } function run() { + test_pointerEvent = setup_pointerevent_test("got/lost pointercapture: subsequent events to target", ALL_POINTERS); // set up test harness var listener = document.getElementById("listener"); var target0 = document.getElementById("target0"); target0.style["touchAction"] = "none"; @@ -96,18 +116,19 @@ </script> </head> <body onload="run()"> + <h2 id="pointerTypeDescription"></h2> <div id="listener"></div> <h1>Pointer Event: releasePointerCapture() - subsequent events follow normal hitting testing mechanisms</h1> <!-- <h4> Test Description: + Use your pointer and press down in the black box. Then move around in the box and release your pointer. After invoking the releasePointerCapture method on an element, subsequent events for the specified - pointer must follow normal hit testing mechanisms for determining the event target + pointer must follow normal hit testing mechanisms for determining the event target. </h4> <br /> --> <div id="target0"> - Use mouse, touch or pen to contact here and move around. </div> <div id="complete-notice"> <p>Test complete: Scroll to Summary to view Pass/Fail Results.</p> diff --git a/dom/events/test/pointerevents/test_bug1285128.html b/dom/events/test/pointerevents/test_bug1285128.html index f7f1eb698..9577940c1 100644 --- a/dom/events/test/pointerevents/test_bug1285128.html +++ b/dom/events/test/pointerevents/test_bug1285128.html @@ -13,7 +13,8 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=1285128 <body> <a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1285128">Mozilla Bug 1285128</a> <p id="display"></p> -<div id="target0" style="width: 200px; height: 200px; background: green"></div> +<div id="target0" style="width: 50px; height: 50px; background: green"></div> +<div id="target1" style="width: 50px; height: 50px; background: red"></div> <script type="text/javascript"> /** Test for Bug 1285128 **/ @@ -31,7 +32,7 @@ function runTests() { }, false); }); - target0.addEventListener("mouseenter", () => { + target1.addEventListener("mouseup", () => { ok(!receivedPointerEvents, "synthesized mousemove should not trigger any pointer events"); SimpleTest.finish(); }); @@ -39,6 +40,8 @@ function runTests() { synthesizeMouseAtCenter(target0, { type: "mousemove", inputSource: SpecialPowers.Ci.nsIDOMMouseEvent.MOZ_SOURCE_MOUSE, isWidgetEventSynthesized: true }); + synthesizeMouseAtCenter(target1, { type: "mousedown" }); + synthesizeMouseAtCenter(target1, { type: "mouseup" }); } SpecialPowers.pushPrefEnv({"set": [["dom.w3c_pointer_events.enabled", true]]}, runTests); diff --git a/dom/events/test/pointerevents/test_bug1323158.html b/dom/events/test/pointerevents/test_bug1323158.html new file mode 100644 index 000000000..fac96c97a --- /dev/null +++ b/dom/events/test/pointerevents/test_bug1323158.html @@ -0,0 +1,93 @@ +<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=1323158
+-->
+<head>
+ <meta charset="utf-8">
+ <title>This is a test to check if target and relatedTarget of mouse events are the same as pointer events</title>
+ <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+ <script type="text/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+</head>
+<body>
+<p id="content"></p>
+<script type="text/javascript">
+
+/** Test for Bug 1323158 **/
+SimpleTest.waitForExplicitFinish();
+
+function runTests() {
+ let content = document.getElementById('content');
+ let iframe = document.createElement('iframe');
+ iframe.width = 500;
+ iframe.height = 500;
+ content.appendChild(iframe);
+ iframe.contentDocument.body.innerHTML =
+ "<br><div id='target0' style='width: 30px; height: 30px; background: black;'></div>" +
+ "<br><div id='target1' style='width: 30px; height: 30px; background: red;'></div>" +
+ "<br><div id='done' style='width: 30px; height: 30px; background: green;'></div>";
+
+ let target0 = iframe.contentDocument.getElementById("target0");
+ let target1 = iframe.contentDocument.getElementById("target1");
+ let done = iframe.contentDocument.getElementById("done");
+ let pointerBoundaryEvents = ["pointerover", "pointerenter", "pointerleave", "pointerout"];
+ let mouseBoundaryEvents = ["mouseover", "mouseenter", "mouseleave", "mouseout"];
+ let receivedPointerBoundaryEvents = {};
+ let mouseEvent2pointerEvent = {"mouseover": "pointerover",
+ "mouseenter": "pointerenter",
+ "mouseleave": "pointerleave",
+ "mouseout": "pointerout"
+ };
+
+ pointerBoundaryEvents.forEach((event) => {
+ target1.addEventListener(event, (e) => {
+ receivedPointerBoundaryEvents[event] = e;
+ });
+ });
+
+ let attributes = ["target", "relatedTarget"];
+ mouseBoundaryEvents.forEach((event) => {
+ target1.addEventListener(event, (e) => {
+ let correspondingPointerEv = receivedPointerBoundaryEvents[mouseEvent2pointerEvent[event]];
+ ok(correspondingPointerEv, "Should receive " + mouseEvent2pointerEvent[event] + " before " + e.type);
+ if (correspondingPointerEv) {
+ attributes.forEach((attr) => {
+ ok(correspondingPointerEv[attr] == e[attr],
+ attr + " of " + e.type + " should be the same as the correcponding pointer event expect " +
+ correspondingPointerEv[attr] + " got " + e[attr]);
+ });
+ }
+ receivedPointerBoundaryEvents[mouseEvent2pointerEvent[event]] = null;
+ });
+ });
+ target0.addEventListener("pointerdown", (e) => {
+ target1.setPointerCapture(e.pointerId);
+ });
+ done.addEventListener("mouseup", () => {
+ SimpleTest.finish();
+ });
+ let source = SpecialPowers.Ci.nsIDOMMouseEvent.MOZ_SOURCE_MOUSE;
+ synthesizeMouse(target0, 5, 5, { type: "mousemove", inputSource: source },
+ iframe.contentWindow);
+ synthesizeMouse(target0, 5, 5, { type: "mousedown", inputSource: source },
+ iframe.contentWindow);
+ synthesizeMouse(target0, 5, 5, { type: "mousemove", inputSource: source },
+ iframe.contentWindow);
+ synthesizeMouse(target0, 5, 5, { type: "mouseup", inputSource: source },
+ iframe.contentWindow);
+ synthesizeMouse(target0, 5, 5, { type: "mousemove", inputSource: source },
+ iframe.contentWindow);
+ synthesizeMouse(done, 5, 5, { type: "mousedown", inputSource: source },
+ iframe.contentWindow);
+ synthesizeMouse(done, 5, 5, { type: "mouseup", inputSource: source },
+ iframe.contentWindow);
+}
+
+SimpleTest.waitForFocus(() => {
+ SpecialPowers.pushPrefEnv({"set": [["dom.w3c_pointer_events.enabled", true]]}, runTests);
+});
+
+</script>
+</body>
+</html>
diff --git a/dom/events/test/pointerevents/test_pointerevent_capture_suppressing_mouse-manual.html b/dom/events/test/pointerevents/test_pointerevent_capture_suppressing_mouse-manual.html index dc3903592..2b08e2bb8 100644 --- a/dom/events/test/pointerevents/test_pointerevent_capture_suppressing_mouse-manual.html +++ b/dom/events/test/pointerevents/test_pointerevent_capture_suppressing_mouse-manual.html @@ -19,7 +19,8 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=1000870 function executeTest(int_win) { sendMouseEvent(int_win, "target0", "mousemove"); sendMouseEvent(int_win, "target1", "mousemove"); - sendMouseEvent(int_win, "btnCapture", "mousedown", {button:1}); + sendMouseEvent(int_win, "btnCapture", "mousemove"); + sendMouseEvent(int_win, "btnCapture", "mousedown"); sendMouseEvent(int_win, "target1", "mousemove"); sendMouseEvent(int_win, "target0", "mousemove"); sendMouseEvent(int_win, "target1", "mousemove"); diff --git a/dom/events/test/pointerevents/test_pointerevent_releasepointercapture_events_to_original_target-manual.html b/dom/events/test/pointerevents/test_pointerevent_releasepointercapture_events_to_original_target-manual.html index cbf91df74..35350e016 100644 --- a/dom/events/test/pointerevents/test_pointerevent_releasepointercapture_events_to_original_target-manual.html +++ b/dom/events/test/pointerevents/test_pointerevent_releasepointercapture_events_to_original_target-manual.html @@ -17,9 +17,30 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=1000870 runTestInNewWindow("pointerevent_releasepointercapture_events_to_original_target-manual.html"); } function executeTest(int_win) { - sendTouchEvent(int_win, "target0", "touchstart"); - sendTouchEvent(int_win, "target0", "touchmove"); - sendTouchEvent(int_win, "target0", "touchend"); + // Synthesize mouse events to run this test. + sendMouseEvent(int_win, "target0", "mousemove"); + sendMouseEvent(int_win, "target0", "mousedown"); + sendMouseEvent(int_win, "target0", "mousemove", {buttons: 1}); + sendMouseEvent(int_win, "target0", "mousemove", {buttons: 1}); + sendMouseEvent(int_win, "target0", "mouseup"); + + window.addEventListener("message", function(aEvent) { + if (aEvent.data == "Test Touch") { + // Synthesize touch events to run this test. + sendTouchEvent(int_win, "target0", "touchstart"); + sendTouchEvent(int_win, "target0", "touchmove"); + sendTouchEvent(int_win, "target0", "touchend"); + window.postMessage("Test Pen", "*"); + } else if (aEvent.data == "Test Pen") { + // Synthesize pen events to run this test. + sendMouseEvent(int_win, "target0", "mousemove", {inputSource:MouseEvent.MOZ_SOURCE_PEN}); + sendMouseEvent(int_win, "target0", "mousedown", {inputSource:MouseEvent.MOZ_SOURCE_PEN}); + sendMouseEvent(int_win, "target0", "mousemove", {inputSource:MouseEvent.MOZ_SOURCE_PEN, buttons: 1}); + sendMouseEvent(int_win, "target0", "mousemove", {inputSource:MouseEvent.MOZ_SOURCE_PEN, buttons: 1}); + sendMouseEvent(int_win, "target0", "mouseup", {inputSource:MouseEvent.MOZ_SOURCE_PEN}); + } + }); + window.postMessage("Test Touch", "*"); } </script> </head> diff --git a/dom/events/test/pointerevents/test_pointerevent_setpointercapture_relatedtarget-manual.html b/dom/events/test/pointerevents/test_pointerevent_setpointercapture_relatedtarget-manual.html index 0883d616b..09e97ec97 100644 --- a/dom/events/test/pointerevents/test_pointerevent_setpointercapture_relatedtarget-manual.html +++ b/dom/events/test/pointerevents/test_pointerevent_setpointercapture_relatedtarget-manual.html @@ -19,8 +19,8 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=1000870 function executeTest(int_win) { sendMouseEvent(int_win, "target1", "mousemove"); sendMouseEvent(int_win, "btnCapture", "mousedown"); - sendMouseEvent(int_win, "target1", "mousemove"); - sendMouseEvent(int_win, "target1", "mouseup"); + sendMouseEvent(int_win, "btnCapture", "mousemove"); + sendMouseEvent(int_win, "btnCapture", "mouseup"); } </script> </head> diff --git a/dom/webidl/PointerEvent.webidl b/dom/webidl/PointerEvent.webidl index 2e83922c8..4e8a0eb90 100644 --- a/dom/webidl/PointerEvent.webidl +++ b/dom/webidl/PointerEvent.webidl @@ -17,8 +17,10 @@ interface PointerEvent : MouseEvent readonly attribute long width; readonly attribute long height; readonly attribute float pressure; + readonly attribute float tangentialPressure; readonly attribute long tiltX; readonly attribute long tiltY; + readonly attribute long twist; readonly attribute DOMString pointerType; readonly attribute boolean isPrimary; }; @@ -29,8 +31,10 @@ dictionary PointerEventInit : MouseEventInit long width = 1; long height = 1; float pressure = 0; + float tangentialPressure = 0; long tiltX = 0; long tiltY = 0; + long twist = 0; DOMString pointerType = ""; boolean isPrimary = false; }; diff --git a/layout/base/nsIPresShell.h b/layout/base/nsIPresShell.h index cbbae0e8f..5990402ed 100644 --- a/layout/base/nsIPresShell.h +++ b/layout/base/nsIPresShell.h @@ -1298,11 +1298,11 @@ public: } }; - static void DispatchGotOrLostPointerCaptureEvent(bool aIsGotCapture, - uint32_t aPointerId, - uint16_t aPointerType, - bool aIsPrimary, - nsIContent* aCaptureTarget); + static void DispatchGotOrLostPointerCaptureEvent( + bool aIsGotCapture, + const mozilla::WidgetPointerEvent* aPointerEvent, + nsIContent* aCaptureTarget); + static PointerCaptureInfo* GetPointerCaptureInfo(uint32_t aPointerId); static void SetPointerCapturingContent(uint32_t aPointerId, nsIContent* aContent); @@ -1311,8 +1311,8 @@ public: // CheckPointerCaptureState checks cases, when got/lostpointercapture events // should be fired. - static void CheckPointerCaptureState(uint32_t aPointerId, - uint16_t aPointerType, bool aIsPrimary); + static void CheckPointerCaptureState( + const mozilla::WidgetPointerEvent* aPointerEvent); // GetPointerInfo returns true if pointer with aPointerId is situated in // device, false otherwise. diff --git a/layout/base/nsPresShell.cpp b/layout/base/nsPresShell.cpp index 56ac370b9..63dfbd8a3 100644 --- a/layout/base/nsPresShell.cpp +++ b/layout/base/nsPresShell.cpp @@ -6514,10 +6514,11 @@ nsIPresShell::GetPointerCapturingContent(uint32_t aPointerId) } /* static */ void -nsIPresShell::CheckPointerCaptureState(uint32_t aPointerId, - uint16_t aPointerType, bool aIsPrimary) +nsIPresShell::CheckPointerCaptureState(const WidgetPointerEvent* aPointerEvent) { - PointerCaptureInfo* captureInfo = GetPointerCaptureInfo(aPointerId); + PointerCaptureInfo* captureInfo = + GetPointerCaptureInfo(aPointerEvent->pointerId); + if (captureInfo && captureInfo->mPendingContent != captureInfo->mOverrideContent) { // cache captureInfo->mPendingContent since it may be changed in the pointer @@ -6525,17 +6526,16 @@ nsIPresShell::CheckPointerCaptureState(uint32_t aPointerId, nsIContent* pendingContent = captureInfo->mPendingContent.get(); if (captureInfo->mOverrideContent) { DispatchGotOrLostPointerCaptureEvent(/* aIsGotCapture */ false, - aPointerId, aPointerType, aIsPrimary, + aPointerEvent, captureInfo->mOverrideContent); } if (pendingContent) { - DispatchGotOrLostPointerCaptureEvent(/* aIsGotCapture */ true, aPointerId, - aPointerType, aIsPrimary, - pendingContent); + DispatchGotOrLostPointerCaptureEvent(/* aIsGotCapture */ true, + aPointerEvent, pendingContent); } captureInfo->mOverrideContent = pendingContent; if (captureInfo->Empty()) { - sPointerCaptureList->Remove(aPointerId); + sPointerCaptureList->Remove(aPointerEvent->pointerId); } } } @@ -6976,37 +6976,30 @@ DispatchPointerFromMouseOrTouch(PresShell* aShell, return NS_OK; } -class ReleasePointerCaptureCaller +class ReleasePointerCaptureCaller final { public: - ReleasePointerCaptureCaller() : - mPointerId(0), - mPointerType(nsIDOMMouseEvent::MOZ_SOURCE_UNKNOWN), - mIsPrimary(false), - mIsSet(false) + ReleasePointerCaptureCaller() + : mPointerEvent(nullptr) { } ~ReleasePointerCaptureCaller() { - if (mIsSet) { - nsIPresShell::ReleasePointerCapturingContent(mPointerId); - nsIPresShell::CheckPointerCaptureState(mPointerId, mPointerType, - mIsPrimary); + if (mPointerEvent) { + nsIPresShell::ReleasePointerCapturingContent(mPointerEvent->pointerId); + nsIPresShell::CheckPointerCaptureState(mPointerEvent); } } - void SetTarget(uint32_t aPointerId, uint16_t aPointerType, bool aIsPrimary) + + void SetTarget(const WidgetPointerEvent* aPointerEvent) { - mPointerId = aPointerId; - mPointerType = aPointerType; - mIsPrimary = aIsPrimary; - mIsSet = true; + MOZ_ASSERT(aPointerEvent); + mPointerEvent = aPointerEvent; } private: - int32_t mPointerId; - uint16_t mPointerType; - bool mIsPrimary; - bool mIsSet; + // This is synchronously used inside PresShell::HandleEvent. + const WidgetPointerEvent* mPointerEvent; }; static bool @@ -7719,9 +7712,7 @@ PresShell::HandleEvent(nsIFrame* aFrame, nsWeakFrame frameKeeper(frame); // Handle pending pointer capture before any pointer events except // gotpointercapture / lostpointercapture. - CheckPointerCaptureState(pointerEvent->pointerId, - pointerEvent->inputSource, - pointerEvent->mIsPrimary); + CheckPointerCaptureState(pointerEvent); // Prevent application crashes, in case damaged frame. if (!frameKeeper.IsAlive()) { frame = nullptr; @@ -7742,33 +7733,29 @@ PresShell::HandleEvent(nsIFrame* aFrame, } } - if (aEvent->mClass == ePointerEventClass && - aEvent->mMessage != ePointerDown) { - if (WidgetPointerEvent* pointerEvent = aEvent->AsPointerEvent()) { - uint32_t pointerId = pointerEvent->pointerId; + // Mouse events should be fired to the same target as their mapped pointer + // events + if ((aEvent->mClass == ePointerEventClass || + aEvent->mClass == eMouseEventClass) && + aEvent->mMessage != ePointerDown && aEvent->mMessage != eMouseDown) { + if (WidgetMouseEvent* mouseEvent = aEvent->AsMouseEvent()) { + uint32_t pointerId = mouseEvent->pointerId; nsIContent* pointerCapturingContent = GetPointerCapturingContent(pointerId); if (pointerCapturingContent) { if (nsIFrame* capturingFrame = pointerCapturingContent->GetPrimaryFrame()) { - // If pointer capture is set, we should suppress - // pointerover/pointerenter events for all elements except element - // which have pointer capture. (Code in EventStateManager) - pointerEvent->retargetedByPointerCapture = - frame && frame->GetContent() && - !nsContentUtils::ContentIsDescendantOf(frame->GetContent(), - pointerCapturingContent); frame = capturingFrame; } - if (pointerEvent->mMessage == ePointerUp || - pointerEvent->mMessage == ePointerCancel) { + if (aEvent->mMessage == ePointerUp || + aEvent->mMessage == ePointerCancel) { // Implicitly releasing capture for given pointer. // ePointerLostCapture should be send after ePointerUp or // ePointerCancel. - releasePointerCaptureCaller.SetTarget(pointerId, - pointerEvent->inputSource, - pointerEvent->mIsPrimary); + WidgetPointerEvent* pointerEvent = aEvent->AsPointerEvent(); + MOZ_ASSERT(pointerEvent); + releasePointerCaptureCaller.SetTarget(pointerEvent); } } } @@ -8340,35 +8327,44 @@ PresShell::HandleEventInternal(WidgetEvent* aEvent, return rv; } -void -nsIPresShell::DispatchGotOrLostPointerCaptureEvent(bool aIsGotCapture, - uint32_t aPointerId, - uint16_t aPointerType, - bool aIsPrimary, - nsIContent* aCaptureTarget) -{ - PointerEventInit init; - init.mPointerId = aPointerId; - init.mBubbles = true; - ConvertPointerTypeToString(aPointerType, init.mPointerType); - init.mIsPrimary = aIsPrimary; - RefPtr<mozilla::dom::PointerEvent> event; - event = PointerEvent::Constructor(aCaptureTarget, - aIsGotCapture - ? NS_LITERAL_STRING("gotpointercapture") - : NS_LITERAL_STRING("lostpointercapture"), - init); - if (event) { +/* static */ void +nsIPresShell::DispatchGotOrLostPointerCaptureEvent( + bool aIsGotCapture, + const WidgetPointerEvent* aPointerEvent, + nsIContent* aCaptureTarget) +{ + nsIDocument* targetDoc = aCaptureTarget->OwnerDoc(); + nsCOMPtr<nsIPresShell> shell = targetDoc->GetShell(); + NS_ENSURE_TRUE_VOID(shell); + + if (!aIsGotCapture && !aCaptureTarget->IsInUncomposedDoc()) { + // If the capturing element was removed from the DOM tree, fire + // ePointerLostCapture at the document. + PointerEventInit init; + init.mPointerId = aPointerEvent->pointerId; + init.mBubbles = true; + init.mComposed = true; + ConvertPointerTypeToString(aPointerEvent->inputSource, init.mPointerType); + init.mIsPrimary = aPointerEvent->mIsPrimary; + RefPtr<mozilla::dom::PointerEvent> event; + event = PointerEvent::Constructor(aCaptureTarget, + NS_LITERAL_STRING("lostpointercapture"), + init); bool dummy; - // If the capturing element was removed from the DOM tree, - // lostpointercapture event should be fired at the document. - if (!aIsGotCapture && !aCaptureTarget->IsInUncomposedDoc()) { - aCaptureTarget->OwnerDoc()->DispatchEvent(event->InternalDOMEvent(), - &dummy); - } else { - aCaptureTarget->DispatchEvent(event->InternalDOMEvent(), &dummy); - } + targetDoc->DispatchEvent(event->InternalDOMEvent(), &dummy); + return; } + nsEventStatus status = nsEventStatus_eIgnore; + WidgetPointerEvent localEvent(aPointerEvent->IsTrusted(), + aIsGotCapture ? ePointerGotCapture : + ePointerLostCapture, + aPointerEvent->mWidget); + localEvent.AssignPointerEventData(*aPointerEvent, true); + nsresult rv = shell->HandleEventWithTarget( + &localEvent, + aCaptureTarget->GetPrimaryFrame(), + aCaptureTarget, &status); + NS_ENSURE_SUCCESS_VOID(rv); } nsresult diff --git a/layout/base/tests/bug1078327_inner.html b/layout/base/tests/bug1078327_inner.html index 9e32fc996..0cfb9da7f 100644 --- a/layout/base/tests/bug1078327_inner.html +++ b/layout/base/tests/bug1078327_inner.html @@ -24,16 +24,16 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=1078327 var test_mediator_move = false; var test_mediator_out = false; var test_listener = false; + var test_lost_capture = false; function TargetHandler(event) { logger("Target receive event: " + event.type + ". Mediator.setPointerCapture()"); mediator.setPointerCapture(event.pointerId); test_target = true; + test_capture = true; } function MediatorHandler(event) { logger("Mediator receive event: " + event.type); - if(event.type == "gotpointercapture") - test_capture = true; if(!test_capture) return; if(event.type == "pointermove") @@ -43,7 +43,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=1078327 if(event.type == "pointerout") test_mediator_out++; if(event.type == "lostpointercapture") - test_capture = false; + test_lost_capture = true; } function ListenerHandler(event) { logger("Listener receive event: " + event.type); @@ -86,7 +86,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=1078327 } function finishTest() { parent.is(test_target, true, "pointerdown event should be received by target"); - parent.is(test_capture, false, "test_capture should be false at the end of the test"); + parent.is(test_lost_capture, true, "mediator should receive lostpointercapture"); parent.is(test_mediator_over, 1, "mediator should receive pointerover event only once"); parent.is(test_mediator_move, 5, "mediator should receive pointermove event five times"); parent.is(test_mediator_out, 1, "mediator should receive pointerout event only once"); diff --git a/layout/base/tests/bug1162990_inner_1.html b/layout/base/tests/bug1162990_inner_1.html index 4ea5edb5c..0f950df8d 100644 --- a/layout/base/tests/bug1162990_inner_1.html +++ b/layout/base/tests/bug1162990_inner_1.html @@ -111,10 +111,10 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=1162990 } function finishTest() { - parent.is(test_basketLeave, 0, "Part1: basket should not receive pointerleave event after pointer capturing"); + parent.is(test_basketLeave, 1, "Part1: basket should receive pointerleave event after pointer capturing"); parent.is(test_targetGotCapture, 1, "Part1: target should receive gotpointercapture event"); parent.is(test_targetLostCapture, 1, "Part1: target should receive lostpointercapture event"); - parent.is(test_targetLeave, 2, "Part1: target should receive pointerleave event two times"); + parent.is(test_targetLeave, 1, "Part1: target should receive pointerleave event only one time"); parent.is(test_childLeave, 0, "Part1: child should not receive pointerleave event after pointer capturing"); parent.is(test_listenerDown, 1, "Part1: listener should receive pointerdown event"); parent.is(test_listenerLeave, 1, "Part1: listener should receive pointerleave event only one time"); diff --git a/layout/base/tests/bug1162990_inner_2.html b/layout/base/tests/bug1162990_inner_2.html index 54aa74ca3..e418927bd 100644 --- a/layout/base/tests/bug1162990_inner_2.html +++ b/layout/base/tests/bug1162990_inner_2.html @@ -116,7 +116,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=1162990 parent.is(test_targetDown, 1, "Part2: target should receive pointerdown event"); parent.is(test_targetGotCapture, 1, "Part2: target should receive gotpointercapture event"); parent.is(test_targetLostCapture, 1, "Part2: target should receive lostpointercapture event"); - parent.is(test_targetLeave, 1, "Part2: target should receive pointerleave event"); + parent.is(test_targetLeave, 0, "Part2: target should not receive pointerleave event"); parent.is(test_childLeave, 0, "Part2: child should not receive pointerleave event after pointer capturing"); parent.is(test_listenerLeave, 0, "Part2: listener should not receive pointerleave event after pointer capturing"); logger("finishTest"); diff --git a/layout/base/tests/bug976963_inner.html b/layout/base/tests/bug976963_inner.html deleted file mode 100644 index 2c55fbccd..000000000 --- a/layout/base/tests/bug976963_inner.html +++ /dev/null @@ -1,241 +0,0 @@ -<!DOCTYPE HTML> -<html> -<!-- -https://bugzilla.mozilla.org/show_bug.cgi?id=976963 ---> -<head> - <meta charset="utf-8"> - <title>Test for Bug 976963</title> - <meta name="author" content="Maksim Lebedev" /> - <script type="application/javascript" src="/tests/SimpleTest/EventUtils.js"></script> - <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> - <style> - div#listener { - background: yellow; - position: absolute; - top: -100px; - } - div#middler { - background: yellow; - margin: 10px; - } - div#target { - background: yellow; - } - </style> - <script type="application/javascript"> - /** Test for Bug 976963 **/ - var All_Pointer_Events = ["pointerover", "pointerenter", - "pointermove", - "pointerdown", "pointerup", - "pointerout", "pointerleave", - "pointercancel", - "gotpointercapture", "lostpointercapture"]; - - function on_event(object, event, callback) { - object.addEventListener(event, callback, false); - } - function ok(check, msg) { - parent.ok(check, msg); - } - function is(a, b, msg) { - parent.is(a, b, msg); - } - - var listener = undefined; - var middler = undefined; - var target = undefined; - - var test_ListenerGotCapture = 0; - var test_ListenerUnwanted = 0; - var test_ListenerLostCapture = 0; - var test_ListenerAfterCapture = 0; - var test_MiddlerGotCapture = 0; - var test_MiddlerOver = 0; - var test_MiddlerLeave = 0; - var test_MiddlerUp = 0; - var test_MiddlerLostCapture = 0; - var test_TargetDown = 0; - var test_TargetUnwanted = 0; - var test_TargetUp = 0; - - var captured_event = undefined; - var f_gotPointerCapture = false; - var f_lostPointerCapture = false; - var f_gotMiddlerPointerCapture = false; - - function listenerEventHandler(event) { - logger("Listener: " + event.type + ". Captured_event: " + captured_event); - if(test_ListenerLostCapture) - test_ListenerAfterCapture++; - if (event.type == "gotpointercapture") { - f_gotPointerCapture = true; - test_ListenerGotCapture++; - } - else if (event.type == "lostpointercapture") { - f_lostPointerCapture = true; - f_gotPointerCapture = false; - test_ListenerLostCapture++; - } - else if (event.type == "pointermove") { - ok(captured_event && captured_event.pointerId == event.pointerId, "Listener: equals pointerId for lostpointercapture event"); - if (f_gotPointerCapture) { - // on first event received for capture, release capture - logger("Listener call release"); - ok(!!listener, "Listener should be live!"); - ok(typeof(listener.releasePointerCapture) == "function", "Listener should have a function releasePointerCapture"); - listener.releasePointerCapture(event.pointerId); - } - else { - logger("Listener.ASSERT: " + event.type); - test_ListenerUnwanted++; - // if any other events are received after releaseCapture, then the test fails - ok(false, event.target.id + "-" + event.type + " should be handled by target element handler"); - } - } - else { - test_ListenerUnwanted++; - logger("Listener.ASSERT: " + event.type); - ok(false, event.type + "should be never handled by listener"); - } - } - - function middlerEventHandler(event) { - logger("Middler: " + event.type + ". Captured_event: " + captured_event); - if (event.type == "gotpointercapture") { - test_MiddlerGotCapture++; - f_gotMiddlerPointerCapture = true; - ok(captured_event && captured_event.pointerId == event.pointerId, "Middler: equals pointerId for gotpointercapture event"); - } - else if (event.type == "pointerover") { - test_MiddlerOver++; - ok(captured_event && captured_event.pointerId == event.pointerId, "Middler: equals pointerId for pointerover event"); - } - else if (event.type == "pointerleave") { - test_MiddlerLeave++; - ok(captured_event && captured_event.pointerId == event.pointerId, "Middler: equals pointerId for pointerleave event"); - ok(!!listener, "Listener should be live!"); - ok(typeof(listener.setPointerCapture) == "function", "Listener should have a function setPointerCapture"); - listener.setPointerCapture(event.pointerId); - } - else if (event.type == "lostpointercapture") { - test_MiddlerLostCapture++; - f_gotMiddlerPointerCapture = false; - ok(captured_event && captured_event.pointerId == event.pointerId, "Middler: equals pointerId for lostpointercapture event"); - } - else if (event.type == "pointerup" ) { - test_MiddlerUp++; - } - } - - function targetEventHandler(event) { - logger("Target: " + event.type + ". Captured_event: " + captured_event); - if (f_gotPointerCapture || f_gotMiddlerPointerCapture) { - if (event.type != "pointerout" && event.type != "pointerleave") { - logger("Target.ASSERT: " + event.type + " " + event.pointerId); - test_TargetUnwanted++; - ok(false, "The Target element should not have received any events while capture is active. Event recieved:" + event.type + ". "); - } - } - if (event.type == "pointerdown") { - logger("Target.pointerdown 1: " + captured_event); - test_TargetDown++; - captured_event = event; - ok(!!middler, "Middler should be live!"); - ok(typeof(middler.setPointerCapture) == "function", "Middler should have a function setPointerCapture"); - middler.setPointerCapture(event.pointerId); - logger("Target.pointerdown 2: " + captured_event); - } - else if (event.type == "pointerup") { - ok(f_lostPointerCapture, "Target should have received pointerup"); - ok(captured_event && captured_event.pointerId == event.pointerId, "Target: equals pointerId for lostpointercapture event"); - test_TargetUp++; // complete test - } - } - - function colorerHandler(event) { - if(event.type == "pointerover") - event.target.style.background = "red"; - else if(event.type == "pointerout") - event.target.style.background = "yellow"; - } - - function setEventHandlers() { - listener = document.getElementById("listener"); - middler = document.getElementById("middler"); - target = document.getElementById("target"); - target.style["touchAction"] = "none"; - - // target and listener - handle all events - for (var i = 0; i < All_Pointer_Events.length; i++) { - on_event(target, All_Pointer_Events[i], targetEventHandler); - on_event(listener, All_Pointer_Events[i], listenerEventHandler); - on_event(middler, All_Pointer_Events[i], middlerEventHandler); - on_event(target, All_Pointer_Events[i], colorerHandler); - on_event(middler, All_Pointer_Events[i], colorerHandler); - } - } - - function prepareTest() { - SpecialPowers.pushPrefEnv({ - "set": [ - ["dom.w3c_pointer_events.enabled", true] - ] - }, executeTest); - } - - function executeTest() - { - logger("executeTest"); - setEventHandlers(); - document.body.offsetLeft; - var rect = target.getBoundingClientRect(); - synthesizePointer(target, rect.width/2, rect.height/2, {type: "pointermove"}); - synthesizePointer(target, rect.width/2, rect.height/2, {type: "pointerdown"}); - synthesizePointer(target, rect.width/3, rect.height/3, {type: "pointermove"}); - synthesizePointer(middler, rect.width/2, rect.height/2, {type: "pointermove"}); - synthesizePointer(target, rect.width/2, rect.height/2, {type: "pointermove"}); - synthesizePointer(middler, rect.width/2, rect.height/2, {type: "pointermove"}); - synthesizePointer(target, rect.width/2, rect.height/2, {type: "pointermove"}); - synthesizePointer(target, rect.width/2, rect.height/2, {type: "pointerup"}); - finishTest(); - } - - function finishTest() { - setTimeout(function() { - is(test_ListenerGotCapture, 1, "Listener should receive gotpointercapture event"); - is(test_ListenerUnwanted, 0, "Listener should not receive any unwanted events"); - is(test_ListenerLostCapture, 1, "Listener should receive lostpointercapture event"); - is(test_ListenerAfterCapture, 0, "Listener should not receive any events after release pointer capture"); - is(test_MiddlerGotCapture, 1, "Middler should receive gotpointercapture event"); - is(test_MiddlerOver, 1, "Middler should receive pointerover event"); - is(test_MiddlerLeave, 1, "Middler should receive pointerleave event"); - is(test_MiddlerUp, 0, "Middler should not receive pointerup event"); - is(test_MiddlerLostCapture, 1, "Middler should receive lostpointercapture event"); - is(test_TargetDown, 1, "Target should receive pointerdown event"); - is(test_TargetUnwanted, 0, "Target should not receive any event while pointer capture is active"); - is(test_TargetUp, 1, "Target should receive pointerup event"); - logger("finishTest"); - parent.finishTest(); - }, 1000); - } - - function logger(message) { - console.log(message); - var log = document.getElementById('log'); - log.innerHTML = message + "<br>" + log.innerHTML; - } - </script> -</head> -<body onload="prepareTest()"> - <a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=976963">Mozilla Bug 976963</a> - <p id="display"></p> - <div id="content" style="display: none"> - </div> - <div id="listener">div id=listener</div> - <div id="middler">div id=middler</div> - <div id="target">div id=target</div> - <pre id="log"> - </pre> -</body> -</html> diff --git a/layout/base/tests/bug977003_inner_5.html b/layout/base/tests/bug977003_inner_5.html index 70fc5ba40..81094043c 100644 --- a/layout/base/tests/bug977003_inner_5.html +++ b/layout/base/tests/bug977003_inner_5.html @@ -26,6 +26,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=1098139 var test_lost_listener = false; var test_lost_type = ""; var test_move_listener = false; + var test_over_listener = false; var test_listener = false; var test_lost_primary = false; @@ -53,6 +54,10 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=1098139 logger("Receive event on Listener: " + event.type); test_move_listener = true; } + function ListenerOverHandler(event) { + logger("Receive event on Listener: " + event.type); + test_over_listener = true; + } function ListenerHandler(event) { logger("Receive event on Listener: " + event.type); test_listener = true; @@ -74,7 +79,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=1098139 target.addEventListener("pointerdown", TargetDownHandler, false); listener.addEventListener("gotpointercapture", ListenerGotPCHandler, false); listener.addEventListener("lostpointercapture", ListenerLostPCHandler, false); - listener.addEventListener("pointerover", ListenerHandler, false); + listener.addEventListener("pointerover", ListenerOverHandler, false); listener.addEventListener("pointermove", ListenerMoveHandler, false); listener.addEventListener("pointerup", ListenerHandler, false); listener.addEventListener("pointerout", ListenerHandler, false); @@ -93,6 +98,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=1098139 parent.is(test_lost_type, "touch", "Part 5: lostpointercapture event should have pointerType touch"); parent.is(test_lost_primary, true, "Part 5: lostpointercapture event should have isPrimary as true"); parent.is(test_move_listener, true, "Part 5: gotpointercapture should be triggered by pointermove"); + parent.is(test_over_listener, true, "Part 5: listener should receive pointerover when capturing pointer"); parent.is(test_listener, false, "Part 5: listener should not receive any other events"); logger("finishTest"); parent.finishTest(); diff --git a/layout/base/tests/bug977003_inner_6.html b/layout/base/tests/bug977003_inner_6.html index 12424b1f2..b60ca5c31 100644 --- a/layout/base/tests/bug977003_inner_6.html +++ b/layout/base/tests/bug977003_inner_6.html @@ -19,6 +19,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=1073563 var listener = undefined; var test_target = false; var test_move = false; + var test_over = false; var test_listener = false; var receive_lostpointercapture = false; @@ -44,6 +45,8 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=1073563 } } else if(event.type == "pointermove") { test_move = true; + } else if(event.type == "pointerover") { + test_over = true; } else { test_listener = true; } @@ -81,7 +84,8 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=1073563 // PE level 2 defines that the pending pointer capture is processed when firing next pointer events. // In this test case, pointer capture release is processed when firing pointermove parent.is(test_move, true, "Part 6: gotpointercapture should be triggered by pointermove"); - parent.is(test_listener, false, "Part 6: no other pointerevents should be fired before gotpointercapture"); + parent.is(test_over, true, "Part 6: pointerover should be received when capturing pointer"); + parent.is(test_listener, false, "Part 6: no other pointerevents should be fired before gotpointercapture except pointerover"); logger("finishTest"); parent.finishTest(); } diff --git a/layout/base/tests/mochitest.ini b/layout/base/tests/mochitest.ini index 279b0af8a..405697977 100644 --- a/layout/base/tests/mochitest.ini +++ b/layout/base/tests/mochitest.ini @@ -256,8 +256,6 @@ skip-if = toolkit == 'android' support-files = bug851445_helper.html [test_bug970964.html] support-files = bug970964_inner.html -[test_bug976963.html] -support-files = bug976963_inner.html [test_bug977003.html] support-files = bug977003_inner_1.html diff --git a/layout/base/tests/test_bug976963.html b/layout/base/tests/test_bug976963.html deleted file mode 100644 index 4b8da3a6e..000000000 --- a/layout/base/tests/test_bug976963.html +++ /dev/null @@ -1,35 +0,0 @@ -<!DOCTYPE HTML> -<html> -<!-- -https://bugzilla.mozilla.org/show_bug.cgi?id=976963 ---> - <head> - <meta charset="utf-8"> - <meta name="author" content="Maksim Lebedev" /> - <title>Test for Bug 976963</title> - <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> - <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> - <script type="text/javascript"> - function prepareTest() { - SimpleTest.waitForExplicitFinish(); - SimpleTest.requestFlakyTimeout("untriaged"); - SpecialPowers.pushPrefEnv({ - "set": [ - ["dom.w3c_pointer_events.enabled", true], - ["layout.reflow.synthMouseMove", false] - ] - }, startTest); - } - function startTest() { - var iframe = document.getElementById("testFrame"); - iframe.src = "bug976963_inner.html"; - } - function finishTest() { - SimpleTest.finish(); - } - </script> - </head> - <body onload="prepareTest()"> - <iframe id="testFrame" height="700" width="700"></iframe> - </body> -</html> diff --git a/old-configure.in b/old-configure.in index 9d57839e3..511f40653 100644 --- a/old-configure.in +++ b/old-configure.in @@ -2411,15 +2411,6 @@ if test -n "$WITH_APP_BASENAME" ; then MOZ_APP_BASENAME="$WITH_APP_BASENAME" fi -# Special cases where we need to AC_DEFINE something. Also a holdover for apps -# that haven't made a confvars.sh yet. Don't add new stuff here, use -# MOZ_BUILD_APP. -case "$MOZ_BUILD_APP" in -xulrunner) - AC_DEFINE(MOZ_XULRUNNER) - ;; -esac - if test -n "$MOZ_B2G"; then AC_DEFINE(MOZ_B2G) fi @@ -2429,7 +2420,6 @@ if test -n "$MOZ_GRAPHENE"; then AC_DEFINE(MOZ_GRAPHENE) fi -AC_SUBST(MOZ_XULRUNNER) AC_SUBST(MOZ_B2G) AC_SUBST(MOZ_B2G_VERSION) diff --git a/toolkit/components/places/nsNavBookmarks.cpp b/toolkit/components/places/nsNavBookmarks.cpp index 74707be99..693aaf5db 100644 --- a/toolkit/components/places/nsNavBookmarks.cpp +++ b/toolkit/components/places/nsNavBookmarks.cpp @@ -2518,8 +2518,6 @@ nsNavBookmarks::GetURIForKeyword(const nsAString& aUserCasedKeyword, NS_ENSURE_TRUE(!aUserCasedKeyword.IsEmpty(), NS_ERROR_INVALID_ARG); *aURI = nullptr; - PLACES_WARN_DEPRECATED(); - // Shortcuts are always lowercased internally. nsAutoString keyword(aUserCasedKeyword); ToLowerCase(keyword); diff --git a/toolkit/components/places/nsNavHistory.cpp b/toolkit/components/places/nsNavHistory.cpp index 7f4007c1a..49d911d65 100644 --- a/toolkit/components/places/nsNavHistory.cpp +++ b/toolkit/components/places/nsNavHistory.cpp @@ -2796,8 +2796,6 @@ nsNavHistory::MarkPageAsFollowedLink(nsIURI *aURI) NS_IMETHODIMP nsNavHistory::GetPageTitle(nsIURI* aURI, nsAString& aTitle) { - PLACES_WARN_DEPRECATED(); - NS_ASSERTION(NS_IsMainThread(), "This can only be called on the main thread"); NS_ENSURE_ARG(aURI); diff --git a/toolkit/components/webextensions/ExtensionChild.jsm b/toolkit/components/webextensions/ExtensionChild.jsm index c953dd685..5dc4e2277 100644 --- a/toolkit/components/webextensions/ExtensionChild.jsm +++ b/toolkit/components/webextensions/ExtensionChild.jsm @@ -325,7 +325,7 @@ class Messenger { return this.sendMessage(messageManager, msg, recipient, responseCallback); } - onMessage(name) { + _onMessage(name, filter) { return new SingletonEventManager(this.context, name, callback => { let listener = { messageFilterPermissive: this.optionalFilter, @@ -333,7 +333,8 @@ class Messenger { filterMessage: (sender, recipient) => { // Ignore the message if it was sent by this Messenger. - return sender.contextId !== this.context.contextId; + return (sender.contextId !== this.context.contextId && + filter(sender, recipient)); }, receiveMessage: ({target, data: message, sender, recipient}) => { @@ -373,6 +374,14 @@ class Messenger { }).api(); } + onMessage(name) { + return this._onMessage(name, sender => sender.id === this.sender.id); + } + + onMessageExternal(name) { + return this._onMessage(name, sender => sender.id !== this.sender.id); + } + _connect(messageManager, port, recipient) { let msg = { name: port.name, @@ -407,7 +416,7 @@ class Messenger { return this._connect(messageManager, port, recipient); } - onConnect(name) { + _onConnect(name, filter) { return new SingletonEventManager(this.context, name, callback => { let listener = { messageFilterPermissive: this.optionalFilter, @@ -415,7 +424,8 @@ class Messenger { filterMessage: (sender, recipient) => { // Ignore the port if it was created by this Messenger. - return sender.contextId !== this.context.contextId; + return (sender.contextId !== this.context.contextId && + filter(sender, recipient)); }, receiveMessage: ({target, data: message, sender}) => { @@ -438,6 +448,14 @@ class Messenger { }; }).api(); } + + onConnect(name) { + return this._onConnect(name, sender => sender.id === this.sender.id); + } + + onConnectExternal(name) { + return this._onConnect(name, sender => sender.id !== this.sender.id); + } } var apiManager = new class extends SchemaAPIManager { @@ -745,7 +763,7 @@ class ExtensionPageContextChild extends BaseContext { // This is the MessageSender property passed to extension. // It can be augmented by the "page-open" hook. - let sender = {id: extension.uuid}; + let sender = {id: extension.id}; if (viewType == "tab") { sender.tabId = tabId; this.tabId = tabId; diff --git a/toolkit/components/webextensions/ExtensionCommon.jsm b/toolkit/components/webextensions/ExtensionCommon.jsm index a339fb27e..9ec84b5c7 100644 --- a/toolkit/components/webextensions/ExtensionCommon.jsm +++ b/toolkit/components/webextensions/ExtensionCommon.jsm @@ -197,10 +197,9 @@ class BaseContext { * @returns {Promise} */ sendMessage(target, messageName, data, options = {}) { - options.recipient = options.recipient || {}; + options.recipient = Object.assign({extensionId: this.extension.id}, options.recipient); options.sender = options.sender || {}; - options.recipient.extensionId = this.extension.id; options.sender.extensionId = this.extension.id; options.sender.contextId = this.contextId; diff --git a/toolkit/components/webextensions/ExtensionContent.jsm b/toolkit/components/webextensions/ExtensionContent.jsm index 9b9a02091..5bdcde6f5 100644 --- a/toolkit/components/webextensions/ExtensionContent.jsm +++ b/toolkit/components/webextensions/ExtensionContent.jsm @@ -456,7 +456,7 @@ class ContentScriptContextChild extends BaseContext { defineLazyGetter(ContentScriptContextChild.prototype, "messenger", function() { // The |sender| parameter is passed directly to the extension. - let sender = {id: this.extension.uuid, frameId: this.frameId, url: this.url}; + let sender = {id: this.extension.id, frameId: this.frameId, url: this.url}; let filter = {extensionId: this.extension.id}; let optionalFilter = {frameId: this.frameId}; diff --git a/toolkit/components/webextensions/LegacyExtensionsUtils.jsm b/toolkit/components/webextensions/LegacyExtensionsUtils.jsm index 7632548e3..e8d276fe9 100644 --- a/toolkit/components/webextensions/LegacyExtensionsUtils.jsm +++ b/toolkit/components/webextensions/LegacyExtensionsUtils.jsm @@ -64,7 +64,7 @@ var LegacyExtensionContext = class extends BaseContext { {value: cloneScope, enumerable: true, configurable: true, writable: true} ); - let sender = {id: targetExtension.uuid}; + let sender = {id: targetExtension.id}; let filter = {extensionId: targetExtension.id}; // Legacy addons live in the main process. Messages from other addons are // Messages from WebExtensions are sent to the main process and forwarded via diff --git a/toolkit/components/webextensions/ext-c-runtime.js b/toolkit/components/webextensions/ext-c-runtime.js index 8adca60ca..1dcac35da 100644 --- a/toolkit/components/webextensions/ext-c-runtime.js +++ b/toolkit/components/webextensions/ext-c-runtime.js @@ -9,6 +9,10 @@ function runtimeApiFactory(context) { onMessage: context.messenger.onMessage("runtime.onMessage"), + onConnectExternal: context.messenger.onConnectExternal("runtime.onConnectExternal"), + + onMessageExternal: context.messenger.onMessageExternal("runtime.onMessageExternal"), + connect: function(extensionId, connectInfo) { let name = connectInfo !== null && connectInfo.name || ""; extensionId = extensionId || extension.id; @@ -47,7 +51,6 @@ function runtimeApiFactory(context) { if (options != null && typeof options != "object") { return Promise.reject({message: "runtime.sendMessage's options argument is invalid"}); } - // TODO(robwu): Validate option keys and values when we support it. extensionId = extensionId || extension.id; let recipient = {extensionId}; diff --git a/toolkit/components/webextensions/schemas/runtime.json b/toolkit/components/webextensions/schemas/runtime.json index b3f12a768..575df7d27 100644 --- a/toolkit/components/webextensions/schemas/runtime.json +++ b/toolkit/components/webextensions/schemas/runtime.json @@ -535,7 +535,6 @@ }, { "name": "onConnectExternal", - "unsupported": true, "type": "function", "description": "Fired when a connection is made from another extension.", "parameters": [ @@ -560,7 +559,6 @@ }, { "name": "onMessageExternal", - "unsupported": true, "type": "function", "description": "Fired when a message is sent from another extension/app. Cannot be used in a content script.", "parameters": [ diff --git a/toolkit/components/webextensions/test/mochitest/mochitest.ini b/toolkit/components/webextensions/test/mochitest/mochitest.ini index 45586237e..1f61060ad 100644 --- a/toolkit/components/webextensions/test/mochitest/mochitest.ini +++ b/toolkit/components/webextensions/test/mochitest/mochitest.ini @@ -59,6 +59,7 @@ skip-if = os == 'android' # Android does not support tabs API. Bug 1260250 [test_ext_contentscript_teardown.html] skip-if = (os == 'android') # Android does not support tabs API. Bug 1260250 [test_ext_exclude_include_globs.html] +[test_ext_external_messaging.html] [test_ext_i18n_css.html] [test_ext_generate.html] [test_ext_notifications.html] diff --git a/toolkit/components/webextensions/test/mochitest/test_ext_all_apis.js b/toolkit/components/webextensions/test/mochitest/test_ext_all_apis.js index 0f617c37e..25d04b36b 100644 --- a/toolkit/components/webextensions/test/mochitest/test_ext_all_apis.js +++ b/toolkit/components/webextensions/test/mochitest/test_ext_all_apis.js @@ -75,7 +75,9 @@ let expectedBackgroundApis = [ "runtime.getBackgroundPage", "runtime.getBrowserInfo", "runtime.getPlatformInfo", + "runtime.onConnectExternal", "runtime.onInstalled", + "runtime.onMessageExternal", "runtime.onStartup", "runtime.onUpdateAvailable", "runtime.openOptionsPage", diff --git a/toolkit/components/webextensions/test/mochitest/test_ext_external_messaging.html b/toolkit/components/webextensions/test/mochitest/test_ext_external_messaging.html new file mode 100644 index 000000000..dfc1f9427 --- /dev/null +++ b/toolkit/components/webextensions/test/mochitest/test_ext_external_messaging.html @@ -0,0 +1,111 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>WebExtension external messaging</title> + <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <script type="text/javascript" src="/tests/SimpleTest/SpawnTask.js"></script> + <script type="text/javascript" src="/tests/SimpleTest/ExtensionTestUtils.js"></script> + <script type="text/javascript" src="head.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body> + +<script type="text/javascript"> +"use strict"; + +function backgroundScript(id, otherId) { + browser.runtime.onMessage.addListener((msg, sender) => { + browser.test.fail(`Got unexpected message: ${uneval(msg)} ${uneval(sender)}`); + }); + + browser.runtime.onConnect.addListener(port => { + browser.test.fail(`Got unexpected connection: ${uneval(port.sender)}`); + }); + + browser.runtime.onMessageExternal.addListener((msg, sender) => { + browser.test.assertEq(otherId, sender.id, `${id}: Got expected external sender ID`); + browser.test.assertEq(`helo-${id}`, msg, "Got expected message"); + + browser.test.sendMessage("onMessage-done"); + + return Promise.resolve(`ehlo-${otherId}`); + }); + + browser.runtime.onConnectExternal.addListener(port => { + browser.test.assertEq(otherId, port.sender.id, `${id}: Got expected external connecter ID`); + + port.onMessage.addListener(msg => { + browser.test.assertEq(`helo-${id}`, msg, "Got expected port message"); + + port.postMessage(`ehlo-${otherId}`); + + browser.test.sendMessage("onConnect-done"); + }); + }); + + browser.test.onMessage.addListener(msg => { + if (msg === "go") { + browser.runtime.sendMessage(otherId, `helo-${otherId}`).then(result => { + browser.test.assertEq(`ehlo-${id}`, result, "Got expected reply"); + browser.test.sendMessage("sendMessage-done"); + }); + + let port = browser.runtime.connect(otherId); + port.postMessage(`helo-${otherId}`); + + port.onMessage.addListener(msg => { + port.disconnect(); + + browser.test.assertEq(msg, `ehlo-${id}`, "Got expected port reply"); + browser.test.sendMessage("connect-done"); + }); + } + }); +} + +function makeExtension(id, otherId) { + let args = `${JSON.stringify(id)}, ${JSON.stringify(otherId)}`; + + let extensionData = { + background: `(${backgroundScript})(${args})`, + manifest: { + "applications": {"gecko": {id}}, + }, + }; + + return ExtensionTestUtils.loadExtension(extensionData); +} + +add_task(function* test_contentscript() { + const ID1 = "foo-message@mochitest.mozilla.org"; + const ID2 = "bar-message@mochitest.mozilla.org"; + + let extension1 = makeExtension(ID1, ID2); + let extension2 = makeExtension(ID2, ID1); + + yield Promise.all([extension1.startup(), extension2.startup()]); + + extension1.sendMessage("go"); + extension2.sendMessage("go"); + + yield Promise.all([ + extension1.awaitMessage("sendMessage-done"), + extension2.awaitMessage("sendMessage-done"), + + extension1.awaitMessage("onMessage-done"), + extension2.awaitMessage("onMessage-done"), + + extension1.awaitMessage("connect-done"), + extension2.awaitMessage("connect-done"), + + extension1.awaitMessage("onConnect-done"), + extension2.awaitMessage("onConnect-done"), + ]); + + yield extension1.unload(); + yield extension2.unload(); +}); +</script> + +</body> +</html> diff --git a/toolkit/components/webextensions/test/mochitest/test_ext_sendmessage_reply2.html b/toolkit/components/webextensions/test/mochitest/test_ext_sendmessage_reply2.html index 1ebc1b40f..5c350be2f 100644 --- a/toolkit/components/webextensions/test/mochitest/test_ext_sendmessage_reply2.html +++ b/toolkit/components/webextensions/test/mochitest/test_ext_sendmessage_reply2.html @@ -13,48 +13,119 @@ <script type="text/javascript"> "use strict"; -function backgroundScript(token) { +function backgroundScript(token, id, otherId) { + browser.tabs.create({url: "tab.html"}); + browser.runtime.onMessage.addListener((msg, sender, sendReply) => { - browser.test.assertTrue(sender.tab.url.endsWith("file_sample.html"), "sender url correct"); + browser.test.assertEq(id, sender.id, `${id}: Got expected sender ID`); - if (msg == "done") { - browser.test.notifyPass("sendmessage_reply"); - return; + if (msg === `content-${token}`) { + browser.test.assertTrue(sender.tab.url.endsWith("file_sample.html"), + `${id}: sender url correct`); + + let tabId = sender.tab.id; + browser.tabs.sendMessage(tabId, `${token}-contentMessage`); + + sendReply(`${token}-done`); + } else if (msg === `tab-${token}`) { + browser.runtime.sendMessage(otherId, `${otherId}-tabMessage`); + browser.runtime.sendMessage(`${token}-tabMessage`); + + sendReply(`${token}-done`); + } else { + browser.test.fail(`${id}: Unexpected runtime message received: ${msg} ${uneval(sender)}`); } + }); + + browser.runtime.onMessageExternal.addListener((msg, sender, sendReply) => { + browser.test.assertEq(otherId, sender.id, `${id}: Got expected external sender ID`); + + if (msg === `content-${id}`) { + browser.test.assertTrue(sender.tab.url.endsWith("file_sample.html"), + `${id}: external sender url correct`); + + sendReply(`${otherId}-done`); + } else if (msg === `tab-${id}`) { + sendReply(`${otherId}-done`); + } else if (msg !== `${id}-tabMessage`) { + browser.test.fail(`${id}: Unexpected runtime external message received: ${msg} ${uneval(sender)}`); + } + }); +} + +function contentScript(token, id, otherId) { + let gotContentMessage = false; + browser.runtime.onMessage.addListener((msg, sender, sendReply) => { + browser.test.assertEq(id, sender.id, `${id}: Got expected sender ID`); + + browser.test.assertEq(`${token}-contentMessage`, msg, + `${id}: Correct content script message`); + if (msg === `${token}-contentMessage`) { + gotContentMessage = true; + } + }); + + Promise.all([ + browser.runtime.sendMessage(otherId, `content-${otherId}`).then(resp => { + browser.test.assertEq(`${id}-done`, resp, `${id}: Correct content script external response token`); + }), - let tabId = sender.tab.id; - browser.tabs.sendMessage(tabId, `${token}-tabMessage`); + browser.runtime.sendMessage(`content-${token}`).then(resp => { + browser.test.assertEq(`${token}-done`, resp, `${id}: Correct content script response token`); + }), + ]).then(() => { + browser.test.assertTrue(gotContentMessage, `${id}: Got content script message`); - browser.test.assertEq(msg, token, "token matches"); - sendReply(`${token}-done`); + browser.test.sendMessage("content-script-done"); }); } -function contentScript(token) { +function tabScript(token, id, otherId) { let gotTabMessage = false; - let badTabMessage = false; browser.runtime.onMessage.addListener((msg, sender, sendReply) => { - if (msg == `${token}-tabMessage`) { + browser.test.assertEq(id, sender.id, `${id}: Got expected sender ID`); + + if (String(msg).startsWith("content-")) { + return; + } + + browser.test.assertEq(`${token}-tabMessage`, msg, + `${id}: Correct tab script message`); + if (msg === `${token}-tabMessage`) { gotTabMessage = true; - } else { - badTabMessage = true; } }); - browser.runtime.sendMessage(token, function(resp) { - if (resp != `${token}-done` || !gotTabMessage || badTabMessage) { - return; // test failed - } - browser.runtime.sendMessage("done"); + Promise.all([ + browser.runtime.sendMessage(otherId, `tab-${otherId}`).then(resp => { + browser.test.assertEq(`${id}-done`, resp, `${id}: Correct tab script external response token`); + }), + + browser.runtime.sendMessage(`tab-${token}`).then(resp => { + browser.test.assertEq(`${token}-done`, resp, `${id}: Correct tab script response token`); + }), + ]).then(() => { + browser.test.assertTrue(gotTabMessage, `${id}: Got tab script message`); + + window.close(); + + browser.test.sendMessage("tab-script-done"); }); } -function makeExtension() { +function makeExtension(id, otherId) { let token = Math.random(); + + let args = `${token}, ${JSON.stringify(id)}, ${JSON.stringify(otherId)}`; + let extensionData = { - background: `(${backgroundScript})(${token})`, + background: `(${backgroundScript})(${args})`, manifest: { + "applications": {"gecko": {id}}, + "permissions": ["tabs"], + + "content_scripts": [{ "matches": ["http://mochi.test/*/file_sample.html"], "js": ["content_script.js"], @@ -63,29 +134,46 @@ function makeExtension() { }, files: { - "content_script.js": `(${contentScript})(${token})`, + "tab.html": `<!DOCTYPE html> + <html> + <head> + <meta charset="utf-8"> + <script src="tab.js"><\/script> + </head> + </html>`, + + "tab.js": `(${tabScript})(${args})`, + + "content_script.js": `(${contentScript})(${args})`, }, }; return extensionData; } add_task(function* test_contentscript() { - let extension1 = ExtensionTestUtils.loadExtension(makeExtension()); - let extension2 = ExtensionTestUtils.loadExtension(makeExtension()); + const ID1 = "sendmessage1@mochitest.mozilla.org"; + const ID2 = "sendmessage2@mochitest.mozilla.org"; + + let extension1 = ExtensionTestUtils.loadExtension(makeExtension(ID1, ID2)); + let extension2 = ExtensionTestUtils.loadExtension(makeExtension(ID2, ID1)); yield Promise.all([extension1.startup(), extension2.startup()]); let win = window.open("file_sample.html"); - yield Promise.all([waitForLoad(win), - extension1.awaitFinish("sendmessage_reply"), - extension2.awaitFinish("sendmessage_reply")]); + yield waitForLoad(win); + + yield Promise.all([ + extension1.awaitMessage("content-script-done"), + extension2.awaitMessage("content-script-done"), + extension1.awaitMessage("tab-script-done"), + extension2.awaitMessage("tab-script-done"), + ]); win.close(); yield extension1.unload(); yield extension2.unload(); - info("extensions unloaded"); }); </script> diff --git a/toolkit/components/webextensions/test/xpcshell/test_ext_legacy_extension_context.js b/toolkit/components/webextensions/test/xpcshell/test_ext_legacy_extension_context.js index 63d5361a1..770851472 100644 --- a/toolkit/components/webextensions/test/xpcshell/test_ext_legacy_extension_context.js +++ b/toolkit/components/webextensions/test/xpcshell/test_ext_legacy_extension_context.js @@ -108,7 +108,7 @@ add_task(function* test_legacy_extension_context() { "Got the expected message"); ok(msgSender, "Got a message sender object"); - equal(msgSender.id, extensionInfo.uuid, "The sender has the expected id property"); + equal(msgSender.id, extension.id, "The sender has the expected id property"); equal(msgSender.url, extensionInfo.bgURL, "The sender has the expected url property"); // Wait confirmation that the reply has been received. @@ -136,7 +136,7 @@ add_task(function* test_legacy_extension_context() { ok(port, "Got the Port API object"); ok(port.sender, "The port has a sender property"); - equal(port.sender.id, extensionInfo.uuid, + equal(port.sender.id, extension.id, "The port sender has the expected id property"); equal(port.sender.url, extensionInfo.bgURL, "The port sender has the expected url property"); diff --git a/toolkit/jetpack/moz.build b/toolkit/jetpack/moz.build index ad11e90a3..2e5dbe5e8 100644 --- a/toolkit/jetpack/moz.build +++ b/toolkit/jetpack/moz.build @@ -128,9 +128,10 @@ EXTRA_JS_MODULES.commonjs += [ 'test.js', ] -EXTRA_JS_MODULES.commonjs.sdk += [ - 'sdk/webextension.js', -] +if CONFIG['MOZ_WEBEXTENSIONS']: + EXTRA_JS_MODULES.commonjs.sdk += [ + 'sdk/webextension.js', + ] EXTRA_JS_MODULES.commonjs.dev += [ 'dev/debuggee.js', @@ -228,7 +229,6 @@ EXTRA_PP_JS_MODULES.commonjs.sdk += [ ] EXTRA_JS_MODULES.commonjs.sdk.addon += [ - 'sdk/addon/bootstrap.js', 'sdk/addon/events.js', 'sdk/addon/host.js', 'sdk/addon/installer.js', @@ -237,6 +237,10 @@ EXTRA_JS_MODULES.commonjs.sdk.addon += [ 'sdk/addon/window.js', ] +EXTRA_PP_JS_MODULES.commonjs.sdk.addon += [ + 'sdk/addon/bootstrap.js', +] + EXTRA_JS_MODULES.commonjs.sdk.browser += [ 'sdk/browser/events.js', ] diff --git a/toolkit/jetpack/sdk/addon/bootstrap.js b/toolkit/jetpack/sdk/addon/bootstrap.js index 0397d91e5..6c5827f1e 100644 --- a/toolkit/jetpack/sdk/addon/bootstrap.js +++ b/toolkit/jetpack/sdk/addon/bootstrap.js @@ -134,8 +134,10 @@ Bootstrap.prototype = { const main = command === "test" ? "sdk/test/runner" : null; const prefsURI = `${baseURI}defaults/preferences/prefs.js`; +#ifdef MOZ_WEBEXTENSIONS // Init the 'sdk/webextension' module from the bootstrap addon parameter. require("sdk/webextension").initFromBootstrapAddonParam(addon); +#endif const { startup } = require("sdk/addon/runner"); startup(reason, {loader, main, prefsURI}); diff --git a/toolkit/xre/MozMeegoAppService.h b/toolkit/xre/MozMeegoAppService.h deleted file mode 100644 index 063d03e02..000000000 --- a/toolkit/xre/MozMeegoAppService.h +++ /dev/null @@ -1,28 +0,0 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=2 et sw=2 tw=80: */ -/* 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/. */ - -#ifndef MOZMEEGOAPPSERVICE_H -#define MOZMEEGOAPPSERVICE_H - -#include <MApplicationService> - -/** - * App service class, which prevents registration to d-bus - * and allows multiple instances of application. This is - * required for Mozillas remote service to work, because - * it is initialized after MApplication. - */ -class MozMeegoAppService: public MApplicationService -{ - Q_OBJECT -public: - MozMeegoAppService(): MApplicationService(QString()) {} -public Q_SLOTS: - virtual QString registeredName() { return QString(); } - virtual bool isRegistered() { return false; } - virtual bool registerService() { return true; } -}; -#endif // MOZMEEGOAPPSERVICE_H diff --git a/toolkit/xre/nsAppRunner.cpp b/toolkit/xre/nsAppRunner.cpp index 776044d72..3493cd837 100644 --- a/toolkit/xre/nsAppRunner.cpp +++ b/toolkit/xre/nsAppRunner.cpp @@ -4306,7 +4306,6 @@ MultiprocessBlockPolicy() { if (addonsCanDisable && disabledByAddons) { gMultiprocessBlockPolicy = kE10sDisabledForAddons; - return gMultiprocessBlockPolicy; } #if defined(XP_WIN) @@ -4340,16 +4339,13 @@ MultiprocessBlockPolicy() { if (disabledForA11y) { gMultiprocessBlockPolicy = kE10sDisabledForAccessibility; - return gMultiprocessBlockPolicy; } #endif + + // We do not support E10S, block by policy. + gMultiprocessBlockPolicy = kE10sForceDisabled; - /* - * None of the blocking policies matched, so e10s is allowed to run. - * Cache the information and return 0, indicating success. - */ - gMultiprocessBlockPolicy = 0; - return 0; + return gMultiprocessBlockPolicy; } bool diff --git a/widget/GfxInfoX11.cpp b/widget/GfxInfoX11.cpp index 4297aaa93..48fc3dbb5 100644 --- a/widget/GfxInfoX11.cpp +++ b/widget/GfxInfoX11.cpp @@ -23,7 +23,7 @@ NS_IMPL_ISUPPORTS_INHERITED(GfxInfo, GfxInfoBase, nsIGfxInfoDebug) #endif // these global variables will be set when firing the glxtest process -int glxtest_pipe = 0; +int glxtest_pipe = -1; pid_t glxtest_pid = 0; nsresult @@ -50,8 +50,8 @@ GfxInfo::GetData() // to understand this function, see bug 639842. We retrieve the OpenGL driver information in a // separate process to protect against bad drivers. - // if glxtest_pipe == 0, that means that we already read the information - if (!glxtest_pipe) + // if glxtest_pipe == -1, that means that we already read the information + if (glxtest_pipe == -1) return; enum { buf_size = 1024 }; @@ -60,7 +60,7 @@ GfxInfo::GetData() &buf, buf_size-1); // -1 because we'll append a zero close(glxtest_pipe); - glxtest_pipe = 0; + glxtest_pipe = -1; // bytesread < 0 would mean that the above read() call failed. // This should never happen. If it did, the outcome would be to blacklist anyway. diff --git a/widget/MouseEvents.h b/widget/MouseEvents.h index 643132618..442ac41e8 100644 --- a/widget/MouseEvents.h +++ b/widget/MouseEvents.h @@ -43,22 +43,31 @@ namespace dom { class WidgetPointerHelper { public: - bool convertToPointer; uint32_t pointerId; uint32_t tiltX; uint32_t tiltY; - bool retargetedByPointerCapture; + uint32_t twist; + float tangentialPressure; + bool convertToPointer; - WidgetPointerHelper() : convertToPointer(true), pointerId(0), tiltX(0), tiltY(0), - retargetedByPointerCapture(false) {} + WidgetPointerHelper() + : pointerId(0) + , tiltX(0) + , tiltY(0) + , twist(0) + , tangentialPressure(0) + , convertToPointer(true) + { + } void AssignPointerHelperData(const WidgetPointerHelper& aEvent) { - convertToPointer = aEvent.convertToPointer; pointerId = aEvent.pointerId; tiltX = aEvent.tiltX; tiltY = aEvent.tiltY; - retargetedByPointerCapture = aEvent.retargetedByPointerCapture; + twist = aEvent.twist; + tangentialPressure = aEvent.tangentialPressure; + convertToPointer = aEvent.convertToPointer; } }; diff --git a/widget/nsGUIEventIPC.h b/widget/nsGUIEventIPC.h index 7a9d870d9..e45189bb1 100644 --- a/widget/nsGUIEventIPC.h +++ b/widget/nsGUIEventIPC.h @@ -219,6 +219,34 @@ struct ParamTraits<mozilla::WidgetWheelEvent> }; template<> +struct ParamTraits<mozilla::WidgetPointerHelper> +{ + typedef mozilla::WidgetPointerHelper paramType; + + static void Write(Message* aMsg, const paramType& aParam) + { + WriteParam(aMsg, aParam.pointerId); + WriteParam(aMsg, aParam.tiltX); + WriteParam(aMsg, aParam.tiltY); + WriteParam(aMsg, aParam.twist); + WriteParam(aMsg, aParam.tangentialPressure); + // We don't serialize convertToPointer since it's temporarily variable and + // should be reset to default. + } + + static bool Read(const Message* aMsg, PickleIterator* aIter, paramType* aResult) + { + bool rv; + rv = ReadParam(aMsg, aIter, &aResult->pointerId) && + ReadParam(aMsg, aIter, &aResult->tiltX) && + ReadParam(aMsg, aIter, &aResult->tiltY) && + ReadParam(aMsg, aIter, &aResult->twist) && + ReadParam(aMsg, aIter, &aResult->tangentialPressure); + return rv; + } +}; + +template<> struct ParamTraits<mozilla::WidgetMouseEvent> { typedef mozilla::WidgetMouseEvent paramType; @@ -226,13 +254,13 @@ struct ParamTraits<mozilla::WidgetMouseEvent> static void Write(Message* aMsg, const paramType& aParam) { WriteParam(aMsg, static_cast<mozilla::WidgetMouseEventBase>(aParam)); + WriteParam(aMsg, static_cast<mozilla::WidgetPointerHelper>(aParam)); WriteParam(aMsg, aParam.mIgnoreRootScrollFrame); WriteParam(aMsg, static_cast<paramType::ReasonType>(aParam.mReason)); WriteParam(aMsg, static_cast<paramType::ContextMenuTriggerType>( aParam.mContextMenuTrigger)); WriteParam(aMsg, static_cast<paramType::ExitFromType>(aParam.mExitFrom)); WriteParam(aMsg, aParam.mClickCount); - WriteParam(aMsg, aParam.pointerId); } static bool Read(const Message* aMsg, PickleIterator* aIter, paramType* aResult) @@ -243,12 +271,13 @@ struct ParamTraits<mozilla::WidgetMouseEvent> paramType::ExitFromType exitFrom = 0; rv = ReadParam(aMsg, aIter, static_cast<mozilla::WidgetMouseEventBase*>(aResult)) && + ReadParam(aMsg, aIter, + static_cast<mozilla::WidgetPointerHelper*>(aResult)) && ReadParam(aMsg, aIter, &aResult->mIgnoreRootScrollFrame) && ReadParam(aMsg, aIter, &reason) && ReadParam(aMsg, aIter, &contextMenuTrigger) && ReadParam(aMsg, aIter, &exitFrom) && - ReadParam(aMsg, aIter, &aResult->mClickCount) && - ReadParam(aMsg, aIter, &aResult->pointerId); + ReadParam(aMsg, aIter, &aResult->mClickCount); aResult->mReason = static_cast<paramType::Reason>(reason); aResult->mContextMenuTrigger = static_cast<paramType::ContextMenuTrigger>(contextMenuTrigger); @@ -290,8 +319,6 @@ struct ParamTraits<mozilla::WidgetPointerEvent> WriteParam(aMsg, static_cast<mozilla::WidgetMouseEvent>(aParam)); WriteParam(aMsg, aParam.mWidth); WriteParam(aMsg, aParam.mHeight); - WriteParam(aMsg, aParam.tiltX); - WriteParam(aMsg, aParam.tiltY); WriteParam(aMsg, aParam.mIsPrimary); } @@ -301,8 +328,6 @@ struct ParamTraits<mozilla::WidgetPointerEvent> ReadParam(aMsg, aIter, static_cast<mozilla::WidgetMouseEvent*>(aResult)) && ReadParam(aMsg, aIter, &aResult->mWidth) && ReadParam(aMsg, aIter, &aResult->mHeight) && - ReadParam(aMsg, aIter, &aResult->tiltX) && - ReadParam(aMsg, aIter, &aResult->tiltY) && ReadParam(aMsg, aIter, &aResult->mIsPrimary); return rv; } |