зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1561435 - Format toolkit/actors, a=automatic-formatting
# ignore-this-changeset Differential Revision: https://phabricator.services.mozilla.com/D36050 --HG-- extra : source : 2540803fff7587f65dd5d6253b6fb544647e5e20
This commit is contained in:
Родитель
57a6febcec
Коммит
d3a1b5aeaa
|
@ -45,7 +45,6 @@ module.exports = {
|
|||
"overrides": [{
|
||||
"files": [
|
||||
"devtools/**",
|
||||
"toolkit/**",
|
||||
"tools/**",
|
||||
"uriloader/**",
|
||||
"view/**",
|
||||
|
|
|
@ -40,7 +40,6 @@ toolkit/components/telemetry/datareporting-prefs.js
|
|||
toolkit/components/telemetry/healthreport-prefs.js
|
||||
|
||||
# Ignore all top-level directories for now.
|
||||
toolkit/**
|
||||
tools/**
|
||||
uriloader/**
|
||||
view/**
|
||||
|
|
|
@ -6,7 +6,9 @@
|
|||
|
||||
var EXPORTED_SYMBOLS = ["AudioPlaybackChild"];
|
||||
|
||||
const {ActorChild} = ChromeUtils.import("resource://gre/modules/ActorChild.jsm");
|
||||
const { ActorChild } = ChromeUtils.import(
|
||||
"resource://gre/modules/ActorChild.jsm"
|
||||
);
|
||||
|
||||
class AudioPlaybackChild extends ActorChild {
|
||||
handleMediaControlMessage(msg) {
|
||||
|
@ -49,14 +51,14 @@ class AudioPlaybackChild extends ActorChild {
|
|||
} else if (data === "activeMediaBlockStop") {
|
||||
name += "ActiveMediaBlockStop";
|
||||
} else {
|
||||
name += (data === "active") ? "Start" : "Stop";
|
||||
name += data === "active" ? "Start" : "Stop";
|
||||
}
|
||||
this.mm.sendAsyncMessage(name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
receiveMessage({name, data}) {
|
||||
receiveMessage({ name, data }) {
|
||||
switch (name) {
|
||||
case "AudioPlayback":
|
||||
this.handleMediaControlMessage(data.type);
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/* vim: set ts=2 sw=2 sts=2 et 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/. */
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
"use strict";
|
||||
|
||||
var EXPORTED_SYMBOLS = ["AutoplayParent"];
|
||||
|
|
|
@ -8,8 +8,10 @@ var EXPORTED_SYMBOLS = ["BrowserElementChild"];
|
|||
|
||||
class BrowserElementChild extends JSWindowActorChild {
|
||||
handleEvent(event) {
|
||||
if (event.type == "DOMWindowClose" &&
|
||||
!this.manager.browsingContext.parent) {
|
||||
if (
|
||||
event.type == "DOMWindowClose" &&
|
||||
!this.manager.browsingContext.parent
|
||||
) {
|
||||
this.sendAsyncMessage("DOMWindowClose", {});
|
||||
}
|
||||
}
|
||||
|
@ -24,7 +26,9 @@ class BrowserElementChild extends JSWindowActorChild {
|
|||
|
||||
let permitUnload = true;
|
||||
if (docShell && docShell.contentViewer) {
|
||||
permitUnload = docShell.contentViewer.permitUnload(message.data.flags);
|
||||
permitUnload = docShell.contentViewer.permitUnload(
|
||||
message.data.flags
|
||||
);
|
||||
}
|
||||
|
||||
this.sendAsyncMessage("Done", { permitUnload });
|
||||
|
|
|
@ -6,12 +6,20 @@
|
|||
|
||||
var EXPORTED_SYMBOLS = ["BrowserElementParent", "PermitUnloader"];
|
||||
|
||||
ChromeUtils.defineModuleGetter(this, "Services",
|
||||
"resource://gre/modules/Services.jsm");
|
||||
ChromeUtils.defineModuleGetter(
|
||||
this,
|
||||
"Services",
|
||||
"resource://gre/modules/Services.jsm"
|
||||
);
|
||||
|
||||
let {XPCOMUtils} = ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm");
|
||||
XPCOMUtils.defineLazyPreferenceGetter(this, "unloadTimeoutMs",
|
||||
"dom.beforeunload_timeout_ms");
|
||||
let { XPCOMUtils } = ChromeUtils.import(
|
||||
"resource://gre/modules/XPCOMUtils.jsm"
|
||||
);
|
||||
XPCOMUtils.defineLazyPreferenceGetter(
|
||||
this,
|
||||
"unloadTimeoutMs",
|
||||
"dom.beforeunload_timeout_ms"
|
||||
);
|
||||
|
||||
// Out-of-process subframes might be in the following states following a request
|
||||
// to permit closing:
|
||||
|
@ -74,9 +82,11 @@ class BrowserElementParent extends JSWindowActorParent {
|
|||
// If this is a non-remote browser, the DOMWindowClose event will bubble
|
||||
// up naturally, and doesn't need to be re-dispatched.
|
||||
if (browser.isRemoteBrowser) {
|
||||
browser.dispatchEvent(new win.CustomEvent("DOMWindowClose", {
|
||||
bubbles: true,
|
||||
}));
|
||||
browser.dispatchEvent(
|
||||
new win.CustomEvent("DOMWindowClose", {
|
||||
bubbles: true,
|
||||
})
|
||||
);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
@ -203,9 +213,13 @@ var PermitUnloader = {
|
|||
actor.sendPermitUnload(flags);
|
||||
}
|
||||
|
||||
timer.initWithCallback(() => {
|
||||
this._onTimeout(frameLoader);
|
||||
}, unloadTimeoutMs, timer.TYPE_ONE_SHOT);
|
||||
timer.initWithCallback(
|
||||
() => {
|
||||
this._onTimeout(frameLoader);
|
||||
},
|
||||
unloadTimeoutMs,
|
||||
timer.TYPE_ONE_SHOT
|
||||
);
|
||||
|
||||
Services.tm.spinEventLoopUntilOrShutdown(() => {
|
||||
return this._finishedPermitUnload(frameStates);
|
||||
|
|
|
@ -6,14 +6,17 @@
|
|||
|
||||
var EXPORTED_SYMBOLS = ["ControllersChild"];
|
||||
|
||||
const {ActorChild} = ChromeUtils.import("resource://gre/modules/ActorChild.jsm");
|
||||
const { ActorChild } = ChromeUtils.import(
|
||||
"resource://gre/modules/ActorChild.jsm"
|
||||
);
|
||||
|
||||
class ControllersChild extends ActorChild {
|
||||
receiveMessage(message) {
|
||||
switch (message.name) {
|
||||
case "ControllerCommands:Do":
|
||||
if (this.docShell.isCommandEnabled(message.data))
|
||||
if (this.docShell.isCommandEnabled(message.data)) {
|
||||
this.docShell.doCommand(message.data);
|
||||
}
|
||||
break;
|
||||
|
||||
case "ControllerCommands:DoWithParams":
|
||||
|
|
|
@ -2,9 +2,12 @@
|
|||
* 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/. */
|
||||
|
||||
const {Services} = ChromeUtils.import("resource://gre/modules/Services.jsm");
|
||||
ChromeUtils.defineModuleGetter(this, "BrowserUtils",
|
||||
"resource://gre/modules/BrowserUtils.jsm");
|
||||
const { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm");
|
||||
ChromeUtils.defineModuleGetter(
|
||||
this,
|
||||
"BrowserUtils",
|
||||
"resource://gre/modules/BrowserUtils.jsm"
|
||||
);
|
||||
|
||||
var EXPORTED_SYMBOLS = ["DateTimePickerChild"];
|
||||
|
||||
|
@ -39,7 +42,8 @@ class DateTimePickerChild extends JSWindowActorChild {
|
|||
// An event dispatch to it can't be accessed by document.
|
||||
let win = this._inputElement.ownerGlobal;
|
||||
dateTimeBoxElement.dispatchEvent(
|
||||
new win.CustomEvent("MozSetDateTimePickerState", { detail: false }));
|
||||
new win.CustomEvent("MozSetDateTimePickerState", { detail: false })
|
||||
);
|
||||
}
|
||||
|
||||
this._inputElement = null;
|
||||
|
@ -64,7 +68,8 @@ class DateTimePickerChild extends JSWindowActorChild {
|
|||
* Helper function that returns the CSS direction property of the element.
|
||||
*/
|
||||
getComputedDirection(aElement) {
|
||||
return aElement.ownerGlobal.getComputedStyle(aElement)
|
||||
return aElement.ownerGlobal
|
||||
.getComputedStyle(aElement)
|
||||
.getPropertyValue("direction");
|
||||
}
|
||||
|
||||
|
@ -105,8 +110,10 @@ class DateTimePickerChild extends JSWindowActorChild {
|
|||
// dateTimeBoxElement is within UA Widget Shadow DOM.
|
||||
// An event dispatch to it can't be accessed by document.
|
||||
dateTimeBoxElement.dispatchEvent(
|
||||
new win.CustomEvent("MozPickerValueChanged",
|
||||
{ detail: Cu.cloneInto(aMessage.data, win) }));
|
||||
new win.CustomEvent("MozPickerValueChanged", {
|
||||
detail: Cu.cloneInto(aMessage.data, win),
|
||||
})
|
||||
);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -123,8 +130,13 @@ class DateTimePickerChild extends JSWindowActorChild {
|
|||
switch (aEvent.type) {
|
||||
case "MozOpenDateTimePicker": {
|
||||
// Time picker is disabled when preffed off
|
||||
if (!(aEvent.originalTarget instanceof aEvent.originalTarget.ownerGlobal.HTMLInputElement) ||
|
||||
(aEvent.originalTarget.type == "time" && !this.getTimePickerPref())) {
|
||||
if (
|
||||
!(
|
||||
aEvent.originalTarget instanceof
|
||||
aEvent.originalTarget.ownerGlobal.HTMLInputElement
|
||||
) ||
|
||||
(aEvent.originalTarget.type == "time" && !this.getTimePickerPref())
|
||||
) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -139,7 +151,9 @@ class DateTimePickerChild extends JSWindowActorChild {
|
|||
|
||||
let dateTimeBoxElement = this._inputElement.dateTimeBoxElement;
|
||||
if (!dateTimeBoxElement) {
|
||||
throw new Error("How do we get this event without a UA Widget or XBL binding?");
|
||||
throw new Error(
|
||||
"How do we get this event without a UA Widget or XBL binding?"
|
||||
);
|
||||
}
|
||||
|
||||
if (this._inputElement.openOrClosedShadowRoot) {
|
||||
|
@ -148,7 +162,8 @@ class DateTimePickerChild extends JSWindowActorChild {
|
|||
// the event is not composed.
|
||||
let win = this._inputElement.ownerGlobal;
|
||||
dateTimeBoxElement.dispatchEvent(
|
||||
new win.CustomEvent("MozSetDateTimePickerState", { detail: true }));
|
||||
new win.CustomEvent("MozSetDateTimePickerState", { detail: true })
|
||||
);
|
||||
}
|
||||
|
||||
this.addListeners(this._inputElement);
|
||||
|
@ -161,8 +176,8 @@ class DateTimePickerChild extends JSWindowActorChild {
|
|||
detail: {
|
||||
// Pass partial value if it's available, otherwise pass input
|
||||
// element's value.
|
||||
value: Object.keys(value).length > 0 ? value
|
||||
: this._inputElement.value,
|
||||
value:
|
||||
Object.keys(value).length > 0 ? value : this._inputElement.value,
|
||||
min: this._inputElement.getMinimum(),
|
||||
max: this._inputElement.getMaximum(),
|
||||
step: this._inputElement.getStep(),
|
||||
|
@ -183,8 +198,10 @@ class DateTimePickerChild extends JSWindowActorChild {
|
|||
break;
|
||||
}
|
||||
case "pagehide": {
|
||||
if (this._inputElement &&
|
||||
this._inputElement.ownerDocument == aEvent.target) {
|
||||
if (
|
||||
this._inputElement &&
|
||||
this._inputElement.ownerDocument == aEvent.target
|
||||
) {
|
||||
this.sendAsyncMessage("FormDateTime:ClosePicker", {});
|
||||
this.close();
|
||||
}
|
||||
|
|
|
@ -13,8 +13,12 @@ function debug(aStr) {
|
|||
|
||||
var EXPORTED_SYMBOLS = ["DateTimePickerParent"];
|
||||
|
||||
const {Services} = ChromeUtils.import("resource://gre/modules/Services.jsm");
|
||||
ChromeUtils.defineModuleGetter(this, "DateTimePickerPanel", "resource://gre/modules/DateTimePickerPanel.jsm");
|
||||
const { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm");
|
||||
ChromeUtils.defineModuleGetter(
|
||||
this,
|
||||
"DateTimePickerPanel",
|
||||
"resource://gre/modules/DateTimePickerPanel.jsm"
|
||||
);
|
||||
|
||||
/*
|
||||
* DateTimePickerParent receives message from content side (input box) and
|
||||
|
@ -78,7 +82,9 @@ class DateTimePickerParent extends JSWindowActorParent {
|
|||
|
||||
this._anchor = aBrowser.popupAnchor;
|
||||
if (!this._anchor) {
|
||||
throw new Error("No popup anchor for this browser, cannot show date picker");
|
||||
throw new Error(
|
||||
"No popup anchor for this browser, cannot show date picker"
|
||||
);
|
||||
}
|
||||
|
||||
this._anchor.left = rect.left;
|
||||
|
@ -91,8 +97,10 @@ class DateTimePickerParent extends JSWindowActorParent {
|
|||
|
||||
let window = aBrowser.ownerGlobal;
|
||||
let tabbrowser = window.gBrowser;
|
||||
if (Services.focus.activeWindow != window ||
|
||||
(tabbrowser && tabbrowser.selectedBrowser != aBrowser)) {
|
||||
if (
|
||||
Services.focus.activeWindow != window ||
|
||||
(tabbrowser && tabbrowser.selectedBrowser != aBrowser)
|
||||
) {
|
||||
// We were sent a message from a window or tab that went into the
|
||||
// background, so we'll ignore it for now.
|
||||
return;
|
||||
|
@ -132,6 +140,9 @@ class DateTimePickerParent extends JSWindowActorParent {
|
|||
return;
|
||||
}
|
||||
this._picker.element.removeEventListener("popuphidden", this);
|
||||
this._picker.element.removeEventListener("DateTimePickerValueChanged", this);
|
||||
this._picker.element.removeEventListener(
|
||||
"DateTimePickerValueChanged",
|
||||
this
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,10 +6,15 @@
|
|||
|
||||
var EXPORTED_SYMBOLS = ["ExtFindChild"];
|
||||
|
||||
const {ActorChild} = ChromeUtils.import("resource://gre/modules/ActorChild.jsm");
|
||||
const { ActorChild } = ChromeUtils.import(
|
||||
"resource://gre/modules/ActorChild.jsm"
|
||||
);
|
||||
|
||||
ChromeUtils.defineModuleGetter(this, "FindContent",
|
||||
"resource://gre/modules/FindContent.jsm");
|
||||
ChromeUtils.defineModuleGetter(
|
||||
this,
|
||||
"FindContent",
|
||||
"resource://gre/modules/FindContent.jsm"
|
||||
);
|
||||
|
||||
class ExtFindChild extends ActorChild {
|
||||
async receiveMessage(message) {
|
||||
|
|
|
@ -6,12 +6,19 @@
|
|||
|
||||
var EXPORTED_SYMBOLS = ["FindBarChild"];
|
||||
|
||||
const {ActorChild} = ChromeUtils.import("resource://gre/modules/ActorChild.jsm");
|
||||
const {Services} = ChromeUtils.import("resource://gre/modules/Services.jsm");
|
||||
const {XPCOMUtils} = ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm");
|
||||
const { ActorChild } = ChromeUtils.import(
|
||||
"resource://gre/modules/ActorChild.jsm"
|
||||
);
|
||||
const { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm");
|
||||
const { XPCOMUtils } = ChromeUtils.import(
|
||||
"resource://gre/modules/XPCOMUtils.jsm"
|
||||
);
|
||||
|
||||
ChromeUtils.defineModuleGetter(this, "BrowserUtils",
|
||||
"resource://gre/modules/BrowserUtils.jsm");
|
||||
ChromeUtils.defineModuleGetter(
|
||||
this,
|
||||
"BrowserUtils",
|
||||
"resource://gre/modules/BrowserUtils.jsm"
|
||||
);
|
||||
|
||||
class FindBarChild extends ActorChild {
|
||||
constructor(dispatcher) {
|
||||
|
@ -19,11 +26,16 @@ class FindBarChild extends ActorChild {
|
|||
|
||||
this._findKey = null;
|
||||
|
||||
XPCOMUtils.defineLazyProxy(this, "FindBarContent", () => {
|
||||
let tmp = {};
|
||||
ChromeUtils.import("resource://gre/modules/FindBarContent.jsm", tmp);
|
||||
return new tmp.FindBarContent(this.mm);
|
||||
}, {inQuickFind: false, inPassThrough: false});
|
||||
XPCOMUtils.defineLazyProxy(
|
||||
this,
|
||||
"FindBarContent",
|
||||
() => {
|
||||
let tmp = {};
|
||||
ChromeUtils.import("resource://gre/modules/FindBarContent.jsm", tmp);
|
||||
return new tmp.FindBarContent(this.mm);
|
||||
},
|
||||
{ inQuickFind: false, inPassThrough: false }
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -54,10 +66,9 @@ class FindBarChild extends ActorChild {
|
|||
}
|
||||
|
||||
onKeypress(event) {
|
||||
let {FindBarContent} = this;
|
||||
let { FindBarContent } = this;
|
||||
|
||||
if (!FindBarContent.inPassThrough &&
|
||||
this.eventMatchesFindShortcut(event)) {
|
||||
if (!FindBarContent.inPassThrough && this.eventMatchesFindShortcut(event)) {
|
||||
return FindBarContent.start(event);
|
||||
}
|
||||
|
||||
|
@ -67,9 +78,14 @@ class FindBarChild extends ActorChild {
|
|||
return null;
|
||||
}
|
||||
|
||||
if (event.ctrlKey || event.altKey || event.metaKey || event.defaultPrevented ||
|
||||
!BrowserUtils.mimeTypeIsTextBased(this.content.document.contentType) ||
|
||||
!BrowserUtils.canFindInPage(location)) {
|
||||
if (
|
||||
event.ctrlKey ||
|
||||
event.altKey ||
|
||||
event.metaKey ||
|
||||
event.defaultPrevented ||
|
||||
!BrowserUtils.mimeTypeIsTextBased(this.content.document.contentType) ||
|
||||
!BrowserUtils.canFindInPage(location)
|
||||
) {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
@ -90,8 +106,13 @@ class FindBarChild extends ActorChild {
|
|||
}
|
||||
}
|
||||
|
||||
XPCOMUtils.defineLazyPreferenceGetter(FindBarChild, "findAsYouType",
|
||||
"accessibility.typeaheadfind");
|
||||
XPCOMUtils.defineLazyPreferenceGetter(FindBarChild, "manualFAYT",
|
||||
"accessibility.typeaheadfind.manual");
|
||||
|
||||
XPCOMUtils.defineLazyPreferenceGetter(
|
||||
FindBarChild,
|
||||
"findAsYouType",
|
||||
"accessibility.typeaheadfind"
|
||||
);
|
||||
XPCOMUtils.defineLazyPreferenceGetter(
|
||||
FindBarChild,
|
||||
"manualFAYT",
|
||||
"accessibility.typeaheadfind.manual"
|
||||
);
|
||||
|
|
|
@ -6,10 +6,15 @@
|
|||
|
||||
var EXPORTED_SYMBOLS = ["FinderChild"];
|
||||
|
||||
const {ActorChild} = ChromeUtils.import("resource://gre/modules/ActorChild.jsm");
|
||||
const { ActorChild } = ChromeUtils.import(
|
||||
"resource://gre/modules/ActorChild.jsm"
|
||||
);
|
||||
|
||||
ChromeUtils.defineModuleGetter(this, "Finder",
|
||||
"resource://gre/modules/Finder.jsm");
|
||||
ChromeUtils.defineModuleGetter(
|
||||
this,
|
||||
"Finder",
|
||||
"resource://gre/modules/Finder.jsm"
|
||||
);
|
||||
|
||||
const MESSAGES = [
|
||||
"Finder:CaseSensitive",
|
||||
|
@ -70,26 +75,36 @@ class FinderChild extends ActorChild {
|
|||
|
||||
case "Finder:SetSearchStringToSelection": {
|
||||
let selection = this._finder.setSearchStringToSelection();
|
||||
this.mm.sendAsyncMessage("Finder:CurrentSelectionResult",
|
||||
{ selection,
|
||||
initial: false });
|
||||
this.mm.sendAsyncMessage("Finder:CurrentSelectionResult", {
|
||||
selection,
|
||||
initial: false,
|
||||
});
|
||||
break;
|
||||
}
|
||||
|
||||
case "Finder:GetInitialSelection": {
|
||||
let selection = this._finder.getActiveSelectionText();
|
||||
this.mm.sendAsyncMessage("Finder:CurrentSelectionResult",
|
||||
{ selection,
|
||||
initial: true });
|
||||
this.mm.sendAsyncMessage("Finder:CurrentSelectionResult", {
|
||||
selection,
|
||||
initial: true,
|
||||
});
|
||||
break;
|
||||
}
|
||||
|
||||
case "Finder:FastFind":
|
||||
this._finder.fastFind(data.searchString, data.linksOnly, data.drawOutline);
|
||||
this._finder.fastFind(
|
||||
data.searchString,
|
||||
data.linksOnly,
|
||||
data.drawOutline
|
||||
);
|
||||
break;
|
||||
|
||||
case "Finder:FindAgain":
|
||||
this._finder.findAgain(data.findBackwards, data.linksOnly, data.drawOutline);
|
||||
this._finder.findAgain(
|
||||
data.findBackwards,
|
||||
data.linksOnly,
|
||||
data.drawOutline
|
||||
);
|
||||
break;
|
||||
|
||||
case "Finder:Highlight":
|
||||
|
|
|
@ -8,8 +8,11 @@
|
|||
|
||||
var EXPORTED_SYMBOLS = ["InlineSpellCheckerChild"];
|
||||
|
||||
ChromeUtils.defineModuleGetter(this, "InlineSpellCheckerContent",
|
||||
"resource://gre/modules/InlineSpellCheckerContent.jsm");
|
||||
ChromeUtils.defineModuleGetter(
|
||||
this,
|
||||
"InlineSpellCheckerContent",
|
||||
"resource://gre/modules/InlineSpellCheckerContent.jsm"
|
||||
);
|
||||
|
||||
class InlineSpellCheckerChild extends JSWindowActorChild {
|
||||
receiveMessage(msg) {
|
||||
|
|
|
@ -10,13 +10,13 @@ var EXPORTED_SYMBOLS = ["InlineSpellCheckerParent"];
|
|||
|
||||
class InlineSpellCheckerParent extends JSWindowActorParent {
|
||||
selectDictionary({ localeCode }) {
|
||||
this.sendAsyncMessage("InlineSpellChecker:selectDictionary",
|
||||
{ localeCode });
|
||||
this.sendAsyncMessage("InlineSpellChecker:selectDictionary", {
|
||||
localeCode,
|
||||
});
|
||||
}
|
||||
|
||||
replaceMisspelling({ index }) {
|
||||
this.sendAsyncMessage("InlineSpellChecker:replaceMisspelling",
|
||||
{ index });
|
||||
this.sendAsyncMessage("InlineSpellChecker:replaceMisspelling", { index });
|
||||
}
|
||||
|
||||
toggleEnabled() {
|
||||
|
|
|
@ -8,9 +8,13 @@
|
|||
|
||||
var EXPORTED_SYMBOLS = ["KeyPressEventModelCheckerChild"];
|
||||
|
||||
const {ActorChild} = ChromeUtils.import("resource://gre/modules/ActorChild.jsm");
|
||||
const {AppConstants} = ChromeUtils.import("resource://gre/modules/AppConstants.jsm");
|
||||
const {Services} = ChromeUtils.import("resource://gre/modules/Services.jsm");
|
||||
const { ActorChild } = ChromeUtils.import(
|
||||
"resource://gre/modules/ActorChild.jsm"
|
||||
);
|
||||
const { AppConstants } = ChromeUtils.import(
|
||||
"resource://gre/modules/AppConstants.jsm"
|
||||
);
|
||||
const { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm");
|
||||
|
||||
class KeyPressEventModelCheckerChild extends ActorChild {
|
||||
// Currently, the event is dispatched only when the document becomes editable
|
||||
|
@ -29,27 +33,33 @@ class KeyPressEventModelCheckerChild extends ActorChild {
|
|||
// here, conflated model isn't used forcibly. If you need it, you need
|
||||
// to change WidgetKeyboardEvent, dom::KeyboardEvent and PresShell.
|
||||
let model = Document.KEYPRESS_EVENT_MODEL_DEFAULT;
|
||||
if (this._isOldOfficeOnlineServer(aEvent.target) ||
|
||||
this._isOldConfluence(aEvent.target.ownerGlobal)) {
|
||||
if (
|
||||
this._isOldOfficeOnlineServer(aEvent.target) ||
|
||||
this._isOldConfluence(aEvent.target.ownerGlobal)
|
||||
) {
|
||||
model = Document.KEYPRESS_EVENT_MODEL_SPLIT;
|
||||
}
|
||||
aEvent.target.setKeyPressEventModel(model);
|
||||
}
|
||||
|
||||
_isOldOfficeOnlineServer(aDocument) {
|
||||
let editingElement =
|
||||
aDocument.getElementById("WACViewPanel_EditingElement");
|
||||
let editingElement = aDocument.getElementById(
|
||||
"WACViewPanel_EditingElement"
|
||||
);
|
||||
// If it's not Office Online Server, don't include it into the telemetry
|
||||
// because we just need to collect percentage of old version in all loaded
|
||||
// Office Online Server instances.
|
||||
if (!editingElement) {
|
||||
return false;
|
||||
}
|
||||
let isOldVersion =
|
||||
!editingElement.classList.contains(
|
||||
"WACViewPanel_DisableLegacyKeyCodeAndCharCode");
|
||||
Services.telemetry.keyedScalarAdd("dom.event.office_online_load_count",
|
||||
isOldVersion ? "old" : "new", 1);
|
||||
let isOldVersion = !editingElement.classList.contains(
|
||||
"WACViewPanel_DisableLegacyKeyCodeAndCharCode"
|
||||
);
|
||||
Services.telemetry.keyedScalarAdd(
|
||||
"dom.event.office_online_load_count",
|
||||
isOldVersion ? "old" : "new",
|
||||
1
|
||||
);
|
||||
return isOldVersion;
|
||||
}
|
||||
|
||||
|
@ -85,8 +95,10 @@ class KeyPressEventModelCheckerChild extends ActorChild {
|
|||
// instance. So, let's check the version whether it allows conflated
|
||||
// keypress event model.
|
||||
try {
|
||||
let {author, version} =
|
||||
new tinyMCEObject.plugins.CursorTargetPlugin().getInfo();
|
||||
let {
|
||||
author,
|
||||
version,
|
||||
} = new tinyMCEObject.plugins.CursorTargetPlugin().getInfo();
|
||||
// If it's not Confluence, don't include it into the telemetry because
|
||||
// we just need to collect percentage of old version in all loaded
|
||||
// Confluence instances.
|
||||
|
@ -94,8 +106,11 @@ class KeyPressEventModelCheckerChild extends ActorChild {
|
|||
return false;
|
||||
}
|
||||
let isOldVersion = version === "1.0";
|
||||
Services.telemetry.keyedScalarAdd("dom.event.confluence_load_count",
|
||||
isOldVersion ? "old" : "new", 1);
|
||||
Services.telemetry.keyedScalarAdd(
|
||||
"dom.event.confluence_load_count",
|
||||
isOldVersion ? "old" : "new",
|
||||
1
|
||||
);
|
||||
return isOldVersion;
|
||||
} catch (e) {
|
||||
return false;
|
||||
|
|
|
@ -6,13 +6,23 @@
|
|||
|
||||
var EXPORTED_SYMBOLS = ["PictureInPictureChild", "PictureInPictureToggleChild"];
|
||||
|
||||
const {ActorChild} = ChromeUtils.import("resource://gre/modules/ActorChild.jsm");
|
||||
const {XPCOMUtils} = ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm");
|
||||
const { ActorChild } = ChromeUtils.import(
|
||||
"resource://gre/modules/ActorChild.jsm"
|
||||
);
|
||||
const { XPCOMUtils } = ChromeUtils.import(
|
||||
"resource://gre/modules/XPCOMUtils.jsm"
|
||||
);
|
||||
|
||||
ChromeUtils.defineModuleGetter(this, "DeferredTask",
|
||||
"resource://gre/modules/DeferredTask.jsm");
|
||||
ChromeUtils.defineModuleGetter(this, "Services",
|
||||
"resource://gre/modules/Services.jsm");
|
||||
ChromeUtils.defineModuleGetter(
|
||||
this,
|
||||
"DeferredTask",
|
||||
"resource://gre/modules/DeferredTask.jsm"
|
||||
);
|
||||
ChromeUtils.defineModuleGetter(
|
||||
this,
|
||||
"Services",
|
||||
"resource://gre/modules/Services.jsm"
|
||||
);
|
||||
|
||||
XPCOMUtils.defineLazyGlobalGetters(this, ["InspectorUtils"]);
|
||||
|
||||
|
@ -97,10 +107,12 @@ class PictureInPictureToggleChild extends ActorChild {
|
|||
|
||||
switch (event.type) {
|
||||
case "canplay": {
|
||||
if (this.toggleEnabled &&
|
||||
event.target instanceof this.content.HTMLVideoElement &&
|
||||
!event.target.controls &&
|
||||
event.target.ownerDocument == this.content.document) {
|
||||
if (
|
||||
this.toggleEnabled &&
|
||||
event.target instanceof this.content.HTMLVideoElement &&
|
||||
!event.target.controls &&
|
||||
event.target.ownerDocument == this.content.document
|
||||
) {
|
||||
this.registerVideo(event.target);
|
||||
}
|
||||
break;
|
||||
|
@ -229,29 +241,37 @@ class PictureInPictureToggleChild extends ActorChild {
|
|||
// part of the outer window, we need to also remove it in a
|
||||
// pagehide event listener in the event that the page unloads
|
||||
// before stopTrackingMouseOverVideos fires.
|
||||
this.content.windowRoot.addEventListener("pointerdown", this,
|
||||
{ capture: true });
|
||||
this.content.windowRoot.addEventListener("mousedown", this,
|
||||
{ capture: true });
|
||||
this.content.windowRoot.addEventListener("mouseup", this,
|
||||
{ capture: true });
|
||||
this.content.windowRoot.addEventListener("pointerup", this,
|
||||
{ capture: true });
|
||||
this.content.windowRoot.addEventListener("click", this,
|
||||
{ capture: true });
|
||||
this.content.windowRoot.addEventListener("pointerdown", this, {
|
||||
capture: true,
|
||||
});
|
||||
this.content.windowRoot.addEventListener("mousedown", this, {
|
||||
capture: true,
|
||||
});
|
||||
this.content.windowRoot.addEventListener("mouseup", this, {
|
||||
capture: true,
|
||||
});
|
||||
this.content.windowRoot.addEventListener("pointerup", this, {
|
||||
capture: true,
|
||||
});
|
||||
this.content.windowRoot.addEventListener("click", this, { capture: true });
|
||||
}
|
||||
|
||||
removeMouseButtonListeners() {
|
||||
this.content.windowRoot.removeEventListener("pointerdown", this,
|
||||
{ capture: true });
|
||||
this.content.windowRoot.removeEventListener("mousedown", this,
|
||||
{ capture: true });
|
||||
this.content.windowRoot.removeEventListener("mouseup", this,
|
||||
{ capture: true });
|
||||
this.content.windowRoot.removeEventListener("pointerup", this,
|
||||
{ capture: true });
|
||||
this.content.windowRoot.removeEventListener("click", this,
|
||||
{ capture: true });
|
||||
this.content.windowRoot.removeEventListener("pointerdown", this, {
|
||||
capture: true,
|
||||
});
|
||||
this.content.windowRoot.removeEventListener("mousedown", this, {
|
||||
capture: true,
|
||||
});
|
||||
this.content.windowRoot.removeEventListener("mouseup", this, {
|
||||
capture: true,
|
||||
});
|
||||
this.content.windowRoot.removeEventListener("pointerup", this, {
|
||||
capture: true,
|
||||
});
|
||||
this.content.windowRoot.removeEventListener("click", this, {
|
||||
capture: true,
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -274,8 +294,10 @@ class PictureInPictureToggleChild extends ActorChild {
|
|||
this.checkLastMouseMove();
|
||||
}, MOUSEMOVE_PROCESSING_DELAY_MS);
|
||||
}
|
||||
this.content.document.addEventListener("mousemove", this,
|
||||
{ mozSystemGroup: true, capture: true });
|
||||
this.content.document.addEventListener("mousemove", this, {
|
||||
mozSystemGroup: true,
|
||||
capture: true,
|
||||
});
|
||||
this.addMouseButtonListeners();
|
||||
}
|
||||
|
||||
|
@ -287,8 +309,10 @@ class PictureInPictureToggleChild extends ActorChild {
|
|||
stopTrackingMouseOverVideos() {
|
||||
let state = this.docState;
|
||||
state.mousemoveDeferredTask.disarm();
|
||||
this.content.document.removeEventListener("mousemove", this,
|
||||
{ mozSystemGroup: true, capture: true });
|
||||
this.content.document.removeEventListener("mousemove", this, {
|
||||
mozSystemGroup: true,
|
||||
capture: true,
|
||||
});
|
||||
this.removeMouseButtonListeners();
|
||||
let oldOverVideo = state.weakOverVideo && state.weakOverVideo.get();
|
||||
if (oldOverVideo) {
|
||||
|
@ -329,8 +353,17 @@ class PictureInPictureToggleChild extends ActorChild {
|
|||
// We pass the aOnlyVisible boolean argument to check that the video isn't
|
||||
// occluded by anything visible at the point of mousedown. If it is, we'll
|
||||
// ignore the mousedown.
|
||||
let elements = winUtils.nodesFromRect(clientX, clientY, 1, 1, 1, 1, true,
|
||||
false, true /* aOnlyVisible */);
|
||||
let elements = winUtils.nodesFromRect(
|
||||
clientX,
|
||||
clientY,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
true,
|
||||
false,
|
||||
true /* aOnlyVisible */
|
||||
);
|
||||
if (!Array.from(elements).includes(video)) {
|
||||
return;
|
||||
}
|
||||
|
@ -341,12 +374,15 @@ class PictureInPictureToggleChild extends ActorChild {
|
|||
state.clickedElement = Cu.getWeakReference(event.originalTarget);
|
||||
event.stopImmediatePropagation();
|
||||
|
||||
Services.telemetry.keyedScalarAdd("pictureinpicture.opened_method", "toggle", 1);
|
||||
Services.telemetry.keyedScalarAdd(
|
||||
"pictureinpicture.opened_method",
|
||||
"toggle",
|
||||
1
|
||||
);
|
||||
|
||||
let pipEvent =
|
||||
new this.content.CustomEvent("MozTogglePictureInPicture", {
|
||||
bubbles: true,
|
||||
});
|
||||
let pipEvent = new this.content.CustomEvent("MozTogglePictureInPicture", {
|
||||
bubbles: true,
|
||||
});
|
||||
video.dispatchEvent(pipEvent);
|
||||
|
||||
// Since we've initiated Picture-in-Picture, we can go ahead and
|
||||
|
@ -379,7 +415,7 @@ class PictureInPictureToggleChild extends ActorChild {
|
|||
let isMouseUpOnOtherElement =
|
||||
event.type == "mouseup" &&
|
||||
(!state.clickedElement ||
|
||||
state.clickedElement.get() != event.originalTarget);
|
||||
state.clickedElement.get() != event.originalTarget);
|
||||
|
||||
if (isMouseUpOnOtherElement || event.type == "click") {
|
||||
// The click is complete, so now we reset the state so that
|
||||
|
@ -416,12 +452,23 @@ class PictureInPictureToggleChild extends ActorChild {
|
|||
// We use winUtils.nodesFromRect instead of document.elementsFromPoint,
|
||||
// since document.elementsFromPoint always flushes layout. The 1's in that
|
||||
// function call are for the size of the rect that we want, which is 1x1.
|
||||
let elements = winUtils.nodesFromRect(clientX, clientY, 1, 1, 1, 1, true,
|
||||
false, false);
|
||||
let elements = winUtils.nodesFromRect(
|
||||
clientX,
|
||||
clientY,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
true,
|
||||
false,
|
||||
false
|
||||
);
|
||||
|
||||
for (let element of elements) {
|
||||
if (state.weakVisibleVideos.has(element) &&
|
||||
!element.isCloningElementVisually) {
|
||||
if (
|
||||
state.weakVisibleVideos.has(element) &&
|
||||
!element.isCloningElementVisually
|
||||
) {
|
||||
this.onMouseOverVideo(element, event);
|
||||
return;
|
||||
}
|
||||
|
@ -527,13 +574,16 @@ class PictureInPictureToggleChild extends ActorChild {
|
|||
* @return {Boolean}
|
||||
*/
|
||||
isMouseOverToggle(toggle, event) {
|
||||
let toggleRect =
|
||||
toggle.ownerGlobal.windowUtils.getBoundsWithoutFlushing(toggle);
|
||||
let toggleRect = toggle.ownerGlobal.windowUtils.getBoundsWithoutFlushing(
|
||||
toggle
|
||||
);
|
||||
let { clientX, clientY } = event;
|
||||
return clientX >= toggleRect.left &&
|
||||
clientX <= toggleRect.right &&
|
||||
clientY >= toggleRect.top &&
|
||||
clientY <= toggleRect.bottom;
|
||||
return (
|
||||
clientX >= toggleRect.left &&
|
||||
clientX <= toggleRect.right &&
|
||||
clientY >= toggleRect.top &&
|
||||
clientY <= toggleRect.bottom
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -547,7 +597,12 @@ class PictureInPictureToggleChild extends ActorChild {
|
|||
|
||||
class PictureInPictureChild extends ActorChild {
|
||||
static videoIsPlaying(video) {
|
||||
return !!(video.currentTime > 0 && !video.paused && !video.ended && video.readyState > 2);
|
||||
return !!(
|
||||
video.currentTime > 0 &&
|
||||
!video.paused &&
|
||||
!video.ended &&
|
||||
video.readyState > 2
|
||||
);
|
||||
}
|
||||
|
||||
handleEvent(event) {
|
||||
|
@ -660,8 +715,9 @@ class PictureInPictureChild extends ActorChild {
|
|||
if (this.weakPlayerContent) {
|
||||
if (!this.weakPlayerContent.closed) {
|
||||
await new Promise(resolve => {
|
||||
this.weakPlayerContent.addEventListener("unload", resolve,
|
||||
{ once: true });
|
||||
this.weakPlayerContent.addEventListener("unload", resolve, {
|
||||
once: true,
|
||||
});
|
||||
});
|
||||
}
|
||||
// Nothing should be holding a reference to the Picture-in-Picture
|
||||
|
@ -740,9 +796,9 @@ class PictureInPictureChild extends ActorChild {
|
|||
return;
|
||||
}
|
||||
|
||||
let webProgress = this.mm
|
||||
.docShell.QueryInterface(Ci.nsIInterfaceRequestor)
|
||||
.getInterface(Ci.nsIWebProgress);
|
||||
let webProgress = this.mm.docShell
|
||||
.QueryInterface(Ci.nsIInterfaceRequestor)
|
||||
.getInterface(Ci.nsIWebProgress);
|
||||
if (webProgress.isLoadingDocument) {
|
||||
await new Promise(resolve => {
|
||||
this.mm.addEventListener("load", resolve, {
|
||||
|
@ -777,12 +833,16 @@ class PictureInPictureChild extends ActorChild {
|
|||
|
||||
this.trackOriginatingVideo(originatingVideo);
|
||||
|
||||
this.content.addEventListener("unload", () => {
|
||||
if (this.weakVideo) {
|
||||
this.weakVideo.stopCloningElementVisually();
|
||||
}
|
||||
gWeakVideo = null;
|
||||
}, { once: true });
|
||||
this.content.addEventListener(
|
||||
"unload",
|
||||
() => {
|
||||
if (this.weakVideo) {
|
||||
this.weakVideo.stopCloningElementVisually();
|
||||
}
|
||||
gWeakVideo = null;
|
||||
},
|
||||
{ once: true }
|
||||
);
|
||||
|
||||
gWeakPlayerContent = Cu.getWeakReference(this.content);
|
||||
}
|
||||
|
|
|
@ -7,8 +7,12 @@
|
|||
|
||||
var EXPORTED_SYMBOLS = ["PopupBlockingChild"];
|
||||
|
||||
const {ActorChild} = ChromeUtils.import("resource://gre/modules/ActorChild.jsm");
|
||||
const {XPCOMUtils} = ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm");
|
||||
const { ActorChild } = ChromeUtils.import(
|
||||
"resource://gre/modules/ActorChild.jsm"
|
||||
);
|
||||
const { XPCOMUtils } = ChromeUtils.import(
|
||||
"resource://gre/modules/XPCOMUtils.jsm"
|
||||
);
|
||||
|
||||
class PopupBlockingChild extends ActorChild {
|
||||
constructor(dispatcher) {
|
||||
|
@ -36,7 +40,11 @@ class PopupBlockingChild extends ActorChild {
|
|||
// If we have a requesting window and the requesting document is
|
||||
// still the current document, open the popup.
|
||||
if (dwi && dwi.document == internals.requestingDocument) {
|
||||
dwi.open(data.popupWindowURIspec, data.popupWindowName, data.popupWindowFeatures);
|
||||
dwi.open(
|
||||
data.popupWindowURIspec,
|
||||
data.popupWindowName,
|
||||
data.popupWindowFeatures
|
||||
);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
@ -60,10 +68,12 @@ class PopupBlockingChild extends ActorChild {
|
|||
popupWindowURIspec = popupWindowURIspec.substring(0, 500);
|
||||
}
|
||||
|
||||
popupData.push({popupWindowURIspec});
|
||||
popupData.push({ popupWindowURIspec });
|
||||
}
|
||||
|
||||
this.mm.sendAsyncMessage("PopupBlocking:ReplyGetBlockedPopupList", {popupData});
|
||||
this.mm.sendAsyncMessage("PopupBlocking:ReplyGetBlockedPopupList", {
|
||||
popupData,
|
||||
});
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -93,7 +103,9 @@ class PopupBlockingChild extends ActorChild {
|
|||
}
|
||||
|
||||
let obj = {
|
||||
popupWindowURIspec: ev.popupWindowURI ? ev.popupWindowURI.spec : "about:blank",
|
||||
popupWindowURIspec: ev.popupWindowURI
|
||||
? ev.popupWindowURI.spec
|
||||
: "about:blank",
|
||||
popupWindowFeatures: ev.popupWindowFeatures,
|
||||
popupWindowName: ev.popupWindowName,
|
||||
};
|
||||
|
@ -113,10 +125,15 @@ class PopupBlockingChild extends ActorChild {
|
|||
let i = 0;
|
||||
let oldLength = this.popupData.length;
|
||||
while (i < this.popupData.length) {
|
||||
let {requestingWindow, requestingDocument} = this.popupDataInternal[i];
|
||||
let { requestingWindow, requestingDocument } = this.popupDataInternal[
|
||||
i
|
||||
];
|
||||
// Filter out irrelevant reports.
|
||||
if (requestingWindow && requestingWindow.document == requestingDocument &&
|
||||
requestingDocument != removedDoc) {
|
||||
if (
|
||||
requestingWindow &&
|
||||
requestingWindow.document == requestingDocument &&
|
||||
requestingDocument != removedDoc
|
||||
) {
|
||||
i++;
|
||||
} else {
|
||||
this.popupData.splice(i, 1);
|
||||
|
@ -134,13 +151,15 @@ class PopupBlockingChild extends ActorChild {
|
|||
}
|
||||
|
||||
updateBlockedPopups(freshPopup) {
|
||||
this.mm.sendAsyncMessage("PopupBlocking:UpdateBlockedPopups",
|
||||
{
|
||||
count: this.popupData ? this.popupData.length : 0,
|
||||
freshPopup,
|
||||
});
|
||||
this.mm.sendAsyncMessage("PopupBlocking:UpdateBlockedPopups", {
|
||||
count: this.popupData ? this.popupData.length : 0,
|
||||
freshPopup,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
XPCOMUtils.defineLazyPreferenceGetter(PopupBlockingChild, "maxReportedPopups",
|
||||
"privacy.popups.maxReported");
|
||||
XPCOMUtils.defineLazyPreferenceGetter(
|
||||
PopupBlockingChild,
|
||||
"maxReportedPopups",
|
||||
"privacy.popups.maxReported"
|
||||
);
|
||||
|
|
|
@ -6,11 +6,16 @@
|
|||
|
||||
var EXPORTED_SYMBOLS = ["PrintingChild"];
|
||||
|
||||
const {ActorChild} = ChromeUtils.import("resource://gre/modules/ActorChild.jsm");
|
||||
const {Services} = ChromeUtils.import("resource://gre/modules/Services.jsm");
|
||||
const { ActorChild } = ChromeUtils.import(
|
||||
"resource://gre/modules/ActorChild.jsm"
|
||||
);
|
||||
const { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm");
|
||||
|
||||
ChromeUtils.defineModuleGetter(this, "ReaderMode",
|
||||
"resource://gre/modules/ReaderMode.jsm");
|
||||
ChromeUtils.defineModuleGetter(
|
||||
this,
|
||||
"ReaderMode",
|
||||
"resource://gre/modules/ReaderMode.jsm"
|
||||
);
|
||||
|
||||
class PrintingChild extends ActorChild {
|
||||
// Bug 1088061: nsPrintJob's DoCommonPrint currently expects the
|
||||
|
@ -21,8 +26,10 @@ class PrintingChild extends ActorChild {
|
|||
// this hackery.
|
||||
|
||||
get shouldSavePrintSettings() {
|
||||
return Services.prefs.getBoolPref("print.use_global_printsettings") &&
|
||||
Services.prefs.getBoolPref("print.save_print_settings");
|
||||
return (
|
||||
Services.prefs.getBoolPref("print.use_global_printsettings") &&
|
||||
Services.prefs.getBoolPref("print.save_print_settings")
|
||||
);
|
||||
}
|
||||
|
||||
handleEvent(event) {
|
||||
|
@ -72,10 +79,12 @@ class PrintingChild extends ActorChild {
|
|||
let data = message.data;
|
||||
switch (message.name) {
|
||||
case "Printing:Preview:Enter": {
|
||||
this.enterPrintPreview(Services.wm.getOuterWindowWithId(data.windowID),
|
||||
data.simplifiedMode,
|
||||
data.changingBrowsers,
|
||||
data.defaultPrinterName);
|
||||
this.enterPrintPreview(
|
||||
Services.wm.getOuterWindowWithId(data.windowID),
|
||||
data.simplifiedMode,
|
||||
data.changingBrowsers,
|
||||
data.defaultPrinterName
|
||||
);
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -90,14 +99,19 @@ class PrintingChild extends ActorChild {
|
|||
}
|
||||
|
||||
case "Printing:Preview:ParseDocument": {
|
||||
this.parseDocument(data.URL, Services.wm.getOuterWindowWithId(data.windowID));
|
||||
this.parseDocument(
|
||||
data.URL,
|
||||
Services.wm.getOuterWindowWithId(data.windowID)
|
||||
);
|
||||
break;
|
||||
}
|
||||
|
||||
case "Printing:Print": {
|
||||
this.print(Services.wm.getOuterWindowWithId(data.windowID),
|
||||
data.simplifiedMode,
|
||||
data.defaultPrinterName);
|
||||
this.print(
|
||||
Services.wm.getOuterWindowWithId(data.windowID),
|
||||
data.simplifiedMode,
|
||||
data.defaultPrinterName
|
||||
);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -105,19 +119,25 @@ class PrintingChild extends ActorChild {
|
|||
|
||||
getPrintSettings(defaultPrinterName) {
|
||||
try {
|
||||
let PSSVC = Cc["@mozilla.org/gfx/printsettings-service;1"]
|
||||
.getService(Ci.nsIPrintSettingsService);
|
||||
let PSSVC = Cc["@mozilla.org/gfx/printsettings-service;1"].getService(
|
||||
Ci.nsIPrintSettingsService
|
||||
);
|
||||
|
||||
let printSettings = PSSVC.globalPrintSettings;
|
||||
if (!printSettings.printerName) {
|
||||
printSettings.printerName = defaultPrinterName;
|
||||
}
|
||||
// First get any defaults from the printer
|
||||
PSSVC.initPrintSettingsFromPrinter(printSettings.printerName,
|
||||
printSettings);
|
||||
PSSVC.initPrintSettingsFromPrinter(
|
||||
printSettings.printerName,
|
||||
printSettings
|
||||
);
|
||||
// now augment them with any values from last time
|
||||
PSSVC.initPrintSettingsFromPrefs(printSettings, true,
|
||||
printSettings.kInitSaveAll);
|
||||
PSSVC.initPrintSettingsFromPrefs(
|
||||
printSettings,
|
||||
true,
|
||||
printSettings.kInitSaveAll
|
||||
);
|
||||
|
||||
return printSettings;
|
||||
} catch (e) {
|
||||
|
@ -130,12 +150,14 @@ class PrintingChild extends ActorChild {
|
|||
parseDocument(URL, contentWindow) {
|
||||
// By using ReaderMode primitives, we parse given document and place the
|
||||
// resulting JS object into the DOM of current browser.
|
||||
let articlePromise = ReaderMode.parseDocument(contentWindow.document).catch(Cu.reportError);
|
||||
articlePromise.then((article) => {
|
||||
let articlePromise = ReaderMode.parseDocument(contentWindow.document).catch(
|
||||
Cu.reportError
|
||||
);
|
||||
articlePromise.then(article => {
|
||||
// We make use of a web progress listener in order to know when the content we inject
|
||||
// into the DOM has finished rendering. If our layout engine is still painting, we
|
||||
// will wait for MozAfterPaint event to be fired.
|
||||
let {mm} = this;
|
||||
let { mm } = this;
|
||||
let webProgressListener = {
|
||||
onStateChange(webProgress, req, flags, status) {
|
||||
if (flags & Ci.nsIWebProgressListener.STATE_STOP) {
|
||||
|
@ -167,12 +189,16 @@ class PrintingChild extends ActorChild {
|
|||
]),
|
||||
};
|
||||
|
||||
const {content, docShell} = this.mm;
|
||||
const { content, docShell } = this.mm;
|
||||
|
||||
// Here we QI the docShell into a nsIWebProgress passing our web progress listener in.
|
||||
let webProgress = docShell.QueryInterface(Ci.nsIInterfaceRequestor)
|
||||
.getInterface(Ci.nsIWebProgress);
|
||||
webProgress.addProgressListener(webProgressListener, Ci.nsIWebProgress.NOTIFY_STATE_REQUEST);
|
||||
let webProgress = docShell
|
||||
.QueryInterface(Ci.nsIInterfaceRequestor)
|
||||
.getInterface(Ci.nsIWebProgress);
|
||||
webProgress.addProgressListener(
|
||||
webProgressListener,
|
||||
Ci.nsIWebProgress.NOTIFY_STATE_REQUEST
|
||||
);
|
||||
|
||||
content.document.head.innerHTML = "";
|
||||
|
||||
|
@ -186,14 +212,20 @@ class PrintingChild extends ActorChild {
|
|||
// Create link element referencing aboutReader.css and append it to head
|
||||
let headStyleElement = content.document.createElement("link");
|
||||
headStyleElement.setAttribute("rel", "stylesheet");
|
||||
headStyleElement.setAttribute("href", "chrome://global/skin/aboutReader.css");
|
||||
headStyleElement.setAttribute(
|
||||
"href",
|
||||
"chrome://global/skin/aboutReader.css"
|
||||
);
|
||||
headStyleElement.setAttribute("type", "text/css");
|
||||
content.document.head.appendChild(headStyleElement);
|
||||
|
||||
// Create link element referencing simplifyMode.css and append it to head
|
||||
headStyleElement = content.document.createElement("link");
|
||||
headStyleElement.setAttribute("rel", "stylesheet");
|
||||
headStyleElement.setAttribute("href", "chrome://global/content/simplifyMode.css");
|
||||
headStyleElement.setAttribute(
|
||||
"href",
|
||||
"chrome://global/content/simplifyMode.css"
|
||||
);
|
||||
headStyleElement.setAttribute("type", "text/css");
|
||||
content.document.head.appendChild(headStyleElement);
|
||||
|
||||
|
@ -242,18 +274,29 @@ class PrintingChild extends ActorChild {
|
|||
contentElement.appendChild(readerContent);
|
||||
|
||||
let articleUri = Services.io.newURI(article.url);
|
||||
let parserUtils = Cc["@mozilla.org/parserutils;1"].getService(Ci.nsIParserUtils);
|
||||
let contentFragment = parserUtils.parseFragment(article.content,
|
||||
Ci.nsIParserUtils.SanitizerDropForms | Ci.nsIParserUtils.SanitizerAllowStyle,
|
||||
false, articleUri, readerContent);
|
||||
let parserUtils = Cc["@mozilla.org/parserutils;1"].getService(
|
||||
Ci.nsIParserUtils
|
||||
);
|
||||
let contentFragment = parserUtils.parseFragment(
|
||||
article.content,
|
||||
Ci.nsIParserUtils.SanitizerDropForms |
|
||||
Ci.nsIParserUtils.SanitizerAllowStyle,
|
||||
false,
|
||||
articleUri,
|
||||
readerContent
|
||||
);
|
||||
|
||||
readerContent.appendChild(contentFragment);
|
||||
|
||||
// Display reader content element
|
||||
readerContent.style.display = "block";
|
||||
} else {
|
||||
let aboutReaderStrings = Services.strings.createBundle("chrome://global/locale/aboutReader.properties");
|
||||
let errorMessage = aboutReaderStrings.GetStringFromName("aboutReader.loadError");
|
||||
let aboutReaderStrings = Services.strings.createBundle(
|
||||
"chrome://global/locale/aboutReader.properties"
|
||||
);
|
||||
let errorMessage = aboutReaderStrings.GetStringFromName(
|
||||
"aboutReader.loadError"
|
||||
);
|
||||
|
||||
content.document.title = errorMessage;
|
||||
|
||||
|
@ -269,16 +312,22 @@ class PrintingChild extends ActorChild {
|
|||
});
|
||||
}
|
||||
|
||||
enterPrintPreview(contentWindow, simplifiedMode, changingBrowsers, defaultPrinterName) {
|
||||
const {docShell} = this;
|
||||
enterPrintPreview(
|
||||
contentWindow,
|
||||
simplifiedMode,
|
||||
changingBrowsers,
|
||||
defaultPrinterName
|
||||
) {
|
||||
const { docShell } = this;
|
||||
try {
|
||||
let printSettings = this.getPrintSettings(defaultPrinterName);
|
||||
|
||||
// If we happen to be on simplified mode, we need to set docURL in order
|
||||
// to generate header/footer content correctly, since simplified tab has
|
||||
// "about:blank" as its URI.
|
||||
if (printSettings && simplifiedMode)
|
||||
if (printSettings && simplifiedMode) {
|
||||
printSettings.docURL = contentWindow.document.baseURI;
|
||||
}
|
||||
|
||||
// The print preview docshell will be in a different TabGroup, so
|
||||
// printPreviewInitialize must be run in a separate runnable to avoid
|
||||
|
@ -288,13 +337,17 @@ class PrintingChild extends ActorChild {
|
|||
let listener = new PrintingListener(this.mm);
|
||||
|
||||
this.printPreviewInitializingInfo = { changingBrowsers };
|
||||
docShell.initOrReusePrintPreviewViewer().printPreview(printSettings, contentWindow, listener);
|
||||
docShell
|
||||
.initOrReusePrintPreviewViewer()
|
||||
.printPreview(printSettings, contentWindow, listener);
|
||||
} catch (error) {
|
||||
// This might fail if we, for example, attempt to print a XUL document.
|
||||
// In that case, we inform the parent to bail out of print preview.
|
||||
Cu.reportError(error);
|
||||
this.printPreviewInitializingInfo = null;
|
||||
this.mm.sendAsyncMessage("Printing:Preview:Entered", { failed: true });
|
||||
this.mm.sendAsyncMessage("Printing:Preview:Entered", {
|
||||
failed: true,
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -302,8 +355,10 @@ class PrintingChild extends ActorChild {
|
|||
// initial setup of a previous preview request. We delay this one until
|
||||
// that has finished because running them at the same time will almost
|
||||
// certainly cause failures.
|
||||
if (this.printPreviewInitializingInfo &&
|
||||
!this.printPreviewInitializingInfo.entered) {
|
||||
if (
|
||||
this.printPreviewInitializingInfo &&
|
||||
!this.printPreviewInitializingInfo.entered
|
||||
) {
|
||||
this.printPreviewInitializingInfo.nextRequest = printPreviewInitialize;
|
||||
} else {
|
||||
Services.tm.dispatchToMainThread(printPreviewInitialize);
|
||||
|
@ -367,15 +422,24 @@ class PrintingChild extends ActorChild {
|
|||
}
|
||||
}
|
||||
|
||||
if ((!printCancelled || printSettings.saveOnCancel) &&
|
||||
this.shouldSavePrintSettings) {
|
||||
let PSSVC = Cc["@mozilla.org/gfx/printsettings-service;1"]
|
||||
.getService(Ci.nsIPrintSettingsService);
|
||||
if (
|
||||
(!printCancelled || printSettings.saveOnCancel) &&
|
||||
this.shouldSavePrintSettings
|
||||
) {
|
||||
let PSSVC = Cc["@mozilla.org/gfx/printsettings-service;1"].getService(
|
||||
Ci.nsIPrintSettingsService
|
||||
);
|
||||
|
||||
PSSVC.savePrintSettingsToPrefs(printSettings, true,
|
||||
printSettings.kInitSaveAll);
|
||||
PSSVC.savePrintSettingsToPrefs(printSettings, false,
|
||||
printSettings.kInitSavePrinterName);
|
||||
PSSVC.savePrintSettingsToPrefs(
|
||||
printSettings,
|
||||
true,
|
||||
printSettings.kInitSaveAll
|
||||
);
|
||||
PSSVC.savePrintSettingsToPrefs(
|
||||
printSettings,
|
||||
false,
|
||||
printSettings.kInitSavePrinterName
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -385,19 +449,23 @@ class PrintingChild extends ActorChild {
|
|||
}
|
||||
|
||||
updatePageCount() {
|
||||
let numPages = this.docShell.initOrReusePrintPreviewViewer().printPreviewNumPages;
|
||||
let numPages = this.docShell.initOrReusePrintPreviewViewer()
|
||||
.printPreviewNumPages;
|
||||
this.mm.sendAsyncMessage("Printing:Preview:UpdatePageCount", {
|
||||
numPages,
|
||||
});
|
||||
}
|
||||
|
||||
navigate(navType, pageNum) {
|
||||
this.docShell.initOrReusePrintPreviewViewer().printPreviewScrollToPage(navType, pageNum);
|
||||
this.docShell
|
||||
.initOrReusePrintPreviewViewer()
|
||||
.printPreviewScrollToPage(navType, pageNum);
|
||||
}
|
||||
}
|
||||
|
||||
PrintingChild.prototype.QueryInterface =
|
||||
ChromeUtils.generateQI([Ci.nsIPrintingPromptService]);
|
||||
PrintingChild.prototype.QueryInterface = ChromeUtils.generateQI([
|
||||
Ci.nsIPrintingPromptService,
|
||||
]);
|
||||
|
||||
function PrintingListener(global) {
|
||||
this.global = global;
|
||||
|
@ -412,9 +480,14 @@ PrintingListener.prototype = {
|
|||
});
|
||||
},
|
||||
|
||||
onProgressChange(aWebProgress, aRequest, aCurSelfProgress,
|
||||
aMaxSelfProgress, aCurTotalProgress,
|
||||
aMaxTotalProgress) {
|
||||
onProgressChange(
|
||||
aWebProgress,
|
||||
aRequest,
|
||||
aCurSelfProgress,
|
||||
aMaxSelfProgress,
|
||||
aCurTotalProgress,
|
||||
aMaxTotalProgress
|
||||
) {
|
||||
this.global.sendAsyncMessage("Printing:Preview:ProgressChange", {
|
||||
curSelfProgress: aCurSelfProgress,
|
||||
maxSelfProgress: aMaxSelfProgress,
|
||||
|
|
|
@ -6,14 +6,17 @@
|
|||
|
||||
var EXPORTED_SYMBOLS = ["PurgeSessionHistoryChild"];
|
||||
|
||||
const {ActorChild} = ChromeUtils.import("resource://gre/modules/ActorChild.jsm");
|
||||
const { ActorChild } = ChromeUtils.import(
|
||||
"resource://gre/modules/ActorChild.jsm"
|
||||
);
|
||||
|
||||
class PurgeSessionHistoryChild extends ActorChild {
|
||||
receiveMessage(message) {
|
||||
if (message.name != "Browser:PurgeSessionHistory") {
|
||||
return;
|
||||
}
|
||||
let sessionHistory = this.docShell.QueryInterface(Ci.nsIWebNavigation).sessionHistory;
|
||||
let sessionHistory = this.docShell.QueryInterface(Ci.nsIWebNavigation)
|
||||
.sessionHistory;
|
||||
if (!sessionHistory) {
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -6,12 +6,20 @@
|
|||
|
||||
var EXPORTED_SYMBOLS = ["SelectChild"];
|
||||
|
||||
const {XPCOMUtils} = ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm");
|
||||
const { XPCOMUtils } = ChromeUtils.import(
|
||||
"resource://gre/modules/XPCOMUtils.jsm"
|
||||
);
|
||||
|
||||
ChromeUtils.defineModuleGetter(this, "BrowserUtils",
|
||||
"resource://gre/modules/BrowserUtils.jsm");
|
||||
ChromeUtils.defineModuleGetter(this, "DeferredTask",
|
||||
"resource://gre/modules/DeferredTask.jsm");
|
||||
ChromeUtils.defineModuleGetter(
|
||||
this,
|
||||
"BrowserUtils",
|
||||
"resource://gre/modules/BrowserUtils.jsm"
|
||||
);
|
||||
ChromeUtils.defineModuleGetter(
|
||||
this,
|
||||
"DeferredTask",
|
||||
"resource://gre/modules/DeferredTask.jsm"
|
||||
);
|
||||
|
||||
XPCOMUtils.defineLazyGlobalGetters(this, ["InspectorUtils"]);
|
||||
|
||||
|
@ -60,7 +68,9 @@ this.SelectContentHelper.prototype = {
|
|||
let win = this.element.ownerGlobal;
|
||||
win.addEventListener("pagehide", this, { mozSystemGroup: true });
|
||||
this.element.addEventListener("blur", this, { mozSystemGroup: true });
|
||||
this.element.addEventListener("transitionend", this, { mozSystemGroup: true });
|
||||
this.element.addEventListener("transitionend", this, {
|
||||
mozSystemGroup: true,
|
||||
});
|
||||
let MutationObserver = this.element.ownerGlobal.MutationObserver;
|
||||
this.mut = new MutationObserver(mutations => {
|
||||
// Something changed the <select> while it was open, so
|
||||
|
@ -68,7 +78,11 @@ this.SelectContentHelper.prototype = {
|
|||
// in the very near future.
|
||||
this._updateTimer.arm();
|
||||
});
|
||||
this.mut.observe(this.element, {childList: true, subtree: true, attributes: true});
|
||||
this.mut.observe(this.element, {
|
||||
childList: true,
|
||||
subtree: true,
|
||||
attributes: true,
|
||||
});
|
||||
},
|
||||
|
||||
uninit() {
|
||||
|
@ -76,7 +90,9 @@ this.SelectContentHelper.prototype = {
|
|||
let win = this.element.ownerGlobal;
|
||||
win.removeEventListener("pagehide", this, { mozSystemGroup: true });
|
||||
this.element.removeEventListener("blur", this, { mozSystemGroup: true });
|
||||
this.element.removeEventListener("transitionend", this, { mozSystemGroup: true });
|
||||
this.element.removeEventListener("transitionend", this, {
|
||||
mozSystemGroup: true,
|
||||
});
|
||||
this.element = null;
|
||||
this.actor = null;
|
||||
this.mut.disconnect();
|
||||
|
@ -91,7 +107,9 @@ this.SelectContentHelper.prototype = {
|
|||
let rect = this._getBoundingContentRect();
|
||||
let computedStyles = getComputedStyles(this.element);
|
||||
let options = this._buildOptionList();
|
||||
let defaultStyles = this.element.ownerGlobal.getDefaultComputedStyle(this.element);
|
||||
let defaultStyles = this.element.ownerGlobal.getDefaultComputedStyle(
|
||||
this.element
|
||||
);
|
||||
this.actor.sendAsyncMessage("Forms:ShowDropDown", {
|
||||
isOpenedViaTouch: this.isOpenedViaTouch,
|
||||
options,
|
||||
|
@ -112,7 +130,9 @@ this.SelectContentHelper.prototype = {
|
|||
// any styles.
|
||||
this._pseudoStylesSetup = true;
|
||||
InspectorUtils.addPseudoClassLock(this.element, ":focus");
|
||||
let lockedDescendants = this._lockedDescendants = this.element.querySelectorAll(":checked");
|
||||
let lockedDescendants = (this._lockedDescendants = this.element.querySelectorAll(
|
||||
":checked"
|
||||
));
|
||||
for (let child of lockedDescendants) {
|
||||
// Selected options have the :checked pseudo-class, which
|
||||
// we want to disable before calculating the computed
|
||||
|
@ -158,7 +178,9 @@ this.SelectContentHelper.prototype = {
|
|||
// have :focus, though it is here for belt-and-suspenders.
|
||||
this._setupPseudoClassStyles();
|
||||
let computedStyles = getComputedStyles(this.element);
|
||||
let defaultStyles = this.element.ownerGlobal.getDefaultComputedStyle(this.element);
|
||||
let defaultStyles = this.element.ownerGlobal.getDefaultComputedStyle(
|
||||
this.element
|
||||
);
|
||||
this.actor.sendAsyncMessage("Forms:UpdateDropDown", {
|
||||
options: this._buildOptionList(),
|
||||
selectedIndex: this.element.selectedIndex,
|
||||
|
@ -185,52 +207,55 @@ this.SelectContentHelper.prototype = {
|
|||
break;
|
||||
|
||||
case "Forms:DismissedDropDown": {
|
||||
if (!this.element) {
|
||||
return;
|
||||
}
|
||||
|
||||
let win = this.element.ownerGlobal;
|
||||
let selectedOption = this.element.item(this.element.selectedIndex);
|
||||
|
||||
// For ordering of events, we're using non-e10s as our guide here,
|
||||
// since the spec isn't exactly clear. In non-e10s:
|
||||
// - If the user clicks on an element in the dropdown, we fire
|
||||
// mousedown, mouseup, input, change, and click events.
|
||||
// - If the user uses the keyboard to select an element in the
|
||||
// dropdown, we only fire input and change events.
|
||||
// - If the user pressed ESC key or clicks outside the dropdown,
|
||||
// we fire nothing as the selected option is unchanged.
|
||||
if (this.closedWithClickOn) {
|
||||
this.dispatchMouseEvent(win, selectedOption, "mousedown");
|
||||
this.dispatchMouseEvent(win, selectedOption, "mouseup");
|
||||
}
|
||||
|
||||
// Clear active document no matter user selects via keyboard or mouse
|
||||
InspectorUtils.removeContentState(this.element, kStateActive,
|
||||
/* aClearActiveDocument */ true);
|
||||
|
||||
// Fire input and change events when selected option changes
|
||||
if (this.initialSelection !== selectedOption) {
|
||||
let inputEvent = new win.Event("input", {
|
||||
bubbles: true,
|
||||
});
|
||||
this.element.dispatchEvent(inputEvent);
|
||||
|
||||
let changeEvent = new win.Event("change", {
|
||||
bubbles: true,
|
||||
});
|
||||
this.element.dispatchEvent(changeEvent);
|
||||
}
|
||||
|
||||
// Fire click event
|
||||
if (this.closedWithClickOn) {
|
||||
this.dispatchMouseEvent(win, selectedOption, "click");
|
||||
}
|
||||
|
||||
this.uninit();
|
||||
break;
|
||||
if (!this.element) {
|
||||
return;
|
||||
}
|
||||
|
||||
let win = this.element.ownerGlobal;
|
||||
let selectedOption = this.element.item(this.element.selectedIndex);
|
||||
|
||||
// For ordering of events, we're using non-e10s as our guide here,
|
||||
// since the spec isn't exactly clear. In non-e10s:
|
||||
// - If the user clicks on an element in the dropdown, we fire
|
||||
// mousedown, mouseup, input, change, and click events.
|
||||
// - If the user uses the keyboard to select an element in the
|
||||
// dropdown, we only fire input and change events.
|
||||
// - If the user pressed ESC key or clicks outside the dropdown,
|
||||
// we fire nothing as the selected option is unchanged.
|
||||
if (this.closedWithClickOn) {
|
||||
this.dispatchMouseEvent(win, selectedOption, "mousedown");
|
||||
this.dispatchMouseEvent(win, selectedOption, "mouseup");
|
||||
}
|
||||
|
||||
// Clear active document no matter user selects via keyboard or mouse
|
||||
InspectorUtils.removeContentState(
|
||||
this.element,
|
||||
kStateActive,
|
||||
/* aClearActiveDocument */ true
|
||||
);
|
||||
|
||||
// Fire input and change events when selected option changes
|
||||
if (this.initialSelection !== selectedOption) {
|
||||
let inputEvent = new win.Event("input", {
|
||||
bubbles: true,
|
||||
});
|
||||
this.element.dispatchEvent(inputEvent);
|
||||
|
||||
let changeEvent = new win.Event("change", {
|
||||
bubbles: true,
|
||||
});
|
||||
this.element.dispatchEvent(changeEvent);
|
||||
}
|
||||
|
||||
// Fire click event
|
||||
if (this.closedWithClickOn) {
|
||||
this.dispatchMouseEvent(win, selectedOption, "click");
|
||||
}
|
||||
|
||||
this.uninit();
|
||||
break;
|
||||
}
|
||||
|
||||
case "Forms:MouseOver":
|
||||
InspectorUtils.setContentState(this.element, kStateHover);
|
||||
break;
|
||||
|
@ -342,8 +367,7 @@ function buildOptionListForChildren(node, uniqueStyles) {
|
|||
}
|
||||
|
||||
let textContent =
|
||||
tagName == "OPTGROUP" ? child.getAttribute("label")
|
||||
: child.text;
|
||||
tagName == "OPTGROUP" ? child.getAttribute("label") : child.text;
|
||||
if (textContent == null) {
|
||||
textContent = "";
|
||||
}
|
||||
|
@ -356,9 +380,10 @@ function buildOptionListForChildren(node, uniqueStyles) {
|
|||
disabled: child.disabled,
|
||||
display: cs.display,
|
||||
tooltip: child.title,
|
||||
children: tagName == "OPTGROUP"
|
||||
? buildOptionListForChildren(child, uniqueStyles)
|
||||
: [],
|
||||
children:
|
||||
tagName == "OPTGROUP"
|
||||
? buildOptionListForChildren(child, uniqueStyles)
|
||||
: [],
|
||||
// Most options have the same style. In order to reduce the size of the
|
||||
// IPC message, coalesce them in uniqueStyles.
|
||||
styleIndex: uniqueStylesIndex(cs, uniqueStyles),
|
||||
|
@ -370,7 +395,6 @@ function buildOptionListForChildren(node, uniqueStyles) {
|
|||
return result;
|
||||
}
|
||||
|
||||
|
||||
// Hold the instance of SelectContentHelper created
|
||||
// when the dropdown list is opened. This variable helps
|
||||
// re-route the received message from SelectChild to SelectContentHelper object.
|
||||
|
@ -389,19 +413,25 @@ class SelectChild extends JSWindowActorChild {
|
|||
}
|
||||
|
||||
switch (event.type) {
|
||||
case "mozshowdropdown":
|
||||
{
|
||||
let contentHelper = new SelectContentHelper(event.target, {isOpenedViaTouch: false}, this);
|
||||
currentSelectContentHelper.set(this, contentHelper);
|
||||
break;
|
||||
}
|
||||
case "mozshowdropdown": {
|
||||
let contentHelper = new SelectContentHelper(
|
||||
event.target,
|
||||
{ isOpenedViaTouch: false },
|
||||
this
|
||||
);
|
||||
currentSelectContentHelper.set(this, contentHelper);
|
||||
break;
|
||||
}
|
||||
|
||||
case "mozshowdropdown-sourcetouch":
|
||||
{
|
||||
let contentHelper = new SelectContentHelper(event.target, {isOpenedViaTouch: true}, this);
|
||||
currentSelectContentHelper.set(this, contentHelper);
|
||||
break;
|
||||
}
|
||||
case "mozshowdropdown-sourcetouch": {
|
||||
let contentHelper = new SelectContentHelper(
|
||||
event.target,
|
||||
{ isOpenedViaTouch: true },
|
||||
this
|
||||
);
|
||||
currentSelectContentHelper.set(this, contentHelper);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -4,13 +4,12 @@
|
|||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
"use strict";
|
||||
|
||||
var EXPORTED_SYMBOLS = [
|
||||
"SelectParent",
|
||||
"SelectParentHelper",
|
||||
];
|
||||
var EXPORTED_SYMBOLS = ["SelectParent", "SelectParentHelper"];
|
||||
|
||||
const {AppConstants} = ChromeUtils.import("resource://gre/modules/AppConstants.jsm");
|
||||
const {Services} = ChromeUtils.import("resource://gre/modules/Services.jsm");
|
||||
const { AppConstants } = ChromeUtils.import(
|
||||
"resource://gre/modules/AppConstants.jsm"
|
||||
);
|
||||
const { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm");
|
||||
|
||||
// Maximum number of rows to display in the select dropdown.
|
||||
const MAX_ROWS = 20;
|
||||
|
@ -25,7 +24,9 @@ const PROPERTIES_RESET_WHEN_ACTIVE = [
|
|||
"text-shadow",
|
||||
];
|
||||
|
||||
const customStylingEnabled = Services.prefs.getBoolPref("dom.forms.select.customstyling");
|
||||
const customStylingEnabled = Services.prefs.getBoolPref(
|
||||
"dom.forms.select.customstyling"
|
||||
);
|
||||
|
||||
var SelectParentHelper = {
|
||||
/**
|
||||
|
@ -59,8 +60,15 @@ var SelectParentHelper = {
|
|||
* FIXME(emilio, bug 1530709): At the very least we should use CSSOM to avoid
|
||||
* trusting the IPC message too much.
|
||||
*/
|
||||
populate(menulist, items, uniqueItemStyles, selectedIndex, zoom,
|
||||
uaStyle, selectStyle) {
|
||||
populate(
|
||||
menulist,
|
||||
items,
|
||||
uniqueItemStyles,
|
||||
selectedIndex,
|
||||
zoom,
|
||||
uaStyle,
|
||||
selectStyle
|
||||
) {
|
||||
// Clear the current contents of the popup
|
||||
menulist.menupopup.textContent = "";
|
||||
let stylesheet = menulist.querySelector("#ContentSelectDropdownStylesheet");
|
||||
|
@ -88,8 +96,10 @@ var SelectParentHelper = {
|
|||
|
||||
// Some webpages set the <select> backgroundColor to transparent,
|
||||
// but they don't intend to change the popup to transparent.
|
||||
if (customStylingEnabled &&
|
||||
selectStyle["background-color"] != uaStyle["background-color"]) {
|
||||
if (
|
||||
customStylingEnabled &&
|
||||
selectStyle["background-color"] != uaStyle["background-color"]
|
||||
) {
|
||||
let color = selectStyle["background-color"];
|
||||
selectStyle["background-image"] = `linear-gradient(${color}, ${color});`;
|
||||
selectBackgroundSet = true;
|
||||
|
@ -101,26 +111,36 @@ var SelectParentHelper = {
|
|||
|
||||
if (customStylingEnabled) {
|
||||
if (selectStyle["text-shadow"] != "none") {
|
||||
sheet.insertRule(`#ContentSelectDropdown > menupopup > [_moz-menuactive="true"] {
|
||||
sheet.insertRule(
|
||||
`#ContentSelectDropdown > menupopup > [_moz-menuactive="true"] {
|
||||
text-shadow: none;
|
||||
}`, 0);
|
||||
}`,
|
||||
0
|
||||
);
|
||||
}
|
||||
|
||||
let ruleBody = "";
|
||||
for (let property in selectStyle) {
|
||||
if (property == "background-color" || property == "direction")
|
||||
continue; // Handled above, or before.
|
||||
if (property == "background-color" || property == "direction") {
|
||||
continue;
|
||||
} // Handled above, or before.
|
||||
if (selectStyle[property] != uaStyle[property]) {
|
||||
ruleBody += `${property}: ${selectStyle[property]};`;
|
||||
}
|
||||
}
|
||||
if (ruleBody) {
|
||||
sheet.insertRule(`#ContentSelectDropdown > menupopup {
|
||||
sheet.insertRule(
|
||||
`#ContentSelectDropdown > menupopup {
|
||||
${ruleBody}
|
||||
}`, 0);
|
||||
sheet.insertRule(`#ContentSelectDropdown > menupopup > :not([_moz-menuactive="true"]) {
|
||||
}`,
|
||||
0
|
||||
);
|
||||
sheet.insertRule(
|
||||
`#ContentSelectDropdown > menupopup > :not([_moz-menuactive="true"]) {
|
||||
color: inherit;
|
||||
}`, 0);
|
||||
}`,
|
||||
0
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -135,8 +155,16 @@ var SelectParentHelper = {
|
|||
|
||||
this._currentZoom = zoom;
|
||||
this._currentMenulist = menulist;
|
||||
this.populateChildren(menulist, items, uniqueItemStyles, selectedIndex, zoom,
|
||||
selectStyle, selectBackgroundSet, sheet);
|
||||
this.populateChildren(
|
||||
menulist,
|
||||
items,
|
||||
uniqueItemStyles,
|
||||
selectedIndex,
|
||||
zoom,
|
||||
selectStyle,
|
||||
selectBackgroundSet,
|
||||
sheet
|
||||
);
|
||||
},
|
||||
|
||||
open(browser, menulist, rect, isOpenedViaTouch, selectParentActor) {
|
||||
|
@ -161,23 +189,37 @@ var SelectParentHelper = {
|
|||
|
||||
// Include the padding and border on the popup.
|
||||
let cs = win.getComputedStyle(menupopup);
|
||||
let bpHeight = parseFloat(cs.borderTopWidth) + parseFloat(cs.borderBottomWidth) +
|
||||
parseFloat(cs.paddingTop) + parseFloat(cs.paddingBottom);
|
||||
menupopup.style.maxHeight = (itemHeight * MAX_ROWS + bpHeight) + "px";
|
||||
let bpHeight =
|
||||
parseFloat(cs.borderTopWidth) +
|
||||
parseFloat(cs.borderBottomWidth) +
|
||||
parseFloat(cs.paddingTop) +
|
||||
parseFloat(cs.paddingBottom);
|
||||
menupopup.style.maxHeight = itemHeight * MAX_ROWS + bpHeight + "px";
|
||||
}
|
||||
|
||||
menupopup.classList.toggle("isOpenedViaTouch", isOpenedViaTouch);
|
||||
|
||||
if (browser.getAttribute("selectmenuconstrained") != "false") {
|
||||
let constraintRect = browser.getBoundingClientRect();
|
||||
constraintRect = new win.DOMRect(constraintRect.left + win.mozInnerScreenX,
|
||||
constraintRect.top + win.mozInnerScreenY,
|
||||
constraintRect.width, constraintRect.height);
|
||||
constraintRect = new win.DOMRect(
|
||||
constraintRect.left + win.mozInnerScreenX,
|
||||
constraintRect.top + win.mozInnerScreenY,
|
||||
constraintRect.width,
|
||||
constraintRect.height
|
||||
);
|
||||
menupopup.setConstraintRect(constraintRect);
|
||||
} else {
|
||||
menupopup.setConstraintRect(new win.DOMRect(0, 0, 0, 0));
|
||||
}
|
||||
menupopup.openPopupAtScreenRect(AppConstants.platform == "macosx" ? "selection" : "after_start", rect.left, rect.top, rect.width, rect.height, false, false);
|
||||
menupopup.openPopupAtScreenRect(
|
||||
AppConstants.platform == "macosx" ? "selection" : "after_start",
|
||||
rect.left,
|
||||
rect.top,
|
||||
rect.width,
|
||||
rect.height,
|
||||
false,
|
||||
false
|
||||
);
|
||||
},
|
||||
|
||||
hide(menulist, browser) {
|
||||
|
@ -190,12 +232,20 @@ var SelectParentHelper = {
|
|||
switch (event.type) {
|
||||
case "mouseup":
|
||||
function inRect(rect, x, y) {
|
||||
return x >= rect.left && x <= rect.left + rect.width && y >= rect.top && y <= rect.top + rect.height;
|
||||
return (
|
||||
x >= rect.left &&
|
||||
x <= rect.left + rect.width &&
|
||||
y >= rect.top &&
|
||||
y <= rect.top + rect.height
|
||||
);
|
||||
}
|
||||
|
||||
let x = event.screenX, y = event.screenY;
|
||||
let onAnchor = !inRect(this._currentMenulist.menupopup.getOuterScreenRect(), x, y) &&
|
||||
inRect(this._selectRect, x, y) && this._currentMenulist.menupopup.state == "open";
|
||||
let x = event.screenX,
|
||||
y = event.screenY;
|
||||
let onAnchor =
|
||||
!inRect(this._currentMenulist.menupopup.getOuterScreenRect(), x, y) &&
|
||||
inRect(this._selectRect, x, y) &&
|
||||
this._currentMenulist.menupopup.state == "open";
|
||||
this._actor.sendAsyncMessage("Forms:MouseUp", { onAnchor });
|
||||
break;
|
||||
|
||||
|
@ -260,9 +310,15 @@ var SelectParentHelper = {
|
|||
|
||||
let options = msg.data.options;
|
||||
let selectedIndex = msg.data.selectedIndex;
|
||||
this.populate(this._currentMenulist, options.options, options.uniqueStyles,
|
||||
selectedIndex, this._currentZoom, msg.data.defaultStyle,
|
||||
msg.data.style);
|
||||
this.populate(
|
||||
this._currentMenulist,
|
||||
options.options,
|
||||
options.uniqueStyles,
|
||||
selectedIndex,
|
||||
this._currentZoom,
|
||||
msg.data.defaultStyle,
|
||||
msg.data.style
|
||||
);
|
||||
|
||||
// Restore scroll position to what it was prior to the update.
|
||||
scrollBox.scrollTop = scrollTop;
|
||||
|
@ -315,21 +371,34 @@ var SelectParentHelper = {
|
|||
*
|
||||
* FIXME(emilio): Again, using a stylesheet + :nth-child is not really efficient.
|
||||
*/
|
||||
populateChildren(menulist, options, uniqueOptionStyles, selectedIndex,
|
||||
zoom, selectStyle, selectBackgroundSet, sheet,
|
||||
parentElement = null, isGroupDisabled = false,
|
||||
addSearch = true, nthChildIndex = 1) {
|
||||
populateChildren(
|
||||
menulist,
|
||||
options,
|
||||
uniqueOptionStyles,
|
||||
selectedIndex,
|
||||
zoom,
|
||||
selectStyle,
|
||||
selectBackgroundSet,
|
||||
sheet,
|
||||
parentElement = null,
|
||||
isGroupDisabled = false,
|
||||
addSearch = true,
|
||||
nthChildIndex = 1
|
||||
) {
|
||||
let element = menulist.menupopup;
|
||||
|
||||
for (let option of options) {
|
||||
let isOptGroup = (option.tagName == "OPTGROUP");
|
||||
let item = element.ownerDocument.createXULElement(isOptGroup ? "menucaption" : "menuitem");
|
||||
let isOptGroup = option.tagName == "OPTGROUP";
|
||||
let item = element.ownerDocument.createXULElement(
|
||||
isOptGroup ? "menucaption" : "menuitem"
|
||||
);
|
||||
let style = uniqueOptionStyles[option.styleIndex];
|
||||
|
||||
item.setAttribute("label", option.textContent);
|
||||
item.style.direction = style.direction;
|
||||
item.style.fontSize = (zoom * parseFloat(style["font-size"], 10)) + "px";
|
||||
item.hidden = option.display == "none" || (parentElement && parentElement.hidden);
|
||||
item.style.fontSize = zoom * parseFloat(style["font-size"], 10) + "px";
|
||||
item.hidden =
|
||||
option.display == "none" || (parentElement && parentElement.hidden);
|
||||
// Keep track of which options are hidden by page content, so we can avoid showing
|
||||
// them on search input
|
||||
item.hiddenByContent = item.hidden;
|
||||
|
@ -339,7 +408,8 @@ var SelectParentHelper = {
|
|||
style["background-color"] = selectStyle["background-color"];
|
||||
}
|
||||
|
||||
let optionBackgroundSet = style["background-color"] != selectStyle["background-color"];
|
||||
let optionBackgroundSet =
|
||||
style["background-color"] != selectStyle["background-color"];
|
||||
|
||||
if (style.color == style["background-color"]) {
|
||||
style.color = selectStyle.color;
|
||||
|
@ -348,10 +418,12 @@ var SelectParentHelper = {
|
|||
if (customStylingEnabled) {
|
||||
let ruleBody = "";
|
||||
for (let property in style) {
|
||||
if (property == "direction" || property == "font-size")
|
||||
continue; // handled above
|
||||
if (style[property] == selectStyle[property])
|
||||
if (property == "direction" || property == "font-size") {
|
||||
continue;
|
||||
} // handled above
|
||||
if (style[property] == selectStyle[property]) {
|
||||
continue;
|
||||
}
|
||||
if (PROPERTIES_RESET_WHEN_ACTIVE.includes(property)) {
|
||||
ruleBody += `${property}: ${style[property]};`;
|
||||
} else {
|
||||
|
@ -360,23 +432,34 @@ var SelectParentHelper = {
|
|||
}
|
||||
|
||||
if (ruleBody) {
|
||||
sheet.insertRule(`#ContentSelectDropdown > menupopup > :nth-child(${nthChildIndex}):not([_moz-menuactive="true"]) {
|
||||
sheet.insertRule(
|
||||
`#ContentSelectDropdown > menupopup > :nth-child(${nthChildIndex}):not([_moz-menuactive="true"]) {
|
||||
${ruleBody}
|
||||
}`, 0);
|
||||
}`,
|
||||
0
|
||||
);
|
||||
|
||||
if (style["text-shadow"] != "none" &&
|
||||
style["text-shadow"] != selectStyle["text-shadow"]) {
|
||||
if (
|
||||
style["text-shadow"] != "none" &&
|
||||
style["text-shadow"] != selectStyle["text-shadow"]
|
||||
) {
|
||||
// Need to explicitly disable the possibly inherited
|
||||
// text-shadow rule when _moz-menuactive=true since
|
||||
// _moz-menuactive=true disables custom option styling.
|
||||
sheet.insertRule(`#ContentSelectDropdown > menupopup > :nth-child(${nthChildIndex})[_moz-menuactive="true"] {
|
||||
sheet.insertRule(
|
||||
`#ContentSelectDropdown > menupopup > :nth-child(${nthChildIndex})[_moz-menuactive="true"] {
|
||||
text-shadow: none;
|
||||
}`, 0);
|
||||
}`,
|
||||
0
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (customStylingEnabled && (optionBackgroundSet || selectBackgroundSet)) {
|
||||
if (
|
||||
customStylingEnabled &&
|
||||
(optionBackgroundSet || selectBackgroundSet)
|
||||
) {
|
||||
item.setAttribute("customoptionstyling", "true");
|
||||
} else {
|
||||
item.removeAttribute("customoptionstyling");
|
||||
|
@ -392,11 +475,20 @@ var SelectParentHelper = {
|
|||
}
|
||||
|
||||
if (isOptGroup) {
|
||||
nthChildIndex =
|
||||
this.populateChildren(menulist, option.children, uniqueOptionStyles,
|
||||
selectedIndex, zoom, selectStyle,
|
||||
selectBackgroundSet, sheet, item, isDisabled, false,
|
||||
nthChildIndex);
|
||||
nthChildIndex = this.populateChildren(
|
||||
menulist,
|
||||
option.children,
|
||||
uniqueOptionStyles,
|
||||
selectedIndex,
|
||||
zoom,
|
||||
selectStyle,
|
||||
selectBackgroundSet,
|
||||
sheet,
|
||||
item,
|
||||
isDisabled,
|
||||
false,
|
||||
nthChildIndex
|
||||
);
|
||||
} else {
|
||||
if (option.index == selectedIndex) {
|
||||
// We expect the parent element of the popup to be a <xul:menulist> that
|
||||
|
@ -424,22 +516,32 @@ var SelectParentHelper = {
|
|||
|
||||
// Check if search pref is enabled, if this is the first time iterating through
|
||||
// the dropdown, and if the list is long enough for a search element to be added.
|
||||
if (Services.prefs.getBoolPref("dom.forms.selectSearch") && addSearch
|
||||
&& element.childElementCount > SEARCH_MINIMUM_ELEMENTS) {
|
||||
if (
|
||||
Services.prefs.getBoolPref("dom.forms.selectSearch") &&
|
||||
addSearch &&
|
||||
element.childElementCount > SEARCH_MINIMUM_ELEMENTS
|
||||
) {
|
||||
// Add a search text field as the first element of the dropdown
|
||||
let searchbox = element.ownerDocument.createXULElement("textbox", {
|
||||
is: "search-textbox",
|
||||
});
|
||||
searchbox.className = "contentSelectDropdown-searchbox";
|
||||
searchbox.addEventListener("input", this.onSearchInput);
|
||||
searchbox.inputField.addEventListener("focus", this.onSearchFocus.bind(this));
|
||||
searchbox.inputField.addEventListener(
|
||||
"focus",
|
||||
this.onSearchFocus.bind(this)
|
||||
);
|
||||
searchbox.inputField.addEventListener("blur", this.onSearchBlur);
|
||||
searchbox.addEventListener("command", this.onSearchInput);
|
||||
|
||||
// Handle special keys for exiting search
|
||||
searchbox.addEventListener("keydown", (event) => {
|
||||
this.onSearchKeydown(event, menulist);
|
||||
}, true);
|
||||
searchbox.addEventListener(
|
||||
"keydown",
|
||||
event => {
|
||||
this.onSearchKeydown(event, menulist);
|
||||
},
|
||||
true
|
||||
);
|
||||
|
||||
element.insertBefore(searchbox, element.children[0]);
|
||||
}
|
||||
|
@ -461,13 +563,17 @@ var SelectParentHelper = {
|
|||
case "Enter":
|
||||
case "Tab":
|
||||
searchbox.blur();
|
||||
if (searchbox.nextElementSibling.localName == "menuitem" &&
|
||||
!searchbox.nextElementSibling.hidden) {
|
||||
if (
|
||||
searchbox.nextElementSibling.localName == "menuitem" &&
|
||||
!searchbox.nextElementSibling.hidden
|
||||
) {
|
||||
menulist.activeChild = searchbox.nextElementSibling;
|
||||
} else {
|
||||
let currentOption = searchbox.nextElementSibling;
|
||||
while (currentOption && (currentOption.localName != "menuitem" ||
|
||||
currentOption.hidden)) {
|
||||
while (
|
||||
currentOption &&
|
||||
(currentOption.localName != "menuitem" || currentOption.hidden)
|
||||
) {
|
||||
currentOption = currentOption.nextElementSibling;
|
||||
}
|
||||
if (currentOption) {
|
||||
|
@ -517,8 +623,12 @@ var SelectParentHelper = {
|
|||
prevCaption = currentItem;
|
||||
allHidden = true;
|
||||
} else {
|
||||
if (!currentItem.classList.contains("contentSelectDropdown-ingroup") &&
|
||||
currentItem.previousElementSibling.classList.contains("contentSelectDropdown-ingroup")) {
|
||||
if (
|
||||
!currentItem.classList.contains("contentSelectDropdown-ingroup") &&
|
||||
currentItem.previousElementSibling.classList.contains(
|
||||
"contentSelectDropdown-ingroup"
|
||||
)
|
||||
) {
|
||||
if (prevCaption != null) {
|
||||
prevCaption.hidden = allHidden;
|
||||
}
|
||||
|
@ -557,8 +667,7 @@ var SelectParentHelper = {
|
|||
class SelectParent extends JSWindowActorParent {
|
||||
receiveMessage(message) {
|
||||
switch (message.name) {
|
||||
case "Forms:ShowDropDown":
|
||||
{
|
||||
case "Forms:ShowDropDown": {
|
||||
let topBrowsingContext = this.manager.browsingContext.top;
|
||||
let browser = topBrowsingContext.embedderElement;
|
||||
|
||||
|
@ -567,7 +676,9 @@ class SelectParent extends JSWindowActorParent {
|
|||
}
|
||||
|
||||
let document = browser.ownerDocument;
|
||||
let menulist = document.getElementById(browser.getAttribute("selectmenulist"));
|
||||
let menulist = document.getElementById(
|
||||
browser.getAttribute("selectmenulist")
|
||||
);
|
||||
|
||||
if (!this._menulist) {
|
||||
// Cache the menulist to have access to it
|
||||
|
@ -578,25 +689,37 @@ class SelectParent extends JSWindowActorParent {
|
|||
let data = message.data;
|
||||
menulist.menupopup.style.direction = data.style.direction;
|
||||
|
||||
let useFullZoom = !browser.isRemoteBrowser ||
|
||||
Services.prefs.getBoolPref("browser.zoom.full") ||
|
||||
browser.isSyntheticDocument;
|
||||
let useFullZoom =
|
||||
!browser.isRemoteBrowser ||
|
||||
Services.prefs.getBoolPref("browser.zoom.full") ||
|
||||
browser.isSyntheticDocument;
|
||||
let zoom = useFullZoom ? browser._fullZoom : browser._textZoom;
|
||||
|
||||
SelectParentHelper.populate(menulist, data.options.options,
|
||||
data.options.uniqueStyles, data.selectedIndex, zoom,
|
||||
data.defaultStyle, data.style);
|
||||
SelectParentHelper.open(browser, menulist, data.rect, data.isOpenedViaTouch, this);
|
||||
SelectParentHelper.populate(
|
||||
menulist,
|
||||
data.options.options,
|
||||
data.options.uniqueStyles,
|
||||
data.selectedIndex,
|
||||
zoom,
|
||||
data.defaultStyle,
|
||||
data.style
|
||||
);
|
||||
SelectParentHelper.open(
|
||||
browser,
|
||||
menulist,
|
||||
data.rect,
|
||||
data.isOpenedViaTouch,
|
||||
this
|
||||
);
|
||||
break;
|
||||
}
|
||||
|
||||
case "Forms:HideDropDown":
|
||||
{
|
||||
let topBrowsingContext = this.manager.browsingContext.top;
|
||||
let browser = topBrowsingContext.embedderElement;
|
||||
SelectParentHelper.hide(this._menulist, browser);
|
||||
break;
|
||||
}
|
||||
case "Forms:HideDropDown": {
|
||||
let topBrowsingContext = this.manager.browsingContext.top;
|
||||
let browser = topBrowsingContext.embedderElement;
|
||||
SelectParentHelper.hide(this._menulist, browser);
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
SelectParentHelper.receiveMessage(message);
|
||||
|
|
|
@ -5,8 +5,10 @@
|
|||
|
||||
var EXPORTED_SYMBOLS = ["SelectionSourceChild"];
|
||||
|
||||
const {ActorChild} = ChromeUtils.import("resource://gre/modules/ActorChild.jsm");
|
||||
const {Services} = ChromeUtils.import("resource://gre/modules/Services.jsm");
|
||||
const { ActorChild } = ChromeUtils.import(
|
||||
"resource://gre/modules/ActorChild.jsm"
|
||||
);
|
||||
const { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm");
|
||||
|
||||
class SelectionSourceChild extends ActorChild {
|
||||
receiveMessage(message) {
|
||||
|
@ -17,7 +19,10 @@ class SelectionSourceChild extends ActorChild {
|
|||
try {
|
||||
selectionDetails = this.getSelection(global);
|
||||
} finally {
|
||||
global.sendAsyncMessage("ViewSource:GetSelectionDone", selectionDetails);
|
||||
global.sendAsyncMessage(
|
||||
"ViewSource:GetSelectionDone",
|
||||
selectionDetails
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -30,11 +35,13 @@ class SelectionSourceChild extends ActorChild {
|
|||
getPath(ancestor, node) {
|
||||
var n = node;
|
||||
var p = n.parentNode;
|
||||
if (n == ancestor || !p)
|
||||
if (n == ancestor || !p) {
|
||||
return null;
|
||||
}
|
||||
var path = [];
|
||||
if (!path)
|
||||
if (!path) {
|
||||
return null;
|
||||
}
|
||||
do {
|
||||
for (var i = 0; i < p.childNodes.length; i++) {
|
||||
if (p.childNodes.item(i) == n) {
|
||||
|
@ -49,7 +56,7 @@ class SelectionSourceChild extends ActorChild {
|
|||
}
|
||||
|
||||
getSelection(global) {
|
||||
const {content} = global;
|
||||
const { content } = global;
|
||||
|
||||
// These are markers used to delimit the selection during processing. They
|
||||
// are removed from the final rendering.
|
||||
|
@ -73,16 +80,20 @@ class SelectionSourceChild extends ActorChild {
|
|||
|
||||
// let the ancestor be an element
|
||||
var Node = doc.defaultView.Node;
|
||||
if (ancestorContainer.nodeType == Node.TEXT_NODE ||
|
||||
ancestorContainer.nodeType == Node.CDATA_SECTION_NODE)
|
||||
if (
|
||||
ancestorContainer.nodeType == Node.TEXT_NODE ||
|
||||
ancestorContainer.nodeType == Node.CDATA_SECTION_NODE
|
||||
) {
|
||||
ancestorContainer = ancestorContainer.parentNode;
|
||||
}
|
||||
|
||||
// for selectAll, let's use the entire document, including <html>...</html>
|
||||
// @see nsDocumentViewer::SelectAll() for how selectAll is implemented
|
||||
try {
|
||||
if (ancestorContainer == doc.body)
|
||||
if (ancestorContainer == doc.body) {
|
||||
ancestorContainer = doc.documentElement;
|
||||
} catch (e) { }
|
||||
}
|
||||
} catch (e) {}
|
||||
|
||||
// each path is a "child sequence" (a.k.a. "tumbler") that
|
||||
// descends from the ancestor down to the boundary point
|
||||
|
@ -95,10 +106,14 @@ class SelectionSourceChild extends ActorChild {
|
|||
// loading and the like. The use of importNode here, as opposed to adoptNode,
|
||||
// is _very_ important.
|
||||
// XXXbz wish there were a less hacky way to create an untrusted document here
|
||||
var isHTML = (doc.createElement("div").tagName == "DIV");
|
||||
var dataDoc = isHTML ?
|
||||
ancestorContainer.ownerDocument.implementation.createHTMLDocument("") :
|
||||
ancestorContainer.ownerDocument.implementation.createDocument("", "", null);
|
||||
var isHTML = doc.createElement("div").tagName == "DIV";
|
||||
var dataDoc = isHTML
|
||||
? ancestorContainer.ownerDocument.implementation.createHTMLDocument("")
|
||||
: ancestorContainer.ownerDocument.implementation.createDocument(
|
||||
"",
|
||||
"",
|
||||
null
|
||||
);
|
||||
ancestorContainer = dataDoc.importNode(ancestorContainer, true);
|
||||
startContainer = ancestorContainer;
|
||||
endContainer = ancestorContainer;
|
||||
|
@ -121,51 +136,75 @@ class SelectionSourceChild extends ActorChild {
|
|||
// note: |startOffset| and |endOffset| are interpreted either as
|
||||
// offsets in the text data or as child indices (see the Range spec)
|
||||
// (here, munging the end point first to keep the start point safe...)
|
||||
if (endContainer.nodeType == Node.TEXT_NODE ||
|
||||
endContainer.nodeType == Node.CDATA_SECTION_NODE) {
|
||||
if (
|
||||
endContainer.nodeType == Node.TEXT_NODE ||
|
||||
endContainer.nodeType == Node.CDATA_SECTION_NODE
|
||||
) {
|
||||
// do some extra tweaks to try to avoid the view-source output to look like
|
||||
// ...<tag>]... or ...]</tag>... (where ']' marks the end of the selection).
|
||||
// To get a neat output, the idea here is to remap the end point from:
|
||||
// 1. ...<tag>]... to ...]<tag>...
|
||||
// 2. ...]</tag>... to ...</tag>]...
|
||||
if ((endOffset > 0 && endOffset < endContainer.data.length) ||
|
||||
!endContainer.parentNode || !endContainer.parentNode.parentNode) {
|
||||
if (
|
||||
(endOffset > 0 && endOffset < endContainer.data.length) ||
|
||||
!endContainer.parentNode ||
|
||||
!endContainer.parentNode.parentNode
|
||||
) {
|
||||
endContainer.insertData(endOffset, MARK_SELECTION_END);
|
||||
} else {
|
||||
tmpNode = dataDoc.createTextNode(MARK_SELECTION_END);
|
||||
endContainer = endContainer.parentNode;
|
||||
if (endOffset === 0)
|
||||
if (endOffset === 0) {
|
||||
endContainer.parentNode.insertBefore(tmpNode, endContainer);
|
||||
else
|
||||
endContainer.parentNode.insertBefore(tmpNode, endContainer.nextSibling);
|
||||
} else {
|
||||
endContainer.parentNode.insertBefore(
|
||||
tmpNode,
|
||||
endContainer.nextSibling
|
||||
);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
tmpNode = dataDoc.createTextNode(MARK_SELECTION_END);
|
||||
endContainer.insertBefore(tmpNode, endContainer.childNodes.item(endOffset));
|
||||
endContainer.insertBefore(
|
||||
tmpNode,
|
||||
endContainer.childNodes.item(endOffset)
|
||||
);
|
||||
}
|
||||
|
||||
if (startContainer.nodeType == Node.TEXT_NODE ||
|
||||
startContainer.nodeType == Node.CDATA_SECTION_NODE) {
|
||||
if (
|
||||
startContainer.nodeType == Node.TEXT_NODE ||
|
||||
startContainer.nodeType == Node.CDATA_SECTION_NODE
|
||||
) {
|
||||
// do some extra tweaks to try to avoid the view-source output to look like
|
||||
// ...<tag>[... or ...[</tag>... (where '[' marks the start of the selection).
|
||||
// To get a neat output, the idea here is to remap the start point from:
|
||||
// 1. ...<tag>[... to ...[<tag>...
|
||||
// 2. ...[</tag>... to ...</tag>[...
|
||||
if ((startOffset > 0 && startOffset < startContainer.data.length) ||
|
||||
!startContainer.parentNode || !startContainer.parentNode.parentNode ||
|
||||
startContainer != startContainer.parentNode.lastChild) {
|
||||
if (
|
||||
(startOffset > 0 && startOffset < startContainer.data.length) ||
|
||||
!startContainer.parentNode ||
|
||||
!startContainer.parentNode.parentNode ||
|
||||
startContainer != startContainer.parentNode.lastChild
|
||||
) {
|
||||
startContainer.insertData(startOffset, MARK_SELECTION_START);
|
||||
} else {
|
||||
tmpNode = dataDoc.createTextNode(MARK_SELECTION_START);
|
||||
startContainer = startContainer.parentNode;
|
||||
if (startOffset === 0)
|
||||
if (startOffset === 0) {
|
||||
startContainer.parentNode.insertBefore(tmpNode, startContainer);
|
||||
else
|
||||
startContainer.parentNode.insertBefore(tmpNode, startContainer.nextSibling);
|
||||
} else {
|
||||
startContainer.parentNode.insertBefore(
|
||||
tmpNode,
|
||||
startContainer.nextSibling
|
||||
);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
tmpNode = dataDoc.createTextNode(MARK_SELECTION_START);
|
||||
startContainer.insertBefore(tmpNode, startContainer.childNodes.item(startOffset));
|
||||
startContainer.insertBefore(
|
||||
tmpNode,
|
||||
startContainer.childNodes.item(startOffset)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -173,11 +212,15 @@ class SelectionSourceChild extends ActorChild {
|
|||
tmpNode = dataDoc.createElementNS("http://www.w3.org/1999/xhtml", "div");
|
||||
tmpNode.appendChild(ancestorContainer);
|
||||
|
||||
return { uri: (isHTML ? "view-source:data:text/html;charset=utf-8," :
|
||||
"view-source:data:application/xml;charset=utf-8,")
|
||||
+ encodeURIComponent(tmpNode.innerHTML),
|
||||
drawSelection: canDrawSelection,
|
||||
baseURI: doc.baseURI };
|
||||
return {
|
||||
uri:
|
||||
(isHTML
|
||||
? "view-source:data:text/html;charset=utf-8,"
|
||||
: "view-source:data:application/xml;charset=utf-8,") +
|
||||
encodeURIComponent(tmpNode.innerHTML),
|
||||
drawSelection: canDrawSelection,
|
||||
baseURI: doc.baseURI,
|
||||
};
|
||||
}
|
||||
|
||||
get wrapLongLines() {
|
||||
|
|
|
@ -4,13 +4,13 @@
|
|||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
"use strict";
|
||||
|
||||
const {Services} = ChromeUtils.import("resource://gre/modules/Services.jsm");
|
||||
const { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm");
|
||||
|
||||
var EXPORTED_SYMBOLS = ["TestChild"];
|
||||
|
||||
class TestChild extends JSWindowActorChild {
|
||||
constructor() {
|
||||
super();
|
||||
super();
|
||||
}
|
||||
|
||||
receiveMessage(aMessage) {
|
||||
|
@ -20,7 +20,7 @@ class TestChild extends JSWindowActorChild {
|
|||
this.sendAsyncMessage("toParent", aMessage.data);
|
||||
break;
|
||||
case "asyncAdd":
|
||||
let {a, b} = aMessage.data;
|
||||
let { a, b } = aMessage.data;
|
||||
return new Promise(resolve => {
|
||||
resolve({ result: a + b });
|
||||
});
|
||||
|
@ -37,7 +37,7 @@ class TestChild extends JSWindowActorChild {
|
|||
}
|
||||
|
||||
observe(subject, topic, data) {
|
||||
this.lastObserved = {subject, topic, data};
|
||||
this.lastObserved = { subject, topic, data };
|
||||
}
|
||||
|
||||
show() {
|
||||
|
@ -46,11 +46,13 @@ class TestChild extends JSWindowActorChild {
|
|||
|
||||
willDestroy() {
|
||||
Services.obs.notifyObservers(
|
||||
this, "test-js-window-actor-willdestroy", true);
|
||||
this,
|
||||
"test-js-window-actor-willdestroy",
|
||||
true
|
||||
);
|
||||
}
|
||||
|
||||
didDestroy() {
|
||||
Services.obs.notifyObservers(
|
||||
this, "test-js-window-actor-diddestroy", true);
|
||||
Services.obs.notifyObservers(this, "test-js-window-actor-diddestroy", true);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
"use strict";
|
||||
|
||||
const {Services} = ChromeUtils.import("resource://gre/modules/Services.jsm");
|
||||
const { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm");
|
||||
|
||||
var EXPORTED_SYMBOLS = ["TestParent"];
|
||||
|
||||
|
@ -17,7 +17,7 @@ class TestParent extends JSWindowActorParent {
|
|||
receiveMessage(aMessage) {
|
||||
switch (aMessage.name) {
|
||||
case "init":
|
||||
aMessage.data.initial = true;
|
||||
aMessage.data.initial = true;
|
||||
this.sendAsyncMessage("toChild", aMessage.data);
|
||||
break;
|
||||
case "toParent":
|
||||
|
@ -25,12 +25,15 @@ class TestParent extends JSWindowActorParent {
|
|||
this.sendAsyncMessage("done", aMessage.data);
|
||||
break;
|
||||
case "asyncMul":
|
||||
let {a, b} = aMessage.data;
|
||||
let { a, b } = aMessage.data;
|
||||
return { result: a * b };
|
||||
|
||||
case "event":
|
||||
Services.obs.notifyObservers(
|
||||
this, "test-js-window-actor-parent-event", aMessage.data.type);
|
||||
this,
|
||||
"test-js-window-actor-parent-event",
|
||||
aMessage.data.type
|
||||
);
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
|
@ -6,11 +6,16 @@
|
|||
|
||||
var EXPORTED_SYMBOLS = ["ThumbnailsChild"];
|
||||
|
||||
const {ActorChild} = ChromeUtils.import("resource://gre/modules/ActorChild.jsm");
|
||||
const {Services} = ChromeUtils.import("resource://gre/modules/Services.jsm");
|
||||
const { ActorChild } = ChromeUtils.import(
|
||||
"resource://gre/modules/ActorChild.jsm"
|
||||
);
|
||||
const { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm");
|
||||
|
||||
ChromeUtils.defineModuleGetter(this, "PageThumbUtils",
|
||||
"resource://gre/modules/PageThumbUtils.jsm");
|
||||
ChromeUtils.defineModuleGetter(
|
||||
this,
|
||||
"PageThumbUtils",
|
||||
"resource://gre/modules/PageThumbUtils.jsm"
|
||||
);
|
||||
|
||||
class ThumbnailsChild extends ActorChild {
|
||||
receiveMessage(message) {
|
||||
|
@ -22,16 +27,23 @@ class ThumbnailsChild extends ActorChild {
|
|||
let args = message.data.additionalArgs;
|
||||
let fullScale = args ? args.fullScale : false;
|
||||
if (fullScale) {
|
||||
snapshot = PageThumbUtils.createSnapshotThumbnail(this.content, null, args);
|
||||
snapshot = PageThumbUtils.createSnapshotThumbnail(
|
||||
this.content,
|
||||
null,
|
||||
args
|
||||
);
|
||||
} else {
|
||||
let snapshotWidth = message.data.canvasWidth;
|
||||
let snapshotHeight = message.data.canvasHeight;
|
||||
snapshot =
|
||||
PageThumbUtils.createCanvas(this.content, snapshotWidth, snapshotHeight);
|
||||
snapshot = PageThumbUtils.createCanvas(
|
||||
this.content,
|
||||
snapshotWidth,
|
||||
snapshotHeight
|
||||
);
|
||||
PageThumbUtils.createSnapshotThumbnail(this.content, snapshot, args);
|
||||
}
|
||||
|
||||
snapshot.toBlob((aBlob) => {
|
||||
snapshot.toBlob(aBlob => {
|
||||
this.mm.sendAsyncMessage("Browser:Thumbnail:Response", {
|
||||
thumbnail: aBlob,
|
||||
id: message.data.id,
|
||||
|
@ -42,7 +54,10 @@ class ThumbnailsChild extends ActorChild {
|
|||
* Remote isSafeForCapture request handler for PageThumbs.
|
||||
*/
|
||||
Services.tm.idleDispatchToMainThread(() => {
|
||||
let result = PageThumbUtils.shouldStoreContentThumbnail(this.content, this.mm.docShell);
|
||||
let result = PageThumbUtils.shouldStoreContentThumbnail(
|
||||
this.content,
|
||||
this.mm.docShell
|
||||
);
|
||||
this.mm.sendAsyncMessage("Browser:Thumbnail:CheckState:Response", {
|
||||
result,
|
||||
});
|
||||
|
|
|
@ -1,21 +1,17 @@
|
|||
/* vim: set ts=2 sw=2 sts=2 et 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/. */
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
"use strict";
|
||||
|
||||
var EXPORTED_SYMBOLS = ["UAWidgetsChild"];
|
||||
|
||||
const {ActorChild} = ChromeUtils.import("resource://gre/modules/ActorChild.jsm");
|
||||
const {Services} = ChromeUtils.import("resource://gre/modules/Services.jsm");
|
||||
const { ActorChild } = ChromeUtils.import(
|
||||
"resource://gre/modules/ActorChild.jsm"
|
||||
);
|
||||
const { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm");
|
||||
|
||||
const HANDLED_ELEMENTS = [
|
||||
"video",
|
||||
"audio",
|
||||
"embed",
|
||||
"object",
|
||||
"marquee",
|
||||
];
|
||||
const HANDLED_ELEMENTS = ["video", "audio", "embed", "object", "marquee"];
|
||||
|
||||
class UAWidgetsChild extends ActorChild {
|
||||
constructor(dispatcher) {
|
||||
|
@ -83,25 +79,33 @@ class UAWidgetsChild extends ActorChild {
|
|||
}
|
||||
|
||||
if (!uri || !widgetName) {
|
||||
Cu.reportError("Getting a UAWidgetSetupOrChange event on undefined element.");
|
||||
Cu.reportError(
|
||||
"Getting a UAWidgetSetupOrChange event on undefined element."
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
let shadowRoot = aElement.openOrClosedShadowRoot;
|
||||
if (!shadowRoot) {
|
||||
Cu.reportError("Getting a UAWidgetSetupOrChange event without the Shadow Root.");
|
||||
Cu.reportError(
|
||||
"Getting a UAWidgetSetupOrChange event without the Shadow Root."
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
let isSystemPrincipal = aElement.nodePrincipal.isSystemPrincipal;
|
||||
let sandbox = isSystemPrincipal ?
|
||||
Object.create(null) : Cu.getUAWidgetScope(aElement.nodePrincipal);
|
||||
let sandbox = isSystemPrincipal
|
||||
? Object.create(null)
|
||||
: Cu.getUAWidgetScope(aElement.nodePrincipal);
|
||||
|
||||
if (!sandbox[widgetName]) {
|
||||
Services.scriptloader.loadSubScript(uri, sandbox);
|
||||
}
|
||||
|
||||
let prefs = Cu.cloneInto(this.getPrefsForUAWidget(widgetName, prefKeys), sandbox);
|
||||
let prefs = Cu.cloneInto(
|
||||
this.getPrefsForUAWidget(widgetName, prefKeys),
|
||||
sandbox
|
||||
);
|
||||
|
||||
let widget = new sandbox[widgetName](shadowRoot, prefs);
|
||||
if (!isSystemPrincipal) {
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
/* vim: set ts=2 sw=2 sts=2 et 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/. */
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
"use strict";
|
||||
|
||||
var EXPORTED_SYMBOLS = ["UAWidgetsDateTimeBoxChild"];
|
||||
|
||||
const {Services} = ChromeUtils.import("resource://gre/modules/Services.jsm");
|
||||
const { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm");
|
||||
|
||||
const HANDLED_ELEMENTS = ["input"];
|
||||
|
||||
|
@ -62,25 +62,33 @@ class UAWidgetsDateTimeBoxChild extends JSWindowActorChild {
|
|||
}
|
||||
|
||||
if (!uri || !widgetName) {
|
||||
Cu.reportError("Getting a UAWidgetSetupOrChange event on undefined element.");
|
||||
Cu.reportError(
|
||||
"Getting a UAWidgetSetupOrChange event on undefined element."
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
let shadowRoot = aElement.openOrClosedShadowRoot;
|
||||
if (!shadowRoot) {
|
||||
Cu.reportError("Getting a UAWidgetSetupOrChange event without the Shadow Root.");
|
||||
Cu.reportError(
|
||||
"Getting a UAWidgetSetupOrChange event without the Shadow Root."
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
let isSystemPrincipal = aElement.nodePrincipal.isSystemPrincipal;
|
||||
let sandbox = isSystemPrincipal ?
|
||||
Object.create(null) : Cu.getUAWidgetScope(aElement.nodePrincipal);
|
||||
let sandbox = isSystemPrincipal
|
||||
? Object.create(null)
|
||||
: Cu.getUAWidgetScope(aElement.nodePrincipal);
|
||||
|
||||
if (!sandbox[widgetName]) {
|
||||
Services.scriptloader.loadSubScript(uri, sandbox);
|
||||
}
|
||||
|
||||
let prefs = Cu.cloneInto(this.getPrefsForUAWidget(widgetName, prefKeys), sandbox);
|
||||
let prefs = Cu.cloneInto(
|
||||
this.getPrefsForUAWidget(widgetName, prefKeys),
|
||||
sandbox
|
||||
);
|
||||
|
||||
let widget = new sandbox[widgetName](shadowRoot, prefs);
|
||||
if (!isSystemPrincipal) {
|
||||
|
|
|
@ -6,17 +6,23 @@
|
|||
|
||||
var EXPORTED_SYMBOLS = ["UnselectedTabHoverChild"];
|
||||
|
||||
const {ActorChild} = ChromeUtils.import("resource://gre/modules/ActorChild.jsm");
|
||||
const {Services} = ChromeUtils.import("resource://gre/modules/Services.jsm");
|
||||
const { ActorChild } = ChromeUtils.import(
|
||||
"resource://gre/modules/ActorChild.jsm"
|
||||
);
|
||||
const { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm");
|
||||
|
||||
class UnselectedTabHoverChild extends ActorChild {
|
||||
receiveMessage(message) {
|
||||
Services.obs.notifyObservers(this.content, "unselected-tab-hover",
|
||||
message.data.hovered);
|
||||
Services.obs.notifyObservers(
|
||||
this.content,
|
||||
"unselected-tab-hover",
|
||||
message.data.hovered
|
||||
);
|
||||
}
|
||||
|
||||
handleEvent(event) {
|
||||
this.mm.sendAsyncMessage("UnselectedTabHover:Toggle",
|
||||
{ enable: event.type == "UnselectedTabHover:Enable" });
|
||||
this.mm.sendAsyncMessage("UnselectedTabHover:Toggle", {
|
||||
enable: event.type == "UnselectedTabHover:Enable",
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,8 +7,10 @@
|
|||
|
||||
var EXPORTED_SYMBOLS = ["WebChannelChild"];
|
||||
|
||||
const {Services} = ChromeUtils.import("resource://gre/modules/Services.jsm");
|
||||
const {ActorChild} = ChromeUtils.import("resource://gre/modules/ActorChild.jsm");
|
||||
const { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm");
|
||||
const { ActorChild } = ChromeUtils.import(
|
||||
"resource://gre/modules/ActorChild.jsm"
|
||||
);
|
||||
|
||||
function getMessageManager(event) {
|
||||
let window = Cu.getGlobalForObject(event.target);
|
||||
|
@ -46,14 +48,17 @@ class WebChannelChild extends ActorChild {
|
|||
if (whitelist != _lastWhitelistValue) {
|
||||
let urls = whitelist.split(/\s+/);
|
||||
_cachedWhitelist = urls.map(origin =>
|
||||
Services.scriptSecurityManager.createCodebasePrincipalFromOrigin(origin));
|
||||
Services.scriptSecurityManager.createCodebasePrincipalFromOrigin(origin)
|
||||
);
|
||||
}
|
||||
return _cachedWhitelist;
|
||||
}
|
||||
|
||||
_onMessageToChrome(e) {
|
||||
// If target is window then we want the document principal, otherwise fallback to target itself.
|
||||
let principal = e.target.nodePrincipal ? e.target.nodePrincipal : e.target.document.nodePrincipal;
|
||||
let principal = e.target.nodePrincipal
|
||||
? e.target.nodePrincipal
|
||||
: e.target.document.nodePrincipal;
|
||||
|
||||
if (e.detail) {
|
||||
if (typeof e.detail != "string") {
|
||||
|
@ -61,17 +66,25 @@ class WebChannelChild extends ActorChild {
|
|||
// non-string values for e.detail. They're whitelisted by site origin,
|
||||
// so we compare on originNoSuffix in order to avoid other origin attributes
|
||||
// that are not relevant here, such as containers or private browsing.
|
||||
let objectsAllowed = this._getWhitelistedPrincipals().some(whitelisted =>
|
||||
principal.originNoSuffix == whitelisted.originNoSuffix);
|
||||
let objectsAllowed = this._getWhitelistedPrincipals().some(
|
||||
whitelisted => principal.originNoSuffix == whitelisted.originNoSuffix
|
||||
);
|
||||
if (!objectsAllowed) {
|
||||
Cu.reportError("WebChannelMessageToChrome sent with an object from a non-whitelisted principal");
|
||||
Cu.reportError(
|
||||
"WebChannelMessageToChrome sent with an object from a non-whitelisted principal"
|
||||
);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
let mm = getMessageManager(e);
|
||||
|
||||
mm.sendAsyncMessage("WebChannelMessageToChrome", e.detail, { eventTarget: e.target }, principal);
|
||||
mm.sendAsyncMessage(
|
||||
"WebChannelMessageToChrome",
|
||||
e.detail,
|
||||
{ eventTarget: e.target },
|
||||
principal
|
||||
);
|
||||
} else {
|
||||
Cu.reportError("WebChannel message failed. No message detail.");
|
||||
}
|
||||
|
@ -86,19 +99,30 @@ class WebChannelChild extends ActorChild {
|
|||
let eventTarget = msg.objects.eventTarget || msg.target.content;
|
||||
|
||||
// Use nodePrincipal if available, otherwise fallback to document principal.
|
||||
let targetPrincipal = eventTarget instanceof Ci.nsIDOMWindow ? eventTarget.document.nodePrincipal : eventTarget.nodePrincipal;
|
||||
let targetPrincipal =
|
||||
eventTarget instanceof Ci.nsIDOMWindow
|
||||
? eventTarget.document.nodePrincipal
|
||||
: eventTarget.nodePrincipal;
|
||||
|
||||
if (msg.principal.subsumes(targetPrincipal)) {
|
||||
// If eventTarget is a window, use it as the targetWindow, otherwise
|
||||
// find the window that owns the eventTarget.
|
||||
let targetWindow = eventTarget instanceof Ci.nsIDOMWindow ? eventTarget : eventTarget.ownerGlobal;
|
||||
let targetWindow =
|
||||
eventTarget instanceof Ci.nsIDOMWindow
|
||||
? eventTarget
|
||||
: eventTarget.ownerGlobal;
|
||||
|
||||
eventTarget.dispatchEvent(new targetWindow.CustomEvent("WebChannelMessageToContent", {
|
||||
detail: Cu.cloneInto({
|
||||
id: msg.data.id,
|
||||
message: msg.data.message,
|
||||
}, targetWindow),
|
||||
}));
|
||||
eventTarget.dispatchEvent(
|
||||
new targetWindow.CustomEvent("WebChannelMessageToContent", {
|
||||
detail: Cu.cloneInto(
|
||||
{
|
||||
id: msg.data.id,
|
||||
message: msg.data.message,
|
||||
},
|
||||
targetWindow
|
||||
),
|
||||
})
|
||||
);
|
||||
} else {
|
||||
Cu.reportError("WebChannel message failed. Principal mismatch.");
|
||||
}
|
||||
|
|
|
@ -6,18 +6,31 @@
|
|||
|
||||
var EXPORTED_SYMBOLS = ["WebNavigationChild"];
|
||||
|
||||
const {ActorChild} = ChromeUtils.import("resource://gre/modules/ActorChild.jsm");
|
||||
const {Services} = ChromeUtils.import("resource://gre/modules/Services.jsm");
|
||||
const {XPCOMUtils} = ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm");
|
||||
const { ActorChild } = ChromeUtils.import(
|
||||
"resource://gre/modules/ActorChild.jsm"
|
||||
);
|
||||
const { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm");
|
||||
const { XPCOMUtils } = ChromeUtils.import(
|
||||
"resource://gre/modules/XPCOMUtils.jsm"
|
||||
);
|
||||
|
||||
ChromeUtils.defineModuleGetter(this, "AppConstants",
|
||||
"resource://gre/modules/AppConstants.jsm");
|
||||
ChromeUtils.defineModuleGetter(this, "E10SUtils",
|
||||
"resource://gre/modules/E10SUtils.jsm");
|
||||
ChromeUtils.defineModuleGetter(
|
||||
this,
|
||||
"AppConstants",
|
||||
"resource://gre/modules/AppConstants.jsm"
|
||||
);
|
||||
ChromeUtils.defineModuleGetter(
|
||||
this,
|
||||
"E10SUtils",
|
||||
"resource://gre/modules/E10SUtils.jsm"
|
||||
);
|
||||
|
||||
XPCOMUtils.defineLazyServiceGetter(this, "CrashReporter",
|
||||
"@mozilla.org/xre/app-info;1",
|
||||
"nsICrashReporter");
|
||||
XPCOMUtils.defineLazyServiceGetter(
|
||||
this,
|
||||
"CrashReporter",
|
||||
"@mozilla.org/xre/app-info;1",
|
||||
"nsICrashReporter"
|
||||
);
|
||||
|
||||
class WebNavigationChild extends ActorChild {
|
||||
get webNavigation() {
|
||||
|
@ -54,7 +67,8 @@ class WebNavigationChild extends ActorChild {
|
|||
try {
|
||||
fn();
|
||||
} finally {
|
||||
this.mm.docShell.QueryInterface(Ci.nsIInterfaceRequestor)
|
||||
this.mm.docShell
|
||||
.QueryInterface(Ci.nsIInterfaceRequestor)
|
||||
.getInterface(Ci.nsIBrowserChild)
|
||||
.notifyNavigationFinished();
|
||||
}
|
||||
|
@ -75,10 +89,7 @@ class WebNavigationChild extends ActorChild {
|
|||
}
|
||||
|
||||
gotoIndex(params) {
|
||||
let {
|
||||
index,
|
||||
cancelContentJSEpoch,
|
||||
} = params || {};
|
||||
let { index, cancelContentJSEpoch } = params || {};
|
||||
this.mm.docShell.setCancelContentJSEpoch(cancelContentJSEpoch);
|
||||
this._wrapURIChangeCall(() => this.webNavigation.gotoIndex(index));
|
||||
}
|
||||
|
@ -101,26 +112,43 @@ class WebNavigationChild extends ActorChild {
|
|||
try {
|
||||
let url = Services.io.newURI(uri);
|
||||
// If the current URI contains a username/password, remove it.
|
||||
url = url.mutate()
|
||||
.setUserPass("")
|
||||
.finalize();
|
||||
url = url
|
||||
.mutate()
|
||||
.setUserPass("")
|
||||
.finalize();
|
||||
annotation = url.spec;
|
||||
} catch (ex) { /* Ignore failures to parse and failures
|
||||
on about: URIs. */ }
|
||||
} catch (ex) {
|
||||
/* Ignore failures to parse and failures
|
||||
on about: URIs. */
|
||||
}
|
||||
CrashReporter.annotateCrashReport("URL", annotation);
|
||||
}
|
||||
if (postData)
|
||||
if (postData) {
|
||||
postData = E10SUtils.makeInputStream(postData);
|
||||
if (headers)
|
||||
}
|
||||
if (headers) {
|
||||
headers = E10SUtils.makeInputStream(headers);
|
||||
if (baseURI)
|
||||
}
|
||||
if (baseURI) {
|
||||
baseURI = Services.io.newURI(baseURI);
|
||||
this._assert(triggeringPrincipal, "We need a triggering principal to continue loading", new Error().lineNumber);
|
||||
}
|
||||
this._assert(
|
||||
triggeringPrincipal,
|
||||
"We need a triggering principal to continue loading",
|
||||
new Error().lineNumber
|
||||
);
|
||||
|
||||
triggeringPrincipal = E10SUtils.deserializePrincipal(triggeringPrincipal, () => {
|
||||
this._assert(false, "Unable to deserialize passed triggering principal", new Error().lineNumber);
|
||||
return Services.scriptSecurityManager.getSystemPrincipal({});
|
||||
});
|
||||
triggeringPrincipal = E10SUtils.deserializePrincipal(
|
||||
triggeringPrincipal,
|
||||
() => {
|
||||
this._assert(
|
||||
false,
|
||||
"Unable to deserialize passed triggering principal",
|
||||
new Error().lineNumber
|
||||
);
|
||||
return Services.scriptSecurityManager.getSystemPrincipal({});
|
||||
}
|
||||
);
|
||||
if (csp) {
|
||||
csp = E10SUtils.deserializeCSP(csp);
|
||||
}
|
||||
|
@ -143,7 +171,11 @@ class WebNavigationChild extends ActorChild {
|
|||
_assert(condition, msg, line = 0) {
|
||||
let debug = Cc["@mozilla.org/xpcom/debug;1"].getService(Ci.nsIDebug2);
|
||||
if (!condition && debug.isDebugBuild) {
|
||||
debug.warning(`${msg} - ${new Error().stack}`, "WebNavigationChild.js", line);
|
||||
debug.warning(
|
||||
`${msg} - ${new Error().stack}`,
|
||||
"WebNavigationChild.js",
|
||||
line
|
||||
);
|
||||
debug.abort("WebNavigationChild.js", line);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,32 +16,28 @@ class ZoomParent extends JSWindowActorParent {
|
|||
let document = browser.ownerGlobal.document;
|
||||
|
||||
switch (message.name) {
|
||||
case "FullZoomChange":
|
||||
{
|
||||
browser._fullZoom = message.data.value;
|
||||
let event = document.createEvent("Events");
|
||||
event.initEvent("FullZoomChange", true, false);
|
||||
browser.dispatchEvent(event);
|
||||
break;
|
||||
}
|
||||
case "FullZoomChange": {
|
||||
browser._fullZoom = message.data.value;
|
||||
let event = document.createEvent("Events");
|
||||
event.initEvent("FullZoomChange", true, false);
|
||||
browser.dispatchEvent(event);
|
||||
break;
|
||||
}
|
||||
|
||||
case "TextZoomChange":
|
||||
{
|
||||
browser._textZoom = message.data.value;
|
||||
let event = document.createEvent("Events");
|
||||
event.initEvent("TextZoomChange", true, false);
|
||||
browser.dispatchEvent(event);
|
||||
break;
|
||||
}
|
||||
case "TextZoomChange": {
|
||||
browser._textZoom = message.data.value;
|
||||
let event = document.createEvent("Events");
|
||||
event.initEvent("TextZoomChange", true, false);
|
||||
browser.dispatchEvent(event);
|
||||
break;
|
||||
}
|
||||
|
||||
case "ZoomChangeUsingMouseWheel":
|
||||
{
|
||||
let event = document.createEvent("Events");
|
||||
event.initEvent("ZoomChangeUsingMouseWheel", true, false);
|
||||
browser.dispatchEvent(event);
|
||||
break;
|
||||
}
|
||||
case "ZoomChangeUsingMouseWheel": {
|
||||
let event = document.createEvent("Events");
|
||||
event.initEvent("ZoomChangeUsingMouseWheel", true, false);
|
||||
browser.dispatchEvent(event);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче