зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1630691: Part 1 - Get rid of most of the remaining mozbrowser API. r=nika,mtigley,bradwerth
Differential Revision: https://phabricator.services.mozilla.com/D71226
This commit is contained in:
Родитель
ba0acfe03a
Коммит
c5353a7809
|
@ -1019,12 +1019,6 @@ bool nsIContent::IsFocusable(int32_t* aTabIndex, bool aWithMouse) {
|
|||
// Ensure that the return value and aTabIndex are consistent in the case
|
||||
// we're in userfocusignored context.
|
||||
if (focusable || (aTabIndex && *aTabIndex != -1)) {
|
||||
if (nsContentUtils::IsUserFocusIgnored(this)) {
|
||||
if (aTabIndex) {
|
||||
*aTabIndex = -1;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
return focusable;
|
||||
}
|
||||
return false;
|
||||
|
|
|
@ -6181,27 +6181,6 @@ bool nsContentUtils::IsSubDocumentTabbable(nsIContent* aContent) {
|
|||
return true;
|
||||
}
|
||||
|
||||
bool nsContentUtils::IsUserFocusIgnored(nsINode* aNode) {
|
||||
if (!StaticPrefs::dom_mozBrowserFramesEnabled()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Check if our mozbrowser iframe ancestors has ignoreuserfocus attribute.
|
||||
while (aNode) {
|
||||
nsCOMPtr<nsIMozBrowserFrame> browserFrame = do_QueryInterface(aNode);
|
||||
if (browserFrame &&
|
||||
aNode->AsElement()->HasAttr(kNameSpaceID_None,
|
||||
nsGkAtoms::ignoreuserfocus) &&
|
||||
browserFrame->GetReallyIsBrowser()) {
|
||||
return true;
|
||||
}
|
||||
nsPIDOMWindowOuter* win = aNode->OwnerDoc()->GetWindow();
|
||||
aNode = win ? win->GetFrameElementInternal() : nullptr;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool nsContentUtils::HasScrollgrab(nsIContent* aContent) {
|
||||
// If we ever standardize this feature we'll want to hook this up properly
|
||||
// again. For now we're removing all the DOM-side code related to it but
|
||||
|
|
|
@ -2483,15 +2483,6 @@ class nsContentUtils {
|
|||
*/
|
||||
static bool IsSubDocumentTabbable(nsIContent* aContent);
|
||||
|
||||
/**
|
||||
* Returns if aNode ignores user focus.
|
||||
*
|
||||
* @param aNode node to test
|
||||
*
|
||||
* @return Whether the node ignores user focus.
|
||||
*/
|
||||
static bool IsUserFocusIgnored(nsINode* aNode);
|
||||
|
||||
/**
|
||||
* Returns if aContent has the 'scrollgrab' property.
|
||||
* aContent may be null (in this case false is returned).
|
||||
|
|
|
@ -1785,8 +1785,7 @@ bool nsFocusManager::IsNonFocusableRoot(nsIContent* aContent) {
|
|||
Document* doc = aContent->GetComposedDoc();
|
||||
NS_ASSERTION(doc, "aContent must have current document");
|
||||
return aContent == doc->GetRootElement() &&
|
||||
(doc->HasFlag(NODE_IS_EDITABLE) || !aContent->IsEditable() ||
|
||||
nsContentUtils::IsUserFocusIgnored(aContent));
|
||||
(doc->HasFlag(NODE_IS_EDITABLE) || !aContent->IsEditable());
|
||||
}
|
||||
|
||||
Element* nsFocusManager::FlushAndCheckIfFocusable(Element* aElement,
|
||||
|
@ -1819,7 +1818,7 @@ Element* nsFocusManager::FlushAndCheckIfFocusable(Element* aElement,
|
|||
// the root content can always be focused,
|
||||
// except in userfocusignored context.
|
||||
if (aElement == doc->GetRootElement()) {
|
||||
return nsContentUtils::IsUserFocusIgnored(aElement) ? nullptr : aElement;
|
||||
return aElement;
|
||||
}
|
||||
|
||||
// cannot focus content in print preview mode. Only the root can be focused.
|
||||
|
@ -2514,10 +2513,7 @@ void nsFocusManager::SendFocusOrBlurEvent(
|
|||
aRelatedTarget = nullptr;
|
||||
}
|
||||
|
||||
bool dontDispatchEvent =
|
||||
eventTargetDoc && nsContentUtils::IsUserFocusIgnored(eventTargetDoc);
|
||||
|
||||
if (!dontDispatchEvent && aDocument && aDocument->EventHandlingSuppressed()) {
|
||||
if (aDocument && aDocument->EventHandlingSuppressed()) {
|
||||
for (uint32_t i = mDelayedBlurFocusEvents.Length(); i > 0; --i) {
|
||||
// if this event was already queued, remove it and append it to the end
|
||||
if (mDelayedBlurFocusEvents[i - 1].mEventMessage == aEventMessage &&
|
||||
|
@ -2550,17 +2546,12 @@ void nsFocusManager::FireFocusOrBlurEvent(EventMessage aEventMessage,
|
|||
nsISupports* aTarget,
|
||||
bool aWindowRaised, bool aIsRefocus,
|
||||
EventTarget* aRelatedTarget) {
|
||||
nsCOMPtr<EventTarget> eventTarget = do_QueryInterface(aTarget);
|
||||
nsCOMPtr<Document> eventTargetDoc = GetDocumentHelper(eventTarget);
|
||||
nsCOMPtr<nsPIDOMWindowOuter> currentWindow = mFocusedWindow;
|
||||
nsCOMPtr<nsPIDOMWindowInner> targetWindow = do_QueryInterface(aTarget);
|
||||
nsCOMPtr<Document> targetDocument = do_QueryInterface(aTarget);
|
||||
nsCOMPtr<nsIContent> currentFocusedContent =
|
||||
currentWindow ? currentWindow->GetFocusedElement() : nullptr;
|
||||
|
||||
bool dontDispatchEvent =
|
||||
eventTargetDoc && nsContentUtils::IsUserFocusIgnored(eventTargetDoc);
|
||||
|
||||
#ifdef ACCESSIBILITY
|
||||
nsAccessibilityService* accService = GetAccService();
|
||||
if (accService) {
|
||||
|
@ -2572,7 +2563,6 @@ void nsFocusManager::FireFocusOrBlurEvent(EventMessage aEventMessage,
|
|||
}
|
||||
#endif
|
||||
|
||||
if (!dontDispatchEvent) {
|
||||
nsContentUtils::AddScriptRunner(
|
||||
new FocusBlurEvent(aTarget, aEventMessage, aPresShell->GetPresContext(),
|
||||
aWindowRaised, aIsRefocus, aRelatedTarget));
|
||||
|
@ -2591,7 +2581,6 @@ void nsFocusManager::FireFocusOrBlurEvent(EventMessage aEventMessage,
|
|||
currentWindow, currentFocusedContent,
|
||||
aRelatedTarget);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void nsFocusManager::ScrollIntoView(PresShell* aPresShell, nsIContent* aContent,
|
||||
|
|
|
@ -3174,18 +3174,16 @@ void nsFrameLoader::InitializeBrowserAPI() {
|
|||
if (!OwnerIsMozBrowserFrame()) {
|
||||
return;
|
||||
}
|
||||
if (!IsRemoteFrame()) {
|
||||
|
||||
nsresult rv = EnsureMessageManager();
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return;
|
||||
}
|
||||
if (mMessageManager) {
|
||||
mMessageManager->LoadFrameScript(
|
||||
NS_LITERAL_STRING("chrome://global/content/BrowserElementChild.js"),
|
||||
/* allowDelayedLoad = */ true,
|
||||
/* aRunInGlobalScope */ true, IgnoreErrors());
|
||||
}
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIMozBrowserFrame> browserFrame = do_QueryInterface(mOwnerContent);
|
||||
if (browserFrame) {
|
||||
browserFrame->InitializeBrowserAPI();
|
||||
|
|
|
@ -17,48 +17,12 @@ function debug(msg) {
|
|||
// mozbrowser API clients.
|
||||
docShell.isActive = true;
|
||||
|
||||
function parentDocShell(docshell) {
|
||||
if (!docshell) {
|
||||
return null;
|
||||
}
|
||||
let treeitem = docshell.QueryInterface(Ci.nsIDocShellTreeItem);
|
||||
return treeitem.parent
|
||||
? treeitem.parent.QueryInterface(Ci.nsIDocShell)
|
||||
: null;
|
||||
}
|
||||
|
||||
function isTopBrowserElement(docShell) {
|
||||
while (docShell) {
|
||||
docShell = parentDocShell(docShell);
|
||||
if (docShell && docShell.isMozBrowser) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
var BrowserElementIsReady;
|
||||
|
||||
debug(`Might load BE scripts: BEIR: ${BrowserElementIsReady}`);
|
||||
if (!BrowserElementIsReady) {
|
||||
debug("Loading BE scripts");
|
||||
if (!("BrowserElementIsPreloaded" in this)) {
|
||||
if (Services.appinfo.processType == Services.appinfo.PROCESS_TYPE_CONTENT) {
|
||||
// general content apps
|
||||
if (isTopBrowserElement(docShell)) {
|
||||
Services.scriptloader.loadSubScript(
|
||||
"chrome://global/content/BrowserElementCopyPaste.js",
|
||||
this
|
||||
);
|
||||
}
|
||||
} else {
|
||||
// rocketbar in system app and other in-process case (ex. B2G desktop client)
|
||||
Services.scriptloader.loadSubScript(
|
||||
"chrome://global/content/BrowserElementCopyPaste.js",
|
||||
this
|
||||
);
|
||||
}
|
||||
|
||||
Services.scriptloader.loadSubScript(
|
||||
"chrome://global/content/BrowserElementChildPreload.js",
|
||||
this
|
||||
|
@ -71,9 +35,6 @@ if (!BrowserElementIsReady) {
|
|||
if (api) {
|
||||
api.destroy();
|
||||
}
|
||||
if ("CopyPasteAssistent" in this) {
|
||||
CopyPasteAssistent.destroy();
|
||||
}
|
||||
|
||||
BrowserElementIsReady = false;
|
||||
}
|
||||
|
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -1,138 +0,0 @@
|
|||
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- /
|
||||
/* vim: set shiftwidth=2 tabstop=2 autoindent cindent expandtab: */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||
* You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
"use strict";
|
||||
|
||||
/*
|
||||
global addMessageListener
|
||||
global removeMessageListener
|
||||
global docShell
|
||||
global content
|
||||
global sendAsyncMsg
|
||||
*/
|
||||
|
||||
function debug(msg) {
|
||||
// dump("BrowserElementCopyPaste - " + msg + "\n");
|
||||
}
|
||||
|
||||
debug("loaded");
|
||||
|
||||
var CopyPasteAssistent = {
|
||||
COMMAND_MAP: {
|
||||
cut: "cmd_cut",
|
||||
copy: "cmd_copy",
|
||||
paste: "cmd_paste",
|
||||
selectall: "cmd_selectAll",
|
||||
},
|
||||
|
||||
init() {
|
||||
addEventListener(
|
||||
"mozcaretstatechanged",
|
||||
this,
|
||||
/* useCapture = */ true,
|
||||
/* wantsUntrusted = */ false
|
||||
);
|
||||
addMessageListener("browser-element-api:call", this);
|
||||
},
|
||||
|
||||
destroy() {
|
||||
removeEventListener(
|
||||
"mozcaretstatechanged",
|
||||
this,
|
||||
/* useCapture = */ true,
|
||||
/* wantsUntrusted = */ false
|
||||
);
|
||||
removeMessageListener("browser-element-api:call", this);
|
||||
},
|
||||
|
||||
handleEvent(event) {
|
||||
switch (event.type) {
|
||||
case "mozcaretstatechanged":
|
||||
this._caretStateChangedHandler(event);
|
||||
break;
|
||||
}
|
||||
},
|
||||
|
||||
receiveMessage(message) {
|
||||
switch (message.name) {
|
||||
case "browser-element-api:call":
|
||||
this._browserAPIHandler(message);
|
||||
break;
|
||||
}
|
||||
},
|
||||
|
||||
_browserAPIHandler(e) {
|
||||
switch (e.data.msg_name) {
|
||||
case "copypaste-do-command":
|
||||
if (this._isCommandEnabled(e.data.command)) {
|
||||
docShell.doCommand(this.COMMAND_MAP[e.data.command]);
|
||||
}
|
||||
break;
|
||||
}
|
||||
},
|
||||
|
||||
_isCommandEnabled(cmd) {
|
||||
let command = this.COMMAND_MAP[cmd];
|
||||
if (!command) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return docShell.isCommandEnabled(command);
|
||||
},
|
||||
|
||||
_caretStateChangedHandler(e) {
|
||||
e.stopPropagation();
|
||||
|
||||
let boundingClientRect = e.boundingClientRect;
|
||||
this._isCommandEnabled("paste");
|
||||
let zoomFactor =
|
||||
content.innerWidth == 0 ? 1 : content.screen.width / content.innerWidth;
|
||||
|
||||
let detail = {
|
||||
rect: {
|
||||
width: boundingClientRect ? boundingClientRect.width : 0,
|
||||
height: boundingClientRect ? boundingClientRect.height : 0,
|
||||
top: boundingClientRect ? boundingClientRect.top : 0,
|
||||
bottom: boundingClientRect ? boundingClientRect.bottom : 0,
|
||||
left: boundingClientRect ? boundingClientRect.left : 0,
|
||||
right: boundingClientRect ? boundingClientRect.right : 0,
|
||||
},
|
||||
commands: {
|
||||
canSelectAll: this._isCommandEnabled("selectall"),
|
||||
canCut: this._isCommandEnabled("cut"),
|
||||
canCopy: this._isCommandEnabled("copy"),
|
||||
canPaste: this._isCommandEnabled("paste"),
|
||||
},
|
||||
zoomFactor,
|
||||
reason: e.reason,
|
||||
collapsed: e.collapsed,
|
||||
caretVisible: e.caretVisible,
|
||||
selectionVisible: e.selectionVisible,
|
||||
selectionEditable: e.selectionEditable,
|
||||
selectedTextContent: e.selectedTextContent,
|
||||
};
|
||||
|
||||
// Get correct geometry information if we have nested iframe.
|
||||
let currentWindow = e.target.defaultView;
|
||||
while (currentWindow.realFrameElement) {
|
||||
let currentRect = currentWindow.realFrameElement.getBoundingClientRect();
|
||||
detail.rect.top += currentRect.top;
|
||||
detail.rect.bottom += currentRect.top;
|
||||
detail.rect.left += currentRect.left;
|
||||
detail.rect.right += currentRect.left;
|
||||
currentWindow = currentWindow.realFrameElement.ownerGlobal;
|
||||
|
||||
let targetDocShell = currentWindow.docShell;
|
||||
if (targetDocShell.isMozBrowser) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
sendAsyncMsg("caretstatechanged", detail);
|
||||
},
|
||||
};
|
||||
|
||||
CopyPasteAssistent.init();
|
|
@ -27,45 +27,8 @@ function handleWindowEvent(e) {
|
|||
}
|
||||
}
|
||||
|
||||
function defineNoReturnMethod(fn) {
|
||||
return function method() {
|
||||
if (!this._domRequestReady) {
|
||||
// Remote browser haven't been created, we just queue the API call.
|
||||
let args = [this, ...arguments];
|
||||
this._pendingAPICalls.push(method.bind.apply(fn, args));
|
||||
return;
|
||||
}
|
||||
if (this._isAlive()) {
|
||||
fn.apply(this, arguments);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
function definePromiseMethod(msgName) {
|
||||
return function() {
|
||||
return this._sendAsyncRequest(msgName);
|
||||
};
|
||||
}
|
||||
|
||||
function BrowserElementParent() {
|
||||
debug("Creating new BrowserElementParent object");
|
||||
this._promiseCounter = 0;
|
||||
this._domRequestReady = false;
|
||||
this._pendingAPICalls = [];
|
||||
this._pendingPromises = {};
|
||||
this._pendingDOMFullscreen = false;
|
||||
|
||||
Services.obs.addObserver(
|
||||
this,
|
||||
"oop-frameloader-crashed",
|
||||
/* ownsWeak = */ true
|
||||
);
|
||||
Services.obs.addObserver(
|
||||
this,
|
||||
"ask-children-to-execute-copypaste-command",
|
||||
/* ownsWeak = */ true
|
||||
);
|
||||
Services.obs.addObserver(this, "back-docommand", /* ownsWeak = */ true);
|
||||
}
|
||||
|
||||
BrowserElementParent.prototype = {
|
||||
|
@ -74,7 +37,6 @@ BrowserElementParent.prototype = {
|
|||
contractID: "@mozilla.org/dom/browser-element-api;1",
|
||||
QueryInterface: ChromeUtils.generateQI([
|
||||
Ci.nsIBrowserElementAPI,
|
||||
Ci.nsIObserver,
|
||||
Ci.nsISupportsWeakReference,
|
||||
]),
|
||||
|
||||
|
@ -99,7 +61,7 @@ BrowserElementParent.prototype = {
|
|||
if (!this._window._browserElementParents) {
|
||||
this._window._browserElementParents = new WeakMap();
|
||||
let handler = handleWindowEvent.bind(this._window);
|
||||
let windowEvents = ["visibilitychange", "fullscreenchange"];
|
||||
let windowEvents = ["visibilitychange"];
|
||||
for (let event of windowEvents) {
|
||||
Services.els.addSystemEventListener(
|
||||
this._window,
|
||||
|
@ -125,21 +87,6 @@ BrowserElementParent.prototype = {
|
|||
this._mm.sendAsyncMessage("browser-element-api:destroy");
|
||||
},
|
||||
|
||||
_runPendingAPICall() {
|
||||
if (!this._pendingAPICalls) {
|
||||
return;
|
||||
}
|
||||
for (let i = 0; i < this._pendingAPICalls.length; i++) {
|
||||
try {
|
||||
this._pendingAPICalls[i]();
|
||||
} catch (e) {
|
||||
// throw the exceptions from pending functions.
|
||||
debug("Exception when running pending API call: " + e);
|
||||
}
|
||||
}
|
||||
delete this._pendingAPICalls;
|
||||
},
|
||||
|
||||
_setupMessageListener() {
|
||||
this._mm = this._frameLoader.messageManager;
|
||||
this._mm.addMessageListener("browser-element-api:call", this);
|
||||
|
@ -156,36 +103,10 @@ BrowserElementParent.prototype = {
|
|||
// on data.msg_name
|
||||
let mmCalls = {
|
||||
hello: this._recvHello,
|
||||
loadstart: this._fireProfiledEventFromMsg,
|
||||
loadend: this._fireProfiledEventFromMsg,
|
||||
close: this._fireEventFromMsg,
|
||||
error: this._fireEventFromMsg,
|
||||
firstpaint: this._fireProfiledEventFromMsg,
|
||||
documentfirstpaint: this._fireProfiledEventFromMsg,
|
||||
"got-can-go-back": this._gotAsyncResult,
|
||||
"got-can-go-forward": this._gotAsyncResult,
|
||||
"requested-dom-fullscreen": this._requestedDOMFullscreen,
|
||||
"fullscreen-origin-change": this._fullscreenOriginChange,
|
||||
"exit-dom-fullscreen": this._exitDomFullscreen,
|
||||
scrollviewchange: this._handleScrollViewChange,
|
||||
caretstatechanged: this._handleCaretStateChanged,
|
||||
};
|
||||
|
||||
let mmSecuritySensitiveCalls = {
|
||||
audioplaybackchange: this._fireEventFromMsg,
|
||||
showmodalprompt: this._handleShowModalPrompt,
|
||||
contextmenu: this._fireCtxMenuEvent,
|
||||
securitychange: this._fireEventFromMsg,
|
||||
locationchange: this._fireEventFromMsg,
|
||||
iconchange: this._fireEventFromMsg,
|
||||
scrollareachanged: this._fireEventFromMsg,
|
||||
titlechange: this._fireProfiledEventFromMsg,
|
||||
opensearch: this._fireEventFromMsg,
|
||||
metachange: this._fireEventFromMsg,
|
||||
resize: this._fireEventFromMsg,
|
||||
activitydone: this._fireEventFromMsg,
|
||||
scroll: this._fireEventFromMsg,
|
||||
opentab: this._fireEventFromMsg,
|
||||
};
|
||||
|
||||
if (aMsg.data.msg_name in mmCalls) {
|
||||
|
@ -219,60 +140,6 @@ BrowserElementParent.prototype = {
|
|||
return this._frameElement.ownerGlobal;
|
||||
},
|
||||
|
||||
get _windowUtils() {
|
||||
return this._window.windowUtils;
|
||||
},
|
||||
|
||||
promptAuth(authDetail, callback) {
|
||||
let evt;
|
||||
let callbackCalled = false;
|
||||
let cancelCallback = function() {
|
||||
if (!callbackCalled) {
|
||||
callbackCalled = true;
|
||||
callback(false, null, null);
|
||||
}
|
||||
};
|
||||
|
||||
// We don't handle password-only prompts.
|
||||
if (authDetail.isOnlyPassword) {
|
||||
cancelCallback();
|
||||
return;
|
||||
}
|
||||
|
||||
/* username and password */
|
||||
let detail = {
|
||||
host: authDetail.host,
|
||||
path: authDetail.path,
|
||||
realm: authDetail.realm,
|
||||
isProxy: authDetail.isProxy,
|
||||
};
|
||||
|
||||
evt = this._createEvent(
|
||||
"usernameandpasswordrequired",
|
||||
detail,
|
||||
/* cancelable */ true
|
||||
);
|
||||
Cu.exportFunction(
|
||||
function(username, password) {
|
||||
if (callbackCalled) {
|
||||
return;
|
||||
}
|
||||
callbackCalled = true;
|
||||
callback(true, username, password);
|
||||
},
|
||||
evt.detail,
|
||||
{ defineAs: "authenticate" }
|
||||
);
|
||||
|
||||
Cu.exportFunction(cancelCallback, evt.detail, { defineAs: "cancel" });
|
||||
|
||||
this._frameElement.dispatchEvent(evt);
|
||||
|
||||
if (!evt.defaultPrevented) {
|
||||
cancelCallback();
|
||||
}
|
||||
},
|
||||
|
||||
_sendAsyncMsg(msg, data) {
|
||||
try {
|
||||
if (!data) {
|
||||
|
@ -297,47 +164,6 @@ BrowserElementParent.prototype = {
|
|||
if (this._window.document.hidden) {
|
||||
this._ownerVisibilityChange();
|
||||
}
|
||||
|
||||
if (!this._domRequestReady) {
|
||||
// At least, one message listener such as for hello is registered.
|
||||
// So we can use sendAsyncMessage now.
|
||||
this._domRequestReady = true;
|
||||
this._runPendingAPICall();
|
||||
}
|
||||
},
|
||||
|
||||
_fireCtxMenuEvent(data) {
|
||||
let detail = data.json;
|
||||
let evtName = detail.msg_name;
|
||||
|
||||
debug("fireCtxMenuEventFromMsg: " + evtName + " " + detail);
|
||||
let evt = this._createEvent(evtName, detail, /* cancellable */ true);
|
||||
|
||||
if (detail.contextmenu) {
|
||||
var self = this;
|
||||
Cu.exportFunction(
|
||||
function(id) {
|
||||
self._sendAsyncMsg("fire-ctx-callback", { menuitem: id });
|
||||
},
|
||||
evt.detail,
|
||||
{ defineAs: "contextMenuItemSelected" }
|
||||
);
|
||||
}
|
||||
|
||||
// The embedder may have default actions on context menu events, so
|
||||
// we fire a context menu event even if the child didn't define a
|
||||
// custom context menu
|
||||
return !this._frameElement.dispatchEvent(evt);
|
||||
},
|
||||
|
||||
/**
|
||||
* add profiler marker for each event fired.
|
||||
*/
|
||||
_fireProfiledEventFromMsg(data) {
|
||||
if (Services.profiler !== undefined) {
|
||||
Services.profiler.AddMarker(data.json.msg_name);
|
||||
}
|
||||
this._fireEventFromMsg(data);
|
||||
},
|
||||
|
||||
/**
|
||||
|
@ -411,51 +237,6 @@ BrowserElementParent.prototype = {
|
|||
}
|
||||
},
|
||||
|
||||
// Called when state of accessible caret in child has changed.
|
||||
// The fields of data is as following:
|
||||
// - rect: Contains bounding rectangle of selection, Include width, height,
|
||||
// top, bottom, left and right.
|
||||
// - commands: Describe what commands can be executed in child. Include canSelectAll,
|
||||
// canCut, canCopy and canPaste. For example: if we want to check if cut
|
||||
// command is available, using following code, if (data.commands.canCut) {}.
|
||||
// - zoomFactor: Current zoom factor in child frame.
|
||||
// - reason: The reason causes the state changed. Include "visibilitychange",
|
||||
// "updateposition", "longpressonemptycontent", "taponcaret", "presscaret",
|
||||
// "releasecaret".
|
||||
// - collapsed: Indicate current selection is collapsed or not.
|
||||
// - caretVisible: Indicate the caret visiibility.
|
||||
// - selectionVisible: Indicate current selection is visible or not.
|
||||
// - selectionEditable: Indicate current selection is editable or not.
|
||||
// - selectedTextContent: Contains current selected text content, which is
|
||||
// equivalent to the string returned by Selection.toString().
|
||||
_handleCaretStateChanged(data) {
|
||||
let evt = this._createEvent(
|
||||
"caretstatechanged",
|
||||
data.json,
|
||||
/* cancelable = */ false
|
||||
);
|
||||
|
||||
let self = this;
|
||||
function sendDoCommandMsg(cmd) {
|
||||
let data = { command: cmd };
|
||||
self._sendAsyncMsg("copypaste-do-command", data);
|
||||
}
|
||||
Cu.exportFunction(sendDoCommandMsg, evt.detail, {
|
||||
defineAs: "sendDoCommandMsg",
|
||||
});
|
||||
|
||||
this._frameElement.dispatchEvent(evt);
|
||||
},
|
||||
|
||||
_handleScrollViewChange(data) {
|
||||
let evt = this._createEvent(
|
||||
"scrollviewchange",
|
||||
data.json,
|
||||
/* cancelable = */ false
|
||||
);
|
||||
this._frameElement.dispatchEvent(evt);
|
||||
},
|
||||
|
||||
_createEvent(evtName, detail, cancelable) {
|
||||
// This will have to change if we ever want to send a CustomEvent with null
|
||||
// detail. For now, it's OK.
|
||||
|
@ -474,117 +255,6 @@ BrowserElementParent.prototype = {
|
|||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* Kick off an async operation in the child process.
|
||||
*
|
||||
* We'll send a message called |msgName| to the child process, passing along
|
||||
* an object with two fields:
|
||||
*
|
||||
* - id: the ID of this async call.
|
||||
* - arg: arguments to pass to the child along with this async call.
|
||||
*
|
||||
* We expect the child to pass the ID back to us upon completion of the
|
||||
* call. See _gotAsyncResult.
|
||||
*/
|
||||
_sendAsyncRequest(msgName, args) {
|
||||
let id = "req_" + this._promiseCounter++;
|
||||
let resolve, reject;
|
||||
let p = new this._window.Promise((res, rej) => {
|
||||
resolve = res;
|
||||
reject = rej;
|
||||
});
|
||||
let self = this;
|
||||
let send = function() {
|
||||
if (!self._isAlive()) {
|
||||
return;
|
||||
}
|
||||
if (self._sendAsyncMsg(msgName, { id, args })) {
|
||||
self._pendingPromises[id] = { p, resolve, reject };
|
||||
} else {
|
||||
reject(new this._window.DOMException("fail"));
|
||||
}
|
||||
};
|
||||
if (this._domRequestReady) {
|
||||
send();
|
||||
} else {
|
||||
// Child haven't been loaded.
|
||||
this._pendingAPICalls.push(send);
|
||||
}
|
||||
return p;
|
||||
},
|
||||
|
||||
/**
|
||||
* Called when the child process finishes handling an async call. data.json
|
||||
* must have the fields [id, successRv], if the async call was successful, or
|
||||
* [id, errorMsg], if the call was not successful.
|
||||
*
|
||||
* The fields have the following meanings:
|
||||
*
|
||||
* - id: the ID of the async call (see _sendAsyncRequest)
|
||||
* - successRv: the call's return value, if the call succeeded
|
||||
* - errorMsg: the message to pass to the Promise reject callback, if the
|
||||
* call failed.
|
||||
*
|
||||
*/
|
||||
_gotAsyncResult(data) {
|
||||
let p = this._pendingPromises[data.json.id];
|
||||
delete this._pendingPromises[data.json.id];
|
||||
|
||||
if ("successRv" in data.json) {
|
||||
debug("Successful gotAsyncResult.");
|
||||
let clientObj = Cu.cloneInto(data.json.successRv, this._window);
|
||||
p.resolve(clientObj);
|
||||
} else {
|
||||
debug("Got error in gotAsyncResult.");
|
||||
p.reject(
|
||||
new this._window.DOMException(
|
||||
Cu.cloneInto(data.json.errorMsg, this._window)
|
||||
)
|
||||
);
|
||||
}
|
||||
},
|
||||
|
||||
sendMouseEvent: defineNoReturnMethod(function(
|
||||
type,
|
||||
x,
|
||||
y,
|
||||
button,
|
||||
clickCount,
|
||||
modifiers
|
||||
) {
|
||||
// This method used to attempt to transform from the parent
|
||||
// coordinate space to the child coordinate space, but the
|
||||
// transform was always a no-op, because this._frameLoader.remoteTab
|
||||
// was null.
|
||||
this._sendAsyncMsg("send-mouse-event", {
|
||||
type,
|
||||
x,
|
||||
y,
|
||||
button,
|
||||
clickCount,
|
||||
modifiers,
|
||||
});
|
||||
}),
|
||||
|
||||
getCanGoBack: definePromiseMethod("get-can-go-back"),
|
||||
getCanGoForward: definePromiseMethod("get-can-go-forward"),
|
||||
|
||||
goBack: defineNoReturnMethod(function() {
|
||||
this._sendAsyncMsg("go-back");
|
||||
}),
|
||||
|
||||
goForward: defineNoReturnMethod(function() {
|
||||
this._sendAsyncMsg("go-forward");
|
||||
}),
|
||||
|
||||
reload: defineNoReturnMethod(function(hardReload) {
|
||||
this._sendAsyncMsg("reload", { hardReload });
|
||||
}),
|
||||
|
||||
stop: defineNoReturnMethod(function() {
|
||||
this._sendAsyncMsg("stop");
|
||||
}),
|
||||
|
||||
/**
|
||||
* Called when the visibility of the window which owns this iframe changes.
|
||||
*/
|
||||
|
@ -594,68 +264,11 @@ BrowserElementParent.prototype = {
|
|||
});
|
||||
},
|
||||
|
||||
_requestedDOMFullscreen() {
|
||||
this._pendingDOMFullscreen = true;
|
||||
this._windowUtils.remoteFrameFullscreenChanged(this._frameElement);
|
||||
},
|
||||
|
||||
_fullscreenOriginChange(data) {
|
||||
Services.obs.notifyObservers(
|
||||
this._frameElement,
|
||||
"fullscreen-origin-change",
|
||||
data.json.originNoSuffix
|
||||
);
|
||||
},
|
||||
|
||||
_exitDomFullscreen(data) {
|
||||
this._windowUtils.remoteFrameFullscreenReverted();
|
||||
},
|
||||
|
||||
_handleOwnerEvent(evt) {
|
||||
switch (evt.type) {
|
||||
case "visibilitychange":
|
||||
this._ownerVisibilityChange();
|
||||
break;
|
||||
case "fullscreenchange":
|
||||
if (!this._window.document.fullscreenElement) {
|
||||
this._sendAsyncMsg("exit-fullscreen");
|
||||
} else if (this._pendingDOMFullscreen) {
|
||||
this._pendingDOMFullscreen = false;
|
||||
this._sendAsyncMsg("entered-fullscreen");
|
||||
}
|
||||
break;
|
||||
}
|
||||
},
|
||||
|
||||
_fireFatalError() {
|
||||
let evt = this._createEvent(
|
||||
"error",
|
||||
{ type: "fatal" },
|
||||
/* cancelable = */ false
|
||||
);
|
||||
this._frameElement.dispatchEvent(evt);
|
||||
},
|
||||
|
||||
observe(subject, topic, data) {
|
||||
switch (topic) {
|
||||
case "oop-frameloader-crashed":
|
||||
if (this._isAlive() && subject == this._frameLoader) {
|
||||
this._fireFatalError();
|
||||
}
|
||||
break;
|
||||
case "ask-children-to-execute-copypaste-command":
|
||||
if (this._isAlive() && this._frameElement == subject.wrappedJSObject) {
|
||||
this._sendAsyncMsg("copypaste-do-command", { command: data });
|
||||
}
|
||||
break;
|
||||
case "back-docommand":
|
||||
if (this._isAlive() && this._frameLoader.visible) {
|
||||
this.goBack();
|
||||
}
|
||||
break;
|
||||
default:
|
||||
debug("Unknown topic: " + topic);
|
||||
break;
|
||||
}
|
||||
},
|
||||
};
|
||||
|
|
|
@ -3155,10 +3155,6 @@ nsresult EventStateManager::PostHandleEvent(nsPresContext* aPresContext,
|
|||
}
|
||||
}
|
||||
|
||||
if (!suppressBlur) {
|
||||
suppressBlur = nsContentUtils::IsUserFocusIgnored(activeContent);
|
||||
}
|
||||
|
||||
// When a root content which isn't editable but has an editable HTML
|
||||
// <body> element is clicked, we should redirect the focus to the
|
||||
// the <body> element. E.g., when an user click bottom of the editor
|
||||
|
|
|
@ -7,7 +7,6 @@
|
|||
#include "nsBrowserElement.h"
|
||||
|
||||
#include "mozilla/Preferences.h"
|
||||
#include "mozilla/dom/BrowserElementBinding.h"
|
||||
#include "mozilla/dom/Promise.h"
|
||||
#include "mozilla/dom/ScriptSettings.h"
|
||||
#include "mozilla/dom/ToJSValue.h"
|
||||
|
@ -55,86 +54,4 @@ void nsBrowserElement::DestroyBrowserElementFrameScripts() {
|
|||
mBrowserElementAPI->DestroyFrameScripts();
|
||||
}
|
||||
|
||||
void nsBrowserElement::SendMouseEvent(const nsAString& aType, uint32_t aX,
|
||||
uint32_t aY, uint32_t aButton,
|
||||
uint32_t aClickCount, uint32_t aModifiers,
|
||||
ErrorResult& aRv) {
|
||||
NS_ENSURE_TRUE_VOID(IsBrowserElementOrThrow(aRv));
|
||||
|
||||
nsresult rv = mBrowserElementAPI->SendMouseEvent(aType, aX, aY, aButton,
|
||||
aClickCount, aModifiers);
|
||||
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
aRv.Throw(NS_ERROR_DOM_INVALID_STATE_ERR);
|
||||
}
|
||||
}
|
||||
|
||||
void nsBrowserElement::GoBack(ErrorResult& aRv) {
|
||||
NS_ENSURE_TRUE_VOID(IsBrowserElementOrThrow(aRv));
|
||||
|
||||
nsresult rv = mBrowserElementAPI->GoBack();
|
||||
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
aRv.Throw(NS_ERROR_DOM_INVALID_STATE_ERR);
|
||||
}
|
||||
}
|
||||
|
||||
void nsBrowserElement::GoForward(ErrorResult& aRv) {
|
||||
NS_ENSURE_TRUE_VOID(IsBrowserElementOrThrow(aRv));
|
||||
|
||||
nsresult rv = mBrowserElementAPI->GoForward();
|
||||
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
aRv.Throw(NS_ERROR_DOM_INVALID_STATE_ERR);
|
||||
}
|
||||
}
|
||||
|
||||
void nsBrowserElement::Reload(bool aHardReload, ErrorResult& aRv) {
|
||||
NS_ENSURE_TRUE_VOID(IsBrowserElementOrThrow(aRv));
|
||||
|
||||
nsresult rv = mBrowserElementAPI->Reload(aHardReload);
|
||||
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
aRv.Throw(NS_ERROR_DOM_INVALID_STATE_ERR);
|
||||
}
|
||||
}
|
||||
|
||||
void nsBrowserElement::Stop(ErrorResult& aRv) {
|
||||
NS_ENSURE_TRUE_VOID(IsBrowserElementOrThrow(aRv));
|
||||
|
||||
nsresult rv = mBrowserElementAPI->Stop();
|
||||
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
aRv.Throw(NS_ERROR_DOM_INVALID_STATE_ERR);
|
||||
}
|
||||
}
|
||||
|
||||
already_AddRefed<Promise> nsBrowserElement::GetCanGoBack(ErrorResult& aRv) {
|
||||
NS_ENSURE_TRUE(IsBrowserElementOrThrow(aRv), nullptr);
|
||||
|
||||
RefPtr<Promise> p;
|
||||
nsresult rv = mBrowserElementAPI->GetCanGoBack(getter_AddRefs(p));
|
||||
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
aRv.Throw(NS_ERROR_DOM_INVALID_STATE_ERR);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return p.forget();
|
||||
}
|
||||
|
||||
already_AddRefed<Promise> nsBrowserElement::GetCanGoForward(ErrorResult& aRv) {
|
||||
NS_ENSURE_TRUE(IsBrowserElementOrThrow(aRv), nullptr);
|
||||
|
||||
RefPtr<Promise> p;
|
||||
nsresult rv = mBrowserElementAPI->GetCanGoForward(getter_AddRefs(p));
|
||||
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
aRv.Throw(NS_ERROR_DOM_INVALID_STATE_ERR);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return p.forget();
|
||||
}
|
||||
|
||||
} // namespace mozilla
|
||||
|
|
|
@ -7,4 +7,3 @@ toolkit.jar:
|
|||
content/global/remote-test-ipc.js (remote-test.js)
|
||||
content/global/BrowserElementChild.js (../browser-element/BrowserElementChild.js)
|
||||
content/global/BrowserElementChildPreload.js (../browser-element/BrowserElementChildPreload.js)
|
||||
content/global/BrowserElementCopyPaste.js (../browser-element/BrowserElementCopyPaste.js)
|
||||
|
|
|
@ -1,47 +0,0 @@
|
|||
/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||
* You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
interface mixin BrowserElement {
|
||||
[Throws,
|
||||
Pref="dom.mozBrowserFramesEnabled",
|
||||
ChromeOnly]
|
||||
void sendMouseEvent(DOMString type,
|
||||
unsigned long x,
|
||||
unsigned long y,
|
||||
unsigned long button,
|
||||
unsigned long clickCount,
|
||||
unsigned long modifiers);
|
||||
|
||||
[Throws,
|
||||
Pref="dom.mozBrowserFramesEnabled",
|
||||
ChromeOnly]
|
||||
void goBack();
|
||||
|
||||
[Throws,
|
||||
Pref="dom.mozBrowserFramesEnabled",
|
||||
ChromeOnly]
|
||||
void goForward();
|
||||
|
||||
[Throws,
|
||||
Pref="dom.mozBrowserFramesEnabled",
|
||||
ChromeOnly]
|
||||
void reload(optional boolean hardReload = false);
|
||||
|
||||
[Throws,
|
||||
Pref="dom.mozBrowserFramesEnabled",
|
||||
ChromeOnly]
|
||||
void stop();
|
||||
|
||||
[Throws,
|
||||
Pref="dom.mozBrowserFramesEnabled",
|
||||
ChromeOnly]
|
||||
Promise<boolean> getCanGoBack();
|
||||
|
||||
[Throws,
|
||||
Pref="dom.mozBrowserFramesEnabled",
|
||||
ChromeOnly]
|
||||
Promise<boolean> getCanGoForward();
|
||||
};
|
|
@ -63,14 +63,7 @@ partial interface HTMLIFrameElement {
|
|||
Document? getSVGDocument();
|
||||
};
|
||||
|
||||
partial interface HTMLIFrameElement {
|
||||
// nsIDOMMozBrowserFrame
|
||||
[ChromeOnly,SetterThrows]
|
||||
attribute boolean mozbrowser;
|
||||
};
|
||||
|
||||
HTMLIFrameElement includes MozFrameLoaderOwner;
|
||||
HTMLIFrameElement includes BrowserElement;
|
||||
|
||||
// https://w3c.github.io/webappsec-feature-policy/#idl-index
|
||||
partial interface HTMLIFrameElement {
|
||||
|
|
|
@ -49,9 +49,6 @@ with Files("Blob*"):
|
|||
with Files("BroadcastChannel.webidl"):
|
||||
BUG_COMPONENT = ("Core", "DOM: postMessage")
|
||||
|
||||
with Files("BrowserElement*"):
|
||||
BUG_COMPONENT = ("Core", "DOM: Core & HTML")
|
||||
|
||||
with Files("CSP*"):
|
||||
BUG_COMPONENT = ("Core", "DOM: Security")
|
||||
|
||||
|
@ -431,7 +428,6 @@ WEBIDL_FILES = [
|
|||
'BiquadFilterNode.webidl',
|
||||
'Blob.webidl',
|
||||
'BroadcastChannel.webidl',
|
||||
'BrowserElement.webidl',
|
||||
'BrowserElementDictionaries.webidl',
|
||||
'Cache.webidl',
|
||||
'CacheStorage.webidl',
|
||||
|
|
Загрузка…
Ссылка в новой задаче