2014-06-25 05:12:07 +00:00
|
|
|
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
2014-03-14 18:45:53 +00:00
|
|
|
/* 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/. */
|
|
|
|
|
2017-02-07 10:52:06 +00:00
|
|
|
/* eslint-env mozilla/frame-script */
|
2018-05-26 01:22:09 +00:00
|
|
|
/* eslint no-unused-vars: ["error", {args: "none"}] */
|
2017-08-24 22:24:00 +00:00
|
|
|
/* global sendAsyncMessage */
|
2017-02-07 10:52:06 +00:00
|
|
|
|
2018-01-29 23:20:18 +00:00
|
|
|
ChromeUtils.import("resource://gre/modules/Services.jsm");
|
|
|
|
ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm");
|
2014-03-14 18:45:53 +00:00
|
|
|
|
2018-07-10 18:57:47 +00:00
|
|
|
ChromeUtils.defineModuleGetter(this, "AutoCompletePopup",
|
|
|
|
"resource://gre/modules/AutoCompletePopupContent.jsm");
|
2018-06-09 21:42:51 +00:00
|
|
|
ChromeUtils.defineModuleGetter(this, "AutoScrollController",
|
|
|
|
"resource://gre/modules/AutoScrollController.jsm");
|
2018-01-29 23:20:18 +00:00
|
|
|
ChromeUtils.defineModuleGetter(this, "BrowserUtils",
|
2016-08-18 14:50:58 +00:00
|
|
|
"resource://gre/modules/BrowserUtils.jsm");
|
2018-01-29 23:20:18 +00:00
|
|
|
ChromeUtils.defineModuleGetter(this, "SelectContentHelper",
|
2016-12-21 16:09:39 +00:00
|
|
|
"resource://gre/modules/SelectContentHelper.jsm");
|
2018-01-29 23:20:18 +00:00
|
|
|
ChromeUtils.defineModuleGetter(this, "FindContent",
|
2017-08-24 22:24:00 +00:00
|
|
|
"resource://gre/modules/FindContent.jsm");
|
2018-05-26 01:22:09 +00:00
|
|
|
ChromeUtils.defineModuleGetter(this, "PrintingContent",
|
|
|
|
"resource://gre/modules/PrintingContent.jsm");
|
2018-03-21 17:10:40 +00:00
|
|
|
ChromeUtils.defineModuleGetter(this, "RemoteFinder",
|
|
|
|
"resource://gre/modules/RemoteFinder.jsm");
|
2016-06-02 13:29:00 +00:00
|
|
|
|
2018-07-10 18:57:47 +00:00
|
|
|
XPCOMUtils.defineLazyServiceGetter(this, "formFill",
|
|
|
|
"@mozilla.org/satchel/form-fill-controller;1",
|
|
|
|
"nsIFormFillController");
|
|
|
|
|
2018-07-10 18:57:55 +00:00
|
|
|
var global = this;
|
|
|
|
|
|
|
|
XPCOMUtils.defineLazyProxy(this, "PopupBlocking", () => {
|
|
|
|
let tmp = {};
|
|
|
|
ChromeUtils.import("resource://gre/modules/PopupBlocking.jsm", tmp);
|
|
|
|
return new tmp.PopupBlocking(global);
|
|
|
|
});
|
|
|
|
|
2018-05-26 01:26:32 +00:00
|
|
|
XPCOMUtils.defineLazyProxy(this, "SelectionSourceContent",
|
|
|
|
"resource://gre/modules/SelectionSourceContent.jsm");
|
|
|
|
|
2018-07-08 03:15:45 +00:00
|
|
|
XPCOMUtils.defineLazyProxy(this, "WebChannelContent",
|
|
|
|
"resource://gre/modules/WebChannelContent.jsm");
|
|
|
|
|
2018-06-09 21:46:39 +00:00
|
|
|
XPCOMUtils.defineLazyProxy(this, "DateTimePickerContent", () => {
|
|
|
|
let tmp = {};
|
|
|
|
ChromeUtils.import("resource://gre/modules/DateTimePickerContent.jsm", tmp);
|
|
|
|
return new tmp.DateTimePickerContent(this);
|
|
|
|
});
|
|
|
|
|
2018-07-29 21:38:44 +00:00
|
|
|
XPCOMUtils.defineLazyProxy(this, "FindBarChild", () => {
|
|
|
|
let tmp = {};
|
|
|
|
ChromeUtils.import("resource://gre/modules/FindBarChild.jsm", tmp);
|
|
|
|
return new tmp.FindBarChild(this);
|
|
|
|
}, {inQuickFind: false, inPassThrough: false});
|
|
|
|
|
2015-04-13 20:23:51 +00:00
|
|
|
|
|
|
|
// Lazily load the finder code
|
2016-11-11 23:22:34 +00:00
|
|
|
addMessageListener("Finder:Initialize", function() {
|
2018-01-29 23:20:18 +00:00
|
|
|
let {RemoteFinderListener} = ChromeUtils.import("resource://gre/modules/RemoteFinder.jsm", {});
|
2015-04-13 20:23:51 +00:00
|
|
|
new RemoteFinderListener(global);
|
|
|
|
});
|
|
|
|
|
2018-06-09 21:42:51 +00:00
|
|
|
var AutoScrollListener = {
|
|
|
|
handleEvent(event) {
|
|
|
|
if (event.isTrusted &
|
|
|
|
!event.defaultPrevented &&
|
|
|
|
event.button == 1) {
|
|
|
|
if (!this._controller) {
|
|
|
|
this._controller = new AutoScrollController(global);
|
|
|
|
}
|
|
|
|
this._controller.handleEvent(event);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
};
|
|
|
|
Services.els.addSystemEventListener(global, "mousedown", AutoScrollListener, true);
|
|
|
|
|
2018-06-09 21:46:39 +00:00
|
|
|
addEventListener("MozOpenDateTimePicker", DateTimePickerContent);
|
|
|
|
|
2018-07-10 18:57:55 +00:00
|
|
|
addEventListener("DOMPopupBlocked", PopupBlocking, true);
|
2014-10-07 18:46:25 +00:00
|
|
|
|
2015-09-15 18:19:45 +00:00
|
|
|
var Printing = {
|
2014-10-28 14:58:07 +00:00
|
|
|
MESSAGES: [
|
|
|
|
"Printing:Preview:Enter",
|
|
|
|
"Printing:Preview:Exit",
|
|
|
|
"Printing:Preview:Navigate",
|
2016-06-02 13:29:00 +00:00
|
|
|
"Printing:Preview:ParseDocument",
|
2014-10-28 14:58:07 +00:00
|
|
|
"Printing:Print",
|
|
|
|
],
|
|
|
|
|
|
|
|
init() {
|
|
|
|
this.MESSAGES.forEach(msgName => addMessageListener(msgName, this));
|
2015-09-16 20:12:54 +00:00
|
|
|
addEventListener("PrintingError", this, true);
|
2017-07-05 17:12:36 +00:00
|
|
|
addEventListener("printPreviewUpdate", this, true);
|
2018-07-08 03:49:30 +00:00
|
|
|
this.init = null;
|
2014-10-28 14:58:07 +00:00
|
|
|
},
|
|
|
|
|
2015-09-16 20:12:54 +00:00
|
|
|
handleEvent(event) {
|
2018-05-26 01:22:09 +00:00
|
|
|
return PrintingContent.handleEvent(global, event);
|
2015-09-16 20:12:54 +00:00
|
|
|
},
|
|
|
|
|
2014-10-28 14:58:07 +00:00
|
|
|
receiveMessage(message) {
|
2018-05-26 01:22:09 +00:00
|
|
|
return PrintingContent.receiveMessage(global, message);
|
2014-10-28 14:58:07 +00:00
|
|
|
},
|
2017-10-15 18:50:30 +00:00
|
|
|
};
|
2014-10-28 14:58:07 +00:00
|
|
|
Printing.init();
|
|
|
|
|
2015-03-11 21:19:18 +00:00
|
|
|
function SwitchDocumentDirection(aWindow) {
|
|
|
|
// document.dir can also be "auto", in which case it won't change
|
|
|
|
if (aWindow.document.dir == "ltr" || aWindow.document.dir == "") {
|
|
|
|
aWindow.document.dir = "rtl";
|
|
|
|
} else if (aWindow.document.dir == "rtl") {
|
|
|
|
aWindow.document.dir = "ltr";
|
|
|
|
}
|
|
|
|
for (let run = 0; run < aWindow.frames.length; run++) {
|
|
|
|
SwitchDocumentDirection(aWindow.frames[run]);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
addMessageListener("SwitchDocumentDirection", () => {
|
|
|
|
SwitchDocumentDirection(content.window);
|
|
|
|
});
|
|
|
|
|
2015-09-15 18:19:45 +00:00
|
|
|
var FindBar = {
|
2018-03-21 17:10:40 +00:00
|
|
|
/**
|
|
|
|
* _findKey and _findModifiers are used to determine whether a keypress
|
|
|
|
* is a user attempting to use the find shortcut, after which we'll
|
|
|
|
* route keypresses to the parent until we know the findbar has focus
|
|
|
|
* there. To do this, we need shortcut data from the parent.
|
|
|
|
*/
|
|
|
|
_findKey: null,
|
|
|
|
|
2015-03-11 20:22:09 +00:00
|
|
|
init() {
|
2018-07-29 21:38:44 +00:00
|
|
|
Services.els.addSystemEventListener(global, "keypress",
|
|
|
|
this.onKeypress.bind(this), false);
|
2018-07-08 03:49:30 +00:00
|
|
|
this.init = null;
|
2015-03-11 20:22:09 +00:00
|
|
|
},
|
|
|
|
|
2018-03-21 17:10:40 +00:00
|
|
|
/**
|
|
|
|
* Check whether this key event will start the findbar in the parent,
|
|
|
|
* in which case we should pass any further key events to the parent to avoid
|
|
|
|
* them being lost.
|
|
|
|
* @param aEvent the key event to check.
|
|
|
|
*/
|
2018-07-29 21:38:44 +00:00
|
|
|
eventMatchesFindShortcut(aEvent) {
|
|
|
|
if (!this._findKey) {
|
|
|
|
this._findKey = Services.cpmm.sharedData.get("Findbar:Shortcut");
|
|
|
|
if (!this._findKey) {
|
|
|
|
return false;
|
|
|
|
}
|
2018-03-21 17:10:40 +00:00
|
|
|
}
|
2018-07-29 21:38:44 +00:00
|
|
|
for (let k in this._findKey) {
|
|
|
|
if (this._findKey[k] != aEvent[k]) {
|
|
|
|
return false;
|
|
|
|
}
|
2018-08-02 00:10:16 +00:00
|
|
|
}
|
2018-07-29 21:38:44 +00:00
|
|
|
return true;
|
2018-08-07 14:30:52 +00:00
|
|
|
},
|
2018-08-02 00:10:16 +00:00
|
|
|
|
2018-07-29 21:38:44 +00:00
|
|
|
onKeypress(event) {
|
|
|
|
if (!FindBarChild.inPassThrough &&
|
|
|
|
this.eventMatchesFindShortcut(event)) {
|
|
|
|
return FindBarChild.start(event);
|
2018-08-07 14:30:52 +00:00
|
|
|
}
|
|
|
|
|
2018-07-29 21:38:44 +00:00
|
|
|
if (event.ctrlKey || event.altKey || event.metaKey || event.defaultPrevented ||
|
|
|
|
!BrowserUtils.canFastFind(content)) {
|
|
|
|
return null;
|
2015-03-11 20:22:09 +00:00
|
|
|
}
|
2018-08-02 00:10:16 +00:00
|
|
|
|
2018-07-29 21:38:44 +00:00
|
|
|
if (FindBarChild.inPassThrough || FindBarChild.inQuickFind) {
|
|
|
|
return FindBarChild.onKeypress(event);
|
2018-08-02 00:10:16 +00:00
|
|
|
}
|
2018-08-07 14:30:52 +00:00
|
|
|
|
2018-07-29 21:38:44 +00:00
|
|
|
if (event.charCode && BrowserUtils.shouldFastFind(event.target)) {
|
|
|
|
let key = String.fromCharCode(event.charCode);
|
|
|
|
if ((key == "/" || key == "'") && RemoteFinder._manualFAYT) {
|
|
|
|
return FindBarChild.startQuickFind(event);
|
|
|
|
}
|
|
|
|
if (key != " " && RemoteFinder._findAsYouType) {
|
|
|
|
return FindBarChild.startQuickFind(event, true);
|
|
|
|
}
|
2018-08-07 14:30:52 +00:00
|
|
|
}
|
2018-07-29 21:38:44 +00:00
|
|
|
return null;
|
2015-03-11 20:22:09 +00:00
|
|
|
},
|
|
|
|
};
|
|
|
|
FindBar.init();
|
2015-06-30 18:46:27 +00:00
|
|
|
|
2018-07-08 03:15:45 +00:00
|
|
|
addEventListener("WebChannelMessageToChrome", WebChannelContent,
|
|
|
|
true, true);
|
|
|
|
addMessageListener("WebChannelMessageToContent", WebChannelContent);
|
2015-07-04 19:00:41 +00:00
|
|
|
|
2015-09-15 18:19:45 +00:00
|
|
|
var AudioPlaybackListener = {
|
2018-04-23 03:55:06 +00:00
|
|
|
QueryInterface: ChromeUtils.generateQI([Ci.nsIObserver]),
|
2015-07-04 19:00:41 +00:00
|
|
|
|
|
|
|
init() {
|
2017-04-14 19:51:38 +00:00
|
|
|
Services.obs.addObserver(this, "audio-playback");
|
2016-04-18 10:48:41 +00:00
|
|
|
|
2016-05-03 01:51:22 +00:00
|
|
|
addMessageListener("AudioPlayback", this);
|
2015-07-04 19:00:41 +00:00
|
|
|
addEventListener("unload", () => {
|
2015-08-01 15:32:12 +00:00
|
|
|
AudioPlaybackListener.uninit();
|
2015-07-04 19:00:41 +00:00
|
|
|
});
|
2018-07-08 03:49:30 +00:00
|
|
|
this.init = null;
|
2015-07-04 19:00:41 +00:00
|
|
|
},
|
|
|
|
|
|
|
|
uninit() {
|
2015-08-01 15:32:12 +00:00
|
|
|
Services.obs.removeObserver(this, "audio-playback");
|
2016-04-18 10:48:41 +00:00
|
|
|
|
2016-05-03 01:51:22 +00:00
|
|
|
removeMessageListener("AudioPlayback", this);
|
|
|
|
},
|
|
|
|
|
|
|
|
handleMediaControlMessage(msg) {
|
2018-07-24 23:47:42 +00:00
|
|
|
let utils = global.content.windowUtils;
|
2017-03-28 04:47:02 +00:00
|
|
|
let suspendTypes = Ci.nsISuspendedTypes;
|
2016-05-03 01:51:22 +00:00
|
|
|
switch (msg) {
|
|
|
|
case "mute":
|
|
|
|
utils.audioMuted = true;
|
|
|
|
break;
|
|
|
|
case "unmute":
|
|
|
|
utils.audioMuted = false;
|
|
|
|
break;
|
2017-03-28 04:47:02 +00:00
|
|
|
case "lostAudioFocus":
|
|
|
|
utils.mediaSuspend = suspendTypes.SUSPENDED_PAUSE_DISPOSABLE;
|
|
|
|
break;
|
|
|
|
case "lostAudioFocusTransiently":
|
|
|
|
utils.mediaSuspend = suspendTypes.SUSPENDED_PAUSE;
|
|
|
|
break;
|
|
|
|
case "gainAudioFocus":
|
|
|
|
utils.mediaSuspend = suspendTypes.NONE_SUSPENDED;
|
|
|
|
break;
|
|
|
|
case "mediaControlPaused":
|
|
|
|
utils.mediaSuspend = suspendTypes.SUSPENDED_PAUSE_DISPOSABLE;
|
|
|
|
break;
|
|
|
|
case "mediaControlStopped":
|
|
|
|
utils.mediaSuspend = suspendTypes.SUSPENDED_STOP_DISPOSABLE;
|
|
|
|
break;
|
|
|
|
case "resumeMedia":
|
2018-07-03 21:32:22 +00:00
|
|
|
// User has clicked the tab audio indicator to play a delayed
|
|
|
|
// media. That's clear user intent to play, so gesture activate
|
|
|
|
// the content document tree so that the block-autoplay logic
|
|
|
|
// allows the media to autoplay.
|
|
|
|
content.document.notifyUserGestureActivation();
|
2017-03-28 04:47:02 +00:00
|
|
|
utils.mediaSuspend = suspendTypes.NONE_SUSPENDED;
|
|
|
|
break;
|
2016-05-03 01:51:22 +00:00
|
|
|
default:
|
|
|
|
dump("Error : wrong media control msg!\n");
|
|
|
|
break;
|
|
|
|
}
|
2015-07-04 19:00:41 +00:00
|
|
|
},
|
|
|
|
|
|
|
|
observe(subject, topic, data) {
|
2015-08-01 15:32:12 +00:00
|
|
|
if (topic === "audio-playback") {
|
2015-07-04 19:00:41 +00:00
|
|
|
if (subject && subject.top == global.content) {
|
2015-08-01 15:32:12 +00:00
|
|
|
let name = "AudioPlayback:";
|
2017-06-29 12:46:20 +00:00
|
|
|
if (data === "activeMediaBlockStart") {
|
|
|
|
name += "ActiveMediaBlockStart";
|
|
|
|
} else if (data === "activeMediaBlockStop") {
|
|
|
|
name += "ActiveMediaBlockStop";
|
2016-11-11 02:42:35 +00:00
|
|
|
} else {
|
|
|
|
name += (data === "active") ? "Start" : "Stop";
|
|
|
|
}
|
2015-07-04 19:00:41 +00:00
|
|
|
sendAsyncMessage(name);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
},
|
2015-07-05 00:47:14 +00:00
|
|
|
|
|
|
|
receiveMessage(msg) {
|
2016-05-03 01:51:22 +00:00
|
|
|
if (msg.name == "AudioPlayback") {
|
|
|
|
this.handleMediaControlMessage(msg.data.type);
|
2015-07-05 00:47:14 +00:00
|
|
|
}
|
|
|
|
},
|
2015-07-04 19:00:41 +00:00
|
|
|
};
|
2015-08-01 15:32:12 +00:00
|
|
|
AudioPlaybackListener.init();
|
2015-08-10 13:42:51 +00:00
|
|
|
|
2017-07-20 07:11:25 +00:00
|
|
|
var UnselectedTabHoverObserver = {
|
|
|
|
init() {
|
|
|
|
addMessageListener("Browser:UnselectedTabHover", this);
|
|
|
|
addEventListener("UnselectedTabHover:Enable", this);
|
|
|
|
addEventListener("UnselectedTabHover:Disable", this);
|
2018-07-08 03:49:30 +00:00
|
|
|
this.init = null;
|
2017-07-20 07:11:25 +00:00
|
|
|
},
|
|
|
|
receiveMessage(message) {
|
|
|
|
Services.obs.notifyObservers(content.window, "unselected-tab-hover",
|
|
|
|
message.data.hovered);
|
|
|
|
},
|
|
|
|
handleEvent(event) {
|
|
|
|
sendAsyncMessage("UnselectedTabHover:Toggle",
|
|
|
|
{ enable: event.type == "UnselectedTabHover:Enable" });
|
|
|
|
}
|
|
|
|
};
|
|
|
|
UnselectedTabHoverObserver.init();
|
|
|
|
|
2018-07-25 16:08:44 +00:00
|
|
|
|
|
|
|
var AudibleAutoplayObserver = {
|
|
|
|
init() {
|
|
|
|
addEventListener("AudibleAutoplayMediaOccurred", this);
|
|
|
|
},
|
|
|
|
handleEvent(event) {
|
|
|
|
sendAsyncMessage("AudibleAutoplayMediaOccurred");
|
|
|
|
}
|
|
|
|
};
|
|
|
|
AudibleAutoplayObserver.init();
|
|
|
|
|
2015-08-10 19:15:11 +00:00
|
|
|
addMessageListener("Browser:PurgeSessionHistory", function BrowserPurgeHistory() {
|
|
|
|
let sessionHistory = docShell.QueryInterface(Ci.nsIWebNavigation).sessionHistory;
|
|
|
|
if (!sessionHistory) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
// place the entry at current index at the end of the history list, so it won't get removed
|
|
|
|
if (sessionHistory.index < sessionHistory.count - 1) {
|
2018-02-01 22:17:00 +00:00
|
|
|
let legacy = sessionHistory.legacySHistory;
|
|
|
|
legacy.QueryInterface(Ci.nsISHistoryInternal);
|
|
|
|
let indexEntry = legacy.getEntryAtIndex(sessionHistory.index, false);
|
2018-02-28 17:51:33 +00:00
|
|
|
indexEntry.QueryInterface(Ci.nsISHEntry);
|
2018-02-01 22:17:00 +00:00
|
|
|
legacy.addEntry(indexEntry, true);
|
2015-08-10 19:15:11 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
let purge = sessionHistory.count;
|
|
|
|
if (global.content.location.href != "about:blank") {
|
|
|
|
--purge; // Don't remove the page the user's staring at from shistory
|
|
|
|
}
|
|
|
|
|
|
|
|
if (purge > 0) {
|
2018-02-01 22:17:00 +00:00
|
|
|
sessionHistory.legacySHistory.PurgeHistory(purge);
|
2015-08-10 19:15:11 +00:00
|
|
|
}
|
|
|
|
});
|
|
|
|
|
2018-05-26 01:26:32 +00:00
|
|
|
addMessageListener("ViewSource:GetSelection", SelectionSourceContent);
|
2016-03-21 10:22:16 +00:00
|
|
|
|
|
|
|
addEventListener("MozApplicationManifest", function(e) {
|
|
|
|
let doc = e.target;
|
|
|
|
let info = {
|
|
|
|
uri: doc.documentURI,
|
|
|
|
characterSet: doc.characterSet,
|
|
|
|
manifest: doc.documentElement.getAttribute("manifest"),
|
|
|
|
principal: doc.nodePrincipal,
|
|
|
|
};
|
|
|
|
sendAsyncMessage("MozApplicationManifest", info);
|
|
|
|
}, false);
|
|
|
|
|
2018-07-10 18:57:47 +00:00
|
|
|
let AutoComplete = {
|
2016-07-28 18:18:50 +00:00
|
|
|
_connected: false,
|
|
|
|
|
2016-12-29 23:34:54 +00:00
|
|
|
init() {
|
2018-07-10 18:57:47 +00:00
|
|
|
addEventListener("unload", this, {once: true});
|
|
|
|
addEventListener("DOMContentLoaded", this, {once: true});
|
2017-06-01 23:20:34 +00:00
|
|
|
// WebExtension browserAction is preloaded and does not receive DCL, wait
|
|
|
|
// on pageshow so we can hookup the formfill controller.
|
2018-07-10 18:57:47 +00:00
|
|
|
addEventListener("pageshow", this, {capture: true, once: true});
|
2016-07-28 18:18:50 +00:00
|
|
|
|
2018-07-10 18:57:47 +00:00
|
|
|
XPCOMUtils.defineLazyProxy(this, "popup", () => new AutoCompletePopup(global),
|
|
|
|
{QueryInterface: null});
|
2018-07-08 03:49:30 +00:00
|
|
|
this.init = null;
|
2017-06-01 23:20:34 +00:00
|
|
|
},
|
|
|
|
|
Bug 1296638 - AutoCompletePopup in browser-content.js and AutoCompletePopup.jsm need to have popupOpen be in sync. r=MattN
The opening of the AutoCompletePopup will always start from content, but closing the
popup can occur in the parent (for example, if the user switches focus from the browser),
or in content (the user hits Esc, for example, which tells the parent to close the popup).
This relationship between content and the popup has been true for a while, but the
patch in bug 1294502 didn't account for it. In particular, before this patch, it was
possible for AutoCompletePopup in browser-content.js and AutoCompletePopup.jsm to get
out of sync on whether or not the popup is open.
Mainly, this is because the parent wasn't telling the content that the popup had
hidden if the hide was initialized by the parent. The other reason, was because
the popupOpen state in browser-content.js was being set immediately, instead
of waiting for the parent to report that the popup had indeed opened or closed.
MozReview-Commit-ID: CRkg49lP1Hd
--HG--
extra : rebase_source : 0a0383170fc78f8639713a5879ab18468fc0eef7
2016-09-17 16:44:04 +00:00
|
|
|
handleEvent(event) {
|
|
|
|
switch (event.type) {
|
2018-07-10 18:57:47 +00:00
|
|
|
case "DOMContentLoaded":
|
|
|
|
case "pageshow":
|
|
|
|
// We need to wait for a content viewer to be available
|
|
|
|
// before we can attach our AutoCompletePopup handler,
|
|
|
|
// since nsFormFillController assumes one will exist
|
|
|
|
// when we call attachToBrowser.
|
|
|
|
if (!this._connected) {
|
|
|
|
formFill.attachToBrowser(docShell, this.popup);
|
|
|
|
this._connected = true;
|
Bug 1296638 - AutoCompletePopup in browser-content.js and AutoCompletePopup.jsm need to have popupOpen be in sync. r=MattN
The opening of the AutoCompletePopup will always start from content, but closing the
popup can occur in the parent (for example, if the user switches focus from the browser),
or in content (the user hits Esc, for example, which tells the parent to close the popup).
This relationship between content and the popup has been true for a while, but the
patch in bug 1294502 didn't account for it. In particular, before this patch, it was
possible for AutoCompletePopup in browser-content.js and AutoCompletePopup.jsm to get
out of sync on whether or not the popup is open.
Mainly, this is because the parent wasn't telling the content that the popup had
hidden if the hide was initialized by the parent. The other reason, was because
the popupOpen state in browser-content.js was being set immediately, instead
of waiting for the parent to report that the popup had indeed opened or closed.
MozReview-Commit-ID: CRkg49lP1Hd
--HG--
extra : rebase_source : 0a0383170fc78f8639713a5879ab18468fc0eef7
2016-09-17 16:44:04 +00:00
|
|
|
}
|
2018-07-10 18:57:47 +00:00
|
|
|
break;
|
Bug 1296638 - AutoCompletePopup in browser-content.js and AutoCompletePopup.jsm need to have popupOpen be in sync. r=MattN
The opening of the AutoCompletePopup will always start from content, but closing the
popup can occur in the parent (for example, if the user switches focus from the browser),
or in content (the user hits Esc, for example, which tells the parent to close the popup).
This relationship between content and the popup has been true for a while, but the
patch in bug 1294502 didn't account for it. In particular, before this patch, it was
possible for AutoCompletePopup in browser-content.js and AutoCompletePopup.jsm to get
out of sync on whether or not the popup is open.
Mainly, this is because the parent wasn't telling the content that the popup had
hidden if the hide was initialized by the parent. The other reason, was because
the popupOpen state in browser-content.js was being set immediately, instead
of waiting for the parent to report that the popup had indeed opened or closed.
MozReview-Commit-ID: CRkg49lP1Hd
--HG--
extra : rebase_source : 0a0383170fc78f8639713a5879ab18468fc0eef7
2016-09-17 16:44:04 +00:00
|
|
|
|
2018-07-10 18:57:47 +00:00
|
|
|
case "unload":
|
|
|
|
if (this._connected) {
|
|
|
|
formFill.detachFromBrowser(docShell);
|
|
|
|
this._connected = false;
|
2016-08-19 21:15:56 +00:00
|
|
|
}
|
2018-07-10 18:57:47 +00:00
|
|
|
break;
|
Bug 1296638 - AutoCompletePopup in browser-content.js and AutoCompletePopup.jsm need to have popupOpen be in sync. r=MattN
The opening of the AutoCompletePopup will always start from content, but closing the
popup can occur in the parent (for example, if the user switches focus from the browser),
or in content (the user hits Esc, for example, which tells the parent to close the popup).
This relationship between content and the popup has been true for a while, but the
patch in bug 1294502 didn't account for it. In particular, before this patch, it was
possible for AutoCompletePopup in browser-content.js and AutoCompletePopup.jsm to get
out of sync on whether or not the popup is open.
Mainly, this is because the parent wasn't telling the content that the popup had
hidden if the hide was initialized by the parent. The other reason, was because
the popupOpen state in browser-content.js was being set immediately, instead
of waiting for the parent to report that the popup had indeed opened or closed.
MozReview-Commit-ID: CRkg49lP1Hd
--HG--
extra : rebase_source : 0a0383170fc78f8639713a5879ab18468fc0eef7
2016-09-17 16:44:04 +00:00
|
|
|
}
|
2016-07-28 18:18:50 +00:00
|
|
|
},
|
2017-10-15 18:50:30 +00:00
|
|
|
};
|
2016-07-28 18:18:50 +00:00
|
|
|
|
2018-07-10 18:57:47 +00:00
|
|
|
AutoComplete.init();
|
2016-10-06 04:17:00 +00:00
|
|
|
|
2016-12-21 16:09:39 +00:00
|
|
|
addEventListener("mozshowdropdown", event => {
|
|
|
|
if (!event.isTrusted)
|
|
|
|
return;
|
|
|
|
|
|
|
|
if (!SelectContentHelper.open) {
|
|
|
|
new SelectContentHelper(event.target, {isOpenedViaTouch: false}, this);
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
|
|
|
addEventListener("mozshowdropdown-sourcetouch", event => {
|
|
|
|
if (!event.isTrusted)
|
|
|
|
return;
|
|
|
|
|
|
|
|
if (!SelectContentHelper.open) {
|
|
|
|
new SelectContentHelper(event.target, {isOpenedViaTouch: true}, this);
|
|
|
|
}
|
|
|
|
});
|
2017-08-24 22:24:00 +00:00
|
|
|
|
|
|
|
let ExtFind = {
|
|
|
|
init() {
|
|
|
|
addMessageListener("ext-Finder:CollectResults", this);
|
|
|
|
addMessageListener("ext-Finder:HighlightResults", this);
|
|
|
|
addMessageListener("ext-Finder:clearHighlighting", this);
|
2018-07-08 03:49:30 +00:00
|
|
|
this.init = null;
|
2017-08-24 22:24:00 +00:00
|
|
|
},
|
|
|
|
|
|
|
|
_findContent: null,
|
|
|
|
|
|
|
|
async receiveMessage(message) {
|
|
|
|
if (!this._findContent) {
|
|
|
|
this._findContent = new FindContent(docShell);
|
|
|
|
}
|
|
|
|
|
|
|
|
let data;
|
|
|
|
switch (message.name) {
|
|
|
|
case "ext-Finder:CollectResults":
|
|
|
|
this.finderInited = true;
|
|
|
|
data = await this._findContent.findRanges(message.data);
|
|
|
|
sendAsyncMessage("ext-Finder:CollectResultsFinished", data);
|
|
|
|
break;
|
|
|
|
case "ext-Finder:HighlightResults":
|
|
|
|
data = this._findContent.highlightResults(message.data);
|
|
|
|
sendAsyncMessage("ext-Finder:HighlightResultsFinished", data);
|
|
|
|
break;
|
|
|
|
case "ext-Finder:clearHighlighting":
|
|
|
|
this._findContent.highlighter.highlight(false);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
},
|
2017-10-15 18:50:30 +00:00
|
|
|
};
|
2017-08-24 22:24:00 +00:00
|
|
|
|
|
|
|
ExtFind.init();
|