mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-24 21:31:04 +00:00
Merge inbound to m-c a=merge
This commit is contained in:
commit
ee92002ede
2
CLOBBER
2
CLOBBER
@ -22,4 +22,4 @@
|
||||
# changes to stick? As of bug 928195, this shouldn't be necessary! Please
|
||||
# don't change CLOBBER for WebIDL changes any more.
|
||||
|
||||
Bug 1299332 for the relanding of Bug 1299276.
|
||||
Bug 1289951 maybe needed a clobber to fix xpcshell tests?
|
||||
|
@ -90,10 +90,7 @@ EnableLogging(const char* aModulesStr)
|
||||
static void
|
||||
LogDocURI(nsIDocument* aDocumentNode)
|
||||
{
|
||||
nsIURI* uri = aDocumentNode->GetDocumentURI();
|
||||
nsAutoCString spec;
|
||||
uri->GetSpec(spec);
|
||||
printf("uri: %s", spec.get());
|
||||
printf("uri: %s", aDocumentNode->GetDocumentURI()->GetSpecOrDefault().get());
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -127,7 +127,7 @@ nsTextEquivUtils::AppendTextEquivFromTextContent(nsIContent *aContent,
|
||||
// get words jammed together in final name.
|
||||
const nsStyleDisplay* display = frame->StyleDisplay();
|
||||
if (display->IsBlockOutsideStyle() ||
|
||||
display->mDisplay == NS_STYLE_DISPLAY_TABLE_CELL) {
|
||||
display->mDisplay == StyleDisplay::TableCell) {
|
||||
isHTMLBlock = true;
|
||||
if (!aString->IsEmpty()) {
|
||||
aString->Append(char16_t(' '));
|
||||
|
@ -90,15 +90,6 @@
|
||||
);
|
||||
} else {
|
||||
SimpleTest.ok(true, "Testing Firefox tabbrowser UI.");
|
||||
let newTabChildren = [];
|
||||
if (SpecialPowers.getBoolPref("privacy.userContext.enabled")) {
|
||||
newTabChildren = [
|
||||
{
|
||||
role: ROLE_MENUPOPUP,
|
||||
children: []
|
||||
}
|
||||
];
|
||||
}
|
||||
|
||||
// NB: The (3) buttons are not visible, unless manually hovered,
|
||||
// probably due to size reduction in this test.
|
||||
@ -128,7 +119,7 @@
|
||||
{
|
||||
// xul:toolbarbutton ("Open a new tab")
|
||||
role: ROLE_PUSHBUTTON,
|
||||
children: newTabChildren
|
||||
children: []
|
||||
}
|
||||
// "List all tabs" dropdown
|
||||
// XXX: This child(?) is not present in this test.
|
||||
|
@ -289,10 +289,10 @@ exports.testActiveWindow = function*(assert) {
|
||||
assert.equal(windows.activeWindow.title, window3.title, "Correct active window - 3");
|
||||
|
||||
yield close(rawWindow2);
|
||||
assert.equal(rawWindow2.closed, true, 'window 2 is closed');
|
||||
|
||||
yield close(rawWindow3);
|
||||
assert.equal(rawWindow3.closed, true, 'window 3 is closed');
|
||||
|
||||
assert.equal(windows.length, 1, "Correct number of browser windows");
|
||||
assert.equal(window.closed, false, "Original window is still open");
|
||||
};
|
||||
|
||||
exports.testTrackWindows = function(assert, done) {
|
||||
|
@ -406,40 +406,6 @@ pref("dom.phonenumber.substringmatching.PE", 7);
|
||||
// WebAlarms
|
||||
pref("dom.mozAlarms.enabled", true);
|
||||
|
||||
// SimplePush
|
||||
pref("services.push.enabled", true);
|
||||
// Debugging enabled.
|
||||
pref("services.push.debug", false);
|
||||
// Is the network connection allowed to be up?
|
||||
// This preference should be used in UX to enable/disable push.
|
||||
pref("services.push.connection.enabled", true);
|
||||
// serverURL to be assigned by services team
|
||||
pref("services.push.serverURL", "wss://push.services.mozilla.com/");
|
||||
pref("services.push.userAgentID", "");
|
||||
// Exponential back-off start is 5 seconds like in HTTP/1.1.
|
||||
// Maximum back-off is pingInterval.
|
||||
pref("services.push.retryBaseInterval", 5000);
|
||||
// Interval at which to ping PushServer to check connection status. In
|
||||
// milliseconds. If no reply is received within requestTimeout, the connection
|
||||
// is considered closed.
|
||||
pref("services.push.pingInterval", 1800000); // 30 minutes
|
||||
// How long before a DOMRequest errors as timeout
|
||||
pref("services.push.requestTimeout", 10000);
|
||||
pref("services.push.pingInterval.default", 180000);// 3 min
|
||||
pref("services.push.pingInterval.mobile", 180000); // 3 min
|
||||
pref("services.push.pingInterval.wifi", 180000); // 3 min
|
||||
// Adaptive ping
|
||||
pref("services.push.adaptive.enabled", true);
|
||||
pref("services.push.adaptive.lastGoodPingInterval", 180000);// 3 min
|
||||
pref("services.push.adaptive.lastGoodPingInterval.mobile", 180000);// 3 min
|
||||
pref("services.push.adaptive.lastGoodPingInterval.wifi", 180000);// 3 min
|
||||
// Valid gap between the biggest good ping and the bad ping
|
||||
pref("services.push.adaptive.gap", 60000); // 1 minute
|
||||
// We limit the ping to this maximum value
|
||||
pref("services.push.adaptive.upperLimit", 1740000); // 29 min
|
||||
// enable udp wakeup support
|
||||
pref("services.push.udp.wakeupEnabled", true);
|
||||
|
||||
// NetworkStats
|
||||
#ifdef MOZ_WIDGET_GONK
|
||||
pref("dom.mozNetworkStats.enabled", true);
|
||||
|
@ -36,7 +36,6 @@ MOZ_APP_ID={3c2e2abc-06d4-11e1-ac3b-374f68613e61}
|
||||
|
||||
MOZ_TIME_MANAGER=1
|
||||
|
||||
MOZ_SIMPLEPUSH=1
|
||||
MOZ_TOOLKIT_SEARCH=
|
||||
MOZ_B2G=1
|
||||
|
||||
|
@ -604,11 +604,7 @@
|
||||
@RESPATH@/components/AppsService.manifest
|
||||
@RESPATH@/components/Push.js
|
||||
@RESPATH@/components/Push.manifest
|
||||
#ifdef MOZ_SIMPLEPUSH
|
||||
@RESPATH@/components/PushServiceLauncher.js
|
||||
#else
|
||||
@RESPATH@/components/PushComponents.js
|
||||
#endif
|
||||
|
||||
@RESPATH@/components/nsDOMIdentity.js
|
||||
@RESPATH@/components/nsIDService.js
|
||||
|
@ -119,16 +119,6 @@ tabbrowser {
|
||||
visibility: hidden; /* temporary space to keep a tab's close button under the cursor */
|
||||
}
|
||||
|
||||
.tabs-newtab-button > .toolbarbutton-menu-dropmarker,
|
||||
#new-tab-button > .toolbarbutton-menu-dropmarker {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.tabs-newtab-button > .toolbarbutton-icon,
|
||||
#new-tab-button > .toolbarbutton-icon {
|
||||
margin-inline-end: 0;
|
||||
}
|
||||
|
||||
.tabbrowser-tab {
|
||||
-moz-binding: url("chrome://browser/content/tabbrowser.xml#tabbrowser-tab");
|
||||
}
|
||||
@ -187,7 +177,6 @@ tabbrowser {
|
||||
transition: transform 200ms ease-out;
|
||||
}
|
||||
|
||||
.new-tab-popup,
|
||||
#alltabs-popup {
|
||||
-moz-binding: url("chrome://browser/content/tabbrowser.xml#tabbrowser-alltabs-popup");
|
||||
}
|
||||
|
@ -261,6 +261,66 @@ function UpdateBackForwardCommands(aWebNavigation) {
|
||||
* XXXmano: should this live in toolbarbutton.xml?
|
||||
*/
|
||||
function SetClickAndHoldHandlers() {
|
||||
var timer;
|
||||
|
||||
function openMenu(aButton) {
|
||||
cancelHold(aButton);
|
||||
aButton.firstChild.hidden = false;
|
||||
aButton.open = true;
|
||||
}
|
||||
|
||||
function mousedownHandler(aEvent) {
|
||||
if (aEvent.button != 0 ||
|
||||
aEvent.currentTarget.open ||
|
||||
aEvent.currentTarget.disabled)
|
||||
return;
|
||||
|
||||
// Prevent the menupopup from opening immediately
|
||||
aEvent.currentTarget.firstChild.hidden = true;
|
||||
|
||||
aEvent.currentTarget.addEventListener("mouseout", mouseoutHandler, false);
|
||||
aEvent.currentTarget.addEventListener("mouseup", mouseupHandler, false);
|
||||
timer = setTimeout(openMenu, 500, aEvent.currentTarget);
|
||||
}
|
||||
|
||||
function mouseoutHandler(aEvent) {
|
||||
let buttonRect = aEvent.currentTarget.getBoundingClientRect();
|
||||
if (aEvent.clientX >= buttonRect.left &&
|
||||
aEvent.clientX <= buttonRect.right &&
|
||||
aEvent.clientY >= buttonRect.bottom)
|
||||
openMenu(aEvent.currentTarget);
|
||||
else
|
||||
cancelHold(aEvent.currentTarget);
|
||||
}
|
||||
|
||||
function mouseupHandler(aEvent) {
|
||||
cancelHold(aEvent.currentTarget);
|
||||
}
|
||||
|
||||
function cancelHold(aButton) {
|
||||
clearTimeout(timer);
|
||||
aButton.removeEventListener("mouseout", mouseoutHandler, false);
|
||||
aButton.removeEventListener("mouseup", mouseupHandler, false);
|
||||
}
|
||||
|
||||
function clickHandler(aEvent) {
|
||||
if (aEvent.button == 0 &&
|
||||
aEvent.target == aEvent.currentTarget &&
|
||||
!aEvent.currentTarget.open &&
|
||||
!aEvent.currentTarget.disabled) {
|
||||
let cmdEvent = document.createEvent("xulcommandevent");
|
||||
cmdEvent.initCommandEvent("command", true, true, window, 0,
|
||||
aEvent.ctrlKey, aEvent.altKey, aEvent.shiftKey,
|
||||
aEvent.metaKey, null);
|
||||
aEvent.currentTarget.dispatchEvent(cmdEvent);
|
||||
}
|
||||
}
|
||||
|
||||
function _addClickAndHoldListenersOnElement(aElm) {
|
||||
aElm.addEventListener("mousedown", mousedownHandler, true);
|
||||
aElm.addEventListener("click", clickHandler, true);
|
||||
}
|
||||
|
||||
// Bug 414797: Clone the back/forward buttons' context menu into both buttons.
|
||||
let popup = document.getElementById("backForwardMenu").cloneNode(true);
|
||||
popup.removeAttribute("id");
|
||||
@ -270,83 +330,13 @@ function SetClickAndHoldHandlers() {
|
||||
let backButton = document.getElementById("back-button");
|
||||
backButton.setAttribute("type", "menu");
|
||||
backButton.appendChild(popup);
|
||||
addClickAndHoldListenersOnElement(backButton);
|
||||
_addClickAndHoldListenersOnElement(backButton);
|
||||
|
||||
let forwardButton = document.getElementById("forward-button");
|
||||
popup = popup.cloneNode(true);
|
||||
forwardButton.setAttribute("type", "menu");
|
||||
forwardButton.appendChild(popup);
|
||||
addClickAndHoldListenersOnElement(forwardButton);
|
||||
}
|
||||
|
||||
let holdTimersMap = new Map();
|
||||
function holdMousedownHandler(aEvent) {
|
||||
if (aEvent.button != 0 ||
|
||||
aEvent.currentTarget.open ||
|
||||
aEvent.currentTarget.disabled)
|
||||
return;
|
||||
|
||||
// Prevent the menupopup from opening immediately
|
||||
aEvent.currentTarget.firstChild.hidden = true;
|
||||
|
||||
aEvent.currentTarget.addEventListener("mouseout", holdMouseoutHandler, false);
|
||||
aEvent.currentTarget.addEventListener("mouseup", holdMouseupHandler, false);
|
||||
holdTimersMap.set(aEvent.currentTarget, setTimeout(holdOpenMenu, 500, aEvent.currentTarget));
|
||||
}
|
||||
|
||||
function holdClickHandler(aEvent) {
|
||||
if (aEvent.button == 0 &&
|
||||
aEvent.target == aEvent.currentTarget &&
|
||||
!aEvent.currentTarget.open &&
|
||||
!aEvent.currentTarget.disabled) {
|
||||
let cmdEvent = document.createEvent("xulcommandevent");
|
||||
cmdEvent.initCommandEvent("command", true, true, window, 0,
|
||||
aEvent.ctrlKey, aEvent.altKey, aEvent.shiftKey,
|
||||
aEvent.metaKey, null);
|
||||
aEvent.currentTarget.dispatchEvent(cmdEvent);
|
||||
}
|
||||
// This is here to cancel the XUL default event
|
||||
// dom.click() triggers a command even if there is a click handler
|
||||
// however this can now be prevented with preventDefault().
|
||||
aEvent.preventDefault();
|
||||
}
|
||||
|
||||
function holdOpenMenu(aButton) {
|
||||
cancelHold(aButton);
|
||||
aButton.firstChild.hidden = false;
|
||||
aButton.open = true;
|
||||
}
|
||||
|
||||
function holdMouseoutHandler(aEvent) {
|
||||
let buttonRect = aEvent.currentTarget.getBoundingClientRect();
|
||||
if (aEvent.clientX >= buttonRect.left &&
|
||||
aEvent.clientX <= buttonRect.right &&
|
||||
aEvent.clientY >= buttonRect.bottom)
|
||||
holdOpenMenu(aEvent.currentTarget);
|
||||
else
|
||||
cancelHold(aEvent.currentTarget);
|
||||
}
|
||||
|
||||
function holdMouseupHandler(aEvent) {
|
||||
cancelHold(aEvent.currentTarget);
|
||||
}
|
||||
|
||||
function cancelHold(aButton) {
|
||||
clearTimeout(holdTimersMap.get(aButton));
|
||||
aButton.removeEventListener("mouseout", holdMouseoutHandler, false);
|
||||
aButton.removeEventListener("mouseup", holdMouseupHandler, false);
|
||||
}
|
||||
|
||||
function removeClickAndHoldListenersOnElement(aElm) {
|
||||
aElm.removeEventListener("mousedown", holdMousedownHandler, true);
|
||||
aElm.removeEventListener("click", holdClickHandler, true);
|
||||
}
|
||||
|
||||
function addClickAndHoldListenersOnElement(aElm) {
|
||||
holdTimersMap.delete(aElm);
|
||||
|
||||
aElm.addEventListener("mousedown", holdMousedownHandler, true);
|
||||
aElm.addEventListener("click", holdClickHandler, true);
|
||||
_addClickAndHoldListenersOnElement(forwardButton);
|
||||
}
|
||||
|
||||
const gSessionHistoryObserver = {
|
||||
@ -7391,6 +7381,8 @@ var gIdentityHandler = {
|
||||
|
||||
let button = document.createElement("button");
|
||||
button.setAttribute("class", "identity-popup-permission-remove-button");
|
||||
let tooltiptext = gNavigatorBundle.getString("permissions.remove.tooltip");
|
||||
button.setAttribute("tooltiptext", tooltiptext);
|
||||
button.addEventListener("command", () => {
|
||||
this._permissionList.removeChild(container);
|
||||
if (aPermission.inUse &&
|
||||
|
@ -4946,7 +4946,7 @@
|
||||
</xul:arrowscrollbox>
|
||||
</content>
|
||||
|
||||
<implementation implements="nsIDOMEventListener, nsIObserver">
|
||||
<implementation implements="nsIDOMEventListener">
|
||||
<constructor>
|
||||
<![CDATA[
|
||||
this.mTabClipWidth = Services.prefs.getIntPref("browser.tabs.tabClipWidth");
|
||||
@ -4965,21 +4965,9 @@
|
||||
this._tabAnimationLoggingEnabled = false;
|
||||
}
|
||||
this._browserNewtabpageEnabled = Services.prefs.getBoolPref("browser.newtabpage.enabled");
|
||||
this.observe(null, "nsPref:changed", "privacy.userContext.enabled");
|
||||
Services.prefs.addObserver("privacy.userContext.enabled", this, false);
|
||||
]]>
|
||||
</constructor>
|
||||
|
||||
<destructor>
|
||||
<![CDATA[
|
||||
Services.prefs.removeObserver("privacy.userContext.enabled", this);
|
||||
]]>
|
||||
</destructor>
|
||||
|
||||
<field name="newtabUndoCloseTab" readonly="true">
|
||||
document.getAnonymousElementByAttribute(this, "anonid", "newtab_undoCloseTab");
|
||||
</field>
|
||||
|
||||
<field name="tabbrowser" readonly="true">
|
||||
document.getElementById(this.getAttribute("tabbrowser"));
|
||||
</field>
|
||||
@ -5005,54 +4993,6 @@
|
||||
<field name="_afterHoveredTab">null</field>
|
||||
<field name="_hoveredTab">null</field>
|
||||
|
||||
<method name="observe">
|
||||
<parameter name="aSubject"/>
|
||||
<parameter name="aTopic"/>
|
||||
<parameter name="aData"/>
|
||||
<body><![CDATA[
|
||||
switch (aTopic) {
|
||||
case "nsPref:changed":
|
||||
// This is the only pref observed.
|
||||
let containersEnabled = Services.prefs.getBoolPref("privacy.userContext.enabled");
|
||||
|
||||
const newTab = document.getElementById("new-tab-button");
|
||||
const newTab2 = document.getAnonymousElementByAttribute(this, "anonid", "tabs-newtab-button")
|
||||
|
||||
if (containersEnabled) {
|
||||
for (let parent of [newTab, newTab2]) {
|
||||
if (!parent)
|
||||
continue;
|
||||
let popup = document.createElementNS(
|
||||
"http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul",
|
||||
"menupopup");
|
||||
if (parent.id) {
|
||||
popup.id = "newtab-popup";
|
||||
} else {
|
||||
popup.setAttribute("anonid", "newtab-popup");
|
||||
}
|
||||
popup.oncommand="event.stopPropagation();";
|
||||
popup.className = "new-tab-popup";
|
||||
popup.setAttribute("position", "after_end");
|
||||
parent.appendChild(popup);
|
||||
|
||||
addClickAndHoldListenersOnElement(parent);
|
||||
parent.setAttribute("type", "menu");
|
||||
}
|
||||
} else {
|
||||
for (let parent of [newTab, newTab2]) {
|
||||
if (!parent)
|
||||
continue;
|
||||
removeClickAndHoldListenersOnElement(parent);
|
||||
parent.removeAttribute("type");
|
||||
parent.firstChild.remove();
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
]]></body>
|
||||
</method>
|
||||
|
||||
<property name="_isCustomizing" readonly="true">
|
||||
<getter>
|
||||
let root = document.documentElement;
|
||||
@ -6740,36 +6680,30 @@
|
||||
}
|
||||
|
||||
let containersEnabled = Services.prefs.getBoolPref("privacy.userContext.enabled");
|
||||
document.getElementById("alltabs-popup-separator-1").hidden = !containersEnabled;
|
||||
let containersTab = document.getElementById("alltabs_containersTab");
|
||||
|
||||
if (event.target.getAttribute('anonid') == "newtab-popup" ||
|
||||
event.target.id == "newtab-popup") {
|
||||
createUserContextMenu(event);
|
||||
} else {
|
||||
document.getElementById("alltabs-popup-separator-1").hidden = !containersEnabled;
|
||||
let containersTab = document.getElementById("alltabs_containersTab");
|
||||
|
||||
containersTab.hidden = !containersEnabled;
|
||||
if (PrivateBrowsingUtils.isWindowPrivate(window)) {
|
||||
containersTab.setAttribute("disabled", "true");
|
||||
}
|
||||
|
||||
document.getElementById("alltabs_undoCloseTab").disabled =
|
||||
SessionStore.getClosedTabCount(window) == 0;
|
||||
|
||||
var tabcontainer = gBrowser.tabContainer;
|
||||
|
||||
// Listen for changes in the tab bar.
|
||||
tabcontainer.addEventListener("TabAttrModified", this, false);
|
||||
tabcontainer.addEventListener("TabClose", this, false);
|
||||
tabcontainer.mTabstrip.addEventListener("scroll", this, false);
|
||||
|
||||
let tabs = gBrowser.visibleTabs;
|
||||
for (var i = 0; i < tabs.length; i++) {
|
||||
if (!tabs[i].pinned)
|
||||
this._createTabMenuItem(tabs[i]);
|
||||
}
|
||||
this._updateTabsVisibilityStatus();
|
||||
containersTab.hidden = !containersEnabled;
|
||||
if (PrivateBrowsingUtils.isWindowPrivate(window)) {
|
||||
containersTab.setAttribute("disabled", "true");
|
||||
}
|
||||
|
||||
document.getElementById("alltabs_undoCloseTab").disabled =
|
||||
SessionStore.getClosedTabCount(window) == 0;
|
||||
|
||||
var tabcontainer = gBrowser.tabContainer;
|
||||
|
||||
// Listen for changes in the tab bar.
|
||||
tabcontainer.addEventListener("TabAttrModified", this, false);
|
||||
tabcontainer.addEventListener("TabClose", this, false);
|
||||
tabcontainer.mTabstrip.addEventListener("scroll", this, false);
|
||||
|
||||
let tabs = gBrowser.visibleTabs;
|
||||
for (var i = 0; i < tabs.length; i++) {
|
||||
if (!tabs[i].pinned)
|
||||
this._createTabMenuItem(tabs[i]);
|
||||
}
|
||||
this._updateTabsVisibilityStatus();
|
||||
]]></handler>
|
||||
|
||||
<handler event="popuphidden">
|
||||
@ -6785,9 +6719,6 @@
|
||||
menuItem.tab.mCorrespondingMenuitem = null;
|
||||
this.removeChild(menuItem);
|
||||
}
|
||||
if (menuItem.hasAttribute("usercontextid")) {
|
||||
this.removeChild(menuItem);
|
||||
}
|
||||
}
|
||||
var tabcontainer = gBrowser.tabContainer;
|
||||
tabcontainer.mTabstrip.removeEventListener("scroll", this, false);
|
||||
|
@ -56,6 +56,12 @@ add_task(function*() {
|
||||
|
||||
is(prompt.hidden, false, "The last prompt should not be hidden.");
|
||||
prompt.onButtonClick(0);
|
||||
|
||||
// The click is handled async; wait for an event loop turn for that to
|
||||
// happen.
|
||||
yield new Promise(function(resolve) {
|
||||
Services.tm.mainThread.dispatch(resolve, Ci.nsIThread.DISPATCH_NORMAL);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -42,6 +42,10 @@ add_task(function*() {
|
||||
// tick box and accept dialog
|
||||
checkbox.checked = true;
|
||||
ourPrompt.onButtonClick(0);
|
||||
// Wait for that click to actually be handled completely.
|
||||
yield new Promise(function(resolve) {
|
||||
Services.tm.mainThread.dispatch(resolve, Ci.nsIThread.DISPATCH_NORMAL);
|
||||
});
|
||||
// check permission is set
|
||||
let ps = Services.perms;
|
||||
is(ps.ALLOW_ACTION, ps.testPermission(makeURI(pageWithAlert), "focus-tab-by-prompt"),
|
||||
|
@ -13,7 +13,6 @@ skip-if = (debug && (os == "win" || os == "linux")) # intermittent negative leak
|
||||
[browser_eme.js]
|
||||
[browser_favicon.js]
|
||||
[browser_forgetaboutsite.js]
|
||||
[browser_newtabButton.js]
|
||||
[browser_usercontext.js]
|
||||
[browser_usercontextid_tabdrop.js]
|
||||
skip-if = os == "mac" || os == "win" # Intermittent failure - bug 1268276
|
||||
|
@ -1,34 +0,0 @@
|
||||
"use strict";
|
||||
|
||||
// Testing that when the user opens the add tab menu and clicks menu items
|
||||
// the correct context id is opened
|
||||
|
||||
add_task(function* test() {
|
||||
yield SpecialPowers.pushPrefEnv({"set": [
|
||||
["privacy.userContext.enabled", true]
|
||||
]});
|
||||
|
||||
let newTab = document.getElementById('tabbrowser-tabs');
|
||||
let newTabButton = document.getAnonymousElementByAttribute(newTab, "anonid", "tabs-newtab-button");
|
||||
ok(newTabButton, "New tab button exists");
|
||||
ok(!newTabButton.hidden, "New tab button is visible");
|
||||
let popup = document.getAnonymousElementByAttribute(newTab, "anonid", "newtab-popup");
|
||||
|
||||
for (let i = 1; i <= 4; i++) {
|
||||
let popupShownPromise = BrowserTestUtils.waitForEvent(popup, "popupshown");
|
||||
EventUtils.synthesizeMouseAtCenter(newTabButton, {type: "mousedown"});
|
||||
|
||||
yield popupShownPromise;
|
||||
let contextIdItem = popup.querySelector(`menuitem[usercontextid="${i}"]`);
|
||||
|
||||
ok(contextIdItem, `User context id ${i} exists`);
|
||||
|
||||
let waitForTabPromise = BrowserTestUtils.waitForNewTab(gBrowser);
|
||||
EventUtils.synthesizeMouseAtCenter(contextIdItem, {});
|
||||
|
||||
let tab = yield waitForTabPromise;
|
||||
|
||||
is(tab.getAttribute('usercontextid'), i, `New tab has UCI equal ${i}`);
|
||||
yield BrowserTestUtils.removeTab(tab);
|
||||
}
|
||||
});
|
@ -59,6 +59,7 @@ function* close_subdialog_and_test_generic_end_state(browser, closingFn, closing
|
||||
info("waiting for dialogclosing");
|
||||
let closingEvent =
|
||||
yield ContentTaskUtils.waitForEvent(frame.contentWindow, "dialogclosing");
|
||||
let closingButton = closingEvent.detail.button;
|
||||
let actualAcceptCount = frame.contentWindow.arguments &&
|
||||
frame.contentWindow.arguments[0].acceptCount;
|
||||
|
||||
@ -70,7 +71,7 @@ function* close_subdialog_and_test_generic_end_state(browser, closingFn, closing
|
||||
Assert.equal(frame.getAttribute("style"), "", "inline styles should be cleared");
|
||||
Assert.equal(frame.contentWindow.location.href.toString(), "about:blank",
|
||||
"sub-dialog should be unloaded");
|
||||
Assert.equal(closingEvent.detail.button, expectations.closingButton,
|
||||
Assert.equal(closingButton, expectations.closingButton,
|
||||
"closing event should indicate button was '" + expectations.closingButton + "'");
|
||||
Assert.equal(actualAcceptCount, expectations.acceptCount,
|
||||
"should be 1 if accepted, 0 if canceled, undefined if closed w/out button");
|
||||
|
@ -23,8 +23,6 @@ support-files =
|
||||
[browser_contextmenu.js]
|
||||
[browser_contextSearchTabPosition.js]
|
||||
skip-if = os == "mac" # bug 967013
|
||||
[browser_eBay.js]
|
||||
[browser_eBay_behavior.js]
|
||||
[browser_google.js]
|
||||
[browser_google_codes.js]
|
||||
[browser_google_behavior.js]
|
||||
|
@ -74,13 +74,6 @@ function test() {
|
||||
verify_about_home_search("Yahoo");
|
||||
}
|
||||
},
|
||||
{
|
||||
name: "Search with eBay from about:home",
|
||||
searchURL: replaceUrl("http://rover.ebay.com/rover/1/711-47294-18009-3/4?mfe=search&mpre=http://www.ebay.com/sch/i.html?_nkw=foo"),
|
||||
run: function () {
|
||||
verify_about_home_search("eBay");
|
||||
}
|
||||
},
|
||||
{
|
||||
name: "Search with Google from about:home",
|
||||
searchURL: replaceUrl("https://www.google.com/search?q=foo&ie=utf-8&oe=utf-8"),
|
||||
|
@ -1,83 +0,0 @@
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
/*
|
||||
* Test eBay search plugin URLs
|
||||
*/
|
||||
|
||||
"use strict";
|
||||
|
||||
const BROWSER_SEARCH_PREF = "browser.search.";
|
||||
|
||||
function test() {
|
||||
let engine = Services.search.getEngineByName("eBay");
|
||||
ok(engine, "eBay");
|
||||
|
||||
let base = "http://rover.ebay.com/rover/1/711-47294-18009-3/4?mfe=search&mpre=http://www.ebay.com/sch/i.html?_nkw=foo";
|
||||
let url;
|
||||
|
||||
// Test search URLs (including purposes).
|
||||
url = engine.getSubmission("foo").uri.spec;
|
||||
is(url, base, "Check search URL for 'foo'");
|
||||
|
||||
// Check search suggestion URL.
|
||||
url = engine.getSubmission("foo", "application/x-suggestions+json").uri.spec;
|
||||
is(url, "http://autosug.ebay.com/autosug?sId=0&kwd=foo&fmt=osr", "Check search suggestion URL for 'foo'");
|
||||
|
||||
// Check all other engine properties.
|
||||
const EXPECTED_ENGINE = {
|
||||
name: "eBay",
|
||||
alias: null,
|
||||
description: "eBay - Online auctions",
|
||||
searchForm: "http://search.ebay.com/",
|
||||
hidden: false,
|
||||
wrappedJSObject: {
|
||||
queryCharset: "ISO-8859-1",
|
||||
"_iconURL": "data:image/x-icon;base64,AAABAAIAEBAAAAAAAAB6AQAAJgAAACAgAAAAAAAAQgMAAKABAACJUE5HDQoaCgAAAA1JSERSAAAAEAAAABAIBgAAAB/z/2EAAAFBSURBVDjLtZPdK0MBGIf3J5Babhx3rinFBWuipaUskX9DYvkopqgV90q5UJpyp0OKrUWM2VrRsS9D0zZKHGaOnW1nj4vtypVtPPe/533r9746QAAOAJXfo5Yzgg44pHrcugon/6Sgo0b+XuAOZ2iZiVQmyPoDpIwmUkYTzqM7GsdDdC7F6Lbf8pzOkfWOouzqeZem2b+2AqAV8zjD8yVBqqcf2b7C66yNiMGMfixIQSvi8Mp0LEbR5ADq1QSKWM+Gx0RC9nOZ2GLzwlIWdPWiuNzk4w/EpThNkyEAXKEP2ud8KGId2sspilhPMrmNwzfCuqePr/xbSfC5I/I0MMSj2YJ3z49gDdO2cEOrLUowJpE9G0QRG1ClKbR0EIdvmOPYcnUtnN+vsnZiQC1k/qnGagQ1n3LNzySUJZVskitnmr8BlQG7T2hvgxsAAAAASUVORK5CYIKJUE5HDQoaCgAAAA1JSERSAAAAIAAAACAIBgAAAHN6evQAAAMJSURBVFjD7ZddSFNhGMeHXXQTZFFCWfR1pRhUECQlBdWVToo+6KYu1KigtDASG5qUfZgFZvahEDosECPDktKZS1FL+1DRnEvdUptjug91X2dnZzv/3vO6OZbWnR4v9sADL+fs7P97/s/znu2VAJD4UkpSSdKG+QubTyPBr+sXz8XCR64fIAHihVTis0SsUAoAVhEBrBKIHCGAEMB/ARi3F5LkbpS2WMRzYEEBXC2tsD6T03R9agsCGLNyqPw6CXmrBT06JvhbPHZwmkdwtR0B138PPKOHgzXD5jLAy3tmibo4K9weZwDAazJj/FQKRnfugfHMeRiTz0K3Ixam1HQKcPC+Fisu9NK1P08Uj4DleHgMdXC+WQ7nu3UEOhFMfTQcVUvQ1H4IN2sj8H2k7K+2TqCc3GseyA8AmDOzMBq7D9bS8sAr6nEJdNt3UbHVF1XQGtmZew8bTPT6tWoD3KpsUvlR8NxUoEICMvl6KQo+xqCwcRs4T8Ax5c8bFExjbAgAjO7aS8VsLypgq3g5nWStjztAhWRVhqAqeB6IuKTClkw1eNYEbrCQQBwD8yGGOsAooogLYejQPKBi7UPF9DkH+ezd+o141ZkUPAOC+L9SAMivNc7q46YMNSLTe4n1kaQF4XD3ZIDTPgU3XEYciKcAHrsGJS1xKFBGgyVzouiT4VbdGhjt/cEA5isyKsaz7jl3we7bg7Rqf6j0LoSldON4wWcqJDgQNGTN++l13vELA+MK6kKd6iryFOvxtidt9i5gO7owdjKJQliflNAU1pas6xQgnAzg1ux+lJEdILixNr0Pq9JUUA8NwVG9DM73G0jlcnh+V4BpjIWzJmIGQIjnXw5TiDuKSEwxurm3ITc8DNO51BnrLbIcsrW0dNA6RxgUKU1UdGVqLy5X6qGzTLvlnewiBZyGs3Yz6X8UeaYI3olvZDhzwLumZ+eHvooCCC0Q5VUsb4unwycM4YIDqA01tPqmgbzQr2EIYPECiPm33LYoDiZSsY9moh9O/Znoa4d9HkXtPg2pX/cPKCoRQ+ocZa4AAAAASUVORK5CYII=",
|
||||
_urls : [
|
||||
{
|
||||
type: "application/x-suggestions+json",
|
||||
method: "GET",
|
||||
template: "http://autosug.ebay.com/autosug",
|
||||
params: [
|
||||
{
|
||||
name: "sId",
|
||||
value: "0",
|
||||
purpose: undefined,
|
||||
},
|
||||
{
|
||||
name: "kwd",
|
||||
value: "{searchTerms}",
|
||||
purpose: undefined,
|
||||
},
|
||||
{
|
||||
name: "fmt",
|
||||
value: "osr",
|
||||
purpose: undefined,
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
type: "text/html",
|
||||
method: "GET",
|
||||
template: "http://rover.ebay.com/rover/1/711-47294-18009-3/4",
|
||||
params: [
|
||||
{
|
||||
name: "mfe",
|
||||
value: "search",
|
||||
purpose: undefined,
|
||||
},
|
||||
{
|
||||
name: "mpre",
|
||||
value: "http://www.ebay.com/sch/i.html?_nkw={searchTerms}",
|
||||
purpose: undefined,
|
||||
},
|
||||
],
|
||||
mozparams: {},
|
||||
},
|
||||
],
|
||||
},
|
||||
};
|
||||
|
||||
isSubObjectOf(EXPECTED_ENGINE, engine, "eBay");
|
||||
}
|
@ -1,166 +0,0 @@
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
/*
|
||||
* Test eBay search plugin URLs
|
||||
*/
|
||||
|
||||
"use strict";
|
||||
|
||||
const BROWSER_SEARCH_PREF = "browser.search.";
|
||||
|
||||
|
||||
function test() {
|
||||
let engine = Services.search.getEngineByName("eBay");
|
||||
ok(engine, "eBay is installed");
|
||||
|
||||
let previouslySelectedEngine = Services.search.currentEngine;
|
||||
Services.search.currentEngine = engine;
|
||||
engine.alias = 'e';
|
||||
|
||||
let base = "http://rover.ebay.com/rover/1/711-47294-18009-3/4?mfe=search&mpre=http://www.ebay.com/sch/i.html?_nkw=foo";
|
||||
let url;
|
||||
|
||||
// Test search URLs (including purposes).
|
||||
url = engine.getSubmission("foo").uri.spec;
|
||||
is(url, base, "Check search URL for 'foo'");
|
||||
|
||||
waitForExplicitFinish();
|
||||
|
||||
var gCurrTest;
|
||||
var gTests = [
|
||||
{
|
||||
name: "context menu search",
|
||||
searchURL: base,
|
||||
run: function () {
|
||||
// Simulate a contextmenu search
|
||||
// FIXME: This is a bit "low-level"...
|
||||
BrowserSearch.loadSearch("foo", false, "contextmenu");
|
||||
}
|
||||
},
|
||||
{
|
||||
name: "keyword search",
|
||||
searchURL: base,
|
||||
run: function () {
|
||||
gURLBar.value = "? foo";
|
||||
gURLBar.focus();
|
||||
EventUtils.synthesizeKey("VK_RETURN", {});
|
||||
}
|
||||
},
|
||||
{
|
||||
name: "keyword search",
|
||||
searchURL: base,
|
||||
run: function () {
|
||||
gURLBar.value = "e foo";
|
||||
gURLBar.focus();
|
||||
EventUtils.synthesizeKey("VK_RETURN", {});
|
||||
}
|
||||
},
|
||||
{
|
||||
name: "search bar search",
|
||||
searchURL: base,
|
||||
run: function () {
|
||||
let sb = BrowserSearch.searchBar;
|
||||
sb.focus();
|
||||
sb.value = "foo";
|
||||
registerCleanupFunction(function () {
|
||||
sb.value = "";
|
||||
});
|
||||
EventUtils.synthesizeKey("VK_RETURN", {});
|
||||
}
|
||||
},
|
||||
{
|
||||
name: "new tab search",
|
||||
searchURL: base,
|
||||
run: function () {
|
||||
function doSearch(doc) {
|
||||
// Re-add the listener, and perform a search
|
||||
gBrowser.addProgressListener(listener);
|
||||
doc.getElementById("newtab-search-text").value = "foo";
|
||||
doc.getElementById("newtab-search-submit").click();
|
||||
}
|
||||
|
||||
// load about:newtab, but remove the listener first so it doesn't
|
||||
// get in the way
|
||||
gBrowser.removeProgressListener(listener);
|
||||
gBrowser.loadURI("about:newtab");
|
||||
info("Waiting for about:newtab load");
|
||||
tab.linkedBrowser.addEventListener("load", function load(event) {
|
||||
if (event.originalTarget != tab.linkedBrowser.contentDocument ||
|
||||
event.target.location.href == "about:blank") {
|
||||
info("skipping spurious load event");
|
||||
return;
|
||||
}
|
||||
tab.linkedBrowser.removeEventListener("load", load, true);
|
||||
|
||||
// Observe page setup
|
||||
let win = gBrowser.contentWindow;
|
||||
if (win.gSearch.currentEngineName ==
|
||||
Services.search.currentEngine.name) {
|
||||
doSearch(win.document);
|
||||
}
|
||||
else {
|
||||
info("Waiting for newtab search init");
|
||||
win.addEventListener("ContentSearchService", function done(event) {
|
||||
info("Got newtab search event " + event.detail.type);
|
||||
if (event.detail.type == "State") {
|
||||
win.removeEventListener("ContentSearchService", done);
|
||||
// Let gSearch respond to the event before continuing.
|
||||
executeSoon(() => doSearch(win.document));
|
||||
}
|
||||
});
|
||||
}
|
||||
}, true);
|
||||
}
|
||||
}
|
||||
];
|
||||
|
||||
function nextTest() {
|
||||
if (gTests.length) {
|
||||
gCurrTest = gTests.shift();
|
||||
info("Running : " + gCurrTest.name);
|
||||
executeSoon(gCurrTest.run);
|
||||
} else {
|
||||
finish();
|
||||
}
|
||||
}
|
||||
|
||||
let tab = gBrowser.selectedTab = gBrowser.addTab();
|
||||
|
||||
let listener = {
|
||||
onStateChange: function onStateChange(webProgress, req, flags, status) {
|
||||
info("onStateChange");
|
||||
// Only care about top-level document starts
|
||||
let docStart = Ci.nsIWebProgressListener.STATE_IS_DOCUMENT |
|
||||
Ci.nsIWebProgressListener.STATE_START;
|
||||
if (!(flags & docStart) || !webProgress.isTopLevel)
|
||||
return;
|
||||
|
||||
if (req.originalURI.spec == "about:blank")
|
||||
return;
|
||||
|
||||
info("received document start");
|
||||
|
||||
ok(req instanceof Ci.nsIChannel, "req is a channel");
|
||||
is(req.originalURI.spec, gCurrTest.searchURL, "search URL was loaded");
|
||||
info("Actual URI: " + req.URI.spec);
|
||||
|
||||
req.cancel(Components.results.NS_ERROR_FAILURE);
|
||||
|
||||
executeSoon(nextTest);
|
||||
}
|
||||
}
|
||||
|
||||
registerCleanupFunction(function () {
|
||||
engine.alias = undefined;
|
||||
gBrowser.removeProgressListener(listener);
|
||||
gBrowser.removeTab(tab);
|
||||
Services.search.currentEngine = previouslySelectedEngine;
|
||||
});
|
||||
|
||||
tab.linkedBrowser.addEventListener("load", function load() {
|
||||
tab.linkedBrowser.removeEventListener("load", load, true);
|
||||
gBrowser.addProgressListener(listener);
|
||||
nextTest();
|
||||
}, true);
|
||||
}
|
@ -743,3 +743,5 @@ decoder.noCodecsXP.message = To play video, you may need to enable Adobe’s Pri
|
||||
decoder.noCodecsLinux.message = To play video, you may need to install the required video codecs.
|
||||
decoder.noHWAcceleration.message = To improve video quality, you may need to install Microsoft’s Media Feature Pack.
|
||||
decoder.noHWAccelerationVista.message = To improve video quality, you may need to install Microsoft’s Platform Update Supplement for Windows Vista.
|
||||
|
||||
permissions.remove.tooltip = Clear this permission and ask again
|
||||
|
@ -1,20 +0,0 @@
|
||||
<!-- 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/. -->
|
||||
|
||||
<SearchPlugin xmlns="http://www.mozilla.org/2006/browser/search/">
|
||||
<ShortName>eBay</ShortName>
|
||||
<Description>eBay - Online auctions</Description>
|
||||
<InputEncoding>ISO-8859-1</InputEncoding>
|
||||
<Image width="16" height="16">data:image/x-icon;base64,AAABAAIAEBAAAAAAAAB6AQAAJgAAACAgAAAAAAAAQgMAAKABAACJUE5HDQoaCgAAAA1JSERSAAAAEAAAABAIBgAAAB/z/2EAAAFBSURBVDjLtZPdK0MBGIf3J5Babhx3rinFBWuipaUskX9DYvkopqgV90q5UJpyp0OKrUWM2VrRsS9D0zZKHGaOnW1nj4vtypVtPPe/533r9746QAAOAJXfo5Yzgg44pHrcugon/6Sgo0b+XuAOZ2iZiVQmyPoDpIwmUkYTzqM7GsdDdC7F6Lbf8pzOkfWOouzqeZem2b+2AqAV8zjD8yVBqqcf2b7C66yNiMGMfixIQSvi8Mp0LEbR5ADq1QSKWM+Gx0RC9nOZ2GLzwlIWdPWiuNzk4w/EpThNkyEAXKEP2ud8KGId2sspilhPMrmNwzfCuqePr/xbSfC5I/I0MMSj2YJ3z49gDdO2cEOrLUowJpE9G0QRG1ClKbR0EIdvmOPYcnUtnN+vsnZiQC1k/qnGagQ1n3LNzySUJZVskitnmr8BlQG7T2hvgxsAAAAASUVORK5CYIKJUE5HDQoaCgAAAA1JSERSAAAAIAAAACAIBgAAAHN6evQAAAMJSURBVFjD7ZddSFNhGMeHXXQTZFFCWfR1pRhUECQlBdWVToo+6KYu1KigtDASG5qUfZgFZvahEDosECPDktKZS1FL+1DRnEvdUptjug91X2dnZzv/3vO6OZbWnR4v9sADL+fs7P97/s/znu2VAJD4UkpSSdKG+QubTyPBr+sXz8XCR64fIAHihVTis0SsUAoAVhEBrBKIHCGAEMB/ARi3F5LkbpS2WMRzYEEBXC2tsD6T03R9agsCGLNyqPw6CXmrBT06JvhbPHZwmkdwtR0B138PPKOHgzXD5jLAy3tmibo4K9weZwDAazJj/FQKRnfugfHMeRiTz0K3Ixam1HQKcPC+Fisu9NK1P08Uj4DleHgMdXC+WQ7nu3UEOhFMfTQcVUvQ1H4IN2sj8H2k7K+2TqCc3GseyA8AmDOzMBq7D9bS8sAr6nEJdNt3UbHVF1XQGtmZew8bTPT6tWoD3KpsUvlR8NxUoEICMvl6KQo+xqCwcRs4T8Ax5c8bFExjbAgAjO7aS8VsLypgq3g5nWStjztAhWRVhqAqeB6IuKTClkw1eNYEbrCQQBwD8yGGOsAooogLYejQPKBi7UPF9DkH+ezd+o141ZkUPAOC+L9SAMivNc7q46YMNSLTe4n1kaQF4XD3ZIDTPgU3XEYciKcAHrsGJS1xKFBGgyVzouiT4VbdGhjt/cEA5isyKsaz7jl3we7bg7Rqf6j0LoSldON4wWcqJDgQNGTN++l13vELA+MK6kKd6iryFOvxtidt9i5gO7owdjKJQliflNAU1pas6xQgnAzg1ux+lJEdILixNr0Pq9JUUA8NwVG9DM73G0jlcnh+V4BpjIWzJmIGQIjnXw5TiDuKSEwxurm3ITc8DNO51BnrLbIcsrW0dNA6RxgUKU1UdGVqLy5X6qGzTLvlnewiBZyGs3Yz6X8UeaYI3olvZDhzwLumZ+eHvooCCC0Q5VUsb4unwycM4YIDqA01tPqmgbzQr2EIYPECiPm33LYoDiZSsY9moh9O/Znoa4d9HkXtPg2pX/cPKCoRQ+ocZa4AAAAASUVORK5CYII=</Image>
|
||||
<Url type="application/x-suggestions+json" method="GET" template="http://autosug.ebay.com/autosug">
|
||||
<Param name="sId" value="0" />
|
||||
<Param name="kwd" value="{searchTerms}" />
|
||||
<Param name="fmt" value="osr" />
|
||||
</Url>
|
||||
<Url type="text/html" method="GET" template="http://rover.ebay.com/rover/1/711-47294-18009-3/4" resultdomain="ebay.com">
|
||||
<Param name="mfe" value="search" />
|
||||
<Param name="mpre" value="http://www.ebay.com/sch/i.html?_nkw={searchTerms}" />
|
||||
</Url>
|
||||
<SearchForm>http://search.ebay.com/</SearchForm>
|
||||
</SearchPlugin>
|
@ -1,6 +1,5 @@
|
||||
amazondotcom
|
||||
bing
|
||||
eBay
|
||||
google
|
||||
twitter
|
||||
wikipedia
|
||||
|
@ -396,7 +396,9 @@ this.ContentSearch = {
|
||||
if (methodName in this) {
|
||||
yield this._initService();
|
||||
yield this[methodName](msg, msg.data.data);
|
||||
msg.target.removeEventListener("SwapDocShells", msg, true);
|
||||
if (!Cu.isDeadWrapper(msg.target)) {
|
||||
msg.target.removeEventListener("SwapDocShells", msg, true);
|
||||
}
|
||||
}
|
||||
}),
|
||||
|
||||
@ -489,7 +491,7 @@ this.ContentSearch = {
|
||||
_reply: function (msg, type, data) {
|
||||
// We reply asyncly to messages, and by the time we reply the browser we're
|
||||
// responding to may have been destroyed. messageManager is null then.
|
||||
if (msg.target.messageManager) {
|
||||
if (!Cu.isDeadWrapper(msg.target) && msg.target.messageManager) {
|
||||
msg.target.messageManager.sendAsyncMessage(...this._msgArgs(type, data));
|
||||
}
|
||||
},
|
||||
|
@ -254,6 +254,14 @@ interface nsIScriptSecurityManager : nsISupports
|
||||
*/
|
||||
nsIPrincipal getChannelURIPrincipal(in nsIChannel aChannel);
|
||||
|
||||
/**
|
||||
* Get the principal for a sandbox object.
|
||||
*
|
||||
* This function is currently only used in tests.
|
||||
*/
|
||||
[implicit_jscontext]
|
||||
nsIPrincipal getSandboxPrincipal(in jsval aSandbox);
|
||||
|
||||
/**
|
||||
* Check whether a given principal is a system principal. This allows us
|
||||
* to avoid handing back the system principal to script while allowing
|
||||
|
@ -674,7 +674,14 @@ struct OriginComparator
|
||||
}
|
||||
};
|
||||
|
||||
nsExpandedPrincipal::nsExpandedPrincipal(nsTArray<nsCOMPtr <nsIPrincipal> > &aWhiteList)
|
||||
nsExpandedPrincipal::nsExpandedPrincipal(nsTArray<nsCOMPtr<nsIPrincipal>> &aWhiteList,
|
||||
const PrincipalOriginAttributes& aOriginAttributes)
|
||||
: nsExpandedPrincipal(aWhiteList)
|
||||
{
|
||||
mOriginAttributes = aOriginAttributes;
|
||||
}
|
||||
|
||||
nsExpandedPrincipal::nsExpandedPrincipal(nsTArray<nsCOMPtr<nsIPrincipal>> &aWhiteList)
|
||||
{
|
||||
// We force the principals to be sorted by origin so that nsExpandedPrincipal
|
||||
// origins can have a canonical form.
|
||||
|
@ -67,7 +67,9 @@ protected:
|
||||
class nsExpandedPrincipal : public nsIExpandedPrincipal, public mozilla::BasePrincipal
|
||||
{
|
||||
public:
|
||||
explicit nsExpandedPrincipal(nsTArray< nsCOMPtr<nsIPrincipal> > &aWhiteList);
|
||||
nsExpandedPrincipal(nsTArray<nsCOMPtr<nsIPrincipal>> &aWhiteList,
|
||||
const mozilla::PrincipalOriginAttributes& aOriginAttributes);
|
||||
explicit nsExpandedPrincipal(nsTArray<nsCOMPtr<nsIPrincipal>> &aWhiteList);
|
||||
|
||||
NS_DECL_NSIEXPANDEDPRINCIPAL
|
||||
NS_DECL_NSISERIALIZABLE
|
||||
|
@ -67,6 +67,7 @@
|
||||
#include "nsJSUtils.h"
|
||||
#include "nsILoadInfo.h"
|
||||
#include "nsXPCOMStrings.h"
|
||||
#include "xpcprivate.h"
|
||||
|
||||
// This should be probably defined on some other place... but I couldn't find it
|
||||
#define WEBAPPS_PERM_NAME "webapps-manage"
|
||||
@ -256,8 +257,10 @@ nsScriptSecurityManager::AppStatusForPrincipal(nsIPrincipal *aPrin)
|
||||
// mozbrowser frames.
|
||||
bool inIsolatedMozBrowser = aPrin->GetIsInIsolatedMozBrowserElement();
|
||||
|
||||
NS_WARN_IF_FALSE(appId != nsIScriptSecurityManager::UNKNOWN_APP_ID,
|
||||
"Asking for app status on a principal with an unknown app id");
|
||||
NS_WARNING_ASSERTION(
|
||||
appId != nsIScriptSecurityManager::UNKNOWN_APP_ID,
|
||||
"Asking for app status on a principal with an unknown app id");
|
||||
|
||||
// Installed apps have a valid app id (not NO_APP_ID or UNKNOWN_APP_ID)
|
||||
// and they are not inside a mozbrowser.
|
||||
if (appId == nsIScriptSecurityManager::NO_APP_ID ||
|
||||
@ -472,6 +475,18 @@ nsScriptSecurityManager::GetChannelURIPrincipal(nsIChannel* aChannel,
|
||||
return *aPrincipal ? NS_OK : NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsScriptSecurityManager::GetSandboxPrincipal(JS::HandleValue aSandboxArg,
|
||||
JSContext* aCx,
|
||||
nsIPrincipal** aPrincipal)
|
||||
{
|
||||
if (!aSandboxArg.isObject()) {
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
}
|
||||
JS::RootedObject sandbox(aCx, &aSandboxArg.toObject());
|
||||
return xpc::GetSandboxPrincipal(aCx, sandbox, aPrincipal);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsScriptSecurityManager::IsSystemPrincipal(nsIPrincipal* aPrincipal,
|
||||
bool* aIsSystem)
|
||||
|
@ -139,9 +139,8 @@ nsChromeProtocolHandler::NewChannel2(nsIURI* aURI,
|
||||
rv = nsChromeRegistry::gChromeRegistry->ConvertChromeURL(aURI, getter_AddRefs(resolvedURI));
|
||||
if (NS_FAILED(rv)) {
|
||||
#ifdef DEBUG
|
||||
nsAutoCString spec;
|
||||
aURI->GetSpec(spec);
|
||||
printf("Couldn't convert chrome URL: %s\n", spec.get());
|
||||
printf("Couldn't convert chrome URL: %s\n",
|
||||
aURI->GetSpecOrDefault().get());
|
||||
#endif
|
||||
return rv;
|
||||
}
|
||||
|
@ -453,7 +453,8 @@ nsChromeRegistryChrome::SendRegisteredChrome(
|
||||
DebugOnly<bool> success =
|
||||
parents[i]->SendRegisterChrome(packages, resources, overrides,
|
||||
mSelectedLocale, true);
|
||||
NS_WARN_IF_FALSE(success, "couldn't reset a child's registered chrome");
|
||||
NS_WARNING_ASSERTION(success,
|
||||
"couldn't reset a child's registered chrome");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -48,6 +48,7 @@ const ErrorDocs = {
|
||||
JSMSG_UNTERMINATED_STRING: "Unterminated_string_literal",
|
||||
JSMSG_NOT_CONSTRUCTOR: "Not_a_constructor",
|
||||
JSMSG_CURLY_AFTER_LIST: "Missing_curly_after_property_list",
|
||||
JSMSG_DEPRECATED_FOR_EACH: "For-each-in_loops_are_deprecated",
|
||||
};
|
||||
|
||||
const MIXED_CONTENT_LEARN_MORE = "https://developer.mozilla.org/docs/Web/Security/Mixed_content";
|
||||
|
@ -1877,11 +1877,8 @@ nsDocShell::SetCurrentURI(nsIURI* aURI, nsIRequest* aRequest,
|
||||
bool aFireOnLocationChange, uint32_t aLocationFlags)
|
||||
{
|
||||
if (gDocShellLeakLog && MOZ_LOG_TEST(gDocShellLeakLog, LogLevel::Debug)) {
|
||||
nsAutoCString spec;
|
||||
if (aURI) {
|
||||
aURI->GetSpec(spec);
|
||||
}
|
||||
PR_LogPrint("DOCSHELL %p SetCurrentURI %s\n", this, spec.get());
|
||||
PR_LogPrint("DOCSHELL %p SetCurrentURI %s\n",
|
||||
this, aURI ? aURI->GetSpecOrDefault().get() : "");
|
||||
}
|
||||
|
||||
// We don't want to send a location change when we're displaying an error
|
||||
@ -5249,9 +5246,6 @@ nsDocShell::LoadErrorPage(nsIURI* aURI, const char16_t* aURL,
|
||||
{
|
||||
#if defined(DEBUG)
|
||||
if (MOZ_LOG_TEST(gDocShellLog, LogLevel::Debug)) {
|
||||
nsAutoCString spec;
|
||||
aURI->GetSpec(spec);
|
||||
|
||||
nsAutoCString chanName;
|
||||
if (aFailedChannel) {
|
||||
aFailedChannel->GetName(chanName);
|
||||
@ -5261,7 +5255,8 @@ nsDocShell::LoadErrorPage(nsIURI* aURI, const char16_t* aURL,
|
||||
|
||||
MOZ_LOG(gDocShellLog, LogLevel::Debug,
|
||||
("nsDocShell[%p]::LoadErrorPage(\"%s\", \"%s\", {...}, [%s])\n", this,
|
||||
spec.get(), NS_ConvertUTF16toUTF8(aURL).get(), chanName.get()));
|
||||
aURI->GetSpecOrDefault().get(), NS_ConvertUTF16toUTF8(aURL).get(),
|
||||
chanName.get()));
|
||||
}
|
||||
#endif
|
||||
mFailedChannel = aFailedChannel;
|
||||
@ -6336,9 +6331,9 @@ nsDocShell::SetMixedContentChannel(nsIChannel* aMixedContentChannel)
|
||||
// Get the root docshell.
|
||||
nsCOMPtr<nsIDocShellTreeItem> root;
|
||||
GetSameTypeRootTreeItem(getter_AddRefs(root));
|
||||
NS_WARN_IF_FALSE(root.get() == static_cast<nsIDocShellTreeItem*>(this),
|
||||
"Setting mMixedContentChannel on a docshell that is not "
|
||||
"the root docshell");
|
||||
NS_WARNING_ASSERTION(root.get() == static_cast<nsIDocShellTreeItem*>(this),
|
||||
"Setting mMixedContentChannel on a docshell that is "
|
||||
"not the root docshell");
|
||||
}
|
||||
#endif
|
||||
mMixedContentChannel = aMixedContentChannel;
|
||||
@ -9718,11 +9713,8 @@ nsDocShell::InternalLoad(nsIURI* aURI,
|
||||
mOriginalUriString.Truncate();
|
||||
|
||||
if (gDocShellLeakLog && MOZ_LOG_TEST(gDocShellLeakLog, LogLevel::Debug)) {
|
||||
nsAutoCString spec;
|
||||
if (aURI) {
|
||||
aURI->GetSpec(spec);
|
||||
}
|
||||
PR_LogPrint("DOCSHELL %p InternalLoad %s\n", this, spec.get());
|
||||
PR_LogPrint("DOCSHELL %p InternalLoad %s\n",
|
||||
this, aURI ? aURI->GetSpecOrDefault().get() : "");
|
||||
}
|
||||
// Initialize aDocShell/aRequest
|
||||
if (aDocShell) {
|
||||
@ -11433,9 +11425,6 @@ nsDocShell::OnNewURI(nsIURI* aURI, nsIChannel* aChannel,
|
||||
|
||||
#if defined(DEBUG)
|
||||
if (MOZ_LOG_TEST(gDocShellLog, LogLevel::Debug)) {
|
||||
nsAutoCString spec;
|
||||
aURI->GetSpec(spec);
|
||||
|
||||
nsAutoCString chanName;
|
||||
if (aChannel) {
|
||||
aChannel->GetName(chanName);
|
||||
@ -11444,8 +11433,8 @@ nsDocShell::OnNewURI(nsIURI* aURI, nsIChannel* aChannel,
|
||||
}
|
||||
|
||||
MOZ_LOG(gDocShellLog, LogLevel::Debug,
|
||||
("nsDocShell[%p]::OnNewURI(\"%s\", [%s], 0x%x)\n", this, spec.get(),
|
||||
chanName.get(), aLoadType));
|
||||
("nsDocShell[%p]::OnNewURI(\"%s\", [%s], 0x%x)\n",
|
||||
this, aURI->GetSpecOrDefault().get(), chanName.get(), aLoadType));
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -12079,9 +12068,6 @@ nsDocShell::AddToSessionHistory(nsIURI* aURI, nsIChannel* aChannel,
|
||||
|
||||
#if defined(DEBUG)
|
||||
if (MOZ_LOG_TEST(gDocShellLog, LogLevel::Debug)) {
|
||||
nsAutoCString spec;
|
||||
aURI->GetSpec(spec);
|
||||
|
||||
nsAutoCString chanName;
|
||||
if (aChannel) {
|
||||
aChannel->GetName(chanName);
|
||||
@ -12090,8 +12076,8 @@ nsDocShell::AddToSessionHistory(nsIURI* aURI, nsIChannel* aChannel,
|
||||
}
|
||||
|
||||
MOZ_LOG(gDocShellLog, LogLevel::Debug,
|
||||
("nsDocShell[%p]::AddToSessionHistory(\"%s\", [%s])\n",
|
||||
this, spec.get(), chanName.get()));
|
||||
("nsDocShell[%p]::AddToSessionHistory(\"%s\", [%s])\n",
|
||||
this, aURI->GetSpecOrDefault().get(), chanName.get()));
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -12887,7 +12873,7 @@ nsDocShell::ExtractLastVisit(nsIChannel* aChannel,
|
||||
rv = props->GetPropertyAsUint32(NS_LITERAL_STRING("docshell.previousFlags"),
|
||||
aChannelRedirectFlags);
|
||||
|
||||
NS_WARN_IF_FALSE(
|
||||
NS_WARNING_ASSERTION(
|
||||
NS_SUCCEEDED(rv),
|
||||
"Could not fetch previous flags, URI will be treated like referrer");
|
||||
}
|
||||
@ -14241,8 +14227,7 @@ nsDocShell::SetOriginAttributes(const DocShellOriginAttributes& aAttrs)
|
||||
if (!uri) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
nsAutoCString uriSpec;
|
||||
uri->GetSpec(uriSpec);
|
||||
nsCString uriSpec = uri->GetSpecOrDefault();
|
||||
MOZ_ASSERT(uriSpec.EqualsLiteral("about:blank"));
|
||||
if (!uriSpec.EqualsLiteral("about:blank")) {
|
||||
return NS_ERROR_FAILURE;
|
||||
@ -14471,8 +14456,7 @@ nsDocShell::ShouldPrepareForIntercept(nsIURI* aURI, bool aIsNonSubresourceReques
|
||||
if (mCurrentURI &&
|
||||
nsContentUtils::CookiesBehavior() == nsICookieService::BEHAVIOR_REJECT_FOREIGN) {
|
||||
nsAutoCString uriSpec;
|
||||
mCurrentURI->GetSpec(uriSpec);
|
||||
if (!(uriSpec.EqualsLiteral("about:blank"))) {
|
||||
if (!(mCurrentURI->GetSpecOrDefault().EqualsLiteral("about:blank"))) {
|
||||
// Reject the interception of third-party iframes if the cookie behaviour
|
||||
// is set to reject all third-party cookies (1). In case that this pref
|
||||
// is not set or can't be read, we default to allow all cookies (0) as
|
||||
|
@ -74,7 +74,7 @@ static LazyLogModule gSHistoryLog("nsSHistory");
|
||||
if (MOZ_LOG_TEST(gSHistoryLog, LogLevel::Debug)) { \
|
||||
nsAutoCString _specStr(NS_LITERAL_CSTRING("(null)"));\
|
||||
if (uri) { \
|
||||
uri->GetSpec(_specStr); \
|
||||
_specStr = uri->GetSpecOrDefault(); \
|
||||
} \
|
||||
const char* _spec = _specStr.get(); \
|
||||
LOG(format); \
|
||||
|
@ -5,17 +5,155 @@
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "mozilla/dom/CustomElementsRegistry.h"
|
||||
|
||||
#include "mozilla/dom/CustomElementsRegistryBinding.h"
|
||||
#include "mozilla/dom/HTMLElementBinding.h"
|
||||
#include "mozilla/dom/WebComponentsBinding.h"
|
||||
#include "nsIParserService.h"
|
||||
#include "jsapi.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
|
||||
void
|
||||
CustomElementCallback::Call()
|
||||
{
|
||||
ErrorResult rv;
|
||||
switch (mType) {
|
||||
case nsIDocument::eCreated:
|
||||
{
|
||||
// For the duration of this callback invocation, the element is being created
|
||||
// flag must be set to true.
|
||||
mOwnerData->mElementIsBeingCreated = true;
|
||||
|
||||
// The callback hasn't actually been invoked yet, but we need to flip
|
||||
// this now in order to enqueue the attached callback. This is a spec
|
||||
// bug (w3c bug 27437).
|
||||
mOwnerData->mCreatedCallbackInvoked = true;
|
||||
|
||||
// If ELEMENT is in a document and this document has a browsing context,
|
||||
// enqueue attached callback for ELEMENT.
|
||||
nsIDocument* document = mThisObject->GetComposedDoc();
|
||||
if (document && document->GetDocShell()) {
|
||||
nsContentUtils::EnqueueLifecycleCallback(
|
||||
document, nsIDocument::eAttached, mThisObject);
|
||||
}
|
||||
|
||||
static_cast<LifecycleCreatedCallback *>(mCallback.get())->Call(mThisObject, rv);
|
||||
mOwnerData->mElementIsBeingCreated = false;
|
||||
break;
|
||||
}
|
||||
case nsIDocument::eAttached:
|
||||
static_cast<LifecycleAttachedCallback *>(mCallback.get())->Call(mThisObject, rv);
|
||||
break;
|
||||
case nsIDocument::eDetached:
|
||||
static_cast<LifecycleDetachedCallback *>(mCallback.get())->Call(mThisObject, rv);
|
||||
break;
|
||||
case nsIDocument::eAttributeChanged:
|
||||
static_cast<LifecycleAttributeChangedCallback *>(mCallback.get())->Call(mThisObject,
|
||||
mArgs.name, mArgs.oldValue, mArgs.newValue, rv);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
CustomElementCallback::Traverse(nsCycleCollectionTraversalCallback& aCb) const
|
||||
{
|
||||
NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(aCb, "mThisObject");
|
||||
aCb.NoteXPCOMChild(mThisObject);
|
||||
|
||||
NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(aCb, "mCallback");
|
||||
aCb.NoteXPCOMChild(mCallback);
|
||||
}
|
||||
|
||||
CustomElementCallback::CustomElementCallback(Element* aThisObject,
|
||||
nsIDocument::ElementCallbackType aCallbackType,
|
||||
mozilla::dom::CallbackFunction* aCallback,
|
||||
CustomElementData* aOwnerData)
|
||||
: mThisObject(aThisObject),
|
||||
mCallback(aCallback),
|
||||
mType(aCallbackType),
|
||||
mOwnerData(aOwnerData)
|
||||
{
|
||||
}
|
||||
|
||||
CustomElementData::CustomElementData(nsIAtom* aType)
|
||||
: mType(aType),
|
||||
mCurrentCallback(-1),
|
||||
mElementIsBeingCreated(false),
|
||||
mCreatedCallbackInvoked(true),
|
||||
mAssociatedMicroTask(-1)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
CustomElementData::RunCallbackQueue()
|
||||
{
|
||||
// Note: It's possible to re-enter this method.
|
||||
while (static_cast<uint32_t>(++mCurrentCallback) < mCallbackQueue.Length()) {
|
||||
mCallbackQueue[mCurrentCallback]->Call();
|
||||
}
|
||||
|
||||
mCallbackQueue.Clear();
|
||||
mCurrentCallback = -1;
|
||||
}
|
||||
|
||||
// Only needed for refcounted objects.
|
||||
NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(CustomElementsRegistry, mWindow)
|
||||
NS_IMPL_CYCLE_COLLECTION_CLASS(CustomElementsRegistry)
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(CustomElementsRegistry)
|
||||
tmp->mCustomDefinitions.Clear();
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK(mWindow)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_PRESERVED_WRAPPER
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(CustomElementsRegistry)
|
||||
for (auto iter = tmp->mCustomDefinitions.Iter(); !iter.Done(); iter.Next()) {
|
||||
nsAutoPtr<LifecycleCallbacks>& callbacks = iter.UserData()->mCallbacks;
|
||||
|
||||
if (callbacks->mAttributeChangedCallback.WasPassed()) {
|
||||
NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb,
|
||||
"mCustomDefinitions->mCallbacks->mAttributeChangedCallback");
|
||||
cb.NoteXPCOMChild(callbacks->mAttributeChangedCallback.Value());
|
||||
}
|
||||
|
||||
if (callbacks->mCreatedCallback.WasPassed()) {
|
||||
NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb,
|
||||
"mCustomDefinitions->mCallbacks->mCreatedCallback");
|
||||
cb.NoteXPCOMChild(callbacks->mCreatedCallback.Value());
|
||||
}
|
||||
|
||||
if (callbacks->mAttachedCallback.WasPassed()) {
|
||||
NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb,
|
||||
"mCustomDefinitions->mCallbacks->mAttachedCallback");
|
||||
cb.NoteXPCOMChild(callbacks->mAttachedCallback.Value());
|
||||
}
|
||||
|
||||
if (callbacks->mDetachedCallback.WasPassed()) {
|
||||
NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb,
|
||||
"mCustomDefinitions->mCallbacks->mDetachedCallback");
|
||||
cb.NoteXPCOMChild(callbacks->mDetachedCallback.Value());
|
||||
}
|
||||
}
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mWindow)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN(CustomElementsRegistry)
|
||||
for (auto iter = tmp->mCustomDefinitions.Iter(); !iter.Done(); iter.Next()) {
|
||||
aCallbacks.Trace(&iter.UserData()->mConstructor,
|
||||
"mCustomDefinitions constructor",
|
||||
aClosure);
|
||||
aCallbacks.Trace(&iter.UserData()->mPrototype,
|
||||
"mCustomDefinitions prototype",
|
||||
aClosure);
|
||||
}
|
||||
NS_IMPL_CYCLE_COLLECTION_TRACE_PRESERVED_WRAPPER
|
||||
NS_IMPL_CYCLE_COLLECTION_TRACE_END
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTING_ADDREF(CustomElementsRegistry)
|
||||
NS_IMPL_CYCLE_COLLECTING_RELEASE(CustomElementsRegistry)
|
||||
|
||||
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(CustomElementsRegistry)
|
||||
NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
|
||||
NS_INTERFACE_MAP_ENTRY(nsISupports)
|
||||
@ -43,18 +181,329 @@ CustomElementsRegistry::Create(nsPIDOMWindowInner* aWindow)
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (!Preferences::GetBool("dom.webcomponents.customelements.enabled") &&
|
||||
!Preferences::GetBool("dom.webcomponents.enabled")) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
RefPtr<CustomElementsRegistry> customElementsRegistry =
|
||||
new CustomElementsRegistry(aWindow);
|
||||
return customElementsRegistry.forget();
|
||||
}
|
||||
|
||||
/* static */ void
|
||||
CustomElementsRegistry::ProcessTopElementQueue()
|
||||
{
|
||||
MOZ_ASSERT(nsContentUtils::IsSafeToRunScript());
|
||||
|
||||
nsTArray<RefPtr<CustomElementData>>& stack = *sProcessingStack;
|
||||
uint32_t firstQueue = stack.LastIndexOf((CustomElementData*) nullptr);
|
||||
|
||||
for (uint32_t i = firstQueue + 1; i < stack.Length(); ++i) {
|
||||
// Callback queue may have already been processed in an earlier
|
||||
// element queue or in an element queue that was popped
|
||||
// off more recently.
|
||||
if (stack[i]->mAssociatedMicroTask != -1) {
|
||||
stack[i]->RunCallbackQueue();
|
||||
stack[i]->mAssociatedMicroTask = -1;
|
||||
}
|
||||
}
|
||||
|
||||
// If this was actually the base element queue, don't bother trying to pop
|
||||
// the first "queue" marker (sentinel).
|
||||
if (firstQueue != 0) {
|
||||
stack.SetLength(firstQueue);
|
||||
} else {
|
||||
// Don't pop sentinel for base element queue.
|
||||
stack.SetLength(1);
|
||||
}
|
||||
}
|
||||
|
||||
/* static */ void
|
||||
CustomElementsRegistry::XPCOMShutdown()
|
||||
{
|
||||
sProcessingStack.reset();
|
||||
}
|
||||
|
||||
/* static */ Maybe<nsTArray<RefPtr<CustomElementData>>>
|
||||
CustomElementsRegistry::sProcessingStack;
|
||||
|
||||
CustomElementsRegistry::CustomElementsRegistry(nsPIDOMWindowInner* aWindow)
|
||||
: mWindow(aWindow)
|
||||
, mIsCustomDefinitionRunning(false)
|
||||
{
|
||||
mozilla::HoldJSObjects(this);
|
||||
|
||||
if (!sProcessingStack) {
|
||||
sProcessingStack.emplace();
|
||||
// Add the base queue sentinel to the processing stack.
|
||||
sProcessingStack->AppendElement((CustomElementData*) nullptr);
|
||||
}
|
||||
}
|
||||
|
||||
CustomElementsRegistry::~CustomElementsRegistry()
|
||||
{
|
||||
mozilla::DropJSObjects(this);
|
||||
}
|
||||
|
||||
CustomElementDefinition*
|
||||
CustomElementsRegistry::LookupCustomElementDefinition(const nsAString& aLocalName,
|
||||
const nsAString* aIs) const
|
||||
{
|
||||
nsCOMPtr<nsIAtom> localNameAtom = NS_Atomize(aLocalName);
|
||||
nsCOMPtr<nsIAtom> typeAtom = aIs ? NS_Atomize(*aIs) : localNameAtom;
|
||||
|
||||
CustomElementDefinition* data = mCustomDefinitions.Get(typeAtom);
|
||||
if (data && data->mLocalName == localNameAtom) {
|
||||
return data;
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void
|
||||
CustomElementsRegistry::RegisterUnresolvedElement(Element* aElement, nsIAtom* aTypeName)
|
||||
{
|
||||
mozilla::dom::NodeInfo* info = aElement->NodeInfo();
|
||||
|
||||
// Candidate may be a custom element through extension,
|
||||
// in which case the custom element type name will not
|
||||
// match the element tag name. e.g. <button is="x-button">.
|
||||
nsCOMPtr<nsIAtom> typeName = aTypeName;
|
||||
if (!typeName) {
|
||||
typeName = info->NameAtom();
|
||||
}
|
||||
|
||||
if (mCustomDefinitions.Get(typeName)) {
|
||||
return;
|
||||
}
|
||||
|
||||
nsTArray<nsWeakPtr>* unresolved = mCandidatesMap.LookupOrAdd(typeName);
|
||||
nsWeakPtr* elem = unresolved->AppendElement();
|
||||
*elem = do_GetWeakReference(aElement);
|
||||
aElement->AddStates(NS_EVENT_STATE_UNRESOLVED);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void
|
||||
CustomElementsRegistry::SetupCustomElement(Element* aElement,
|
||||
const nsAString* aTypeExtension)
|
||||
{
|
||||
nsCOMPtr<nsIAtom> tagAtom = aElement->NodeInfo()->NameAtom();
|
||||
nsCOMPtr<nsIAtom> typeAtom = aTypeExtension ?
|
||||
NS_Atomize(*aTypeExtension) : tagAtom;
|
||||
|
||||
if (aTypeExtension && !aElement->HasAttr(kNameSpaceID_None, nsGkAtoms::is)) {
|
||||
// Custom element setup in the parser happens after the "is"
|
||||
// attribute is added.
|
||||
aElement->SetAttr(kNameSpaceID_None, nsGkAtoms::is, *aTypeExtension, true);
|
||||
}
|
||||
|
||||
CustomElementDefinition* data = LookupCustomElementDefinition(
|
||||
aElement->NodeInfo()->LocalName(), aTypeExtension);
|
||||
|
||||
if (!data) {
|
||||
// The type extension doesn't exist in the registry,
|
||||
// thus we don't need to enqueue callback or adjust
|
||||
// the "is" attribute, but it is possibly an upgrade candidate.
|
||||
RegisterUnresolvedElement(aElement, typeAtom);
|
||||
return;
|
||||
}
|
||||
|
||||
if (data->mLocalName != tagAtom) {
|
||||
// The element doesn't match the local name for the
|
||||
// definition, thus the element isn't a custom element
|
||||
// and we don't need to do anything more.
|
||||
return;
|
||||
}
|
||||
|
||||
// Enqueuing the created callback will set the CustomElementData on the
|
||||
// element, causing prototype swizzling to occur in Element::WrapObject.
|
||||
EnqueueLifecycleCallback(nsIDocument::eCreated, aElement, nullptr, data);
|
||||
}
|
||||
|
||||
void
|
||||
CustomElementsRegistry::EnqueueLifecycleCallback(nsIDocument::ElementCallbackType aType,
|
||||
Element* aCustomElement,
|
||||
LifecycleCallbackArgs* aArgs,
|
||||
CustomElementDefinition* aDefinition)
|
||||
{
|
||||
CustomElementData* elementData = aCustomElement->GetCustomElementData();
|
||||
|
||||
// Let DEFINITION be ELEMENT's definition
|
||||
CustomElementDefinition* definition = aDefinition;
|
||||
if (!definition) {
|
||||
mozilla::dom::NodeInfo* info = aCustomElement->NodeInfo();
|
||||
|
||||
// Make sure we get the correct definition in case the element
|
||||
// is a extended custom element e.g. <button is="x-button">.
|
||||
nsCOMPtr<nsIAtom> typeAtom = elementData ?
|
||||
elementData->mType.get() : info->NameAtom();
|
||||
|
||||
definition = mCustomDefinitions.Get(typeAtom);
|
||||
if (!definition || definition->mLocalName != info->NameAtom()) {
|
||||
// Trying to enqueue a callback for an element that is not
|
||||
// a custom element. We are done, nothing to do.
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (!elementData) {
|
||||
// Create the custom element data the first time
|
||||
// that we try to enqueue a callback.
|
||||
elementData = new CustomElementData(definition->mType);
|
||||
// aCustomElement takes ownership of elementData
|
||||
aCustomElement->SetCustomElementData(elementData);
|
||||
MOZ_ASSERT(aType == nsIDocument::eCreated,
|
||||
"First callback should be the created callback");
|
||||
}
|
||||
|
||||
// Let CALLBACK be the callback associated with the key NAME in CALLBACKS.
|
||||
CallbackFunction* func = nullptr;
|
||||
switch (aType) {
|
||||
case nsIDocument::eCreated:
|
||||
if (definition->mCallbacks->mCreatedCallback.WasPassed()) {
|
||||
func = definition->mCallbacks->mCreatedCallback.Value();
|
||||
}
|
||||
break;
|
||||
|
||||
case nsIDocument::eAttached:
|
||||
if (definition->mCallbacks->mAttachedCallback.WasPassed()) {
|
||||
func = definition->mCallbacks->mAttachedCallback.Value();
|
||||
}
|
||||
break;
|
||||
|
||||
case nsIDocument::eDetached:
|
||||
if (definition->mCallbacks->mDetachedCallback.WasPassed()) {
|
||||
func = definition->mCallbacks->mDetachedCallback.Value();
|
||||
}
|
||||
break;
|
||||
|
||||
case nsIDocument::eAttributeChanged:
|
||||
if (definition->mCallbacks->mAttributeChangedCallback.WasPassed()) {
|
||||
func = definition->mCallbacks->mAttributeChangedCallback.Value();
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
// If there is no such callback, stop.
|
||||
if (!func) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (aType == nsIDocument::eCreated) {
|
||||
elementData->mCreatedCallbackInvoked = false;
|
||||
} else if (!elementData->mCreatedCallbackInvoked) {
|
||||
// Callbacks other than created callback must not be enqueued
|
||||
// until after the created callback has been invoked.
|
||||
return;
|
||||
}
|
||||
|
||||
// Add CALLBACK to ELEMENT's callback queue.
|
||||
CustomElementCallback* callback = new CustomElementCallback(aCustomElement,
|
||||
aType,
|
||||
func,
|
||||
elementData);
|
||||
// Ownership of callback is taken by mCallbackQueue.
|
||||
elementData->mCallbackQueue.AppendElement(callback);
|
||||
if (aArgs) {
|
||||
callback->SetArgs(*aArgs);
|
||||
}
|
||||
|
||||
if (!elementData->mElementIsBeingCreated) {
|
||||
CustomElementData* lastData =
|
||||
sProcessingStack->SafeLastElement(nullptr);
|
||||
|
||||
// A new element queue needs to be pushed if the queue at the
|
||||
// top of the stack is associated with another microtask level.
|
||||
bool shouldPushElementQueue =
|
||||
(!lastData || lastData->mAssociatedMicroTask <
|
||||
static_cast<int32_t>(nsContentUtils::MicroTaskLevel()));
|
||||
|
||||
// Push a new element queue onto the processing stack when appropriate
|
||||
// (when we enter a new microtask).
|
||||
if (shouldPushElementQueue) {
|
||||
// Push a sentinel value on the processing stack to mark the
|
||||
// boundary between the element queues.
|
||||
sProcessingStack->AppendElement((CustomElementData*) nullptr);
|
||||
}
|
||||
|
||||
sProcessingStack->AppendElement(elementData);
|
||||
elementData->mAssociatedMicroTask =
|
||||
static_cast<int32_t>(nsContentUtils::MicroTaskLevel());
|
||||
|
||||
// Add a script runner to pop and process the element queue at
|
||||
// the top of the processing stack.
|
||||
if (shouldPushElementQueue) {
|
||||
// Lifecycle callbacks enqueued by user agent implementation
|
||||
// should be invoked prior to returning control back to script.
|
||||
// Create a script runner to process the top of the processing
|
||||
// stack as soon as it is safe to run script.
|
||||
nsCOMPtr<nsIRunnable> runnable =
|
||||
NS_NewRunnableFunction(&CustomElementsRegistry::ProcessTopElementQueue);
|
||||
nsContentUtils::AddScriptRunner(runnable);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
CustomElementsRegistry::GetCustomPrototype(nsIAtom* aAtom,
|
||||
JS::MutableHandle<JSObject*> aPrototype)
|
||||
{
|
||||
mozilla::dom::CustomElementDefinition* definition = mCustomDefinitions.Get(aAtom);
|
||||
if (definition) {
|
||||
aPrototype.set(definition->mPrototype);
|
||||
} else {
|
||||
aPrototype.set(nullptr);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
CustomElementsRegistry::UpgradeCandidates(JSContext* aCx,
|
||||
nsIAtom* aKey,
|
||||
CustomElementDefinition* aDefinition)
|
||||
{
|
||||
nsAutoPtr<nsTArray<nsWeakPtr>> candidates;
|
||||
mCandidatesMap.RemoveAndForget(aKey, candidates);
|
||||
if (candidates) {
|
||||
for (size_t i = 0; i < candidates->Length(); ++i) {
|
||||
nsCOMPtr<Element> elem = do_QueryReferent(candidates->ElementAt(i));
|
||||
if (!elem) {
|
||||
continue;
|
||||
}
|
||||
|
||||
elem->RemoveStates(NS_EVENT_STATE_UNRESOLVED);
|
||||
|
||||
// Make sure that the element name matches the name in the definition.
|
||||
// (e.g. a definition for x-button extending button should match
|
||||
// <button is="x-button"> but not <x-button>.
|
||||
if (elem->NodeInfo()->NameAtom() != aDefinition->mLocalName) {
|
||||
//Skip over this element because definition does not apply.
|
||||
continue;
|
||||
}
|
||||
|
||||
MOZ_ASSERT(elem->IsHTMLElement(aDefinition->mLocalName));
|
||||
nsWrapperCache* cache;
|
||||
CallQueryInterface(elem, &cache);
|
||||
MOZ_ASSERT(cache, "Element doesn't support wrapper cache?");
|
||||
|
||||
// We want to set the custom prototype in the caller's comparment.
|
||||
// In the case that element is in a different compartment,
|
||||
// this will set the prototype on the element's wrapper and
|
||||
// thus only visible in the wrapper's compartment.
|
||||
JS::RootedObject wrapper(aCx);
|
||||
JS::Rooted<JSObject*> prototype(aCx, aDefinition->mPrototype);
|
||||
if ((wrapper = cache->GetWrapper()) && JS_WrapObject(aCx, &wrapper)) {
|
||||
if (!JS_SetPrototype(aCx, wrapper, prototype)) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
nsContentUtils::EnqueueLifecycleCallback(
|
||||
elem->OwnerDoc(), nsIDocument::eCreated, elem, nullptr, aDefinition);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
JSObject*
|
||||
@ -68,13 +517,278 @@ nsISupports* CustomElementsRegistry::GetParentObject() const
|
||||
return mWindow;
|
||||
}
|
||||
|
||||
void CustomElementsRegistry::Define(const nsAString& aName,
|
||||
Function& aFunctionConstructor,
|
||||
const ElementDefinitionOptions& aOptions,
|
||||
ErrorResult& aRv)
|
||||
static const char* kLifeCycleCallbackNames[] = {
|
||||
"connectedCallback",
|
||||
"disconnectedCallback",
|
||||
"adoptedCallback",
|
||||
"attributeChangedCallback",
|
||||
// The life cycle callbacks from v0 spec.
|
||||
"createdCallback",
|
||||
"attachedCallback",
|
||||
"detachedCallback"
|
||||
};
|
||||
|
||||
static void
|
||||
CheckLifeCycleCallbacks(JSContext* aCx,
|
||||
JS::Handle<JSObject*> aConstructor,
|
||||
ErrorResult& aRv)
|
||||
{
|
||||
// TODO: This function will be implemented in bug 1275835
|
||||
aRv.Throw(NS_ERROR_NOT_IMPLEMENTED);
|
||||
for (size_t i = 0; i < ArrayLength(kLifeCycleCallbackNames); ++i) {
|
||||
const char* callbackName = kLifeCycleCallbackNames[i];
|
||||
JS::Rooted<JS::Value> callbackValue(aCx);
|
||||
if (!JS_GetProperty(aCx, aConstructor, callbackName, &callbackValue)) {
|
||||
aRv.StealExceptionFromJSContext(aCx);
|
||||
return;
|
||||
}
|
||||
if (!callbackValue.isUndefined()) {
|
||||
if (!callbackValue.isObject()) {
|
||||
aRv.ThrowTypeError<MSG_NOT_OBJECT>(NS_ConvertASCIItoUTF16(callbackName));
|
||||
return;
|
||||
}
|
||||
JS::Rooted<JSObject*> callback(aCx, &callbackValue.toObject());
|
||||
if (!JS::IsCallable(callback)) {
|
||||
aRv.ThrowTypeError<MSG_NOT_CALLABLE>(NS_ConvertASCIItoUTF16(callbackName));
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// https://html.spec.whatwg.org/multipage/scripting.html#element-definition
|
||||
void
|
||||
CustomElementsRegistry::Define(const nsAString& aName,
|
||||
Function& aFunctionConstructor,
|
||||
const ElementDefinitionOptions& aOptions,
|
||||
ErrorResult& aRv)
|
||||
{
|
||||
aRv.MightThrowJSException();
|
||||
|
||||
AutoJSAPI jsapi;
|
||||
if (NS_WARN_IF(!jsapi.Init(mWindow))) {
|
||||
aRv.Throw(NS_ERROR_FAILURE);
|
||||
return;
|
||||
}
|
||||
|
||||
JSContext *cx = jsapi.cx();
|
||||
JS::Rooted<JSObject*> constructor(cx, aFunctionConstructor.Callable());
|
||||
|
||||
/**
|
||||
* 1. If IsConstructor(constructor) is false, then throw a TypeError and abort
|
||||
* these steps.
|
||||
*/
|
||||
// For now, all wrappers are constructable if they are callable. So we need to
|
||||
// unwrap constructor to check it is really constructable.
|
||||
JS::Rooted<JSObject*> constructorUnwrapped(cx, js::CheckedUnwrap(constructor));
|
||||
if (!constructorUnwrapped) {
|
||||
// If the caller's compartment does not have permission to access the
|
||||
// unwrapped constructor then throw.
|
||||
aRv.Throw(NS_ERROR_DOM_SECURITY_ERR);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!JS::IsConstructor(constructorUnwrapped)) {
|
||||
aRv.ThrowTypeError<MSG_NOT_CONSTRUCTOR>(NS_LITERAL_STRING("Argument 2 of CustomElementsRegistry.define"));
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* 2. If name is not a valid custom element name, then throw a "SyntaxError"
|
||||
* DOMException and abort these steps.
|
||||
*/
|
||||
nsCOMPtr<nsIAtom> nameAtom(NS_Atomize(aName));
|
||||
if (!nsContentUtils::IsCustomElementName(nameAtom)) {
|
||||
aRv.Throw(NS_ERROR_DOM_SYNTAX_ERR);
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* 3. If this CustomElementsRegistry contains an entry with name name, then
|
||||
* throw a "NotSupportedError" DOMException and abort these steps.
|
||||
*/
|
||||
if (mCustomDefinitions.Get(nameAtom)) {
|
||||
aRv.Throw(NS_ERROR_DOM_NOT_SUPPORTED_ERR);
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* 4. If this CustomElementsRegistry contains an entry with constructor constructor,
|
||||
* then throw a "NotSupportedError" DOMException and abort these steps.
|
||||
*/
|
||||
// TODO: Step 3 of HTMLConstructor also needs a way to look up definition by
|
||||
// using constructor. So I plans to figure out a solution to support both of
|
||||
// them in bug 1274159.
|
||||
|
||||
/**
|
||||
* 5. Let localName be name.
|
||||
* 6. Let extends be the value of the extends member of options, or null if
|
||||
* no such member exists.
|
||||
* 7. If extends is not null, then:
|
||||
* 1. If extends is a valid custom element name, then throw a
|
||||
* "NotSupportedError" DOMException.
|
||||
* 2. If the element interface for extends and the HTML namespace is
|
||||
* HTMLUnknownElement (e.g., if extends does not indicate an element
|
||||
* definition in this specification), then throw a "NotSupportedError"
|
||||
* DOMException.
|
||||
* 3. Set localName to extends.
|
||||
*/
|
||||
nsAutoString localName(aName);
|
||||
if (aOptions.mExtends.WasPassed()) {
|
||||
nsCOMPtr<nsIAtom> extendsAtom(NS_Atomize(aOptions.mExtends.Value()));
|
||||
if (nsContentUtils::IsCustomElementName(extendsAtom)) {
|
||||
aRv.Throw(NS_ERROR_DOM_NOT_SUPPORTED_ERR);
|
||||
return;
|
||||
}
|
||||
|
||||
nsIParserService* ps = nsContentUtils::GetParserService();
|
||||
if (!ps) {
|
||||
aRv.Throw(NS_ERROR_UNEXPECTED);
|
||||
return;
|
||||
}
|
||||
|
||||
// bgsound and multicol are unknown html element.
|
||||
int32_t tag = ps->HTMLCaseSensitiveAtomTagToId(extendsAtom);
|
||||
if (tag == eHTMLTag_userdefined ||
|
||||
tag == eHTMLTag_bgsound ||
|
||||
tag == eHTMLTag_multicol) {
|
||||
aRv.Throw(NS_ERROR_DOM_NOT_SUPPORTED_ERR);
|
||||
return;
|
||||
}
|
||||
|
||||
localName.Assign(aOptions.mExtends.Value());
|
||||
}
|
||||
|
||||
/**
|
||||
* 8. If this CustomElementRegistry's element definition is running flag is set,
|
||||
* then throw a "NotSupportedError" DOMException and abort these steps.
|
||||
*/
|
||||
if (mIsCustomDefinitionRunning) {
|
||||
aRv.Throw(NS_ERROR_DOM_NOT_SUPPORTED_ERR);
|
||||
return;
|
||||
}
|
||||
|
||||
JS::Rooted<JSObject*> constructorPrototype(cx);
|
||||
nsAutoPtr<LifecycleCallbacks> callbacksHolder(new LifecycleCallbacks());
|
||||
{ // Set mIsCustomDefinitionRunning.
|
||||
/**
|
||||
* 9. Set this CustomElementRegistry's element definition is running flag.
|
||||
*/
|
||||
AutoSetRunningFlag as(this);
|
||||
|
||||
{ // Enter constructor's compartment.
|
||||
/**
|
||||
* 10.1. Let prototype be Get(constructor, "prototype"). Rethrow any exceptions.
|
||||
*/
|
||||
JSAutoCompartment ac(cx, constructor);
|
||||
JS::Rooted<JS::Value> prototypev(cx);
|
||||
// The .prototype on the constructor passed from document.registerElement
|
||||
// is the "expando" of a wrapper. So we should get it from wrapper instead
|
||||
// instead of underlying object.
|
||||
if (!JS_GetProperty(cx, constructor, "prototype", &prototypev)) {
|
||||
aRv.StealExceptionFromJSContext(cx);
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* 10.2. If Type(prototype) is not Object, then throw a TypeError exception.
|
||||
*/
|
||||
if (!prototypev.isObject()) {
|
||||
aRv.ThrowTypeError<MSG_NOT_OBJECT>(NS_LITERAL_STRING("constructor.prototype"));
|
||||
return;
|
||||
}
|
||||
|
||||
constructorPrototype = &prototypev.toObject();
|
||||
} // Leave constructor's compartment.
|
||||
|
||||
JS::Rooted<JSObject*> constructorProtoUnwrapped(cx, js::CheckedUnwrap(constructorPrototype));
|
||||
if (!constructorProtoUnwrapped) {
|
||||
// If the caller's compartment does not have permission to access the
|
||||
// unwrapped prototype then throw.
|
||||
aRv.Throw(NS_ERROR_DOM_SECURITY_ERR);
|
||||
return;
|
||||
}
|
||||
|
||||
{ // Enter constructorProtoUnwrapped's compartment
|
||||
JSAutoCompartment ac(cx, constructorProtoUnwrapped);
|
||||
|
||||
/**
|
||||
* 10.3. Let lifecycleCallbacks be a map with the four keys
|
||||
* "connectedCallback", "disconnectedCallback", "adoptedCallback", and
|
||||
* "attributeChangedCallback", each of which belongs to an entry whose
|
||||
* value is null.
|
||||
* 10.4. For each of the four keys callbackName in lifecycleCallbacks:
|
||||
* 1. Let callbackValue be Get(prototype, callbackName). Rethrow any
|
||||
* exceptions.
|
||||
* 2. If callbackValue is not undefined, then set the value of the
|
||||
* entry in lifecycleCallbacks with key callbackName to the result
|
||||
* of converting callbackValue to the Web IDL Function callback type.
|
||||
* Rethrow any exceptions from the conversion.
|
||||
*/
|
||||
// Will do the same checking for the life cycle callbacks from v0 spec.
|
||||
CheckLifeCycleCallbacks(cx, constructorProtoUnwrapped, aRv);
|
||||
if (aRv.Failed()) {
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* 10.5. Let observedAttributes be an empty sequence<DOMString>.
|
||||
* 10.6. If the value of the entry in lifecycleCallbacks with key
|
||||
* "attributeChangedCallback" is not null, then:
|
||||
* 1. Let observedAttributesIterable be Get(constructor,
|
||||
* "observedAttributes"). Rethrow any exceptions.
|
||||
* 2. If observedAttributesIterable is not undefined, then set
|
||||
* observedAttributes to the result of converting
|
||||
* observedAttributesIterable to a sequence<DOMString>. Rethrow
|
||||
* any exceptions from the conversion.
|
||||
*/
|
||||
// TODO: Bug 1293921 - Implement connected/disconnected/adopted/attributeChanged lifecycle callbacks for custom elements
|
||||
|
||||
// Note: We call the init from the constructorProtoUnwrapped's compartment
|
||||
// here.
|
||||
JS::RootedValue rootedv(cx, JS::ObjectValue(*constructorProtoUnwrapped));
|
||||
if (!JS_WrapValue(cx, &rootedv) || !callbacksHolder->Init(cx, rootedv)) {
|
||||
aRv.Throw(NS_ERROR_FAILURE);
|
||||
return;
|
||||
}
|
||||
} // Leave constructorProtoUnwrapped's compartment.
|
||||
} // Unset mIsCustomDefinitionRunning
|
||||
|
||||
/**
|
||||
* 11. Let definition be a new custom element definition with name name,
|
||||
* local name localName, constructor constructor, prototype prototype,
|
||||
* observed attributes observedAttributes, and lifecycle callbacks
|
||||
* lifecycleCallbacks.
|
||||
*/
|
||||
// Associate the definition with the custom element.
|
||||
nsCOMPtr<nsIAtom> localNameAtom(NS_Atomize(localName));
|
||||
LifecycleCallbacks* callbacks = callbacksHolder.forget();
|
||||
CustomElementDefinition* definition =
|
||||
new CustomElementDefinition(nameAtom,
|
||||
localNameAtom,
|
||||
constructor,
|
||||
constructorPrototype,
|
||||
callbacks,
|
||||
0 /* TODO dependent on HTML imports. Bug 877072 */);
|
||||
|
||||
/**
|
||||
* 12. Add definition to this CustomElementsRegistry.
|
||||
*/
|
||||
mCustomDefinitions.Put(nameAtom, definition);
|
||||
|
||||
/**
|
||||
* 13. 14. 15. Upgrade candidates
|
||||
*/
|
||||
// TODO: Bug 1299363 - Implement custom element v1 upgrade algorithm
|
||||
UpgradeCandidates(cx, nameAtom, definition);
|
||||
|
||||
/**
|
||||
* 16. If this CustomElementsRegistry's when-defined promise map contains an
|
||||
* entry with key name:
|
||||
* 1. Let promise be the value of that entry.
|
||||
* 2. Resolve promise with undefined.
|
||||
* 3. Delete the entry with key name from this CustomElementsRegistry's
|
||||
* when-defined promise map.
|
||||
*/
|
||||
// TODO: Bug 1275839 - Implement CustomElementsRegistry whenDefined function
|
||||
}
|
||||
|
||||
void
|
||||
@ -94,17 +808,17 @@ CustomElementsRegistry::WhenDefined(const nsAString& name, ErrorResult& aRv)
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
CustomElementDefinition::CustomElementDefinition(JSObject* aPrototype,
|
||||
nsIAtom* aType,
|
||||
CustomElementDefinition::CustomElementDefinition(nsIAtom* aType,
|
||||
nsIAtom* aLocalName,
|
||||
JSObject* aConstructor,
|
||||
JSObject* aPrototype,
|
||||
LifecycleCallbacks* aCallbacks,
|
||||
uint32_t aNamespaceID,
|
||||
uint32_t aDocOrder)
|
||||
: mPrototype(aPrototype),
|
||||
mType(aType),
|
||||
: mType(aType),
|
||||
mLocalName(aLocalName),
|
||||
mConstructor(aConstructor),
|
||||
mPrototype(aPrototype),
|
||||
mCallbacks(aCallbacks),
|
||||
mNamespaceID(aNamespaceID),
|
||||
mDocOrder(aDocOrder)
|
||||
{
|
||||
}
|
||||
|
@ -15,75 +15,110 @@
|
||||
#include "nsWrapperCache.h"
|
||||
#include "mozilla/dom/FunctionBinding.h"
|
||||
|
||||
class nsDocument;
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
|
||||
struct CustomElementData;
|
||||
struct ElementDefinitionOptions;
|
||||
struct LifecycleCallbacks;
|
||||
class CallbackFunction;
|
||||
class Function;
|
||||
class Promise;
|
||||
|
||||
class CustomElementHashKey : public PLDHashEntryHdr
|
||||
struct LifecycleCallbackArgs
|
||||
{
|
||||
nsString name;
|
||||
nsString oldValue;
|
||||
nsString newValue;
|
||||
};
|
||||
|
||||
class CustomElementCallback
|
||||
{
|
||||
public:
|
||||
typedef CustomElementHashKey *KeyType;
|
||||
typedef const CustomElementHashKey *KeyTypePointer;
|
||||
|
||||
CustomElementHashKey(int32_t aNamespaceID, nsIAtom *aAtom)
|
||||
: mNamespaceID(aNamespaceID),
|
||||
mAtom(aAtom)
|
||||
{}
|
||||
explicit CustomElementHashKey(const CustomElementHashKey* aKey)
|
||||
: mNamespaceID(aKey->mNamespaceID),
|
||||
mAtom(aKey->mAtom)
|
||||
{}
|
||||
~CustomElementHashKey()
|
||||
{}
|
||||
|
||||
KeyType GetKey() const { return const_cast<KeyType>(this); }
|
||||
bool KeyEquals(const KeyTypePointer aKey) const
|
||||
CustomElementCallback(Element* aThisObject,
|
||||
nsIDocument::ElementCallbackType aCallbackType,
|
||||
CallbackFunction* aCallback,
|
||||
CustomElementData* aOwnerData);
|
||||
void Traverse(nsCycleCollectionTraversalCallback& aCb) const;
|
||||
void Call();
|
||||
void SetArgs(LifecycleCallbackArgs& aArgs)
|
||||
{
|
||||
MOZ_ASSERT(mNamespaceID != kNameSpaceID_Unknown,
|
||||
"This equals method is not transitive, nor symmetric. "
|
||||
"A key with a namespace of kNamespaceID_Unknown should "
|
||||
"not be stored in a hashtable.");
|
||||
return (kNameSpaceID_Unknown == aKey->mNamespaceID ||
|
||||
mNamespaceID == aKey->mNamespaceID) &&
|
||||
aKey->mAtom == mAtom;
|
||||
MOZ_ASSERT(mType == nsIDocument::eAttributeChanged,
|
||||
"Arguments are only used by attribute changed callback.");
|
||||
mArgs = aArgs;
|
||||
}
|
||||
|
||||
static KeyTypePointer KeyToPointer(KeyType aKey) { return aKey; }
|
||||
static PLDHashNumber HashKey(const KeyTypePointer aKey)
|
||||
{
|
||||
return aKey->mAtom->hash();
|
||||
}
|
||||
enum { ALLOW_MEMMOVE = true };
|
||||
|
||||
private:
|
||||
int32_t mNamespaceID;
|
||||
nsCOMPtr<nsIAtom> mAtom;
|
||||
// The this value to use for invocation of the callback.
|
||||
RefPtr<Element> mThisObject;
|
||||
RefPtr<CallbackFunction> mCallback;
|
||||
// The type of callback (eCreated, eAttached, etc.)
|
||||
nsIDocument::ElementCallbackType mType;
|
||||
// Arguments to be passed to the callback,
|
||||
// used by the attribute changed callback.
|
||||
LifecycleCallbackArgs mArgs;
|
||||
// CustomElementData that contains this callback in the
|
||||
// callback queue.
|
||||
CustomElementData* mOwnerData;
|
||||
};
|
||||
|
||||
// Each custom element has an associated callback queue and an element is
|
||||
// being created flag.
|
||||
struct CustomElementData
|
||||
{
|
||||
NS_INLINE_DECL_REFCOUNTING(CustomElementData)
|
||||
|
||||
explicit CustomElementData(nsIAtom* aType);
|
||||
// Objects in this array are transient and empty after each microtask
|
||||
// checkpoint.
|
||||
nsTArray<nsAutoPtr<CustomElementCallback>> mCallbackQueue;
|
||||
// Custom element type, for <button is="x-button"> or <x-button>
|
||||
// this would be x-button.
|
||||
nsCOMPtr<nsIAtom> mType;
|
||||
// The callback that is next to be processed upon calling RunCallbackQueue.
|
||||
int32_t mCurrentCallback;
|
||||
// Element is being created flag as described in the custom elements spec.
|
||||
bool mElementIsBeingCreated;
|
||||
// Flag to determine if the created callback has been invoked, thus it
|
||||
// determines if other callbacks can be enqueued.
|
||||
bool mCreatedCallbackInvoked;
|
||||
// The microtask level associated with the callbacks in the callback queue,
|
||||
// it is used to determine if a new queue needs to be pushed onto the
|
||||
// processing stack.
|
||||
int32_t mAssociatedMicroTask;
|
||||
|
||||
// Empties the callback queue.
|
||||
void RunCallbackQueue();
|
||||
|
||||
private:
|
||||
virtual ~CustomElementData() {}
|
||||
};
|
||||
|
||||
// The required information for a custom element as defined in:
|
||||
// https://dvcs.w3.org/hg/webcomponents/raw-file/tip/spec/custom/index.html
|
||||
// https://html.spec.whatwg.org/multipage/scripting.html#custom-element-definition
|
||||
struct CustomElementDefinition
|
||||
{
|
||||
CustomElementDefinition(JSObject* aPrototype,
|
||||
nsIAtom* aType,
|
||||
CustomElementDefinition(nsIAtom* aType,
|
||||
nsIAtom* aLocalName,
|
||||
JSObject* aConstructor,
|
||||
JSObject* aPrototype,
|
||||
mozilla::dom::LifecycleCallbacks* aCallbacks,
|
||||
uint32_t aNamespaceID,
|
||||
uint32_t aDocOrder);
|
||||
|
||||
// The prototype to use for new custom elements of this type.
|
||||
JS::Heap<JSObject *> mPrototype;
|
||||
|
||||
// The type (name) for this custom element.
|
||||
nsCOMPtr<nsIAtom> mType;
|
||||
|
||||
// The localname to (e.g. <button is=type> -- this would be button).
|
||||
nsCOMPtr<nsIAtom> mLocalName;
|
||||
|
||||
// The custom element constructor.
|
||||
JS::Heap<JSObject *> mConstructor;
|
||||
|
||||
// The prototype to use for new custom elements of this type.
|
||||
JS::Heap<JSObject *> mPrototype;
|
||||
|
||||
// The lifecycle callbacks to call for this custom element.
|
||||
nsAutoPtr<mozilla::dom::LifecycleCallbacks> mCallbacks;
|
||||
|
||||
@ -91,8 +126,8 @@ struct CustomElementDefinition
|
||||
// of this type.
|
||||
bool mElementIsBeingCreated;
|
||||
|
||||
// Element namespace.
|
||||
int32_t mNamespaceID;
|
||||
// A construction stack.
|
||||
// TODO: Bug 1287348 - Implement construction stack for upgrading an element
|
||||
|
||||
// The document custom element order.
|
||||
uint32_t mDocOrder;
|
||||
@ -101,6 +136,9 @@ struct CustomElementDefinition
|
||||
class CustomElementsRegistry final : public nsISupports,
|
||||
public nsWrapperCache
|
||||
{
|
||||
// Allow nsDocument to access mCustomDefinitions and mCandidatesMap.
|
||||
friend class ::nsDocument;
|
||||
|
||||
public:
|
||||
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
|
||||
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(CustomElementsRegistry)
|
||||
@ -108,13 +146,98 @@ public:
|
||||
public:
|
||||
static bool IsCustomElementsEnabled(JSContext* aCx, JSObject* aObject);
|
||||
static already_AddRefed<CustomElementsRegistry> Create(nsPIDOMWindowInner* aWindow);
|
||||
already_AddRefed<nsIDocument> GetOwnerDocument() const;
|
||||
static void ProcessTopElementQueue();
|
||||
|
||||
static void XPCOMShutdown();
|
||||
|
||||
/**
|
||||
* Looking up a custom element definition.
|
||||
* https://html.spec.whatwg.org/#look-up-a-custom-element-definition
|
||||
*/
|
||||
CustomElementDefinition* LookupCustomElementDefinition(
|
||||
const nsAString& aLocalName, const nsAString* aIs = nullptr) const;
|
||||
|
||||
/**
|
||||
* Enqueue created callback or register upgrade candidate for
|
||||
* newly created custom elements, possibly extending an existing type.
|
||||
* ex. <x-button>, <button is="x-button> (type extension)
|
||||
*/
|
||||
void SetupCustomElement(Element* aElement, const nsAString* aTypeExtension);
|
||||
|
||||
void EnqueueLifecycleCallback(nsIDocument::ElementCallbackType aType,
|
||||
Element* aCustomElement,
|
||||
LifecycleCallbackArgs* aArgs,
|
||||
CustomElementDefinition* aDefinition);
|
||||
|
||||
void GetCustomPrototype(nsIAtom* aAtom,
|
||||
JS::MutableHandle<JSObject*> aPrototype);
|
||||
|
||||
private:
|
||||
explicit CustomElementsRegistry(nsPIDOMWindowInner* aWindow);
|
||||
~CustomElementsRegistry();
|
||||
|
||||
/**
|
||||
* Registers an unresolved custom element that is a candidate for
|
||||
* upgrade when the definition is registered via registerElement.
|
||||
* |aTypeName| is the name of the custom element type, if it is not
|
||||
* provided, then element name is used. |aTypeName| should be provided
|
||||
* when registering a custom element that extends an existing
|
||||
* element. e.g. <button is="x-button">.
|
||||
*/
|
||||
void RegisterUnresolvedElement(Element* aElement,
|
||||
nsIAtom* aTypeName = nullptr);
|
||||
|
||||
void UpgradeCandidates(JSContext* aCx,
|
||||
nsIAtom* aKey,
|
||||
CustomElementDefinition* aDefinition);
|
||||
|
||||
typedef nsClassHashtable<nsISupportsHashKey, CustomElementDefinition>
|
||||
DefinitionMap;
|
||||
typedef nsClassHashtable<nsISupportsHashKey, nsTArray<nsWeakPtr>>
|
||||
CandidateMap;
|
||||
|
||||
// Hashtable for custom element definitions in web components.
|
||||
// Custom prototypes are stored in the compartment where
|
||||
// registerElement was called.
|
||||
DefinitionMap mCustomDefinitions;
|
||||
|
||||
// The "upgrade candidates map" from the web components spec. Maps from a
|
||||
// namespace id and local name to a list of elements to upgrade if that
|
||||
// element is registered as a custom element.
|
||||
CandidateMap mCandidatesMap;
|
||||
|
||||
nsCOMPtr<nsPIDOMWindowInner> mWindow;
|
||||
|
||||
// Array representing the processing stack in the custom elements
|
||||
// specification. The processing stack is conceptually a stack of
|
||||
// element queues. Each queue is represented by a sequence of
|
||||
// CustomElementData in this array, separated by nullptr that
|
||||
// represent the boundaries of the items in the stack. The first
|
||||
// queue in the stack is the base element queue.
|
||||
static mozilla::Maybe<nsTArray<RefPtr<CustomElementData>>> sProcessingStack;
|
||||
|
||||
// It is used to prevent reentrant invocations of element definition.
|
||||
bool mIsCustomDefinitionRunning;
|
||||
|
||||
private:
|
||||
class MOZ_RAII AutoSetRunningFlag final {
|
||||
public:
|
||||
explicit AutoSetRunningFlag(CustomElementsRegistry* aRegistry)
|
||||
: mRegistry(aRegistry)
|
||||
{
|
||||
MOZ_ASSERT(!mRegistry->mIsCustomDefinitionRunning,
|
||||
"IsCustomDefinitionRunning flag should be initially false");
|
||||
mRegistry->mIsCustomDefinitionRunning = true;
|
||||
}
|
||||
|
||||
~AutoSetRunningFlag() {
|
||||
mRegistry->mIsCustomDefinitionRunning = false;
|
||||
}
|
||||
|
||||
private:
|
||||
CustomElementsRegistry* mRegistry;
|
||||
};
|
||||
|
||||
public:
|
||||
nsISupports* GetParentObject() const;
|
||||
|
||||
|
@ -133,7 +133,6 @@ DOMImplementation::CreateDocument(const nsAString& aNamespaceURI,
|
||||
|
||||
if (aNamespaceURI.EqualsLiteral("http://www.w3.org/1999/xhtml")) {
|
||||
doc->SetContentType(NS_LITERAL_STRING("application/xhtml+xml"));
|
||||
doc->UseRegistryFromDocument(mOwner);
|
||||
} else if (aNamespaceURI.EqualsLiteral("http://www.w3.org/2000/svg")) {
|
||||
doc->SetContentType(NS_LITERAL_STRING("image/svg+xml"));
|
||||
} else {
|
||||
@ -235,10 +234,6 @@ DOMImplementation::CreateHTMLDocument(const nsAString& aTitle,
|
||||
rv = root->AppendChildTo(body, false);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// When the createHTMLDocument method is invoked,
|
||||
// use the registry of the associated document to the new instance.
|
||||
doc->UseRegistryFromDocument(mOwner);
|
||||
|
||||
doc->SetReadyStateInternal(nsIDocument::READYSTATE_COMPLETE);
|
||||
|
||||
doc.forget(aDocument);
|
||||
|
@ -470,8 +470,8 @@ Element::WrapObject(JSContext *aCx, JS::Handle<JSObject*> aGivenProto)
|
||||
CustomElementData* data = GetCustomElementData();
|
||||
if (data) {
|
||||
// If this is a registered custom element then fix the prototype.
|
||||
nsDocument* document = static_cast<nsDocument*>(OwnerDoc());
|
||||
document->GetCustomPrototype(NodeInfo()->NamespaceID(), data->mType, &customProto);
|
||||
nsContentUtils::GetCustomPrototype(OwnerDoc(), NodeInfo()->NamespaceID(),
|
||||
data->mType, &customProto);
|
||||
if (customProto &&
|
||||
NodePrincipal()->SubsumesConsideringDomain(nsContentUtils::ObjectPrincipal(customProto))) {
|
||||
// Just go ahead and create with the right proto up front. Set
|
||||
@ -956,7 +956,7 @@ Element::GetClientAreaRect()
|
||||
}
|
||||
|
||||
if (styledFrame &&
|
||||
(styledFrame->StyleDisplay()->mDisplay != NS_STYLE_DISPLAY_INLINE ||
|
||||
(styledFrame->StyleDisplay()->mDisplay != StyleDisplay::Inline ||
|
||||
styledFrame->IsFrameOfType(nsIFrame::eReplaced))) {
|
||||
// Special case code to make client area work even when there isn't
|
||||
// a scroll view, see bug 180552, bug 227567.
|
||||
@ -1608,7 +1608,8 @@ Element::BindToTree(nsIDocument* aDocument, nsIContent* aParent,
|
||||
// document and this document has a browsing context.
|
||||
if (GetCustomElementData() && composedDoc->GetDocShell()) {
|
||||
// Enqueue an attached callback for the custom element.
|
||||
composedDoc->EnqueueLifecycleCallback(nsIDocument::eAttached, this);
|
||||
nsContentUtils::EnqueueLifecycleCallback(
|
||||
composedDoc, nsIDocument::eAttached, this);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1889,7 +1890,8 @@ Element::UnbindFromTree(bool aDeep, bool aNullParent)
|
||||
// the document and this document has a browsing context.
|
||||
if (GetCustomElementData() && document->GetDocShell()) {
|
||||
// Enqueue a detached callback for the custom element.
|
||||
document->EnqueueLifecycleCallback(nsIDocument::eDetached, this);
|
||||
nsContentUtils::EnqueueLifecycleCallback(
|
||||
document, nsIDocument::eDetached, this);
|
||||
}
|
||||
}
|
||||
|
||||
@ -2495,7 +2497,8 @@ Element::SetAttrAndNotify(int32_t aNamespaceID,
|
||||
nsDependentAtomString(newValueAtom)
|
||||
};
|
||||
|
||||
ownerDoc->EnqueueLifecycleCallback(nsIDocument::eAttributeChanged, this, &args);
|
||||
nsContentUtils::EnqueueLifecycleCallback(
|
||||
ownerDoc, nsIDocument::eAttributeChanged, this, &args);
|
||||
}
|
||||
|
||||
if (aCallAfterSetAttr) {
|
||||
@ -2749,7 +2752,8 @@ Element::UnsetAttr(int32_t aNameSpaceID, nsIAtom* aName,
|
||||
NullString()
|
||||
};
|
||||
|
||||
ownerDoc->EnqueueLifecycleCallback(nsIDocument::eAttributeChanged, this, &args);
|
||||
nsContentUtils::EnqueueLifecycleCallback(
|
||||
ownerDoc, nsIDocument::eAttributeChanged, this, &args);
|
||||
}
|
||||
|
||||
if (aNotify) {
|
||||
|
@ -136,6 +136,7 @@ class EventStateManager;
|
||||
namespace dom {
|
||||
|
||||
class Animation;
|
||||
class CustomElementsRegistry;
|
||||
class Link;
|
||||
class UndoManager;
|
||||
class DOMRect;
|
||||
@ -424,7 +425,9 @@ private:
|
||||
friend class mozilla::EventStateManager;
|
||||
friend class ::nsGlobalWindow;
|
||||
friend class ::nsFocusManager;
|
||||
friend class ::nsDocument;
|
||||
|
||||
// Allow CusomtElementRegistry to call AddStates.
|
||||
friend class CustomElementsRegistry;
|
||||
|
||||
// Also need to allow Link to call UpdateLinkState.
|
||||
friend class Link;
|
||||
|
@ -735,7 +735,8 @@ protected:
|
||||
nsresult rv =
|
||||
#endif
|
||||
mFile->Remove(false);
|
||||
NS_WARN_IF_FALSE(NS_SUCCEEDED(rv), "Failed to remove temporary DOMFile.");
|
||||
NS_WARNING_ASSERTION(NS_SUCCEEDED(rv),
|
||||
"Failed to remove temporary DOMFile.");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -21,7 +21,8 @@ SameProcessMessageQueue::~SameProcessMessageQueue()
|
||||
// This code should run during shutdown, and we should already have pumped the
|
||||
// event loop. So we should only see messages here if someone is sending
|
||||
// messages pretty late in shutdown.
|
||||
NS_WARN_IF_FALSE(mQueue.IsEmpty(), "Shouldn't send messages during shutdown");
|
||||
NS_WARNING_ASSERTION(mQueue.IsEmpty(),
|
||||
"Shouldn't send messages during shutdown");
|
||||
sSingleton = nullptr;
|
||||
}
|
||||
|
||||
|
@ -1734,9 +1734,9 @@ nsAttrValue::LoadImage(nsIDocument* aDocument)
|
||||
|
||||
MiscContainer* cont = GetMiscContainer();
|
||||
mozilla::css::URLValue* url = cont->mValue.mURL;
|
||||
mozilla::css::ImageValue* image =
|
||||
new css::ImageValue(url->GetURI(), url->mString, url->mReferrer,
|
||||
url->mOriginPrincipal, aDocument);
|
||||
mozilla::css::ImageValue* image =
|
||||
new css::ImageValue(url->GetURI(), url->mString, url->mBaseURI,
|
||||
url->mReferrer, url->mOriginPrincipal, aDocument);
|
||||
|
||||
NS_ADDREF(image);
|
||||
cont->mValue.mImage = image;
|
||||
|
@ -203,29 +203,25 @@ nsContentPolicy::CheckPolicy(CPMethod policyMethod,
|
||||
|
||||
//uses the parameters from ShouldXYZ to produce and log a message
|
||||
//logType must be a literal string constant
|
||||
#define LOG_CHECK(logType) \
|
||||
PR_BEGIN_MACRO \
|
||||
/* skip all this nonsense if the call failed or logging is disabled */ \
|
||||
if (NS_SUCCEEDED(rv) && MOZ_LOG_TEST(gConPolLog, LogLevel::Debug)) { \
|
||||
const char *resultName; \
|
||||
if (decision) { \
|
||||
resultName = NS_CP_ResponseName(*decision); \
|
||||
} else { \
|
||||
resultName = "(null ptr)"; \
|
||||
} \
|
||||
nsAutoCString spec("None"); \
|
||||
if (contentLocation) { \
|
||||
contentLocation->GetSpec(spec); \
|
||||
} \
|
||||
nsAutoCString refSpec("None"); \
|
||||
if (requestingLocation) { \
|
||||
requestingLocation->GetSpec(refSpec); \
|
||||
} \
|
||||
MOZ_LOG(gConPolLog, LogLevel::Debug, \
|
||||
("Content Policy: " logType ": <%s> <Ref:%s> result=%s", \
|
||||
spec.get(), refSpec.get(), resultName) \
|
||||
); \
|
||||
} \
|
||||
#define LOG_CHECK(logType) \
|
||||
PR_BEGIN_MACRO \
|
||||
/* skip all this nonsense if the call failed or logging is disabled */ \
|
||||
if (NS_SUCCEEDED(rv) && MOZ_LOG_TEST(gConPolLog, LogLevel::Debug)) { \
|
||||
const char *resultName; \
|
||||
if (decision) { \
|
||||
resultName = NS_CP_ResponseName(*decision); \
|
||||
} else { \
|
||||
resultName = "(null ptr)"; \
|
||||
} \
|
||||
MOZ_LOG(gConPolLog, LogLevel::Debug, \
|
||||
("Content Policy: " logType ": <%s> <Ref:%s> result=%s", \
|
||||
contentLocation ? contentLocation->GetSpecOrDefault().get() \
|
||||
: "None", \
|
||||
requestingLocation ? requestingLocation->GetSpecOrDefault().get()\
|
||||
: "None", \
|
||||
resultName) \
|
||||
); \
|
||||
} \
|
||||
PR_END_MACRO
|
||||
|
||||
NS_IMETHODIMP
|
||||
|
@ -38,6 +38,7 @@
|
||||
#include "mozilla/DebugOnly.h"
|
||||
#include "mozilla/LoadInfo.h"
|
||||
#include "mozilla/dom/ContentChild.h"
|
||||
#include "mozilla/dom/CustomElementsRegistry.h"
|
||||
#include "mozilla/dom/DocumentFragment.h"
|
||||
#include "mozilla/dom/DOMTypes.h"
|
||||
#include "mozilla/dom/Element.h"
|
||||
@ -5157,9 +5158,7 @@ nsContentUtils::WarnScriptWasIgnored(nsIDocument* aDocument)
|
||||
if (aDocument) {
|
||||
nsCOMPtr<nsIURI> uri = aDocument->GetDocumentURI();
|
||||
if (uri) {
|
||||
nsCString spec;
|
||||
uri->GetSpec(spec);
|
||||
msg.Append(NS_ConvertUTF8toUTF16(spec));
|
||||
msg.Append(NS_ConvertUTF8toUTF16(uri->GetSpecOrDefault()));
|
||||
msg.AppendLiteral(" : ");
|
||||
}
|
||||
}
|
||||
@ -9433,3 +9432,123 @@ nsContentUtils::HttpsStateIsModern(nsIDocument* aDocument)
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/* static */ CustomElementDefinition*
|
||||
nsContentUtils::LookupCustomElementDefinition(nsIDocument* aDoc,
|
||||
const nsAString& aLocalName,
|
||||
uint32_t aNameSpaceID,
|
||||
const nsAString* aIs)
|
||||
{
|
||||
MOZ_ASSERT(aDoc);
|
||||
|
||||
// To support imported document.
|
||||
nsCOMPtr<nsIDocument> doc = aDoc->MasterDocument();
|
||||
|
||||
if (aNameSpaceID != kNameSpaceID_XHTML ||
|
||||
!doc->GetDocShell()) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsPIDOMWindowInner> window(doc->GetInnerWindow());
|
||||
if (!window) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
RefPtr<CustomElementsRegistry> registry(window->CustomElements());
|
||||
if (!registry) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return registry->LookupCustomElementDefinition(aLocalName, aIs);
|
||||
}
|
||||
|
||||
/* static */ void
|
||||
nsContentUtils::SetupCustomElement(Element* aElement,
|
||||
const nsAString* aTypeExtension)
|
||||
{
|
||||
MOZ_ASSERT(aElement);
|
||||
|
||||
nsCOMPtr<nsIDocument> doc = aElement->OwnerDoc();
|
||||
|
||||
if (!doc) {
|
||||
return;
|
||||
}
|
||||
|
||||
// To support imported document.
|
||||
doc = doc->MasterDocument();
|
||||
|
||||
if (aElement->GetNameSpaceID() != kNameSpaceID_XHTML ||
|
||||
!doc->GetDocShell()) {
|
||||
return;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsPIDOMWindowInner> window(doc->GetInnerWindow());
|
||||
if (!window) {
|
||||
return;
|
||||
}
|
||||
|
||||
RefPtr<CustomElementsRegistry> registry(window->CustomElements());
|
||||
if (!registry) {
|
||||
return;
|
||||
}
|
||||
|
||||
return registry->SetupCustomElement(aElement, aTypeExtension);
|
||||
}
|
||||
|
||||
/* static */ void
|
||||
nsContentUtils::EnqueueLifecycleCallback(nsIDocument* aDoc,
|
||||
nsIDocument::ElementCallbackType aType,
|
||||
Element* aCustomElement,
|
||||
LifecycleCallbackArgs* aArgs,
|
||||
CustomElementDefinition* aDefinition)
|
||||
{
|
||||
MOZ_ASSERT(aDoc);
|
||||
|
||||
// To support imported document.
|
||||
nsCOMPtr<nsIDocument> doc = aDoc->MasterDocument();
|
||||
|
||||
if (!doc->GetDocShell()) {
|
||||
return;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsPIDOMWindowInner> window(doc->GetInnerWindow());
|
||||
if (!window) {
|
||||
return;
|
||||
}
|
||||
|
||||
RefPtr<CustomElementsRegistry> registry(window->CustomElements());
|
||||
if (!registry) {
|
||||
return;
|
||||
}
|
||||
|
||||
registry->EnqueueLifecycleCallback(aType, aCustomElement, aArgs, aDefinition);
|
||||
}
|
||||
|
||||
/* static */ void
|
||||
nsContentUtils::GetCustomPrototype(nsIDocument* aDoc,
|
||||
int32_t aNamespaceID,
|
||||
nsIAtom* aAtom,
|
||||
JS::MutableHandle<JSObject*> aPrototype)
|
||||
{
|
||||
MOZ_ASSERT(aDoc);
|
||||
|
||||
// To support imported document.
|
||||
nsCOMPtr<nsIDocument> doc = aDoc->MasterDocument();
|
||||
|
||||
if (aNamespaceID != kNameSpaceID_XHTML ||
|
||||
!doc->GetDocShell()) {
|
||||
return;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsPIDOMWindowInner> window(doc->GetInnerWindow());
|
||||
if (!window) {
|
||||
return;
|
||||
}
|
||||
|
||||
RefPtr<CustomElementsRegistry> registry(window->CustomElements());
|
||||
if (!registry) {
|
||||
return;
|
||||
}
|
||||
|
||||
return registry->GetCustomPrototype(aAtom, aPrototype);
|
||||
}
|
||||
|
@ -34,6 +34,7 @@
|
||||
#include "mozilla/Logging.h"
|
||||
#include "mozilla/NotNull.h"
|
||||
#include "nsIContentPolicy.h"
|
||||
#include "nsIDocument.h"
|
||||
#include "nsPIDOMWindow.h"
|
||||
|
||||
#if defined(XP_WIN)
|
||||
@ -55,7 +56,6 @@ class nsIContent;
|
||||
class nsIContentPolicy;
|
||||
class nsIContentSecurityPolicy;
|
||||
class nsIDocShellTreeItem;
|
||||
class nsIDocument;
|
||||
class nsIDocumentLoaderFactory;
|
||||
class nsIDOMDocument;
|
||||
class nsIDOMDocumentFragment;
|
||||
@ -119,11 +119,13 @@ class ErrorResult;
|
||||
class EventListenerManager;
|
||||
|
||||
namespace dom {
|
||||
struct CustomElementDefinition;
|
||||
class DocumentFragment;
|
||||
class Element;
|
||||
class EventTarget;
|
||||
class IPCDataTransfer;
|
||||
class IPCDataTransferItem;
|
||||
struct LifecycleCallbackArgs;
|
||||
class NodeInfo;
|
||||
class nsIContentChild;
|
||||
class nsIContentParent;
|
||||
@ -2676,6 +2678,30 @@ public:
|
||||
*/
|
||||
static bool HttpsStateIsModern(nsIDocument* aDocument);
|
||||
|
||||
/**
|
||||
* Looking up a custom element definition.
|
||||
* https://html.spec.whatwg.org/#look-up-a-custom-element-definition
|
||||
*/
|
||||
static mozilla::dom::CustomElementDefinition*
|
||||
LookupCustomElementDefinition(nsIDocument* aDoc,
|
||||
const nsAString& aLocalName,
|
||||
uint32_t aNameSpaceID,
|
||||
const nsAString* aIs = nullptr);
|
||||
|
||||
static void SetupCustomElement(Element* aElement,
|
||||
const nsAString* aTypeExtension = nullptr);
|
||||
|
||||
static void EnqueueLifecycleCallback(nsIDocument* aDoc,
|
||||
nsIDocument::ElementCallbackType aType,
|
||||
Element* aCustomElement,
|
||||
mozilla::dom::LifecycleCallbackArgs* aArgs = nullptr,
|
||||
mozilla::dom::CustomElementDefinition* aDefinition = nullptr);
|
||||
|
||||
static void GetCustomPrototype(nsIDocument* aDoc,
|
||||
int32_t aNamespaceID,
|
||||
nsIAtom* aAtom,
|
||||
JS::MutableHandle<JSObject*> prototype);
|
||||
|
||||
private:
|
||||
static bool InitializeEventTable();
|
||||
|
||||
|
@ -711,8 +711,8 @@ nsDOMMutationObserver::Observe(nsINode& aTarget,
|
||||
|
||||
#ifdef DEBUG
|
||||
for (int32_t i = 0; i < mReceivers.Count(); ++i) {
|
||||
NS_WARN_IF_FALSE(mReceivers[i]->Target(),
|
||||
"All the receivers should have a target!");
|
||||
NS_WARNING_ASSERTION(mReceivers[i]->Target(),
|
||||
"All the receivers should have a target!");
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
@ -218,6 +218,8 @@
|
||||
#include "mozilla/dom/TabChild.h"
|
||||
#include "mozilla/dom/UndoManager.h"
|
||||
#include "mozilla/dom/WebComponentsBinding.h"
|
||||
#include "mozilla/dom/CustomElementsRegistryBinding.h"
|
||||
#include "mozilla/dom/CustomElementsRegistry.h"
|
||||
#include "nsFrame.h"
|
||||
#include "nsDOMCaretPosition.h"
|
||||
#include "nsIDOMHTMLTextAreaElement.h"
|
||||
@ -368,156 +370,6 @@ nsIdentifierMapEntry::RemoveContentChangeCallback(nsIDocument::IDTargetObserver
|
||||
}
|
||||
}
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_CLASS(Registry)
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN(Registry)
|
||||
for (auto iter = tmp->mCustomDefinitions.Iter(); !iter.Done(); iter.Next()) {
|
||||
aCallbacks.Trace(&iter.UserData()->mPrototype,
|
||||
"mCustomDefinitions prototype",
|
||||
aClosure);
|
||||
}
|
||||
NS_IMPL_CYCLE_COLLECTION_TRACE_END
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(Registry)
|
||||
for (auto iter = tmp->mCustomDefinitions.Iter(); !iter.Done(); iter.Next()) {
|
||||
nsAutoPtr<LifecycleCallbacks>& callbacks = iter.UserData()->mCallbacks;
|
||||
|
||||
if (callbacks->mAttributeChangedCallback.WasPassed()) {
|
||||
NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb,
|
||||
"mCustomDefinitions->mCallbacks->mAttributeChangedCallback");
|
||||
cb.NoteXPCOMChild(callbacks->mAttributeChangedCallback.Value());
|
||||
}
|
||||
|
||||
if (callbacks->mCreatedCallback.WasPassed()) {
|
||||
NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb,
|
||||
"mCustomDefinitions->mCallbacks->mCreatedCallback");
|
||||
cb.NoteXPCOMChild(callbacks->mCreatedCallback.Value());
|
||||
}
|
||||
|
||||
if (callbacks->mAttachedCallback.WasPassed()) {
|
||||
NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb,
|
||||
"mCustomDefinitions->mCallbacks->mAttachedCallback");
|
||||
cb.NoteXPCOMChild(callbacks->mAttachedCallback.Value());
|
||||
}
|
||||
|
||||
if (callbacks->mDetachedCallback.WasPassed()) {
|
||||
NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb,
|
||||
"mCustomDefinitions->mCallbacks->mDetachedCallback");
|
||||
cb.NoteXPCOMChild(callbacks->mDetachedCallback.Value());
|
||||
}
|
||||
}
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(Registry)
|
||||
tmp->mCustomDefinitions.Clear();
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
|
||||
|
||||
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(Registry)
|
||||
NS_INTERFACE_MAP_ENTRY(nsISupports)
|
||||
NS_INTERFACE_MAP_END
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTING_ADDREF(Registry)
|
||||
NS_IMPL_CYCLE_COLLECTING_RELEASE(Registry)
|
||||
|
||||
Registry::Registry()
|
||||
{
|
||||
mozilla::HoldJSObjects(this);
|
||||
}
|
||||
|
||||
Registry::~Registry()
|
||||
{
|
||||
mozilla::DropJSObjects(this);
|
||||
}
|
||||
|
||||
void
|
||||
CustomElementCallback::Call()
|
||||
{
|
||||
ErrorResult rv;
|
||||
switch (mType) {
|
||||
case nsIDocument::eCreated:
|
||||
{
|
||||
// For the duration of this callback invocation, the element is being created
|
||||
// flag must be set to true.
|
||||
mOwnerData->mElementIsBeingCreated = true;
|
||||
|
||||
// The callback hasn't actually been invoked yet, but we need to flip
|
||||
// this now in order to enqueue the attached callback. This is a spec
|
||||
// bug (w3c bug 27437).
|
||||
mOwnerData->mCreatedCallbackInvoked = true;
|
||||
|
||||
// If ELEMENT is in a document and this document has a browsing context,
|
||||
// enqueue attached callback for ELEMENT.
|
||||
nsIDocument* document = mThisObject->GetComposedDoc();
|
||||
if (document && document->GetDocShell()) {
|
||||
document->EnqueueLifecycleCallback(nsIDocument::eAttached, mThisObject);
|
||||
}
|
||||
|
||||
static_cast<LifecycleCreatedCallback *>(mCallback.get())->Call(mThisObject, rv);
|
||||
mOwnerData->mElementIsBeingCreated = false;
|
||||
break;
|
||||
}
|
||||
case nsIDocument::eAttached:
|
||||
static_cast<LifecycleAttachedCallback *>(mCallback.get())->Call(mThisObject, rv);
|
||||
break;
|
||||
case nsIDocument::eDetached:
|
||||
static_cast<LifecycleDetachedCallback *>(mCallback.get())->Call(mThisObject, rv);
|
||||
break;
|
||||
case nsIDocument::eAttributeChanged:
|
||||
static_cast<LifecycleAttributeChangedCallback *>(mCallback.get())->Call(mThisObject,
|
||||
mArgs.name, mArgs.oldValue, mArgs.newValue, rv);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
CustomElementCallback::Traverse(nsCycleCollectionTraversalCallback& aCb) const
|
||||
{
|
||||
NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(aCb, "mThisObject");
|
||||
aCb.NoteXPCOMChild(mThisObject);
|
||||
|
||||
NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(aCb, "mCallback");
|
||||
aCb.NoteXPCOMChild(mCallback);
|
||||
}
|
||||
|
||||
CustomElementCallback::CustomElementCallback(Element* aThisObject,
|
||||
nsIDocument::ElementCallbackType aCallbackType,
|
||||
mozilla::dom::CallbackFunction* aCallback,
|
||||
CustomElementData* aOwnerData)
|
||||
: mThisObject(aThisObject),
|
||||
mCallback(aCallback),
|
||||
mType(aCallbackType),
|
||||
mOwnerData(aOwnerData)
|
||||
{
|
||||
}
|
||||
|
||||
CustomElementData::CustomElementData(nsIAtom* aType)
|
||||
: mType(aType),
|
||||
mCurrentCallback(-1),
|
||||
mElementIsBeingCreated(false),
|
||||
mCreatedCallbackInvoked(true),
|
||||
mAssociatedMicroTask(-1)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
CustomElementData::RunCallbackQueue()
|
||||
{
|
||||
// Note: It's possible to re-enter this method.
|
||||
while (static_cast<uint32_t>(++mCurrentCallback) < mCallbackQueue.Length()) {
|
||||
mCallbackQueue[mCurrentCallback]->Call();
|
||||
}
|
||||
|
||||
mCallbackQueue.Clear();
|
||||
mCurrentCallback = -1;
|
||||
}
|
||||
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
||||
|
||||
void
|
||||
nsIdentifierMapEntry::FireChangeCallbacks(Element* aOldElement,
|
||||
Element* aNewElement,
|
||||
@ -1494,12 +1346,6 @@ nsDocument::nsDocument(const char* aContentType)
|
||||
// void state used to differentiate an empty source from an unselected source
|
||||
mPreloadPictureFoundSource.SetIsVoid(true);
|
||||
|
||||
if (!sProcessingStack) {
|
||||
sProcessingStack.emplace();
|
||||
// Add the base queue sentinel to the processing stack.
|
||||
sProcessingStack->AppendElement((CustomElementData*) nullptr);
|
||||
}
|
||||
|
||||
mEverInForeground = false;
|
||||
}
|
||||
|
||||
@ -1617,8 +1463,6 @@ nsDocument::~nsDocument()
|
||||
mInDestructor = true;
|
||||
mInUnlinkOrDeletion = true;
|
||||
|
||||
mRegistry = nullptr;
|
||||
|
||||
mozilla::DropJSObjects(this);
|
||||
|
||||
// Clear mObservers to keep it in sync with the mutationobserver list
|
||||
@ -1792,7 +1636,7 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INTERNAL(nsDocument)
|
||||
uint32_t nsid = tmp->GetDefaultNamespaceID();
|
||||
nsAutoCString uri;
|
||||
if (tmp->mDocumentURI)
|
||||
tmp->mDocumentURI->GetSpec(uri);
|
||||
uri = tmp->mDocumentURI->GetSpecOrDefault();
|
||||
if (nsid < ArrayLength(kNSURIs)) {
|
||||
SprintfLiteral(name, "nsDocument %s %s %s",
|
||||
loadedAsData.get(), kNSURIs[nsid], uri.get());
|
||||
@ -1890,7 +1734,6 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INTERNAL(nsDocument)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mPendingAnimationTracker)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mTemplateContentsOwner)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mChildrenCollection)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mRegistry)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mAnonymousContents)
|
||||
|
||||
// Traverse all our nsCOMArrays.
|
||||
@ -1975,7 +1818,6 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(nsDocument)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK(mPendingAnimationTracker)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK(mTemplateContentsOwner)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK(mChildrenCollection)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK(mRegistry)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK(mMasterDocument)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK(mOrientationPendingPromise)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK(mImportManager)
|
||||
@ -2187,9 +2029,8 @@ nsDocument::ResetToURI(nsIURI *aURI, nsILoadGroup *aLoadGroup,
|
||||
NS_PRECONDITION(aURI, "Null URI passed to ResetToURI");
|
||||
|
||||
if (gDocumentLeakPRLog && MOZ_LOG_TEST(gDocumentLeakPRLog, LogLevel::Debug)) {
|
||||
nsAutoCString spec;
|
||||
aURI->GetSpec(spec);
|
||||
PR_LogPrint("DOCUMENT %p ResetToURI %s", this, spec.get());
|
||||
PR_LogPrint("DOCUMENT %p ResetToURI %s", this,
|
||||
aURI->GetSpecOrDefault().get());
|
||||
}
|
||||
|
||||
mSecurityInfo = nullptr;
|
||||
@ -2226,13 +2067,6 @@ nsDocument::ResetToURI(nsIURI *aURI, nsILoadGroup *aLoadGroup,
|
||||
}
|
||||
mInUnlinkOrDeletion = oldVal;
|
||||
|
||||
if (!mMasterDocument) {
|
||||
// "When creating an import, use the registry of the master document."
|
||||
// Note: at this point the mMasterDocument is already set for imports
|
||||
// (and only for imports)
|
||||
mRegistry = nullptr;
|
||||
}
|
||||
|
||||
// Reset our stylesheets
|
||||
ResetStylesheetsToURI(aURI);
|
||||
|
||||
@ -2528,10 +2362,8 @@ nsDocument::StartDocumentLoad(const char* aCommand, nsIChannel* aChannel,
|
||||
if (gDocumentLeakPRLog && MOZ_LOG_TEST(gDocumentLeakPRLog, LogLevel::Debug)) {
|
||||
nsCOMPtr<nsIURI> uri;
|
||||
aChannel->GetURI(getter_AddRefs(uri));
|
||||
nsAutoCString spec;
|
||||
if (uri)
|
||||
uri->GetSpec(spec);
|
||||
PR_LogPrint("DOCUMENT %p StartDocumentLoad %s", this, spec.get());
|
||||
PR_LogPrint("DOCUMENT %p StartDocumentLoad %s",
|
||||
this, uri ? uri->GetSpecOrDefault().get() : "");
|
||||
}
|
||||
|
||||
MOZ_ASSERT(NodePrincipal()->GetAppId() != nsIScriptSecurityManager::UNKNOWN_APP_ID,
|
||||
@ -4735,10 +4567,6 @@ nsDocument::SetScriptGlobalObject(nsIScriptGlobalObject *aScriptGlobalObject)
|
||||
}
|
||||
|
||||
MaybeRescheduleAnimationFrameNotifications();
|
||||
if (Preferences::GetBool("dom.webcomponents.enabled") ||
|
||||
Preferences::GetBool("dom.webcomponents.customelements.enabled")) {
|
||||
mRegistry = new Registry();
|
||||
}
|
||||
}
|
||||
|
||||
// Remember the pointer to our window (or lack there of), to avoid
|
||||
@ -5564,26 +5392,29 @@ bool IsLowercaseASCII(const nsAString& aValue)
|
||||
return true;
|
||||
}
|
||||
|
||||
CustomElementDefinition*
|
||||
nsDocument::LookupCustomElementDefinition(const nsAString& aLocalName,
|
||||
uint32_t aNameSpaceID,
|
||||
const nsAString* aIs)
|
||||
already_AddRefed<mozilla::dom::CustomElementsRegistry>
|
||||
nsDocument::GetCustomElementsRegistry()
|
||||
{
|
||||
if (!mRegistry || aNameSpaceID != kNameSpaceID_XHTML) {
|
||||
nsAutoString contentType;
|
||||
GetContentType(contentType);
|
||||
if (!IsHTMLDocument() &&
|
||||
!contentType.EqualsLiteral("application/xhtml+xml")) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIAtom> localNameAtom = NS_Atomize(aLocalName);
|
||||
nsCOMPtr<nsIAtom> typeAtom = aIs ? NS_Atomize(*aIs) : localNameAtom;
|
||||
|
||||
CustomElementDefinition* data;
|
||||
CustomElementHashKey key(aNameSpaceID, typeAtom);
|
||||
if (mRegistry->mCustomDefinitions.Get(&key, &data) &&
|
||||
data->mLocalName == localNameAtom) {
|
||||
return data;
|
||||
nsCOMPtr<nsPIDOMWindowInner> window(
|
||||
do_QueryInterface(mScriptGlobalObject ? mScriptGlobalObject
|
||||
: GetScopeObject()));
|
||||
if (!window) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
RefPtr<CustomElementsRegistry> registry = window->CustomElements();
|
||||
if (!registry) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return registry.forget();
|
||||
}
|
||||
|
||||
already_AddRefed<Element>
|
||||
@ -5615,48 +5446,6 @@ nsDocument::CreateElement(const nsAString& aTagName,
|
||||
return elem.forget();
|
||||
}
|
||||
|
||||
void
|
||||
nsDocument::SetupCustomElement(Element* aElement,
|
||||
uint32_t aNamespaceID,
|
||||
const nsAString* aTypeExtension)
|
||||
{
|
||||
if (!mRegistry || aNamespaceID != kNameSpaceID_XHTML) {
|
||||
return;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIAtom> tagAtom = aElement->NodeInfo()->NameAtom();
|
||||
nsCOMPtr<nsIAtom> typeAtom = aTypeExtension ?
|
||||
NS_Atomize(*aTypeExtension) : tagAtom;
|
||||
|
||||
if (aTypeExtension && !aElement->HasAttr(kNameSpaceID_None, nsGkAtoms::is)) {
|
||||
// Custom element setup in the parser happens after the "is"
|
||||
// attribute is added.
|
||||
aElement->SetAttr(kNameSpaceID_None, nsGkAtoms::is, *aTypeExtension, true);
|
||||
}
|
||||
|
||||
CustomElementDefinition* data = LookupCustomElementDefinition(
|
||||
aElement->NodeInfo()->LocalName(), aNamespaceID, aTypeExtension);
|
||||
|
||||
if (!data) {
|
||||
// The type extension doesn't exist in the registry,
|
||||
// thus we don't need to enqueue callback or adjust
|
||||
// the "is" attribute, but it is possibly an upgrade candidate.
|
||||
RegisterUnresolvedElement(aElement, typeAtom);
|
||||
return;
|
||||
}
|
||||
|
||||
if (data->mLocalName != tagAtom) {
|
||||
// The element doesn't match the local name for the
|
||||
// definition, thus the element isn't a custom element
|
||||
// and we don't need to do anything more.
|
||||
return;
|
||||
}
|
||||
|
||||
// Enqueuing the created callback will set the CustomElementData on the
|
||||
// element, causing prototype swizzling to occur in Element::WrapObject.
|
||||
EnqueueLifecycleCallback(nsIDocument::eCreated, aElement, nullptr, data);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDocument::CreateElementNS(const nsAString& aNamespaceURI,
|
||||
const nsAString& aQualifiedName,
|
||||
@ -5916,25 +5705,28 @@ nsDocument::CustomElementConstructor(JSContext* aCx, unsigned aArgc, JS::Value*
|
||||
return true;
|
||||
}
|
||||
|
||||
RefPtr<mozilla::dom::CustomElementsRegistry> registry = window->CustomElements();
|
||||
if (!registry) {
|
||||
return true;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIAtom> typeAtom(NS_Atomize(elemName));
|
||||
CustomElementHashKey key(kNameSpaceID_Unknown, typeAtom);
|
||||
CustomElementDefinition* definition;
|
||||
if (!document->mRegistry ||
|
||||
!document->mRegistry->mCustomDefinitions.Get(&key, &definition)) {
|
||||
CustomElementDefinition* definition = registry->mCustomDefinitions.Get(typeAtom);
|
||||
if (!definition) {
|
||||
return true;
|
||||
}
|
||||
|
||||
nsDependentAtomString localName(definition->mLocalName);
|
||||
|
||||
nsCOMPtr<Element> element =
|
||||
document->CreateElem(localName, nullptr, definition->mNamespaceID);
|
||||
document->CreateElem(localName, nullptr, kNameSpaceID_XHTML);
|
||||
NS_ENSURE_TRUE(element, true);
|
||||
|
||||
if (definition->mLocalName != typeAtom) {
|
||||
// This element is a custom element by extension, thus we need to
|
||||
// do some special setup. For non-extended custom elements, this happens
|
||||
// when the element is created.
|
||||
document->SetupCustomElement(element, definition->mNamespaceID, &elemName);
|
||||
nsContentUtils::SetupCustomElement(element, &elemName);
|
||||
}
|
||||
|
||||
nsresult rv = nsContentUtils::WrapNative(aCx, element, element, args.rval());
|
||||
@ -5975,256 +5767,22 @@ nsDocument::IsWebComponentsEnabled(JSContext* aCx, JSObject* aObject)
|
||||
return false;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsDocument::RegisterUnresolvedElement(Element* aElement, nsIAtom* aTypeName)
|
||||
{
|
||||
if (!mRegistry) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
mozilla::dom::NodeInfo* info = aElement->NodeInfo();
|
||||
|
||||
// Candidate may be a custom element through extension,
|
||||
// in which case the custom element type name will not
|
||||
// match the element tag name. e.g. <button is="x-button">.
|
||||
nsCOMPtr<nsIAtom> typeName = aTypeName;
|
||||
if (!typeName) {
|
||||
typeName = info->NameAtom();
|
||||
}
|
||||
|
||||
CustomElementHashKey key(info->NamespaceID(), typeName);
|
||||
if (mRegistry->mCustomDefinitions.Get(&key)) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsTArray<nsWeakPtr>* unresolved;
|
||||
mRegistry->mCandidatesMap.Get(&key, &unresolved);
|
||||
if (!unresolved) {
|
||||
unresolved = new nsTArray<nsWeakPtr>();
|
||||
// Ownership of unresolved is taken by mCandidatesMap.
|
||||
mRegistry->mCandidatesMap.Put(&key, unresolved);
|
||||
}
|
||||
|
||||
nsWeakPtr* elem = unresolved->AppendElement();
|
||||
*elem = do_GetWeakReference(aElement);
|
||||
aElement->AddStates(NS_EVENT_STATE_UNRESOLVED);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void
|
||||
nsDocument::EnqueueLifecycleCallback(nsIDocument::ElementCallbackType aType,
|
||||
Element* aCustomElement,
|
||||
LifecycleCallbackArgs* aArgs,
|
||||
CustomElementDefinition* aDefinition)
|
||||
{
|
||||
if (!mRegistry) {
|
||||
// The element might not belong to a document that
|
||||
// has a browsing context, and thus no registry.
|
||||
return;
|
||||
}
|
||||
|
||||
CustomElementData* elementData = aCustomElement->GetCustomElementData();
|
||||
|
||||
// Let DEFINITION be ELEMENT's definition
|
||||
CustomElementDefinition* definition = aDefinition;
|
||||
if (!definition) {
|
||||
mozilla::dom::NodeInfo* info = aCustomElement->NodeInfo();
|
||||
|
||||
// Make sure we get the correct definition in case the element
|
||||
// is a extended custom element e.g. <button is="x-button">.
|
||||
nsCOMPtr<nsIAtom> typeAtom = elementData ?
|
||||
elementData->mType.get() : info->NameAtom();
|
||||
|
||||
CustomElementHashKey key(info->NamespaceID(), typeAtom);
|
||||
if (!mRegistry->mCustomDefinitions.Get(&key, &definition) ||
|
||||
definition->mLocalName != info->NameAtom()) {
|
||||
// Trying to enqueue a callback for an element that is not
|
||||
// a custom element. We are done, nothing to do.
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (!elementData) {
|
||||
// Create the custom element data the first time
|
||||
// that we try to enqueue a callback.
|
||||
elementData = new CustomElementData(definition->mType);
|
||||
// aCustomElement takes ownership of elementData
|
||||
aCustomElement->SetCustomElementData(elementData);
|
||||
MOZ_ASSERT(aType == nsIDocument::eCreated,
|
||||
"First callback should be the created callback");
|
||||
}
|
||||
|
||||
// Let CALLBACK be the callback associated with the key NAME in CALLBACKS.
|
||||
CallbackFunction* func = nullptr;
|
||||
switch (aType) {
|
||||
case nsIDocument::eCreated:
|
||||
if (definition->mCallbacks->mCreatedCallback.WasPassed()) {
|
||||
func = definition->mCallbacks->mCreatedCallback.Value();
|
||||
}
|
||||
break;
|
||||
|
||||
case nsIDocument::eAttached:
|
||||
if (definition->mCallbacks->mAttachedCallback.WasPassed()) {
|
||||
func = definition->mCallbacks->mAttachedCallback.Value();
|
||||
}
|
||||
break;
|
||||
|
||||
case nsIDocument::eDetached:
|
||||
if (definition->mCallbacks->mDetachedCallback.WasPassed()) {
|
||||
func = definition->mCallbacks->mDetachedCallback.Value();
|
||||
}
|
||||
break;
|
||||
|
||||
case nsIDocument::eAttributeChanged:
|
||||
if (definition->mCallbacks->mAttributeChangedCallback.WasPassed()) {
|
||||
func = definition->mCallbacks->mAttributeChangedCallback.Value();
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
// If there is no such callback, stop.
|
||||
if (!func) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (aType == nsIDocument::eCreated) {
|
||||
elementData->mCreatedCallbackInvoked = false;
|
||||
} else if (!elementData->mCreatedCallbackInvoked) {
|
||||
// Callbacks other than created callback must not be enqueued
|
||||
// until after the created callback has been invoked.
|
||||
return;
|
||||
}
|
||||
|
||||
// Add CALLBACK to ELEMENT's callback queue.
|
||||
CustomElementCallback* callback = new CustomElementCallback(aCustomElement,
|
||||
aType,
|
||||
func,
|
||||
elementData);
|
||||
// Ownership of callback is taken by mCallbackQueue.
|
||||
elementData->mCallbackQueue.AppendElement(callback);
|
||||
if (aArgs) {
|
||||
callback->SetArgs(*aArgs);
|
||||
}
|
||||
|
||||
if (!elementData->mElementIsBeingCreated) {
|
||||
CustomElementData* lastData =
|
||||
sProcessingStack->SafeLastElement(nullptr);
|
||||
|
||||
// A new element queue needs to be pushed if the queue at the
|
||||
// top of the stack is associated with another microtask level.
|
||||
bool shouldPushElementQueue =
|
||||
(!lastData || lastData->mAssociatedMicroTask <
|
||||
static_cast<int32_t>(nsContentUtils::MicroTaskLevel()));
|
||||
|
||||
// Push a new element queue onto the processing stack when appropriate
|
||||
// (when we enter a new microtask).
|
||||
if (shouldPushElementQueue) {
|
||||
// Push a sentinel value on the processing stack to mark the
|
||||
// boundary between the element queues.
|
||||
sProcessingStack->AppendElement((CustomElementData*) nullptr);
|
||||
}
|
||||
|
||||
sProcessingStack->AppendElement(elementData);
|
||||
elementData->mAssociatedMicroTask =
|
||||
static_cast<int32_t>(nsContentUtils::MicroTaskLevel());
|
||||
|
||||
// Add a script runner to pop and process the element queue at
|
||||
// the top of the processing stack.
|
||||
if (shouldPushElementQueue) {
|
||||
// Lifecycle callbacks enqueued by user agent implementation
|
||||
// should be invoked prior to returning control back to script.
|
||||
// Create a script runner to process the top of the processing
|
||||
// stack as soon as it is safe to run script.
|
||||
nsCOMPtr<nsIRunnable> runnable =
|
||||
NS_NewRunnableFunction(&nsDocument::ProcessTopElementQueue);
|
||||
nsContentUtils::AddScriptRunner(runnable);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// static
|
||||
void
|
||||
nsDocument::ProcessTopElementQueue()
|
||||
{
|
||||
MOZ_ASSERT(nsContentUtils::IsSafeToRunScript());
|
||||
|
||||
nsTArray<RefPtr<CustomElementData>>& stack = *sProcessingStack;
|
||||
uint32_t firstQueue = stack.LastIndexOf((CustomElementData*) nullptr);
|
||||
|
||||
for (uint32_t i = firstQueue + 1; i < stack.Length(); ++i) {
|
||||
// Callback queue may have already been processed in an earlier
|
||||
// element queue or in an element queue that was popped
|
||||
// off more recently.
|
||||
if (stack[i]->mAssociatedMicroTask != -1) {
|
||||
stack[i]->RunCallbackQueue();
|
||||
stack[i]->mAssociatedMicroTask = -1;
|
||||
}
|
||||
}
|
||||
|
||||
// If this was actually the base element queue, don't bother trying to pop
|
||||
// the first "queue" marker (sentinel).
|
||||
if (firstQueue != 0) {
|
||||
stack.SetLength(firstQueue);
|
||||
} else {
|
||||
// Don't pop sentinel for base element queue.
|
||||
stack.SetLength(1);
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
nsDocument::RegisterEnabled()
|
||||
{
|
||||
static bool sPrefValue =
|
||||
Preferences::GetBool("dom.webcomponents.enabled", false);
|
||||
return sPrefValue;
|
||||
}
|
||||
|
||||
// static
|
||||
Maybe<nsTArray<RefPtr<mozilla::dom::CustomElementData>>>
|
||||
nsDocument::sProcessingStack;
|
||||
|
||||
void
|
||||
nsDocument::RegisterElement(JSContext* aCx, const nsAString& aType,
|
||||
const ElementRegistrationOptions& aOptions,
|
||||
JS::MutableHandle<JSObject*> aRetval,
|
||||
ErrorResult& rv)
|
||||
{
|
||||
if (!mRegistry) {
|
||||
RefPtr<CustomElementsRegistry> registry(GetCustomElementsRegistry());
|
||||
if (!registry) {
|
||||
rv.Throw(NS_ERROR_DOM_NOT_SUPPORTED_ERR);
|
||||
return;
|
||||
}
|
||||
|
||||
Registry::DefinitionMap& definitions = mRegistry->mCustomDefinitions;
|
||||
|
||||
// Unconditionally convert TYPE to lowercase.
|
||||
nsAutoString lcType;
|
||||
nsContentUtils::ASCIIToLower(aType, lcType);
|
||||
|
||||
// Only convert NAME to lowercase in HTML documents. Note that NAME is
|
||||
// options.extends.
|
||||
nsAutoString lcName;
|
||||
if (IsHTMLDocument()) {
|
||||
nsContentUtils::ASCIIToLower(aOptions.mExtends, lcName);
|
||||
} else {
|
||||
lcName.Assign(aOptions.mExtends);
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIAtom> typeAtom(NS_Atomize(lcType));
|
||||
if (!nsContentUtils::IsCustomElementName(typeAtom)) {
|
||||
rv.Throw(NS_ERROR_DOM_SYNTAX_ERR);
|
||||
return;
|
||||
}
|
||||
|
||||
// If there already exists a definition with the same TYPE, set ERROR to
|
||||
// DuplicateDefinition and stop.
|
||||
// Note that we need to find existing custom elements from either namespace.
|
||||
CustomElementHashKey duplicateFinder(kNameSpaceID_Unknown, typeAtom);
|
||||
if (definitions.Get(&duplicateFinder)) {
|
||||
rv.Throw(NS_ERROR_DOM_NOT_SUPPORTED_ERR);
|
||||
return;
|
||||
}
|
||||
|
||||
nsIGlobalObject* sgo = GetScopeObject();
|
||||
if (!sgo) {
|
||||
rv.Throw(NS_ERROR_UNEXPECTED);
|
||||
@ -6232,180 +5790,59 @@ nsDocument::RegisterElement(JSContext* aCx, const nsAString& aType,
|
||||
}
|
||||
|
||||
JS::Rooted<JSObject*> global(aCx, sgo->GetGlobalJSObject());
|
||||
nsCOMPtr<nsIAtom> nameAtom;
|
||||
int32_t namespaceID = kNameSpaceID_XHTML;
|
||||
JS::Rooted<JSObject*> protoObject(aCx);
|
||||
{
|
||||
|
||||
if (!aOptions.mPrototype) {
|
||||
JS::Rooted<JSObject*> htmlProto(aCx);
|
||||
{
|
||||
JSAutoCompartment ac(aCx, global);
|
||||
|
||||
htmlProto = HTMLElementBinding::GetProtoObjectHandle(aCx);
|
||||
if (!htmlProto) {
|
||||
rv.Throw(NS_ERROR_OUT_OF_MEMORY);
|
||||
return;
|
||||
}
|
||||
htmlProto = HTMLElementBinding::GetProtoObjectHandle(aCx);
|
||||
if (!htmlProto) {
|
||||
rv.Throw(NS_ERROR_OUT_OF_MEMORY);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!aOptions.mPrototype) {
|
||||
if (!JS_WrapObject(aCx, &htmlProto)) {
|
||||
rv.Throw(NS_ERROR_DOM_NOT_SUPPORTED_ERR);
|
||||
return;
|
||||
}
|
||||
|
||||
protoObject = JS_NewObjectWithGivenProto(aCx, nullptr, htmlProto);
|
||||
if (!protoObject) {
|
||||
rv.Throw(NS_ERROR_UNEXPECTED);
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
protoObject = aOptions.mPrototype;
|
||||
|
||||
// Get the unwrapped prototype to do some checks.
|
||||
JS::Rooted<JSObject*> protoObjectUnwrapped(aCx, js::CheckedUnwrap(protoObject));
|
||||
if (!protoObjectUnwrapped) {
|
||||
// If the caller's compartment does not have permission to access the
|
||||
// unwrapped prototype then throw.
|
||||
rv.Throw(NS_ERROR_DOM_SECURITY_ERR);
|
||||
return;
|
||||
}
|
||||
|
||||
// If PROTOTYPE is already an interface prototype object for any interface
|
||||
// object or PROTOTYPE has a non-configurable property named constructor,
|
||||
// throw a NotSupportedError and stop.
|
||||
const js::Class* clasp = js::GetObjectClass(protoObjectUnwrapped);
|
||||
if (IsDOMIfaceAndProtoClass(clasp)) {
|
||||
rv.Throw(NS_ERROR_DOM_NOT_SUPPORTED_ERR);
|
||||
return;
|
||||
}
|
||||
|
||||
JS::Rooted<JS::PropertyDescriptor> descRoot(aCx);
|
||||
JS::MutableHandle<JS::PropertyDescriptor> desc(&descRoot);
|
||||
// This check may go through a wrapper, but as we checked above
|
||||
// it should be transparent or an xray. This should be fine for now,
|
||||
// until the spec is sorted out.
|
||||
if (!JS_GetPropertyDescriptor(aCx, protoObject, "constructor", desc)) {
|
||||
rv.Throw(NS_ERROR_UNEXPECTED);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!desc.configurable()) {
|
||||
rv.Throw(NS_ERROR_DOM_NOT_SUPPORTED_ERR);
|
||||
return;
|
||||
}
|
||||
|
||||
JS::Rooted<JSObject*> protoProto(aCx, protoObject);
|
||||
|
||||
if (!JS_WrapObject(aCx, &htmlProto)) {
|
||||
rv.Throw(NS_ERROR_DOM_NOT_SUPPORTED_ERR);
|
||||
return;
|
||||
}
|
||||
|
||||
while (protoProto) {
|
||||
if (protoProto == htmlProto) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (!JS_GetPrototype(aCx, protoProto, &protoProto)) {
|
||||
rv.Throw(NS_ERROR_UNEXPECTED);
|
||||
return;
|
||||
}
|
||||
}
|
||||
} // Done with the checks, leave prototype's compartment.
|
||||
|
||||
// If name was provided and not null...
|
||||
if (!lcName.IsEmpty()) {
|
||||
// Let BASE be the element interface for NAME and NAMESPACE.
|
||||
nameAtom = NS_Atomize(lcName);
|
||||
nsIParserService* ps = nsContentUtils::GetParserService();
|
||||
if (!ps) {
|
||||
rv.Throw(NS_ERROR_UNEXPECTED);
|
||||
return;
|
||||
}
|
||||
|
||||
bool known =
|
||||
ps->HTMLCaseSensitiveAtomTagToId(nameAtom) != eHTMLTag_userdefined;
|
||||
|
||||
// If BASE does not exist or is an interface for a custom element, set ERROR
|
||||
// to InvalidName and stop.
|
||||
// If BASE exists, then it cannot be an interface for a custom element.
|
||||
if (!known) {
|
||||
rv.Throw(NS_ERROR_DOM_SYNTAX_ERR);
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
nameAtom = typeAtom;
|
||||
protoObject = JS_NewObjectWithGivenProto(aCx, nullptr, htmlProto);
|
||||
if (!protoObject) {
|
||||
rv.Throw(NS_ERROR_UNEXPECTED);
|
||||
return;
|
||||
}
|
||||
} // Leaving the document's compartment for the LifecycleCallbacks init
|
||||
} else {
|
||||
protoObject = aOptions.mPrototype;
|
||||
|
||||
JS::Rooted<JSObject*> wrappedProto(aCx, protoObject);
|
||||
if (!JS_WrapObject(aCx, &wrappedProto)) {
|
||||
rv.Throw(NS_ERROR_DOM_NOT_SUPPORTED_ERR);
|
||||
return;
|
||||
}
|
||||
// Get the unwrapped prototype to do some checks.
|
||||
JS::Rooted<JSObject*> protoObjectUnwrapped(aCx, js::CheckedUnwrap(protoObject));
|
||||
if (!protoObjectUnwrapped) {
|
||||
// If the caller's compartment does not have permission to access the
|
||||
// unwrapped prototype then throw.
|
||||
rv.Throw(NS_ERROR_DOM_SECURITY_ERR);
|
||||
return;
|
||||
}
|
||||
|
||||
// Note: We call the init from the caller compartment here
|
||||
nsAutoPtr<LifecycleCallbacks> callbacksHolder(new LifecycleCallbacks());
|
||||
JS::RootedValue rootedv(aCx, JS::ObjectValue(*wrappedProto));
|
||||
if (!JS_WrapValue(aCx, &rootedv) || !callbacksHolder->Init(aCx, rootedv)) {
|
||||
rv.Throw(NS_ERROR_FAILURE);
|
||||
return;
|
||||
}
|
||||
// If PROTOTYPE is already an interface prototype object for any interface
|
||||
// object or PROTOTYPE has a non-configurable property named constructor,
|
||||
// throw a NotSupportedError and stop.
|
||||
const js::Class* clasp = js::GetObjectClass(protoObjectUnwrapped);
|
||||
if (IsDOMIfaceAndProtoClass(clasp)) {
|
||||
rv.Throw(NS_ERROR_DOM_NOT_SUPPORTED_ERR);
|
||||
return;
|
||||
}
|
||||
|
||||
// Associate the definition with the custom element.
|
||||
CustomElementHashKey key(namespaceID, typeAtom);
|
||||
LifecycleCallbacks* callbacks = callbacksHolder.forget();
|
||||
CustomElementDefinition* definition =
|
||||
new CustomElementDefinition(wrappedProto,
|
||||
typeAtom,
|
||||
nameAtom,
|
||||
callbacks,
|
||||
namespaceID,
|
||||
0 /* TODO dependent on HTML imports. Bug 877072 */);
|
||||
definitions.Put(&key, definition);
|
||||
JS::Rooted<JS::PropertyDescriptor> descRoot(aCx);
|
||||
JS::MutableHandle<JS::PropertyDescriptor> desc(&descRoot);
|
||||
// This check may go through a wrapper, but as we checked above
|
||||
// it should be transparent or an xray. This should be fine for now,
|
||||
// until the spec is sorted out.
|
||||
if (!JS_GetPropertyDescriptor(aCx, protoObject, "constructor", desc)) {
|
||||
rv.Throw(NS_ERROR_UNEXPECTED);
|
||||
return;
|
||||
}
|
||||
|
||||
// Do element upgrade.
|
||||
nsAutoPtr<nsTArray<nsWeakPtr>> candidates;
|
||||
mRegistry->mCandidatesMap.RemoveAndForget(&key, candidates);
|
||||
if (candidates) {
|
||||
for (size_t i = 0; i < candidates->Length(); ++i) {
|
||||
nsCOMPtr<Element> elem = do_QueryReferent(candidates->ElementAt(i));
|
||||
if (!elem) {
|
||||
continue;
|
||||
}
|
||||
|
||||
elem->RemoveStates(NS_EVENT_STATE_UNRESOLVED);
|
||||
|
||||
// Make sure that the element name matches the name in the definition.
|
||||
// (e.g. a definition for x-button extending button should match
|
||||
// <button is="x-button"> but not <x-button>.
|
||||
if (elem->NodeInfo()->NameAtom() != nameAtom) {
|
||||
//Skip over this element because definition does not apply.
|
||||
continue;
|
||||
}
|
||||
|
||||
MOZ_ASSERT(elem->IsHTMLElement(nameAtom));
|
||||
nsWrapperCache* cache;
|
||||
CallQueryInterface(elem, &cache);
|
||||
MOZ_ASSERT(cache, "Element doesn't support wrapper cache?");
|
||||
|
||||
// We want to set the custom prototype in the caller's comparment.
|
||||
// In the case that element is in a different compartment,
|
||||
// this will set the prototype on the element's wrapper and
|
||||
// thus only visible in the wrapper's compartment.
|
||||
JS::RootedObject wrapper(aCx);
|
||||
if ((wrapper = cache->GetWrapper()) && JS_WrapObject(aCx, &wrapper)) {
|
||||
if (!JS_SetPrototype(aCx, wrapper, wrappedProto)) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
EnqueueLifecycleCallback(nsIDocument::eCreated, elem, nullptr, definition);
|
||||
if (!desc.configurable()) {
|
||||
rv.Throw(NS_ERROR_DOM_NOT_SUPPORTED_ERR);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
JS::Rooted<JSFunction*> constructor(aCx);
|
||||
|
||||
{
|
||||
// Go into the document's global compartment when creating the constructor
|
||||
// function because we want to get the correct document (where the
|
||||
@ -6435,15 +5872,22 @@ nsDocument::RegisterElement(JSContext* aCx, const nsAString& aType,
|
||||
return;
|
||||
}
|
||||
|
||||
aRetval.set(wrappedConstructor);
|
||||
}
|
||||
ElementDefinitionOptions options;
|
||||
if (!aOptions.mExtends.IsVoid()) {
|
||||
// Only convert NAME to lowercase in HTML documents.
|
||||
nsAutoString lcName;
|
||||
IsHTMLDocument() ? nsContentUtils::ASCIIToLower(aOptions.mExtends, lcName)
|
||||
: lcName.Assign(aOptions.mExtends);
|
||||
|
||||
void
|
||||
nsDocument::UseRegistryFromDocument(nsIDocument* aDocument)
|
||||
{
|
||||
nsDocument* doc = static_cast<nsDocument*>(aDocument);
|
||||
MOZ_ASSERT(!mRegistry, "There should be no existing registry.");
|
||||
mRegistry = doc->mRegistry;
|
||||
options.mExtends.Construct(lcName);
|
||||
}
|
||||
|
||||
RootedCallback<OwningNonNull<binding_detail::FastFunction>> functionConstructor(aCx);
|
||||
functionConstructor = new binding_detail::FastFunction(aCx, wrappedConstructor, sgo);
|
||||
|
||||
registry->Define(lcType, functionConstructor, options, rv);
|
||||
|
||||
aRetval.set(wrappedConstructor);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
@ -8990,8 +8434,6 @@ nsDocument::Destroy()
|
||||
// leak-fixing if we fix nsDocumentViewer to do cycle-collection, but
|
||||
// tearing down all those frame trees right now is the right thing to do.
|
||||
mExternalResourceMap.Shutdown();
|
||||
|
||||
mRegistry = nullptr;
|
||||
}
|
||||
|
||||
void
|
||||
@ -10344,7 +9786,8 @@ nsIDocument::CreateStaticClone(nsIDocShell* aCloneContainer)
|
||||
if (sheet->IsGecko()) {
|
||||
RefPtr<CSSStyleSheet> clonedSheet =
|
||||
sheet->AsGecko()->Clone(nullptr, nullptr, clonedDoc, nullptr);
|
||||
NS_WARN_IF_FALSE(clonedSheet, "Cloning a stylesheet didn't work!");
|
||||
NS_WARNING_ASSERTION(clonedSheet,
|
||||
"Cloning a stylesheet didn't work!");
|
||||
if (clonedSheet) {
|
||||
clonedDoc->AddStyleSheet(clonedSheet);
|
||||
}
|
||||
@ -10363,7 +9806,8 @@ nsIDocument::CreateStaticClone(nsIDocShell* aCloneContainer)
|
||||
if (sheet->IsGecko()) {
|
||||
RefPtr<CSSStyleSheet> clonedSheet =
|
||||
sheet->AsGecko()->Clone(nullptr, nullptr, clonedDoc, nullptr);
|
||||
NS_WARN_IF_FALSE(clonedSheet, "Cloning a stylesheet didn't work!");
|
||||
NS_WARNING_ASSERTION(clonedSheet,
|
||||
"Cloning a stylesheet didn't work!");
|
||||
if (clonedSheet) {
|
||||
clonedDoc->AddOnDemandBuiltInUASheet(clonedSheet);
|
||||
}
|
||||
@ -12419,8 +11863,10 @@ nsDocument::SetPointerLock(Element* aElement, int aCursorStyle)
|
||||
nsIFrame* rootFrame = shell->GetRootFrame();
|
||||
if (!NS_WARN_IF(!rootFrame)) {
|
||||
widget = rootFrame->GetNearestWidget();
|
||||
NS_WARN_IF_FALSE(widget, "SetPointerLock(): Unable to find widget "
|
||||
"in shell->GetRootFrame()->GetNearestWidget();");
|
||||
NS_WARNING_ASSERTION(
|
||||
widget,
|
||||
"SetPointerLock(): Unable to find widget in "
|
||||
"shell->GetRootFrame()->GetNearestWidget();");
|
||||
if (aElement && !widget) {
|
||||
return false;
|
||||
}
|
||||
@ -12576,12 +12022,6 @@ nsDocument::OnAppThemeChanged()
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
nsDocument::XPCOMShutdown()
|
||||
{
|
||||
sProcessingStack.reset();
|
||||
}
|
||||
|
||||
void
|
||||
nsDocument::UpdateVisibilityState()
|
||||
{
|
||||
@ -13055,8 +12495,7 @@ nsDocument::ReportUseCounters()
|
||||
}
|
||||
|
||||
if (sDebugUseCounters) {
|
||||
nsCString spec;
|
||||
uri->GetSpec(spec);
|
||||
nsCString spec = uri->GetSpecOrDefault();
|
||||
|
||||
// URIs can be rather long for data documents, so truncate them to
|
||||
// some reasonable length.
|
||||
@ -13467,7 +12906,8 @@ nsDocument::CheckCustomElementName(const ElementCreationOptions& aOptions,
|
||||
nsString* is = const_cast<nsString*>(&(aOptions.mIs.Value()));
|
||||
|
||||
// Throw NotFoundError if 'is' is not-null and definition is null
|
||||
if (!LookupCustomElementDefinition(aLocalName, aNamespaceID, is)) {
|
||||
if (!nsContentUtils::LookupCustomElementDefinition(this, aLocalName,
|
||||
aNamespaceID, is)) {
|
||||
rv.Throw(NS_ERROR_DOM_NOT_FOUND_ERR);
|
||||
}
|
||||
|
||||
|
@ -263,107 +263,6 @@ private:
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
struct LifecycleCallbackArgs
|
||||
{
|
||||
nsString name;
|
||||
nsString oldValue;
|
||||
nsString newValue;
|
||||
};
|
||||
|
||||
struct CustomElementData;
|
||||
|
||||
class CustomElementCallback
|
||||
{
|
||||
public:
|
||||
CustomElementCallback(Element* aThisObject,
|
||||
nsIDocument::ElementCallbackType aCallbackType,
|
||||
mozilla::dom::CallbackFunction* aCallback,
|
||||
CustomElementData* aOwnerData);
|
||||
void Traverse(nsCycleCollectionTraversalCallback& aCb) const;
|
||||
void Call();
|
||||
void SetArgs(LifecycleCallbackArgs& aArgs)
|
||||
{
|
||||
MOZ_ASSERT(mType == nsIDocument::eAttributeChanged,
|
||||
"Arguments are only used by attribute changed callback.");
|
||||
mArgs = aArgs;
|
||||
}
|
||||
|
||||
private:
|
||||
// The this value to use for invocation of the callback.
|
||||
RefPtr<mozilla::dom::Element> mThisObject;
|
||||
RefPtr<mozilla::dom::CallbackFunction> mCallback;
|
||||
// The type of callback (eCreated, eAttached, etc.)
|
||||
nsIDocument::ElementCallbackType mType;
|
||||
// Arguments to be passed to the callback,
|
||||
// used by the attribute changed callback.
|
||||
LifecycleCallbackArgs mArgs;
|
||||
// CustomElementData that contains this callback in the
|
||||
// callback queue.
|
||||
CustomElementData* mOwnerData;
|
||||
};
|
||||
|
||||
// Each custom element has an associated callback queue and an element is
|
||||
// being created flag.
|
||||
struct CustomElementData
|
||||
{
|
||||
NS_INLINE_DECL_REFCOUNTING(CustomElementData)
|
||||
|
||||
explicit CustomElementData(nsIAtom* aType);
|
||||
// Objects in this array are transient and empty after each microtask
|
||||
// checkpoint.
|
||||
nsTArray<nsAutoPtr<CustomElementCallback>> mCallbackQueue;
|
||||
// Custom element type, for <button is="x-button"> or <x-button>
|
||||
// this would be x-button.
|
||||
nsCOMPtr<nsIAtom> mType;
|
||||
// The callback that is next to be processed upon calling RunCallbackQueue.
|
||||
int32_t mCurrentCallback;
|
||||
// Element is being created flag as described in the custom elements spec.
|
||||
bool mElementIsBeingCreated;
|
||||
// Flag to determine if the created callback has been invoked, thus it
|
||||
// determines if other callbacks can be enqueued.
|
||||
bool mCreatedCallbackInvoked;
|
||||
// The microtask level associated with the callbacks in the callback queue,
|
||||
// it is used to determine if a new queue needs to be pushed onto the
|
||||
// processing stack.
|
||||
int32_t mAssociatedMicroTask;
|
||||
|
||||
// Empties the callback queue.
|
||||
void RunCallbackQueue();
|
||||
|
||||
private:
|
||||
virtual ~CustomElementData() {}
|
||||
};
|
||||
|
||||
class Registry : public nsISupports
|
||||
{
|
||||
public:
|
||||
friend class ::nsDocument;
|
||||
|
||||
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
|
||||
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(Registry)
|
||||
|
||||
Registry();
|
||||
|
||||
protected:
|
||||
virtual ~Registry();
|
||||
|
||||
typedef nsClassHashtable<mozilla::dom::CustomElementHashKey,
|
||||
mozilla::dom::CustomElementDefinition>
|
||||
DefinitionMap;
|
||||
typedef nsClassHashtable<mozilla::dom::CustomElementHashKey,
|
||||
nsTArray<nsWeakPtr>>
|
||||
CandidateMap;
|
||||
|
||||
// Hashtable for custom element definitions in web components.
|
||||
// Custom prototypes are stored in the compartment where
|
||||
// registerElement was called.
|
||||
DefinitionMap mCustomDefinitions;
|
||||
|
||||
// The "upgrade candidates map" from the web components spec. Maps from a
|
||||
// namespace id and local name to a list of elements to upgrade if that
|
||||
// element is registered as a custom element.
|
||||
CandidateMap mCandidatesMap;
|
||||
};
|
||||
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
||||
@ -1218,36 +1117,6 @@ public:
|
||||
|
||||
virtual nsIDOMNode* AsDOMNode() override { return this; }
|
||||
|
||||
virtual void EnqueueLifecycleCallback(nsIDocument::ElementCallbackType aType,
|
||||
Element* aCustomElement,
|
||||
mozilla::dom::LifecycleCallbackArgs* aArgs = nullptr,
|
||||
mozilla::dom::CustomElementDefinition* aDefinition = nullptr) override;
|
||||
|
||||
static void ProcessTopElementQueue();
|
||||
|
||||
void GetCustomPrototype(int32_t aNamespaceID,
|
||||
nsIAtom* aAtom,
|
||||
JS::MutableHandle<JSObject*> prototype)
|
||||
{
|
||||
if (!mRegistry) {
|
||||
prototype.set(nullptr);
|
||||
return;
|
||||
}
|
||||
|
||||
mozilla::dom::CustomElementHashKey key(aNamespaceID, aAtom);
|
||||
mozilla::dom::CustomElementDefinition* definition;
|
||||
if (mRegistry->mCustomDefinitions.Get(&key, &definition)) {
|
||||
prototype.set(definition->mPrototype);
|
||||
} else {
|
||||
prototype.set(nullptr);
|
||||
}
|
||||
}
|
||||
|
||||
static bool RegisterEnabled();
|
||||
|
||||
virtual nsresult RegisterUnresolvedElement(mozilla::dom::Element* aElement,
|
||||
nsIAtom* aTypeName = nullptr) override;
|
||||
|
||||
// WebIDL bits
|
||||
virtual mozilla::dom::DOMImplementation*
|
||||
GetImplementation(mozilla::ErrorResult& rv) override;
|
||||
@ -1268,7 +1137,6 @@ public:
|
||||
const nsAString& aQualifiedName,
|
||||
const mozilla::dom::ElementCreationOptions& aOptions,
|
||||
mozilla::ErrorResult& rv) override;
|
||||
virtual void UseRegistryFromDocument(nsIDocument* aDocument) override;
|
||||
|
||||
virtual nsIDocument* MasterDocument() override
|
||||
{
|
||||
@ -1280,7 +1148,6 @@ public:
|
||||
{
|
||||
MOZ_ASSERT(master);
|
||||
mMasterDocument = master;
|
||||
UseRegistryFromDocument(mMasterDocument);
|
||||
}
|
||||
|
||||
virtual bool IsMasterDocument() override
|
||||
@ -1397,8 +1264,6 @@ public:
|
||||
// Set our title
|
||||
virtual void SetTitle(const nsAString& aTitle, mozilla::ErrorResult& rv) override;
|
||||
|
||||
static void XPCOMShutdown();
|
||||
|
||||
bool mIsTopLevelContentDocument: 1;
|
||||
bool mIsContentDocument: 1;
|
||||
|
||||
@ -1503,23 +1368,8 @@ protected:
|
||||
nsWeakPtr mFullscreenRoot;
|
||||
|
||||
private:
|
||||
// Array representing the processing stack in the custom elements
|
||||
// specification. The processing stack is conceptually a stack of
|
||||
// element queues. Each queue is represented by a sequence of
|
||||
// CustomElementData in this array, separated by nullptr that
|
||||
// represent the boundaries of the items in the stack. The first
|
||||
// queue in the stack is the base element queue.
|
||||
static mozilla::Maybe<nsTArray<RefPtr<mozilla::dom::CustomElementData>>> sProcessingStack;
|
||||
|
||||
static bool CustomElementConstructor(JSContext* aCx, unsigned aArgc, JS::Value* aVp);
|
||||
|
||||
/**
|
||||
* Looking up a custom element definition.
|
||||
* https://html.spec.whatwg.org/#look-up-a-custom-element-definition
|
||||
*/
|
||||
mozilla::dom::CustomElementDefinition* LookupCustomElementDefinition(
|
||||
const nsAString& aLocalName, uint32_t aNameSpaceID, const nsAString* aIs);
|
||||
|
||||
/**
|
||||
* Check if the passed custom element name, aOptions.mIs, is a registered
|
||||
* custom element type or not, then return the custom element name for future
|
||||
@ -1535,18 +1385,11 @@ private:
|
||||
ErrorResult& rv);
|
||||
|
||||
public:
|
||||
// Enqueue created callback or register upgrade candidate for
|
||||
// newly created custom elements, possibly extending an existing type.
|
||||
// ex. <x-button>, <button is="x-button> (type extension)
|
||||
virtual void SetupCustomElement(Element* aElement,
|
||||
uint32_t aNamespaceID,
|
||||
const nsAString* aTypeExtension) override;
|
||||
virtual already_AddRefed<mozilla::dom::CustomElementsRegistry>
|
||||
GetCustomElementsRegistry() override;
|
||||
|
||||
static bool IsWebComponentsEnabled(JSContext* aCx, JSObject* aObject);
|
||||
|
||||
// The "registry" from the web components spec.
|
||||
RefPtr<mozilla::dom::Registry> mRegistry;
|
||||
|
||||
RefPtr<mozilla::EventListenerManager> mListenerManager;
|
||||
RefPtr<mozilla::dom::StyleSheetList> mDOMStyleSheets;
|
||||
RefPtr<nsDOMStyleSheetSetList> mStyleSheetSetList;
|
||||
|
@ -512,9 +512,9 @@ nsFocusManager::MoveFocus(mozIDOMWindowProxy* aWindow, nsIDOMElement* aStartElem
|
||||
if (MOZ_LOG_TEST(gFocusLog, LogLevel::Debug) && mFocusedWindow) {
|
||||
nsIDocument* doc = mFocusedWindow->GetExtantDoc();
|
||||
if (doc && doc->GetDocumentURI()) {
|
||||
nsAutoCString spec;
|
||||
doc->GetDocumentURI()->GetSpec(spec);
|
||||
LOGFOCUS((" Focused Window: %p %s", mFocusedWindow.get(), spec.get()));
|
||||
LOGFOCUS((" Focused Window: %p %s",
|
||||
mFocusedWindow.get(),
|
||||
doc->GetDocumentURI()->GetSpecOrDefault().get()));
|
||||
}
|
||||
}
|
||||
|
||||
@ -664,17 +664,16 @@ nsFocusManager::WindowRaised(mozIDOMWindowProxy* aWindow)
|
||||
|
||||
if (MOZ_LOG_TEST(gFocusLog, LogLevel::Debug)) {
|
||||
LOGFOCUS(("Window %p Raised [Currently: %p %p]", aWindow, mActiveWindow.get(), mFocusedWindow.get()));
|
||||
nsAutoCString spec;
|
||||
nsIDocument* doc = window->GetExtantDoc();
|
||||
if (doc && doc->GetDocumentURI()) {
|
||||
doc->GetDocumentURI()->GetSpec(spec);
|
||||
LOGFOCUS((" Raised Window: %p %s", aWindow, spec.get()));
|
||||
LOGFOCUS((" Raised Window: %p %s", aWindow,
|
||||
doc->GetDocumentURI()->GetSpecOrDefault().get()));
|
||||
}
|
||||
if (mActiveWindow) {
|
||||
doc = mActiveWindow->GetExtantDoc();
|
||||
if (doc && doc->GetDocumentURI()) {
|
||||
doc->GetDocumentURI()->GetSpec(spec);
|
||||
LOGFOCUS((" Active Window: %p %s", mActiveWindow.get(), spec.get()));
|
||||
LOGFOCUS((" Active Window: %p %s", mActiveWindow.get(),
|
||||
doc->GetDocumentURI()->GetSpecOrDefault().get()));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -750,17 +749,16 @@ nsFocusManager::WindowLowered(mozIDOMWindowProxy* aWindow)
|
||||
|
||||
if (MOZ_LOG_TEST(gFocusLog, LogLevel::Debug)) {
|
||||
LOGFOCUS(("Window %p Lowered [Currently: %p %p]", aWindow, mActiveWindow.get(), mFocusedWindow.get()));
|
||||
nsAutoCString spec;
|
||||
nsIDocument* doc = window->GetExtantDoc();
|
||||
if (doc && doc->GetDocumentURI()) {
|
||||
doc->GetDocumentURI()->GetSpec(spec);
|
||||
LOGFOCUS((" Lowered Window: %s", spec.get()));
|
||||
LOGFOCUS((" Lowered Window: %s",
|
||||
doc->GetDocumentURI()->GetSpecOrDefault().get()));
|
||||
}
|
||||
if (mActiveWindow) {
|
||||
doc = mActiveWindow->GetExtantDoc();
|
||||
if (doc && doc->GetDocumentURI()) {
|
||||
doc->GetDocumentURI()->GetSpec(spec);
|
||||
LOGFOCUS((" Active Window: %s", spec.get()));
|
||||
LOGFOCUS((" Active Window: %s",
|
||||
doc->GetDocumentURI()->GetSpecOrDefault().get()));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -879,18 +877,17 @@ nsFocusManager::WindowShown(mozIDOMWindowProxy* aWindow, bool aNeedsFocus)
|
||||
|
||||
if (MOZ_LOG_TEST(gFocusLog, LogLevel::Debug)) {
|
||||
LOGFOCUS(("Window %p Shown [Currently: %p %p]", window.get(), mActiveWindow.get(), mFocusedWindow.get()));
|
||||
nsAutoCString spec;
|
||||
nsIDocument* doc = window->GetExtantDoc();
|
||||
if (doc && doc->GetDocumentURI()) {
|
||||
doc->GetDocumentURI()->GetSpec(spec);
|
||||
LOGFOCUS(("Shown Window: %s", spec.get()));
|
||||
LOGFOCUS(("Shown Window: %s",
|
||||
doc->GetDocumentURI()->GetSpecOrDefault().get()));
|
||||
}
|
||||
|
||||
if (mFocusedWindow) {
|
||||
doc = mFocusedWindow->GetExtantDoc();
|
||||
if (doc && doc->GetDocumentURI()) {
|
||||
doc->GetDocumentURI()->GetSpec(spec);
|
||||
LOGFOCUS((" Focused Window: %s", spec.get()));
|
||||
LOGFOCUS((" Focused Window: %s",
|
||||
doc->GetDocumentURI()->GetSpecOrDefault().get()));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -937,23 +934,23 @@ nsFocusManager::WindowHidden(mozIDOMWindowProxy* aWindow)
|
||||
nsAutoCString spec;
|
||||
nsIDocument* doc = window->GetExtantDoc();
|
||||
if (doc && doc->GetDocumentURI()) {
|
||||
doc->GetDocumentURI()->GetSpec(spec);
|
||||
LOGFOCUS((" Hide Window: %s", spec.get()));
|
||||
LOGFOCUS((" Hide Window: %s",
|
||||
doc->GetDocumentURI()->GetSpecOrDefault().get()));
|
||||
}
|
||||
|
||||
if (mFocusedWindow) {
|
||||
doc = mFocusedWindow->GetExtantDoc();
|
||||
if (doc && doc->GetDocumentURI()) {
|
||||
doc->GetDocumentURI()->GetSpec(spec);
|
||||
LOGFOCUS((" Focused Window: %s", spec.get()));
|
||||
LOGFOCUS((" Focused Window: %s",
|
||||
doc->GetDocumentURI()->GetSpecOrDefault().get()));
|
||||
}
|
||||
}
|
||||
|
||||
if (mActiveWindow) {
|
||||
doc = mActiveWindow->GetExtantDoc();
|
||||
if (doc && doc->GetDocumentURI()) {
|
||||
doc->GetDocumentURI()->GetSpec(spec);
|
||||
LOGFOCUS((" Active Window: %s", spec.get()));
|
||||
LOGFOCUS((" Active Window: %s",
|
||||
doc->GetDocumentURI()->GetSpecOrDefault().get()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2229,8 +2229,8 @@ nsFrameLoader::CheckForRecursiveLoad(nsIURI* aURI)
|
||||
// Check that we're still in the docshell tree.
|
||||
nsCOMPtr<nsIDocShellTreeOwner> treeOwner;
|
||||
mDocShell->GetTreeOwner(getter_AddRefs(treeOwner));
|
||||
NS_WARN_IF_FALSE(treeOwner,
|
||||
"Trying to load a new url to a docshell without owner!");
|
||||
NS_WARNING_ASSERTION(treeOwner,
|
||||
"Trying to load a new url to a docshell without owner!");
|
||||
NS_ENSURE_STATE(treeOwner);
|
||||
|
||||
if (mDocShell->ItemType() != nsIDocShellTreeItem::typeContent) {
|
||||
|
@ -970,9 +970,9 @@ nsGenericDOMDataNode::GetWholeText(nsAString& aWholeText)
|
||||
return GetData(aWholeText);
|
||||
|
||||
int32_t index = parent->IndexOf(this);
|
||||
NS_WARN_IF_FALSE(index >= 0,
|
||||
"Trying to use .wholeText with an anonymous"
|
||||
"text node child of a binding parent?");
|
||||
NS_WARNING_ASSERTION(index >= 0,
|
||||
"Trying to use .wholeText with an anonymous"
|
||||
"text node child of a binding parent?");
|
||||
NS_ENSURE_TRUE(index >= 0, NS_ERROR_DOM_NOT_SUPPORTED_ERR);
|
||||
int32_t first =
|
||||
FirstLogicallyAdjacentTextNode(parent, index);
|
||||
|
@ -1359,7 +1359,7 @@ nsGlobalWindow::~nsGlobalWindow()
|
||||
if (!PR_GetEnv("MOZ_QUIET")) {
|
||||
nsAutoCString url;
|
||||
if (mLastOpenedURI) {
|
||||
mLastOpenedURI->GetSpec(url);
|
||||
url = mLastOpenedURI->GetSpecOrDefault();
|
||||
|
||||
// Data URLs can be very long, so truncate to avoid flooding the log.
|
||||
const uint32_t maxURLLength = 1000;
|
||||
@ -1846,7 +1846,7 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INTERNAL(nsGlobalWindow)
|
||||
char name[512];
|
||||
nsAutoCString uri;
|
||||
if (tmp->mDoc && tmp->mDoc->GetDocumentURI()) {
|
||||
tmp->mDoc->GetDocumentURI()->GetSpec(uri);
|
||||
uri = tmp->mDoc->GetDocumentURI()->GetSpecOrDefault();
|
||||
}
|
||||
SprintfLiteral(name, "nsGlobalWindow # %" PRIu64 " %s %s", tmp->mWindowID,
|
||||
tmp->IsInnerWindow() ? "inner" : "outer", uri.get());
|
||||
@ -2993,10 +2993,8 @@ nsGlobalWindow::InnerSetNewDocument(JSContext* aCx, nsIDocument* aDocument)
|
||||
|
||||
if (gDOMLeakPRLog && MOZ_LOG_TEST(gDOMLeakPRLog, LogLevel::Debug)) {
|
||||
nsIURI *uri = aDocument->GetDocumentURI();
|
||||
nsAutoCString spec;
|
||||
if (uri)
|
||||
uri->GetSpec(spec);
|
||||
PR_LogPrint("DOMWINDOW %p SetNewDocument %s", this, spec.get());
|
||||
PR_LogPrint("DOMWINDOW %p SetNewDocument %s",
|
||||
this, uri ? uri->GetSpecOrDefault().get() : "");
|
||||
}
|
||||
|
||||
mDoc = aDocument;
|
||||
@ -6536,7 +6534,7 @@ nsGlobalWindow::FinishFullscreenChange(bool aIsFullscreen)
|
||||
ErrorResult rv;
|
||||
mWakeLock = pmService->NewWakeLock(NS_LITERAL_STRING("DOM_Fullscreen"),
|
||||
AsOuter()->GetCurrentInnerWindow(), rv);
|
||||
NS_WARN_IF_FALSE(!rv.Failed(), "Failed to lock the wakelock");
|
||||
NS_WARNING_ASSERTION(!rv.Failed(), "Failed to lock the wakelock");
|
||||
rv.SuppressException();
|
||||
} else if (mWakeLock && !mFullScreen) {
|
||||
ErrorResult rv;
|
||||
|
@ -2482,34 +2482,13 @@ public:
|
||||
|
||||
nsIDocument* GetTopLevelContentDocument();
|
||||
|
||||
/**
|
||||
* Registers an unresolved custom element that is a candidate for
|
||||
* upgrade when the definition is registered via registerElement.
|
||||
* |aTypeName| is the name of the custom element type, if it is not
|
||||
* provided, then element name is used. |aTypeName| should be provided
|
||||
* when registering a custom element that extends an existing
|
||||
* element. e.g. <button is="x-button">.
|
||||
*/
|
||||
virtual nsresult RegisterUnresolvedElement(Element* aElement,
|
||||
nsIAtom* aTypeName = nullptr) = 0;
|
||||
virtual void EnqueueLifecycleCallback(ElementCallbackType aType,
|
||||
Element* aCustomElement,
|
||||
mozilla::dom::LifecycleCallbackArgs* aArgs = nullptr,
|
||||
mozilla::dom::CustomElementDefinition* aDefinition = nullptr) = 0;
|
||||
virtual void SetupCustomElement(Element* aElement,
|
||||
uint32_t aNamespaceID,
|
||||
const nsAString* aTypeExtension = nullptr) = 0;
|
||||
virtual void
|
||||
RegisterElement(JSContext* aCx, const nsAString& aName,
|
||||
const mozilla::dom::ElementRegistrationOptions& aOptions,
|
||||
JS::MutableHandle<JSObject*> aRetval,
|
||||
mozilla::ErrorResult& rv) = 0;
|
||||
|
||||
/**
|
||||
* In some cases, new document instances must be associated with
|
||||
* an existing web components custom element registry as specified.
|
||||
*/
|
||||
virtual void UseRegistryFromDocument(nsIDocument* aDocument) = 0;
|
||||
virtual already_AddRefed<mozilla::dom::CustomElementsRegistry>
|
||||
GetCustomElementsRegistry() = 0;
|
||||
|
||||
already_AddRefed<nsContentList>
|
||||
GetElementsByTagName(const nsAString& aTagName)
|
||||
|
@ -129,8 +129,8 @@ nsInProcessTabChildGlobal::Init()
|
||||
nsresult rv =
|
||||
#endif
|
||||
InitTabChildGlobal();
|
||||
NS_WARN_IF_FALSE(NS_SUCCEEDED(rv),
|
||||
"Couldn't initialize nsInProcessTabChildGlobal");
|
||||
NS_WARNING_ASSERTION(NS_SUCCEEDED(rv),
|
||||
"Couldn't initialize nsInProcessTabChildGlobal");
|
||||
mMessageManager = new nsFrameMessageManager(this,
|
||||
nullptr,
|
||||
dom::ipc::MM_CHILD);
|
||||
|
@ -531,9 +531,7 @@ PrintWinURI(nsGlobalWindow *win)
|
||||
return;
|
||||
}
|
||||
|
||||
nsAutoCString spec;
|
||||
uri->GetSpec(spec);
|
||||
printf("%s\n", spec.get());
|
||||
printf("%s\n", uri->GetSpecOrDefault().get());
|
||||
}
|
||||
|
||||
void
|
||||
@ -557,9 +555,7 @@ PrintWinCodebase(nsGlobalWindow *win)
|
||||
return;
|
||||
}
|
||||
|
||||
nsAutoCString spec;
|
||||
uri->GetSpec(spec);
|
||||
printf("%s\n", spec.get());
|
||||
printf("%s\n", uri->GetSpecOrDefault().get());
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -471,15 +471,14 @@ nsNodeUtils::CloneAndAdopt(nsINode *aNode, bool aClone, bool aDeep,
|
||||
// enqueing created callback and prototype swizzling.
|
||||
Element* elem = clone->AsElement();
|
||||
if (nsContentUtils::IsCustomElementName(nodeInfo->NameAtom())) {
|
||||
elem->OwnerDoc()->SetupCustomElement(elem, nodeInfo->NamespaceID());
|
||||
nsContentUtils::SetupCustomElement(elem);
|
||||
} else {
|
||||
// Check if node may be custom element by type extension.
|
||||
// ex. <button is="x-button">
|
||||
nsAutoString extension;
|
||||
if (elem->GetAttr(kNameSpaceID_None, nsGkAtoms::is, extension) &&
|
||||
!extension.IsEmpty()) {
|
||||
elem->OwnerDoc()->SetupCustomElement(elem, nodeInfo->NamespaceID(),
|
||||
&extension);
|
||||
nsContentUtils::SetupCustomElement(elem, &extension);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1139,10 +1139,8 @@ nsObjectLoadingContent::OnStartRequest(nsIRequest *aRequest,
|
||||
if (console) {
|
||||
nsCOMPtr<nsIURI> uri;
|
||||
chan->GetURI(getter_AddRefs(uri));
|
||||
nsAutoCString spec;
|
||||
uri->GetSpec(spec);
|
||||
nsString message = NS_LITERAL_STRING("Blocking ") +
|
||||
NS_ConvertASCIItoUTF16(spec.get()) +
|
||||
NS_ConvertASCIItoUTF16(uri->GetSpecOrDefault().get()) +
|
||||
NS_LITERAL_STRING(" since it was found on an internal Firefox blocklist.");
|
||||
console->LogStringMessage(message.get());
|
||||
}
|
||||
@ -1649,12 +1647,8 @@ nsObjectLoadingContent::CheckLoadPolicy(int16_t *aContentPolicy)
|
||||
nsContentUtils::GetSecurityManager());
|
||||
NS_ENSURE_SUCCESS(rv, false);
|
||||
if (NS_CP_REJECTED(*aContentPolicy)) {
|
||||
nsAutoCString uri;
|
||||
nsAutoCString baseUri;
|
||||
mURI->GetSpec(uri);
|
||||
mURI->GetSpec(baseUri);
|
||||
LOG(("OBJLC [%p]: Content policy denied load of %s (base %s)",
|
||||
this, uri.get(), baseUri.get()));
|
||||
LOG(("OBJLC [%p]: Content policy denied load of %s",
|
||||
this, mURI->GetSpecOrDefault().get()));
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -113,7 +113,7 @@ nsPlainTextSerializer::~nsPlainTextSerializer()
|
||||
{
|
||||
delete[] mTagStack;
|
||||
delete[] mOLStack;
|
||||
NS_WARN_IF_FALSE(mHeadLevel == 0, "Wrong head level!");
|
||||
NS_WARNING_ASSERTION(mHeadLevel == 0, "Wrong head level!");
|
||||
}
|
||||
|
||||
NS_IMPL_ISUPPORTS(nsPlainTextSerializer,
|
||||
|
@ -3372,7 +3372,7 @@ GetRequiredInnerTextLineBreakCount(nsIFrame* aFrame)
|
||||
}
|
||||
const nsStyleDisplay* styleDisplay = aFrame->StyleDisplay();
|
||||
if (styleDisplay->IsBlockOutside(aFrame) ||
|
||||
styleDisplay->mDisplay == NS_STYLE_DISPLAY_TABLE_CAPTION) {
|
||||
styleDisplay->mDisplay == StyleDisplay::TableCaption) {
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
@ -3489,17 +3489,19 @@ nsRange::GetInnerTextNoFlush(DOMString& aValue, ErrorResult& aError,
|
||||
result.Append('\n');
|
||||
}
|
||||
switch (f->StyleDisplay()->mDisplay) {
|
||||
case NS_STYLE_DISPLAY_TABLE_CELL:
|
||||
case StyleDisplay::TableCell:
|
||||
if (!IsLastCellOfRow(f)) {
|
||||
result.Append('\t');
|
||||
}
|
||||
break;
|
||||
case NS_STYLE_DISPLAY_TABLE_ROW:
|
||||
case StyleDisplay::TableRow:
|
||||
if (!IsLastRowOfRowGroup(f) ||
|
||||
!IsLastNonemptyRowGroupOfTable(f->GetParent())) {
|
||||
result.Append('\n');
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break; // Do nothing
|
||||
}
|
||||
result.AddRequiredLineBreakCount(GetRequiredInnerTextLineBreakCount(f));
|
||||
}
|
||||
|
@ -1918,6 +1918,8 @@ nsScriptLoader::ProcessRequest(nsScriptLoadRequest* aRequest)
|
||||
mCurrentParserInsertedScript = aRequest->mElement;
|
||||
}
|
||||
|
||||
aRequest->mElement->BeginEvaluating();
|
||||
|
||||
FireScriptAvailable(NS_OK, aRequest);
|
||||
|
||||
// The window may have gone away by this point, in which case there's no point
|
||||
@ -1948,9 +1950,7 @@ nsScriptLoader::ProcessRequest(nsScriptLoadRequest* aRequest)
|
||||
if (doc) {
|
||||
doc->BeginEvaluatingExternalScript();
|
||||
}
|
||||
aRequest->mElement->BeginEvaluating();
|
||||
rv = EvaluateScript(aRequest);
|
||||
aRequest->mElement->EndEvaluating();
|
||||
if (doc) {
|
||||
doc->EndEvaluatingExternalScript();
|
||||
}
|
||||
@ -1963,6 +1963,8 @@ nsScriptLoader::ProcessRequest(nsScriptLoadRequest* aRequest)
|
||||
|
||||
FireScriptEvaluated(rv, aRequest);
|
||||
|
||||
aRequest->mElement->EndEvaluating();
|
||||
|
||||
if (parserCreated) {
|
||||
mCurrentParserInsertedScript = oldParserInsertedScript;
|
||||
}
|
||||
|
@ -170,8 +170,7 @@ AppendWindowURI(nsGlobalWindow *aWindow, nsACString& aStr, bool aAnonymize)
|
||||
if (aAnonymize && !aWindow->IsChromeWindow()) {
|
||||
aStr.AppendPrintf("<anonymized-%llu>", aWindow->WindowID());
|
||||
} else {
|
||||
nsCString spec;
|
||||
uri->GetSpec(spec);
|
||||
nsCString spec = uri->GetSpecOrDefault();
|
||||
|
||||
// A hack: replace forward slashes with '\\' so they aren't
|
||||
// treated as path separators. Users of the reporters
|
||||
|
@ -4479,9 +4479,6 @@ def getJSToNativeConversionInfo(type, descriptorProvider, failureCode=None,
|
||||
|
||||
assert not (isEnforceRange and isClamp) # These are mutually exclusive
|
||||
|
||||
if type.isArray():
|
||||
raise TypeError("Can't handle array arguments yet")
|
||||
|
||||
if type.isSequence():
|
||||
assert not isEnforceRange and not isClamp
|
||||
|
||||
@ -4754,16 +4751,16 @@ def getJSToNativeConversionInfo(type, descriptorProvider, failureCode=None,
|
||||
else:
|
||||
interfaceObject = None
|
||||
|
||||
arrayObjectMemberTypes = filter(lambda t: t.isArray() or t.isSequence(), memberTypes)
|
||||
if len(arrayObjectMemberTypes) > 0:
|
||||
assert len(arrayObjectMemberTypes) == 1
|
||||
name = getUnionMemberName(arrayObjectMemberTypes[0])
|
||||
arrayObject = CGGeneric(
|
||||
sequenceObjectMemberTypes = filter(lambda t: t.isSequence(), memberTypes)
|
||||
if len(sequenceObjectMemberTypes) > 0:
|
||||
assert len(sequenceObjectMemberTypes) == 1
|
||||
name = getUnionMemberName(sequenceObjectMemberTypes[0])
|
||||
sequenceObject = CGGeneric(
|
||||
"done = (failed = !%s.TrySetTo%s(cx, ${val}, tryNext, ${passedToJSImpl})) || !tryNext;\n" %
|
||||
(unionArgumentObj, name))
|
||||
names.append(name)
|
||||
else:
|
||||
arrayObject = None
|
||||
sequenceObject = None
|
||||
|
||||
dateObjectMemberTypes = filter(lambda t: t.isDate(), memberTypes)
|
||||
if len(dateObjectMemberTypes) > 0:
|
||||
@ -4825,16 +4822,16 @@ def getJSToNativeConversionInfo(type, descriptorProvider, failureCode=None,
|
||||
else:
|
||||
object = None
|
||||
|
||||
hasObjectTypes = interfaceObject or arrayObject or dateObject or callbackObject or object or mozMapObject
|
||||
hasObjectTypes = interfaceObject or sequenceObject or dateObject or callbackObject or object or mozMapObject
|
||||
if hasObjectTypes:
|
||||
# "object" is not distinguishable from other types
|
||||
assert not object or not (interfaceObject or arrayObject or dateObject or callbackObject or mozMapObject)
|
||||
if arrayObject or dateObject or callbackObject:
|
||||
# An object can be both an array object and a callback or
|
||||
assert not object or not (interfaceObject or sequenceObject or dateObject or callbackObject or mozMapObject)
|
||||
if sequenceObject or dateObject or callbackObject:
|
||||
# An object can be both an sequence object and a callback or
|
||||
# dictionary, but we shouldn't have both in the union's members
|
||||
# because they are not distinguishable.
|
||||
assert not (arrayObject and callbackObject)
|
||||
templateBody = CGElseChain([arrayObject, dateObject, callbackObject])
|
||||
assert not (sequenceObject and callbackObject)
|
||||
templateBody = CGElseChain([sequenceObject, dateObject, callbackObject])
|
||||
else:
|
||||
templateBody = None
|
||||
if interfaceObject:
|
||||
@ -6240,9 +6237,6 @@ def getWrapTemplateForType(type, descriptorProvider, result, successCode,
|
||||
if type is None or type.isVoid():
|
||||
return (setUndefined(), True)
|
||||
|
||||
if type.isArray():
|
||||
raise TypeError("Can't handle array return values yet")
|
||||
|
||||
if (type.isSequence() or type.isMozMap()) and type.nullable():
|
||||
# These are both wrapped in Nullable<>
|
||||
recTemplate, recInfall = getWrapTemplateForType(type.inner, descriptorProvider,
|
||||
@ -6652,7 +6646,7 @@ def typeMatchesLambda(type, func):
|
||||
return False
|
||||
if type.nullable():
|
||||
return typeMatchesLambda(type.inner, func)
|
||||
if type.isSequence() or type.isMozMap() or type.isArray():
|
||||
if type.isSequence() or type.isMozMap():
|
||||
return typeMatchesLambda(type.inner, func)
|
||||
if type.isUnion():
|
||||
return any(typeMatchesLambda(t, func) for t in
|
||||
@ -7838,12 +7832,11 @@ class CGMethodCall(CGThing):
|
||||
objectSigs.extend(s for s in possibleSignatures
|
||||
if distinguishingType(s).isSequence())
|
||||
|
||||
# Now append all the overloads that take an array or dictionary or
|
||||
# callback interface or MozMap. There should be only one of these!
|
||||
# Now append all the overloads that take a dictionary or callback
|
||||
# interface or MozMap. There should be only one of these!
|
||||
genericObjectSigs = [
|
||||
s for s in possibleSignatures
|
||||
if (distinguishingType(s).isArray() or
|
||||
distinguishingType(s).isDictionary() or
|
||||
if (distinguishingType(s).isDictionary() or
|
||||
distinguishingType(s).isMozMap() or
|
||||
distinguishingType(s).isCallbackInterface())]
|
||||
assert len(genericObjectSigs) <= 1
|
||||
@ -7854,7 +7847,7 @@ class CGMethodCall(CGThing):
|
||||
if len(objectSigs) > 0:
|
||||
# Here it's enough to guard on our argument being an object. The
|
||||
# code for unwrapping non-callback interfaces, typed arrays,
|
||||
# sequences, arrays, and Dates will just bail out and move on to
|
||||
# sequences, and Dates will just bail out and move on to
|
||||
# the next overload if the object fails to unwrap correctly,
|
||||
# while "object" accepts any object anyway. We could even not
|
||||
# do the isObject() check up front here, but in cases where we
|
||||
@ -9086,9 +9079,6 @@ class CGMemberJITInfo(CGThing):
|
||||
if t.isVoid():
|
||||
# No return, every time
|
||||
return "JSVAL_TYPE_UNDEFINED"
|
||||
if t.isArray():
|
||||
# No idea yet
|
||||
assert False
|
||||
if t.isSequence():
|
||||
return "JSVAL_TYPE_OBJECT"
|
||||
if t.isMozMap():
|
||||
@ -9164,9 +9154,6 @@ class CGMemberJITInfo(CGThing):
|
||||
if t.nullable():
|
||||
# Sometimes it might return null, sometimes not
|
||||
return "JSJitInfo::ArgType(JSJitInfo::Null | %s)" % CGMemberJITInfo.getJSArgType(t.inner)
|
||||
if t.isArray():
|
||||
# No idea yet
|
||||
assert False
|
||||
if t.isSequence():
|
||||
return "JSJitInfo::Object"
|
||||
if t.isGeckoInterface():
|
||||
@ -9355,9 +9342,6 @@ def getUnionAccessorSignatureType(type, descriptorProvider):
|
||||
# Flat member types have already unwrapped nullables.
|
||||
assert not type.nullable()
|
||||
|
||||
if type.isArray():
|
||||
raise TypeError("Can't handle array arguments yet")
|
||||
|
||||
if type.isSequence() or type.isMozMap():
|
||||
if type.isSequence():
|
||||
wrapperType = "Sequence"
|
||||
@ -13417,7 +13401,7 @@ class CGBindingRoot(CGThing):
|
||||
def getDependenciesFromType(type):
|
||||
if type.isDictionary():
|
||||
return set([type.unroll().inner])
|
||||
if type.isSequence() or type.isArray():
|
||||
if type.isSequence():
|
||||
return getDependenciesFromType(type.unroll())
|
||||
if type.isUnion():
|
||||
return set([type.unroll()])
|
||||
@ -13796,9 +13780,6 @@ class CGNativeMember(ClassMethod):
|
||||
isMember can be false or one of the strings "Sequence", "Variadic",
|
||||
"MozMap"
|
||||
"""
|
||||
if type.isArray():
|
||||
raise TypeError("Can't handle array arguments yet")
|
||||
|
||||
if type.isSequence():
|
||||
nullable = type.nullable()
|
||||
if nullable:
|
||||
|
@ -26,6 +26,7 @@ MSG_DEF(MSG_INVALID_ENUM_VALUE, 3, JSEXN_TYPEERR, "{0} '{1}' is not a valid valu
|
||||
MSG_DEF(MSG_MISSING_ARGUMENTS, 1, JSEXN_TYPEERR, "Not enough arguments to {0}.")
|
||||
MSG_DEF(MSG_NOT_OBJECT, 1, JSEXN_TYPEERR, "{0} is not an object.")
|
||||
MSG_DEF(MSG_NOT_CALLABLE, 1, JSEXN_TYPEERR, "{0} is not callable.")
|
||||
MSG_DEF(MSG_NOT_CONSTRUCTOR, 1, JSEXN_TYPEERR, "{0} is not a constructor.")
|
||||
MSG_DEF(MSG_DOES_NOT_IMPLEMENT_INTERFACE, 2, JSEXN_TYPEERR, "{0} does not implement interface {1}.")
|
||||
MSG_DEF(MSG_METHOD_THIS_DOES_NOT_IMPLEMENT_INTERFACE, 2, JSEXN_TYPEERR, "'{0}' called on an object that does not implement interface {1}.")
|
||||
MSG_DEF(MSG_METHOD_THIS_UNWRAPPING_DENIED, 1, JSEXN_TYPEERR, "Permission to call '{0}' denied.")
|
||||
|
@ -144,9 +144,6 @@ if CONFIG['MOZ_BUILD_APP'] in ['browser', 'mobile/android', 'xulrunner']:
|
||||
DEFINES['HAVE_SIDEBAR'] = True
|
||||
|
||||
|
||||
if CONFIG['MOZ_SIMPLEPUSH']:
|
||||
DEFINES['MOZ_SIMPLEPUSH'] = True
|
||||
|
||||
PYTHON_UNIT_TESTS += [
|
||||
'mozwebidlcodegen/test/test_mozwebidlcodegen.py',
|
||||
]
|
||||
|
@ -1856,7 +1856,6 @@ class IDLDictionary(IDLObjectWithScope):
|
||||
"""
|
||||
|
||||
if (memberType.nullable() or
|
||||
memberType.isArray() or
|
||||
memberType.isSequence() or
|
||||
memberType.isMozMap()):
|
||||
return typeContainsDictionary(memberType.inner, dictionary)
|
||||
@ -1979,8 +1978,7 @@ class IDLType(IDLObject):
|
||||
'callback',
|
||||
'union',
|
||||
'sequence',
|
||||
'mozmap',
|
||||
'array'
|
||||
'mozmap'
|
||||
)
|
||||
|
||||
def __init__(self, location, name):
|
||||
@ -2033,9 +2031,6 @@ class IDLType(IDLObject):
|
||||
def isMozMap(self):
|
||||
return False
|
||||
|
||||
def isArray(self):
|
||||
return False
|
||||
|
||||
def isArrayBuffer(self):
|
||||
return False
|
||||
|
||||
@ -2261,9 +2256,6 @@ class IDLNullableType(IDLParameterizedType):
|
||||
def isMozMap(self):
|
||||
return self.inner.isMozMap()
|
||||
|
||||
def isArray(self):
|
||||
return self.inner.isArray()
|
||||
|
||||
def isArrayBuffer(self):
|
||||
return self.inner.isArrayBuffer()
|
||||
|
||||
@ -2366,9 +2358,6 @@ class IDLSequenceType(IDLParameterizedType):
|
||||
def isSequence(self):
|
||||
return True
|
||||
|
||||
def isArray(self):
|
||||
return False
|
||||
|
||||
def isDictionary(self):
|
||||
return False
|
||||
|
||||
@ -2573,106 +2562,6 @@ class IDLUnionType(IDLType):
|
||||
return set(self.memberTypes)
|
||||
|
||||
|
||||
class IDLArrayType(IDLType):
|
||||
def __init__(self, location, parameterType):
|
||||
assert not parameterType.isVoid()
|
||||
if parameterType.isSequence():
|
||||
raise WebIDLError("Array type cannot parameterize over a sequence type",
|
||||
[location])
|
||||
if parameterType.isMozMap():
|
||||
raise WebIDLError("Array type cannot parameterize over a MozMap type",
|
||||
[location])
|
||||
if parameterType.isDictionary():
|
||||
raise WebIDLError("Array type cannot parameterize over a dictionary type",
|
||||
[location])
|
||||
|
||||
IDLType.__init__(self, location, parameterType.name)
|
||||
self.inner = parameterType
|
||||
self.builtin = False
|
||||
|
||||
def __eq__(self, other):
|
||||
return isinstance(other, IDLArrayType) and self.inner == other.inner
|
||||
|
||||
def __str__(self):
|
||||
return self.inner.__str__() + "Array"
|
||||
|
||||
def nullable(self):
|
||||
return False
|
||||
|
||||
def isPrimitive(self):
|
||||
return False
|
||||
|
||||
def isString(self):
|
||||
return False
|
||||
|
||||
def isByteString(self):
|
||||
return False
|
||||
|
||||
def isDOMString(self):
|
||||
return False
|
||||
|
||||
def isUSVString(self):
|
||||
return False
|
||||
|
||||
def isVoid(self):
|
||||
return False
|
||||
|
||||
def isSequence(self):
|
||||
assert not self.inner.isSequence()
|
||||
return False
|
||||
|
||||
def isArray(self):
|
||||
return True
|
||||
|
||||
def isDictionary(self):
|
||||
assert not self.inner.isDictionary()
|
||||
return False
|
||||
|
||||
def isInterface(self):
|
||||
return False
|
||||
|
||||
def isEnum(self):
|
||||
return False
|
||||
|
||||
def tag(self):
|
||||
return IDLType.Tags.array
|
||||
|
||||
def resolveType(self, parentScope):
|
||||
assert isinstance(parentScope, IDLScope)
|
||||
self.inner.resolveType(parentScope)
|
||||
|
||||
def isComplete(self):
|
||||
return self.inner.isComplete()
|
||||
|
||||
def complete(self, scope):
|
||||
self.inner = self.inner.complete(scope)
|
||||
self.name = self.inner.name
|
||||
|
||||
if self.inner.isDictionary():
|
||||
raise WebIDLError("Array type must not contain "
|
||||
"dictionary as element type.",
|
||||
[self.inner.location])
|
||||
|
||||
assert not self.inner.isSequence()
|
||||
|
||||
return self
|
||||
|
||||
def unroll(self):
|
||||
return self.inner.unroll()
|
||||
|
||||
def isDistinguishableFrom(self, other):
|
||||
if other.isPromise():
|
||||
return False
|
||||
if other.isUnion():
|
||||
# Just forward to the union; it'll deal
|
||||
return other.isDistinguishableFrom(self)
|
||||
return (other.isPrimitive() or other.isString() or other.isEnum() or
|
||||
other.isDate() or other.isNonCallbackInterface())
|
||||
|
||||
def _getDependentObjects(self):
|
||||
return self.inner._getDependentObjects()
|
||||
|
||||
|
||||
class IDLTypedefType(IDLType):
|
||||
def __init__(self, location, innerType, name):
|
||||
IDLType.__init__(self, location, name)
|
||||
@ -2718,9 +2607,6 @@ class IDLTypedefType(IDLType):
|
||||
def isMozMap(self):
|
||||
return self.inner.isMozMap()
|
||||
|
||||
def isArray(self):
|
||||
return self.inner.isArray()
|
||||
|
||||
def isDictionary(self):
|
||||
return self.inner.isDictionary()
|
||||
|
||||
@ -2836,9 +2722,6 @@ class IDLWrapperType(IDLType):
|
||||
def isSequence(self):
|
||||
return False
|
||||
|
||||
def isArray(self):
|
||||
return False
|
||||
|
||||
def isDictionary(self):
|
||||
return isinstance(self.inner, IDLDictionary)
|
||||
|
||||
@ -2905,8 +2788,7 @@ class IDLWrapperType(IDLType):
|
||||
if self.isEnum():
|
||||
return (other.isPrimitive() or other.isInterface() or other.isObject() or
|
||||
other.isCallback() or other.isDictionary() or
|
||||
other.isSequence() or other.isMozMap() or other.isArray() or
|
||||
other.isDate())
|
||||
other.isSequence() or other.isMozMap() or other.isDate())
|
||||
if self.isDictionary() and other.nullable():
|
||||
return False
|
||||
if (other.isPrimitive() or other.isString() or other.isEnum() or
|
||||
@ -2928,7 +2810,7 @@ class IDLWrapperType(IDLType):
|
||||
(self.isNonCallbackInterface() or
|
||||
other.isNonCallbackInterface()))
|
||||
if (other.isDictionary() or other.isCallback() or
|
||||
other.isMozMap() or other.isArray()):
|
||||
other.isMozMap()):
|
||||
return self.isNonCallbackInterface()
|
||||
|
||||
# Not much else |other| can be
|
||||
@ -3138,20 +3020,17 @@ class IDLBuiltinType(IDLType):
|
||||
return (other.isNumeric() or other.isString() or other.isEnum() or
|
||||
other.isInterface() or other.isObject() or
|
||||
other.isCallback() or other.isDictionary() or
|
||||
other.isSequence() or other.isMozMap() or other.isArray() or
|
||||
other.isDate())
|
||||
other.isSequence() or other.isMozMap() or other.isDate())
|
||||
if self.isNumeric():
|
||||
return (other.isBoolean() or other.isString() or other.isEnum() or
|
||||
other.isInterface() or other.isObject() or
|
||||
other.isCallback() or other.isDictionary() or
|
||||
other.isSequence() or other.isMozMap() or other.isArray() or
|
||||
other.isDate())
|
||||
other.isSequence() or other.isMozMap() or other.isDate())
|
||||
if self.isString():
|
||||
return (other.isPrimitive() or other.isInterface() or
|
||||
other.isObject() or
|
||||
other.isCallback() or other.isDictionary() or
|
||||
other.isSequence() or other.isMozMap() or other.isArray() or
|
||||
other.isDate())
|
||||
other.isSequence() or other.isMozMap() or other.isDate())
|
||||
if self.isAny():
|
||||
# Can't tell "any" apart from anything
|
||||
return False
|
||||
@ -3161,7 +3040,7 @@ class IDLBuiltinType(IDLType):
|
||||
return (other.isPrimitive() or other.isString() or other.isEnum() or
|
||||
other.isInterface() or other.isCallback() or
|
||||
other.isDictionary() or other.isSequence() or
|
||||
other.isMozMap() or other.isArray())
|
||||
other.isMozMap())
|
||||
if self.isVoid():
|
||||
return not other.isVoid()
|
||||
# Not much else we could be!
|
||||
@ -3169,8 +3048,7 @@ class IDLBuiltinType(IDLType):
|
||||
# Like interfaces, but we know we're not a callback
|
||||
return (other.isPrimitive() or other.isString() or other.isEnum() or
|
||||
other.isCallback() or other.isDictionary() or
|
||||
other.isSequence() or other.isMozMap() or other.isArray() or
|
||||
other.isDate() or
|
||||
other.isSequence() or other.isMozMap() or other.isDate() or
|
||||
(other.isInterface() and (
|
||||
# ArrayBuffer is distinguishable from everything
|
||||
# that's not an ArrayBuffer or a callback interface
|
||||
@ -4596,12 +4474,6 @@ class IDLMethod(IDLInterfaceMember, IDLScope):
|
||||
base=IDLInterfaceMember.Special
|
||||
)
|
||||
|
||||
TypeSuffixModifier = enum(
|
||||
'None',
|
||||
'QMark',
|
||||
'Brackets'
|
||||
)
|
||||
|
||||
NamedOrIndexed = enum(
|
||||
'Neither',
|
||||
'Named',
|
||||
@ -6403,9 +6275,9 @@ class Parser(Tokenizer):
|
||||
|
||||
def p_TypeUnionType(self, p):
|
||||
"""
|
||||
Type : UnionType TypeSuffix
|
||||
Type : UnionType Null
|
||||
"""
|
||||
p[0] = self.handleModifiers(p[1], p[2])
|
||||
p[0] = self.handleNullable(p[1], p[2])
|
||||
|
||||
def p_SingleTypeNonAnyType(self, p):
|
||||
"""
|
||||
@ -6415,9 +6287,9 @@ class Parser(Tokenizer):
|
||||
|
||||
def p_SingleTypeAnyType(self, p):
|
||||
"""
|
||||
SingleType : ANY TypeSuffixStartingWithArray
|
||||
SingleType : ANY
|
||||
"""
|
||||
p[0] = self.handleModifiers(BuiltinTypes[IDLBuiltinType.Types.any], p[2])
|
||||
p[0] = BuiltinTypes[IDLBuiltinType.Types.any]
|
||||
|
||||
def p_UnionType(self, p):
|
||||
"""
|
||||
@ -6433,19 +6305,11 @@ class Parser(Tokenizer):
|
||||
"""
|
||||
p[0] = p[1]
|
||||
|
||||
def p_UnionMemberTypeArrayOfAny(self, p):
|
||||
"""
|
||||
UnionMemberTypeArrayOfAny : ANY LBRACKET RBRACKET
|
||||
"""
|
||||
p[0] = IDLArrayType(self.getLocation(p, 2),
|
||||
BuiltinTypes[IDLBuiltinType.Types.any])
|
||||
|
||||
def p_UnionMemberType(self, p):
|
||||
"""
|
||||
UnionMemberType : UnionType TypeSuffix
|
||||
| UnionMemberTypeArrayOfAny TypeSuffix
|
||||
UnionMemberType : UnionType Null
|
||||
"""
|
||||
p[0] = self.handleModifiers(p[1], p[2])
|
||||
p[0] = self.handleNullable(p[1], p[2])
|
||||
|
||||
def p_UnionMemberTypes(self, p):
|
||||
"""
|
||||
@ -6462,10 +6326,10 @@ class Parser(Tokenizer):
|
||||
|
||||
def p_NonAnyType(self, p):
|
||||
"""
|
||||
NonAnyType : PrimitiveOrStringType TypeSuffix
|
||||
| ARRAYBUFFER TypeSuffix
|
||||
| SHAREDARRAYBUFFER TypeSuffix
|
||||
| OBJECT TypeSuffix
|
||||
NonAnyType : PrimitiveOrStringType Null
|
||||
| ARRAYBUFFER Null
|
||||
| SHAREDARRAYBUFFER Null
|
||||
| OBJECT Null
|
||||
"""
|
||||
if p[1] == "object":
|
||||
type = BuiltinTypes[IDLBuiltinType.Types.object]
|
||||
@ -6476,7 +6340,7 @@ class Parser(Tokenizer):
|
||||
else:
|
||||
type = BuiltinTypes[p[1]]
|
||||
|
||||
p[0] = self.handleModifiers(type, p[2])
|
||||
p[0] = self.handleNullable(type, p[2])
|
||||
|
||||
def p_NonAnyTypeSequenceType(self, p):
|
||||
"""
|
||||
@ -6484,9 +6348,7 @@ class Parser(Tokenizer):
|
||||
"""
|
||||
innerType = p[3]
|
||||
type = IDLSequenceType(self.getLocation(p, 1), innerType)
|
||||
if p[5]:
|
||||
type = IDLNullableType(self.getLocation(p, 5), type)
|
||||
p[0] = type
|
||||
p[0] = self.handleNullable(type, p[5])
|
||||
|
||||
# Note: Promise<void> is allowed, so we want to parametrize on
|
||||
# ReturnType, not Type. Also, we want this to end up picking up
|
||||
@ -6498,9 +6360,7 @@ class Parser(Tokenizer):
|
||||
innerType = p[3]
|
||||
promiseIdent = IDLUnresolvedIdentifier(self.getLocation(p, 1), "Promise")
|
||||
type = IDLUnresolvedType(self.getLocation(p, 1), promiseIdent, p[3])
|
||||
if p[5]:
|
||||
type = IDLNullableType(self.getLocation(p, 5), type)
|
||||
p[0] = type
|
||||
p[0] = self.handleNullable(type, p[5])
|
||||
|
||||
def p_NonAnyTypeMozMapType(self, p):
|
||||
"""
|
||||
@ -6508,13 +6368,11 @@ class Parser(Tokenizer):
|
||||
"""
|
||||
innerType = p[3]
|
||||
type = IDLMozMapType(self.getLocation(p, 1), innerType)
|
||||
if p[5]:
|
||||
type = IDLNullableType(self.getLocation(p, 5), type)
|
||||
p[0] = type
|
||||
p[0] = self.handleNullable(type, p[5])
|
||||
|
||||
def p_NonAnyTypeScopedName(self, p):
|
||||
"""
|
||||
NonAnyType : ScopedName TypeSuffix
|
||||
NonAnyType : ScopedName Null
|
||||
"""
|
||||
assert isinstance(p[1], IDLUnresolvedIdentifier)
|
||||
|
||||
@ -6536,29 +6394,27 @@ class Parser(Tokenizer):
|
||||
type = IDLCallbackType(self.getLocation(p, 1), obj)
|
||||
else:
|
||||
type = IDLWrapperType(self.getLocation(p, 1), p[1])
|
||||
p[0] = self.handleModifiers(type, p[2])
|
||||
p[0] = self.handleNullable(type, p[2])
|
||||
return
|
||||
except:
|
||||
pass
|
||||
|
||||
type = IDLUnresolvedType(self.getLocation(p, 1), p[1])
|
||||
p[0] = self.handleModifiers(type, p[2])
|
||||
p[0] = self.handleNullable(type, p[2])
|
||||
|
||||
def p_NonAnyTypeDate(self, p):
|
||||
"""
|
||||
NonAnyType : DATE TypeSuffix
|
||||
NonAnyType : DATE Null
|
||||
"""
|
||||
p[0] = self.handleModifiers(BuiltinTypes[IDLBuiltinType.Types.date],
|
||||
p[2])
|
||||
p[0] = self.handleNullable(BuiltinTypes[IDLBuiltinType.Types.date],
|
||||
p[2])
|
||||
|
||||
def p_ConstType(self, p):
|
||||
"""
|
||||
ConstType : PrimitiveOrStringType Null
|
||||
"""
|
||||
type = BuiltinTypes[p[1]]
|
||||
if p[2]:
|
||||
type = IDLNullableType(self.getLocation(p, 1), type)
|
||||
p[0] = type
|
||||
p[0] = self.handleNullable(type, p[2])
|
||||
|
||||
def p_ConstTypeIdentifier(self, p):
|
||||
"""
|
||||
@ -6567,9 +6423,7 @@ class Parser(Tokenizer):
|
||||
identifier = IDLUnresolvedIdentifier(self.getLocation(p, 1), p[1])
|
||||
|
||||
type = IDLUnresolvedType(self.getLocation(p, 1), identifier)
|
||||
if p[2]:
|
||||
type = IDLNullableType(self.getLocation(p, 1), type)
|
||||
p[0] = type
|
||||
p[0] = self.handleNullable(type, p[2])
|
||||
|
||||
def p_PrimitiveOrStringTypeUint(self, p):
|
||||
"""
|
||||
@ -6677,48 +6531,15 @@ class Parser(Tokenizer):
|
||||
"""
|
||||
p[0] = False
|
||||
|
||||
def p_TypeSuffixBrackets(self, p):
|
||||
"""
|
||||
TypeSuffix : LBRACKET RBRACKET TypeSuffix
|
||||
"""
|
||||
p[0] = [(IDLMethod.TypeSuffixModifier.Brackets, self.getLocation(p, 1))]
|
||||
p[0].extend(p[3])
|
||||
|
||||
def p_TypeSuffixQMark(self, p):
|
||||
"""
|
||||
TypeSuffix : QUESTIONMARK TypeSuffixStartingWithArray
|
||||
"""
|
||||
p[0] = [(IDLMethod.TypeSuffixModifier.QMark, self.getLocation(p, 1))]
|
||||
p[0].extend(p[2])
|
||||
|
||||
def p_TypeSuffixEmpty(self, p):
|
||||
"""
|
||||
TypeSuffix :
|
||||
"""
|
||||
p[0] = []
|
||||
|
||||
def p_TypeSuffixStartingWithArray(self, p):
|
||||
"""
|
||||
TypeSuffixStartingWithArray : LBRACKET RBRACKET TypeSuffix
|
||||
"""
|
||||
p[0] = [(IDLMethod.TypeSuffixModifier.Brackets, self.getLocation(p, 1))]
|
||||
p[0].extend(p[3])
|
||||
|
||||
def p_TypeSuffixStartingWithArrayEmpty(self, p):
|
||||
"""
|
||||
TypeSuffixStartingWithArray :
|
||||
"""
|
||||
p[0] = []
|
||||
|
||||
def p_Null(self, p):
|
||||
"""
|
||||
Null : QUESTIONMARK
|
||||
|
|
||||
"""
|
||||
if len(p) > 1:
|
||||
p[0] = True
|
||||
p[0] = self.getLocation(p, 1)
|
||||
else:
|
||||
p[0] = False
|
||||
p[0] = None
|
||||
|
||||
def p_ReturnTypeType(self, p):
|
||||
"""
|
||||
@ -6876,15 +6697,9 @@ class Parser(Tokenizer):
|
||||
typedef = IDLTypedef(BuiltinLocation("<builtin type>"), scope, builtin, name)
|
||||
|
||||
@ staticmethod
|
||||
def handleModifiers(type, modifiers):
|
||||
for (modifier, modifierLocation) in modifiers:
|
||||
assert (modifier == IDLMethod.TypeSuffixModifier.QMark or
|
||||
modifier == IDLMethod.TypeSuffixModifier.Brackets)
|
||||
|
||||
if modifier == IDLMethod.TypeSuffixModifier.QMark:
|
||||
type = IDLNullableType(modifierLocation, type)
|
||||
elif modifier == IDLMethod.TypeSuffixModifier.Brackets:
|
||||
type = IDLArrayType(modifierLocation, type)
|
||||
def handleNullable(type, questionMarkLocation):
|
||||
if questionMarkLocation is not None:
|
||||
type = IDLNullableType(questionMarkLocation, type)
|
||||
|
||||
return type
|
||||
|
||||
|
@ -1,18 +0,0 @@
|
||||
def WebIDLTest(parser, harness):
|
||||
threw = False
|
||||
try:
|
||||
parser.parse("""
|
||||
dictionary Foo {
|
||||
short a;
|
||||
};
|
||||
|
||||
dictionary Foo1 {
|
||||
Foo[] b;
|
||||
};
|
||||
""")
|
||||
results = parser.finish()
|
||||
except:
|
||||
threw = True
|
||||
|
||||
harness.ok(threw, "Array must not contain dictionary "
|
||||
"as element type.")
|
@ -1,13 +0,0 @@
|
||||
import WebIDL
|
||||
|
||||
def WebIDLTest(parser, harness):
|
||||
parser.parse("""
|
||||
interface A {
|
||||
attribute long a;
|
||||
};
|
||||
|
||||
interface B {
|
||||
attribute A[] b;
|
||||
};
|
||||
""");
|
||||
parser.finish()
|
@ -4,37 +4,37 @@ def WebIDLTest(parser, harness):
|
||||
parser.parse("""
|
||||
interface TestArrayBuffer {
|
||||
attribute ArrayBuffer bufferAttr;
|
||||
void bufferMethod(ArrayBuffer arg1, ArrayBuffer? arg2, ArrayBuffer[] arg3, sequence<ArrayBuffer> arg4);
|
||||
void bufferMethod(ArrayBuffer arg1, ArrayBuffer? arg2, sequence<ArrayBuffer> arg3);
|
||||
|
||||
attribute ArrayBufferView viewAttr;
|
||||
void viewMethod(ArrayBufferView arg1, ArrayBufferView? arg2, ArrayBufferView[] arg3, sequence<ArrayBufferView> arg4);
|
||||
void viewMethod(ArrayBufferView arg1, ArrayBufferView? arg2, sequence<ArrayBufferView> arg3);
|
||||
|
||||
attribute Int8Array int8ArrayAttr;
|
||||
void int8ArrayMethod(Int8Array arg1, Int8Array? arg2, Int8Array[] arg3, sequence<Int8Array> arg4);
|
||||
void int8ArrayMethod(Int8Array arg1, Int8Array? arg2, sequence<Int8Array> arg3);
|
||||
|
||||
attribute Uint8Array uint8ArrayAttr;
|
||||
void uint8ArrayMethod(Uint8Array arg1, Uint8Array? arg2, Uint8Array[] arg3, sequence<Uint8Array> arg4);
|
||||
void uint8ArrayMethod(Uint8Array arg1, Uint8Array? arg2, sequence<Uint8Array> arg3);
|
||||
|
||||
attribute Uint8ClampedArray uint8ClampedArrayAttr;
|
||||
void uint8ClampedArrayMethod(Uint8ClampedArray arg1, Uint8ClampedArray? arg2, Uint8ClampedArray[] arg3, sequence<Uint8ClampedArray> arg4);
|
||||
void uint8ClampedArrayMethod(Uint8ClampedArray arg1, Uint8ClampedArray? arg2, sequence<Uint8ClampedArray> arg3);
|
||||
|
||||
attribute Int16Array int16ArrayAttr;
|
||||
void int16ArrayMethod(Int16Array arg1, Int16Array? arg2, Int16Array[] arg3, sequence<Int16Array> arg4);
|
||||
void int16ArrayMethod(Int16Array arg1, Int16Array? arg2, sequence<Int16Array> arg3);
|
||||
|
||||
attribute Uint16Array uint16ArrayAttr;
|
||||
void uint16ArrayMethod(Uint16Array arg1, Uint16Array? arg2, Uint16Array[] arg3, sequence<Uint16Array> arg4);
|
||||
void uint16ArrayMethod(Uint16Array arg1, Uint16Array? arg2, sequence<Uint16Array> arg3);
|
||||
|
||||
attribute Int32Array int32ArrayAttr;
|
||||
void int32ArrayMethod(Int32Array arg1, Int32Array? arg2, Int32Array[] arg3, sequence<Int32Array> arg4);
|
||||
void int32ArrayMethod(Int32Array arg1, Int32Array? arg2, sequence<Int32Array> arg3);
|
||||
|
||||
attribute Uint32Array uint32ArrayAttr;
|
||||
void uint32ArrayMethod(Uint32Array arg1, Uint32Array? arg2, Uint32Array[] arg3, sequence<Uint32Array> arg4);
|
||||
void uint32ArrayMethod(Uint32Array arg1, Uint32Array? arg2, sequence<Uint32Array> arg3);
|
||||
|
||||
attribute Float32Array float32ArrayAttr;
|
||||
void float32ArrayMethod(Float32Array arg1, Float32Array? arg2, Float32Array[] arg3, sequence<Float32Array> arg4);
|
||||
void float32ArrayMethod(Float32Array arg1, Float32Array? arg2, sequence<Float32Array> arg3);
|
||||
|
||||
attribute Float64Array float64ArrayAttr;
|
||||
void float64ArrayMethod(Float64Array arg1, Float64Array? arg2, Float64Array[] arg3, sequence<Float64Array> arg4);
|
||||
void float64ArrayMethod(Float64Array arg1, Float64Array? arg2, sequence<Float64Array> arg3);
|
||||
};
|
||||
""")
|
||||
|
||||
@ -56,7 +56,7 @@ def WebIDLTest(parser, harness):
|
||||
|
||||
(retType, arguments) = method.signatures()[0]
|
||||
harness.ok(retType.isVoid(), "Should have a void return type")
|
||||
harness.check(len(arguments), 4, "Expect 4 arguments")
|
||||
harness.check(len(arguments), 3, "Expect 3 arguments")
|
||||
|
||||
harness.check(str(arguments[0].type), t, "Expect an ArrayBuffer type")
|
||||
harness.ok(arguments[0].type.isSpiderMonkeyInterface(), "Should test as a js interface")
|
||||
@ -64,12 +64,9 @@ def WebIDLTest(parser, harness):
|
||||
harness.check(str(arguments[1].type), t + "OrNull", "Expect an ArrayBuffer type")
|
||||
harness.ok(arguments[1].type.inner.isSpiderMonkeyInterface(), "Should test as a js interface")
|
||||
|
||||
harness.check(str(arguments[2].type), t + "Array", "Expect an ArrayBuffer type")
|
||||
harness.check(str(arguments[2].type), t + "Sequence", "Expect an ArrayBuffer type")
|
||||
harness.ok(arguments[2].type.inner.isSpiderMonkeyInterface(), "Should test as a js interface")
|
||||
|
||||
harness.check(str(arguments[3].type), t + "Sequence", "Expect an ArrayBuffer type")
|
||||
harness.ok(arguments[3].type.inner.isSpiderMonkeyInterface(), "Should test as a js interface")
|
||||
|
||||
|
||||
checkStuff(members[0], members[1], "ArrayBuffer")
|
||||
checkStuff(members[2], members[3], "ArrayBufferView")
|
||||
|
@ -77,110 +77,6 @@ def WebIDLTest(parser, harness):
|
||||
attribute float? f;
|
||||
readonly attribute float? rf;
|
||||
};
|
||||
|
||||
interface TestAttrArray {
|
||||
attribute byte[] b;
|
||||
readonly attribute byte[] rb;
|
||||
attribute octet[] o;
|
||||
readonly attribute octet[] ro;
|
||||
attribute short[] s;
|
||||
readonly attribute short[] rs;
|
||||
attribute unsigned short[] us;
|
||||
readonly attribute unsigned short[] rus;
|
||||
attribute long[] l;
|
||||
readonly attribute long[] rl;
|
||||
attribute unsigned long[] ul;
|
||||
readonly attribute unsigned long[] rul;
|
||||
attribute long long[] ll;
|
||||
readonly attribute long long[] rll;
|
||||
attribute unsigned long long[] ull;
|
||||
readonly attribute unsigned long long[] rull;
|
||||
attribute DOMString[] str;
|
||||
readonly attribute DOMString[] rstr;
|
||||
attribute object[] obj;
|
||||
readonly attribute object[] robj;
|
||||
attribute object[] _object;
|
||||
attribute float[] f;
|
||||
readonly attribute float[] rf;
|
||||
};
|
||||
|
||||
interface TestAttrNullableArray {
|
||||
attribute byte[]? b;
|
||||
readonly attribute byte[]? rb;
|
||||
attribute octet[]? o;
|
||||
readonly attribute octet[]? ro;
|
||||
attribute short[]? s;
|
||||
readonly attribute short[]? rs;
|
||||
attribute unsigned short[]? us;
|
||||
readonly attribute unsigned short[]? rus;
|
||||
attribute long[]? l;
|
||||
readonly attribute long[]? rl;
|
||||
attribute unsigned long[]? ul;
|
||||
readonly attribute unsigned long[]? rul;
|
||||
attribute long long[]? ll;
|
||||
readonly attribute long long[]? rll;
|
||||
attribute unsigned long long[]? ull;
|
||||
readonly attribute unsigned long long[]? rull;
|
||||
attribute DOMString[]? str;
|
||||
readonly attribute DOMString[]? rstr;
|
||||
attribute object[]? obj;
|
||||
readonly attribute object[]? robj;
|
||||
attribute object[]? _object;
|
||||
attribute float[]? f;
|
||||
readonly attribute float[]? rf;
|
||||
};
|
||||
|
||||
interface TestAttrArrayOfNullableTypes {
|
||||
attribute byte?[] b;
|
||||
readonly attribute byte?[] rb;
|
||||
attribute octet?[] o;
|
||||
readonly attribute octet?[] ro;
|
||||
attribute short?[] s;
|
||||
readonly attribute short?[] rs;
|
||||
attribute unsigned short?[] us;
|
||||
readonly attribute unsigned short?[] rus;
|
||||
attribute long?[] l;
|
||||
readonly attribute long?[] rl;
|
||||
attribute unsigned long?[] ul;
|
||||
readonly attribute unsigned long?[] rul;
|
||||
attribute long long?[] ll;
|
||||
readonly attribute long long?[] rll;
|
||||
attribute unsigned long long?[] ull;
|
||||
readonly attribute unsigned long long?[] rull;
|
||||
attribute DOMString?[] str;
|
||||
readonly attribute DOMString?[] rstr;
|
||||
attribute object?[] obj;
|
||||
readonly attribute object?[] robj;
|
||||
attribute object?[] _object;
|
||||
attribute float?[] f;
|
||||
readonly attribute float?[] rf;
|
||||
};
|
||||
|
||||
interface TestAttrNullableArrayOfNullableTypes {
|
||||
attribute byte?[]? b;
|
||||
readonly attribute byte?[]? rb;
|
||||
attribute octet?[]? o;
|
||||
readonly attribute octet?[]? ro;
|
||||
attribute short?[]? s;
|
||||
readonly attribute short?[]? rs;
|
||||
attribute unsigned short?[]? us;
|
||||
readonly attribute unsigned short?[]? rus;
|
||||
attribute long?[]? l;
|
||||
readonly attribute long?[]? rl;
|
||||
attribute unsigned long?[]? ul;
|
||||
readonly attribute unsigned long?[]? rul;
|
||||
attribute long long?[]? ll;
|
||||
readonly attribute long long?[]? rll;
|
||||
attribute unsigned long long?[]? ull;
|
||||
readonly attribute unsigned long long?[]? rull;
|
||||
attribute DOMString?[]? str;
|
||||
readonly attribute DOMString?[]? rstr;
|
||||
attribute object?[]? obj;
|
||||
readonly attribute object?[]? robj;
|
||||
attribute object?[]? _object;
|
||||
attribute float?[]? f;
|
||||
readonly attribute float?[]? rf;
|
||||
};
|
||||
""")
|
||||
|
||||
results = parser.finish()
|
||||
@ -197,7 +93,7 @@ def WebIDLTest(parser, harness):
|
||||
harness.check(attr.readonly, readonly, "Attr's readonly state is correct")
|
||||
|
||||
harness.ok(True, "TestAttr interface parsed without error.")
|
||||
harness.check(len(results), 6, "Should be six productions.")
|
||||
harness.check(len(results), 2, "Should be two productions.")
|
||||
iface = results[0]
|
||||
harness.ok(isinstance(iface, WebIDL.IDLInterface),
|
||||
"Should be an IDLInterface")
|
||||
@ -228,66 +124,6 @@ def WebIDLTest(parser, harness):
|
||||
(QName, name, type, readonly) = data
|
||||
checkAttr(attr, QName % "Nullable", name, type % "OrNull", readonly)
|
||||
|
||||
iface = results[2]
|
||||
harness.ok(isinstance(iface, WebIDL.IDLInterface),
|
||||
"Should be an IDLInterface")
|
||||
harness.check(iface.identifier.QName(), "::TestAttrArray", "Interface has the right QName")
|
||||
harness.check(iface.identifier.name, "TestAttrArray", "Interface has the right name")
|
||||
harness.check(len(iface.members), len(testData), "Expect %s members" % len(testData))
|
||||
|
||||
attrs = iface.members
|
||||
|
||||
for i in range(len(attrs)):
|
||||
data = testData[i]
|
||||
attr = attrs[i]
|
||||
(QName, name, type, readonly) = data
|
||||
checkAttr(attr, QName % "Array", name, type % "Array", readonly)
|
||||
|
||||
iface = results[3]
|
||||
harness.ok(isinstance(iface, WebIDL.IDLInterface),
|
||||
"Should be an IDLInterface")
|
||||
harness.check(iface.identifier.QName(), "::TestAttrNullableArray", "Interface has the right QName")
|
||||
harness.check(iface.identifier.name, "TestAttrNullableArray", "Interface has the right name")
|
||||
harness.check(len(iface.members), len(testData), "Expect %s members" % len(testData))
|
||||
|
||||
attrs = iface.members
|
||||
|
||||
for i in range(len(attrs)):
|
||||
data = testData[i]
|
||||
attr = attrs[i]
|
||||
(QName, name, type, readonly) = data
|
||||
checkAttr(attr, QName % "NullableArray", name, type % "ArrayOrNull", readonly)
|
||||
|
||||
iface = results[4]
|
||||
harness.ok(isinstance(iface, WebIDL.IDLInterface),
|
||||
"Should be an IDLInterface")
|
||||
harness.check(iface.identifier.QName(), "::TestAttrArrayOfNullableTypes", "Interface has the right QName")
|
||||
harness.check(iface.identifier.name, "TestAttrArrayOfNullableTypes", "Interface has the right name")
|
||||
harness.check(len(iface.members), len(testData), "Expect %s members" % len(testData))
|
||||
|
||||
attrs = iface.members
|
||||
|
||||
for i in range(len(attrs)):
|
||||
data = testData[i]
|
||||
attr = attrs[i]
|
||||
(QName, name, type, readonly) = data
|
||||
checkAttr(attr, QName % "ArrayOfNullableTypes", name, type % "OrNullArray", readonly)
|
||||
|
||||
iface = results[5]
|
||||
harness.ok(isinstance(iface, WebIDL.IDLInterface),
|
||||
"Should be an IDLInterface")
|
||||
harness.check(iface.identifier.QName(), "::TestAttrNullableArrayOfNullableTypes", "Interface has the right QName")
|
||||
harness.check(iface.identifier.name, "TestAttrNullableArrayOfNullableTypes", "Interface has the right name")
|
||||
harness.check(len(iface.members), len(testData), "Expect %s members" % len(testData))
|
||||
|
||||
attrs = iface.members
|
||||
|
||||
for i in range(len(attrs)):
|
||||
data = testData[i]
|
||||
attr = attrs[i]
|
||||
(QName, name, type, readonly) = data
|
||||
checkAttr(attr, QName % "NullableArrayOfNullableTypes", name, type % "OrNullArrayOrNull", readonly)
|
||||
|
||||
parser = parser.reset()
|
||||
threw = False
|
||||
try:
|
||||
|
@ -159,7 +159,7 @@ def WebIDLTest(parser, harness):
|
||||
"object", "Callback", "Callback2", "optional Dict",
|
||||
"optional Dict2", "sequence<long>", "sequence<short>",
|
||||
"MozMap<object>", "MozMap<Dict>", "MozMap<long>",
|
||||
"long[]", "short[]", "Date", "Date?", "any",
|
||||
"Date", "Date?", "any",
|
||||
"Promise<any>", "Promise<any>?",
|
||||
"USVString", "ArrayBuffer", "ArrayBufferView", "SharedArrayBuffer",
|
||||
"Uint8Array", "Uint16Array" ]
|
||||
@ -187,7 +187,6 @@ def WebIDLTest(parser, harness):
|
||||
"Date?", "any", "Promise<any>?"]
|
||||
dates = [ "Date", "Date?" ]
|
||||
sequences = [ "sequence<long>", "sequence<short>" ]
|
||||
arrays = [ "long[]", "short[]" ]
|
||||
nonUserObjects = nonObjects + interfaces + dates + sequences
|
||||
otherObjects = allBut(argTypes, nonUserObjects + ["object"])
|
||||
notRelatedInterfaces = (nonObjects + ["UnrelatedInterface"] +
|
||||
@ -229,14 +228,12 @@ def WebIDLTest(parser, harness):
|
||||
setDistinguishable("optional Dict", allBut(nonUserObjects, nullables))
|
||||
setDistinguishable("optional Dict2", allBut(nonUserObjects, nullables))
|
||||
setDistinguishable("sequence<long>",
|
||||
allBut(argTypes, sequences + arrays + ["object"]))
|
||||
allBut(argTypes, sequences + ["object"]))
|
||||
setDistinguishable("sequence<short>",
|
||||
allBut(argTypes, sequences + arrays + ["object"]))
|
||||
allBut(argTypes, sequences + ["object"]))
|
||||
setDistinguishable("MozMap<object>", nonUserObjects)
|
||||
setDistinguishable("MozMap<Dict>", nonUserObjects)
|
||||
setDistinguishable("MozMap<long>", nonUserObjects)
|
||||
setDistinguishable("long[]", allBut(nonUserObjects, sequences))
|
||||
setDistinguishable("short[]", allBut(nonUserObjects, sequences))
|
||||
setDistinguishable("Date", allBut(argTypes, dates + ["object"]))
|
||||
setDistinguishable("Date?", allBut(argTypes, dates + nullables + ["object"]))
|
||||
setDistinguishable("any", [])
|
||||
|
@ -11,7 +11,6 @@ def WebIDLTest(parser, harness):
|
||||
boolean basicBooleanWithSimpleArgs(boolean arg1, byte arg2, unsigned long arg3);
|
||||
void optionalArg(optional byte? arg1, optional sequence<byte> arg2);
|
||||
void variadicArg(byte?... arg1);
|
||||
void crazyTypes(sequence<long?[]>? arg1, boolean?[][]? arg2);
|
||||
object getObject();
|
||||
void setObject(object arg1);
|
||||
void setAny(any arg1);
|
||||
@ -28,7 +27,7 @@ def WebIDLTest(parser, harness):
|
||||
"Should be an IDLInterface")
|
||||
harness.check(iface.identifier.QName(), "::TestMethods", "Interface has the right QName")
|
||||
harness.check(iface.identifier.name, "TestMethods", "Interface has the right name")
|
||||
harness.check(len(iface.members), 13, "Expect 13 members")
|
||||
harness.check(len(iface.members), 12, "Expect 12 members")
|
||||
|
||||
methods = iface.members
|
||||
|
||||
@ -98,22 +97,17 @@ def WebIDLTest(parser, harness):
|
||||
"variadicArg",
|
||||
[("Void",
|
||||
[("::TestMethods::variadicArg::arg1", "arg1", "ByteOrNull", True, True)])])
|
||||
checkMethod(methods[8], "::TestMethods::crazyTypes",
|
||||
"crazyTypes",
|
||||
[("Void",
|
||||
[("::TestMethods::crazyTypes::arg1", "arg1", "LongOrNullArraySequenceOrNull", False, False),
|
||||
("::TestMethods::crazyTypes::arg2", "arg2", "BooleanOrNullArrayArrayOrNull", False, False)])])
|
||||
checkMethod(methods[9], "::TestMethods::getObject",
|
||||
checkMethod(methods[8], "::TestMethods::getObject",
|
||||
"getObject", [("Object", [])])
|
||||
checkMethod(methods[10], "::TestMethods::setObject",
|
||||
checkMethod(methods[9], "::TestMethods::setObject",
|
||||
"setObject",
|
||||
[("Void",
|
||||
[("::TestMethods::setObject::arg1", "arg1", "Object", False, False)])])
|
||||
checkMethod(methods[11], "::TestMethods::setAny",
|
||||
checkMethod(methods[10], "::TestMethods::setAny",
|
||||
"setAny",
|
||||
[("Void",
|
||||
[("::TestMethods::setAny::arg1", "arg1", "Any", False, False)])])
|
||||
checkMethod(methods[12], "::TestMethods::doFloats",
|
||||
checkMethod(methods[11], "::TestMethods::doFloats",
|
||||
"doFloats",
|
||||
[("Float",
|
||||
[("::TestMethods::doFloats::arg1", "arg1", "Float", False, False)])])
|
||||
|
@ -53,16 +53,6 @@ def WebIDLTest(parser, harness):
|
||||
attribute object a;
|
||||
attribute object? b;
|
||||
};
|
||||
|
||||
interface TestNullableEquivalency11 {
|
||||
attribute double[] a;
|
||||
attribute double[]? b;
|
||||
};
|
||||
|
||||
interface TestNullableEquivalency12 {
|
||||
attribute TestNullableEquivalency9[] a;
|
||||
attribute TestNullableEquivalency9[]? b;
|
||||
};
|
||||
""")
|
||||
|
||||
for decl in parser.finish():
|
||||
|
@ -139,9 +139,6 @@ def WebIDLTest(parser, harness):
|
||||
void method${i}(${type} arg);
|
||||
${type} returnMethod${i}();
|
||||
attribute ${type} attr${i};
|
||||
void arrayMethod${i}(${type}[] arg);
|
||||
${type}[] arrayReturnMethod${i}();
|
||||
attribute ${type}[] arrayAttr${i};
|
||||
void optionalMethod${i}(${type}? arg);
|
||||
""").substitute(i=i, type=type)
|
||||
interface += """
|
||||
|
@ -28,9 +28,9 @@ SendRequest(BluetoothReplyRunnable* aRunnable, const Request& aRequest)
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
MOZ_ASSERT(aRunnable);
|
||||
|
||||
NS_WARN_IF_FALSE(sBluetoothChild,
|
||||
"Calling methods on BluetoothServiceChildProcess during "
|
||||
"shutdown!");
|
||||
NS_WARNING_ASSERTION(
|
||||
sBluetoothChild,
|
||||
"Calling methods on BluetoothServiceChildProcess during shutdown!");
|
||||
|
||||
if (sBluetoothChild) {
|
||||
BluetoothRequestChild* actor = new BluetoothRequestChild(aRunnable);
|
||||
|
@ -1738,7 +1738,7 @@ CanvasRenderingContext2D::TrySkiaGLTarget(RefPtr<gfx::DrawTarget>& aOutDT,
|
||||
DemoteOldestContextIfNecessary();
|
||||
mBufferProvider = nullptr;
|
||||
|
||||
#if USE_SKIA_GPU
|
||||
#ifdef USE_SKIA_GPU
|
||||
SkiaGLGlue* glue = gfxPlatform::GetPlatform()->GetSkiaGLGlue();
|
||||
if (!glue || !glue->GetGrContext() || !glue->GetGLContext()) {
|
||||
return false;
|
||||
|
5
dom/canvas/crashtests/1299062-1.html
Normal file
5
dom/canvas/crashtests/1299062-1.html
Normal file
@ -0,0 +1,5 @@
|
||||
<canvas id='id0' width='35376.4661501'></canvas>
|
||||
<script>
|
||||
var ctx=document.getElementById('id0').getContext('2d');
|
||||
ctx.getImageData(66,-1,32,87);
|
||||
</script>
|
@ -36,4 +36,5 @@ load 1288872-1.html
|
||||
load 1290628-1.html
|
||||
load 1283113-1.html
|
||||
load 1286458-1.html
|
||||
load 1299062-1.html
|
||||
|
||||
|
@ -82,8 +82,8 @@ CellBroadcast::CellBroadcast(nsPIDOMWindowInner* aWindow,
|
||||
{
|
||||
mListener = new Listener(this);
|
||||
DebugOnly<nsresult> rv = aService->RegisterListener(mListener);
|
||||
NS_WARN_IF_FALSE(NS_SUCCEEDED(rv),
|
||||
"Failed registering Cell Broadcast callback");
|
||||
NS_WARNING_ASSERTION(NS_SUCCEEDED(rv),
|
||||
"Failed registering Cell Broadcast callback");
|
||||
}
|
||||
|
||||
CellBroadcast::~CellBroadcast()
|
||||
|
@ -28,7 +28,7 @@ WebCryptoThreadPool::Initialize()
|
||||
MOZ_ASSERT(!gInstance, "More than one instance!");
|
||||
|
||||
gInstance = new WebCryptoThreadPool();
|
||||
NS_WARN_IF_FALSE(gInstance, "Failed create thread pool!");
|
||||
NS_WARNING_ASSERTION(gInstance, "Failed create thread pool!");
|
||||
|
||||
if (gInstance && NS_FAILED(gInstance->Init())) {
|
||||
NS_WARNING("Failed to initialize thread pool!");
|
||||
@ -90,7 +90,7 @@ WebCryptoThreadPool::Shutdown()
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIObserverService> obs = mozilla::services::GetObserverService();
|
||||
NS_WARN_IF_FALSE(obs, "Failed to retrieve observer service!");
|
||||
NS_WARNING_ASSERTION(obs, "Failed to retrieve observer service!");
|
||||
|
||||
if (obs) {
|
||||
if (NS_FAILED(obs->RemoveObserver(this,
|
||||
|
@ -167,7 +167,7 @@ public:
|
||||
|
||||
bool IsValid()
|
||||
{
|
||||
NS_WARN_IF_FALSE(!!(mTarget), "Event target is not valid!");
|
||||
NS_WARNING_ASSERTION(!!(mTarget), "Event target is not valid!");
|
||||
return !!(mTarget);
|
||||
}
|
||||
|
||||
|
@ -387,9 +387,10 @@ EventListenerManager::AddEventListenerInternal(
|
||||
if (window) {
|
||||
#ifdef DEBUG
|
||||
nsCOMPtr<nsIDocument> d = window->GetExtantDoc();
|
||||
NS_WARN_IF_FALSE(!nsContentUtils::IsChromeDoc(d),
|
||||
"Please do not use pointerenter/leave events in chrome. "
|
||||
"They are slower than pointerover/out!");
|
||||
NS_WARNING_ASSERTION(
|
||||
!nsContentUtils::IsChromeDoc(d),
|
||||
"Please do not use pointerenter/leave events in chrome. "
|
||||
"They are slower than pointerover/out!");
|
||||
#endif
|
||||
window->SetHasPointerEnterLeaveEventListeners();
|
||||
}
|
||||
@ -400,9 +401,10 @@ EventListenerManager::AddEventListenerInternal(
|
||||
if (nsPIDOMWindowInner* window = GetInnerWindowForTarget()) {
|
||||
#ifdef DEBUG
|
||||
nsCOMPtr<nsIDocument> d = window->GetExtantDoc();
|
||||
NS_WARN_IF_FALSE(!nsContentUtils::IsChromeDoc(d),
|
||||
"Please do not use mouseenter/leave events in chrome. "
|
||||
"They are slower than mouseover/out!");
|
||||
NS_WARNING_ASSERTION(
|
||||
!nsContentUtils::IsChromeDoc(d),
|
||||
"Please do not use mouseenter/leave events in chrome. "
|
||||
"They are slower than mouseover/out!");
|
||||
#endif
|
||||
window->SetHasMouseEnterLeaveEventListeners();
|
||||
}
|
||||
@ -653,6 +655,8 @@ EventListenerManager::RemoveEventListenerInternal(
|
||||
uint32_t typeCount = 0;
|
||||
bool deviceType = IsDeviceType(aEventMessage);
|
||||
|
||||
RefPtr<EventListenerManager> kungFuDeathGrip(this);
|
||||
|
||||
for (uint32_t i = 0; i < count; ++i) {
|
||||
listener = &mListeners.ElementAt(i);
|
||||
if (EVENT_TYPE_EQUALS(listener, aEventMessage, aUserType, aTypeString,
|
||||
@ -660,7 +664,6 @@ EventListenerManager::RemoveEventListenerInternal(
|
||||
++typeCount;
|
||||
if (listener->mListener == aListenerHolder &&
|
||||
listener->mFlags.EqualsForRemoval(aFlags)) {
|
||||
RefPtr<EventListenerManager> kungFuDeathGrip(this);
|
||||
mListeners.RemoveElementAt(i);
|
||||
--count;
|
||||
NotifyEventListenerRemoved(aUserType);
|
||||
|
@ -523,12 +523,12 @@ EventStateManager::PreHandleEvent(nsPresContext* aPresContext,
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
}
|
||||
|
||||
NS_WARN_IF_FALSE(!aTargetFrame ||
|
||||
!aTargetFrame->GetContent() ||
|
||||
aTargetFrame->GetContent() == aTargetContent ||
|
||||
aTargetFrame->GetContent()->GetFlattenedTreeParent() == aTargetContent ||
|
||||
aTargetFrame->IsGeneratedContentFrame(),
|
||||
"aTargetFrame should be related with aTargetContent");
|
||||
NS_WARNING_ASSERTION(
|
||||
!aTargetFrame || !aTargetFrame->GetContent() ||
|
||||
aTargetFrame->GetContent() == aTargetContent ||
|
||||
aTargetFrame->GetContent()->GetFlattenedTreeParent() == aTargetContent ||
|
||||
aTargetFrame->IsGeneratedContentFrame(),
|
||||
"aTargetFrame should be related with aTargetContent");
|
||||
#if DEBUG
|
||||
if (aTargetFrame && aTargetFrame->IsGeneratedContentFrame()) {
|
||||
nsCOMPtr<nsIContent> targetContent;
|
||||
@ -3022,7 +3022,7 @@ EventStateManager::PostHandleEvent(nsPresContext* aPresContext,
|
||||
// If the mousedown happened inside a popup, don't
|
||||
// try to set focus on one of its containing elements
|
||||
const nsStyleDisplay* display = currFrame->StyleDisplay();
|
||||
if (display->mDisplay == NS_STYLE_DISPLAY_POPUP) {
|
||||
if (display->mDisplay == StyleDisplay::Popup) {
|
||||
newFocus = nullptr;
|
||||
break;
|
||||
}
|
||||
|
@ -331,7 +331,8 @@ WheelTransaction::SetTimeout()
|
||||
DebugOnly<nsresult> rv =
|
||||
sTimer->InitWithFuncCallback(OnTimeout, nullptr, GetTimeoutTime(),
|
||||
nsITimer::TYPE_ONE_SHOT);
|
||||
NS_WARN_IF_FALSE(NS_SUCCEEDED(rv), "nsITimer::InitWithFuncCallback failed");
|
||||
NS_WARNING_ASSERTION(NS_SUCCEEDED(rv),
|
||||
"nsITimer::InitWithFuncCallback failed");
|
||||
}
|
||||
|
||||
/* static */ nsIntPoint
|
||||
|
@ -35,7 +35,9 @@
|
||||
target1.setPointerCapture(e.pointerId);
|
||||
test_pointerEvent.step(function () {
|
||||
assert_equals(target0.hasPointerCapture(e.pointerId), false,
|
||||
"target1.setPointerCapture, target0.hasPointerCapture should be false");
|
||||
"after target1.setPointerCapture, target0.hasPointerCapture should be false");
|
||||
assert_equals(target1.hasPointerCapture(e.pointerId), true,
|
||||
"after target1.setPointerCapture, target1.hasPointerCapture should be true");
|
||||
});
|
||||
target0.setPointerCapture(e.pointerId);
|
||||
set_capture_to_target0 = true;
|
||||
@ -50,6 +52,8 @@
|
||||
test_pointerEvent.step(function () {
|
||||
assert_equals(target0.hasPointerCapture(e.pointerId), false,
|
||||
"after target0.releasePointerCapture, target0.hasPointerCapture should be false");
|
||||
assert_equals(target1.hasPointerCapture(e.pointerId), false,
|
||||
"after target0.releasePointerCapture, target1.hasPointerCapture should be false");
|
||||
});
|
||||
target0.setPointerCapture(e.pointerId);
|
||||
set_capture_to_target0 = true;
|
||||
@ -83,6 +87,13 @@
|
||||
assert_equals(target0.hasPointerCapture(e.pointerId), false,
|
||||
"pointerup target0.hasPointerCapture should be false");
|
||||
});
|
||||
});
|
||||
|
||||
on_event(target1, "pointerup", function (e) {
|
||||
test_pointerEvent.step(function () {
|
||||
assert_equals(target1.hasPointerCapture(e.pointerId), false,
|
||||
"pointerup target1.hasPointerCapture should be false");
|
||||
});
|
||||
test_pointerEvent.done();
|
||||
});
|
||||
}
|
||||
@ -95,14 +106,15 @@
|
||||
Test Description: This test checks if Element.hasPointerCapture returns value correctly
|
||||
<ol>
|
||||
<li> Press black rectangle and do not release
|
||||
<li> Move your pointer to yellow rectangle
|
||||
<li> Move your pointer to purple rectangle
|
||||
<li> Release the pointer
|
||||
<li> Click purple rectangle
|
||||
</ol>
|
||||
</h4>
|
||||
<p>
|
||||
-->
|
||||
<div id="target0" style="background:black"></div>
|
||||
<div id="target1" style="background:yellow"></div>
|
||||
<div id="target0" touch-action:none></div>
|
||||
<div id="target1" touch-action:none></div>
|
||||
<div id="complete-notice">
|
||||
<p>The following pointer types were detected: <span id="pointertype-log"></span>.</p>
|
||||
</div>
|
||||
|
@ -23,6 +23,8 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=1000870
|
||||
sendMouseEvent(int_win, "target0", "mousemove", {button:0});
|
||||
sendMouseEvent(int_win, "target1", "mousemove", {button:0});
|
||||
sendMouseEvent(int_win, "target1", "mouseup", {button:0});
|
||||
sendMouseEvent(int_win, "target1", "mousedown", {button:0});
|
||||
sendMouseEvent(int_win, "target1", "mouseup", {button:0});
|
||||
}
|
||||
</script>
|
||||
</head>
|
||||
|
@ -113,7 +113,7 @@ HTMLMenuElement::CreateBuilder()
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIMenuBuilder> builder = do_CreateInstance(HTMLMENUBUILDER_CONTRACTID);
|
||||
NS_WARN_IF_FALSE(builder, "No builder available");
|
||||
NS_WARNING_ASSERTION(builder, "No builder available");
|
||||
return builder.forget();
|
||||
}
|
||||
|
||||
|
@ -981,7 +981,7 @@ nsGenericHTMLElement::ParseBackgroundAttribute(int32_t aNamespaceID,
|
||||
}
|
||||
|
||||
mozilla::css::URLValue *url =
|
||||
new mozilla::css::URLValue(uri, buffer, doc->GetDocumentURI(),
|
||||
new mozilla::css::URLValue(uri, buffer, baseURI, doc->GetDocumentURI(),
|
||||
NodePrincipal());
|
||||
aResult.SetTo(url, &aValue);
|
||||
return true;
|
||||
@ -1290,7 +1290,7 @@ nsGenericHTMLElement::MapCommonAttributesInto(const nsMappedAttributes* aAttribu
|
||||
nsCSSValue* display = aData->ValueForDisplay();
|
||||
if (display->GetUnit() == eCSSUnit_Null) {
|
||||
if (aAttributes->IndexOfAttr(nsGkAtoms::hidden) >= 0) {
|
||||
display->SetIntValue(NS_STYLE_DISPLAY_NONE, eCSSUnit_Enumerated);
|
||||
display->SetIntValue(StyleDisplay::None_, eCSSUnit_Enumerated);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -3097,7 +3097,7 @@ IsOrHasAncestorWithDisplayNone(Element* aElement, nsIPresShell* aPresShell)
|
||||
sc = nsComputedDOMStyle::GetStyleContextForElementNoFlush(elementsToCheck[i],
|
||||
nullptr, aPresShell);
|
||||
}
|
||||
if (sc->StyleDisplay()->mDisplay == NS_STYLE_DISPLAY_NONE) {
|
||||
if (sc->StyleDisplay()->mDisplay == StyleDisplay::None_) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -257,14 +257,12 @@ NS_NewHTMLElement(Element** aResult, already_AddRefed<mozilla::dom::NodeInfo>&&
|
||||
if ((tag == eHTMLTag_userdefined &&
|
||||
nsContentUtils::IsCustomElementName(name)) ||
|
||||
aIs) {
|
||||
nsIDocument* doc = nodeInfo->GetDocument();
|
||||
|
||||
NS_IF_ADDREF(*aResult = NS_NewHTMLElement(nodeInfo.forget(), aFromParser));
|
||||
if (!*aResult) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
doc->SetupCustomElement(*aResult, kNameSpaceID_XHTML, aIs);
|
||||
nsContentUtils::SetupCustomElement(*aResult, aIs);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -557,7 +557,7 @@ nsHTMLDocument::StartDocumentLoad(const char* aCommand,
|
||||
mCompatMode = eCompatibility_FullStandards;
|
||||
loadAsHtml5 = false;
|
||||
}
|
||||
|
||||
|
||||
// TODO: Proper about:blank treatment is bug 543435
|
||||
if (loadAsHtml5 && view) {
|
||||
// mDocumentURI hasn't been set, yet, so get the URI from the channel
|
||||
@ -567,16 +567,14 @@ nsHTMLDocument::StartDocumentLoad(const char* aCommand,
|
||||
// GetSpec can be expensive for some URIs, so check the scheme first.
|
||||
bool isAbout = false;
|
||||
if (uri && NS_SUCCEEDED(uri->SchemeIs("about", &isAbout)) && isAbout) {
|
||||
nsAutoCString str;
|
||||
uri->GetSpec(str);
|
||||
if (str.EqualsLiteral("about:blank")) {
|
||||
loadAsHtml5 = false;
|
||||
if (uri->GetSpecOrDefault().EqualsLiteral("about:blank")) {
|
||||
loadAsHtml5 = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
CSSLoader()->SetCompatibilityMode(mCompatMode);
|
||||
|
||||
|
||||
nsresult rv = nsDocument::StartDocumentLoad(aCommand,
|
||||
aChannel, aLoadGroup,
|
||||
aContainer,
|
||||
@ -748,7 +746,7 @@ nsHTMLDocument::StartDocumentLoad(const char* aCommand,
|
||||
"How did those end up different here? wyciwyg channels are "
|
||||
"not nsICachingChannel");
|
||||
rv = cachingChan->SetCacheTokenCachedCharset(charset);
|
||||
NS_WARN_IF_FALSE(NS_SUCCEEDED(rv), "cannot SetMetaDataElement");
|
||||
NS_WARNING_ASSERTION(NS_SUCCEEDED(rv), "cannot SetMetaDataElement");
|
||||
rv = NS_OK; // don't propagate error
|
||||
}
|
||||
|
||||
@ -1506,15 +1504,9 @@ nsHTMLDocument::Open(JSContext* cx,
|
||||
#ifdef DEBUG
|
||||
nsCOMPtr<nsIURI> callerDocURI = callerDoc->GetDocumentURI();
|
||||
nsCOMPtr<nsIURI> thisURI = nsIDocument::GetDocumentURI();
|
||||
nsAutoCString callerSpec;
|
||||
nsAutoCString thisSpec;
|
||||
if (callerDocURI) {
|
||||
callerDocURI->GetSpec(callerSpec);
|
||||
}
|
||||
if (thisURI) {
|
||||
thisURI->GetSpec(thisSpec);
|
||||
}
|
||||
printf("nsHTMLDocument::Open callerDoc %s this %s\n", callerSpec.get(), thisSpec.get());
|
||||
printf("nsHTMLDocument::Open callerDoc %s this %s\n",
|
||||
callerDocURI ? callerDocURI->GetSpecOrDefault().get() : "",
|
||||
thisURI ? thisURI->GetSpecOrDefault().get() : "");
|
||||
#endif
|
||||
|
||||
rv.Throw(NS_ERROR_DOM_SECURITY_ERR);
|
||||
|
@ -45,8 +45,8 @@ IccListener::IccListener(IccManager* aIccManager, uint32_t aClientId)
|
||||
}
|
||||
|
||||
DebugOnly<nsresult> rv = mHandler->RegisterListener(this);
|
||||
NS_WARN_IF_FALSE(NS_SUCCEEDED(rv),
|
||||
"Failed registering icc listener with Icc Handler");
|
||||
NS_WARNING_ASSERTION(NS_SUCCEEDED(rv),
|
||||
"Failed registering icc listener with Icc Handler");
|
||||
}
|
||||
|
||||
IccListener::~IccListener()
|
||||
|
@ -13257,16 +13257,19 @@ Factory::Create(const LoggingInfo& aLoggingInfo)
|
||||
if (loggingInfo) {
|
||||
MOZ_ASSERT(aLoggingInfo.backgroundChildLoggingId() == loggingInfo->Id());
|
||||
#if !DISABLE_ASSERTS_FOR_FUZZING
|
||||
NS_WARN_IF_FALSE(aLoggingInfo.nextTransactionSerialNumber() ==
|
||||
loggingInfo->mLoggingInfo.nextTransactionSerialNumber(),
|
||||
"NextTransactionSerialNumber doesn't match!");
|
||||
NS_WARN_IF_FALSE(aLoggingInfo.nextVersionChangeTransactionSerialNumber() ==
|
||||
loggingInfo->mLoggingInfo.
|
||||
nextVersionChangeTransactionSerialNumber(),
|
||||
"NextVersionChangeTransactionSerialNumber doesn't match!");
|
||||
NS_WARN_IF_FALSE(aLoggingInfo.nextRequestSerialNumber() ==
|
||||
loggingInfo->mLoggingInfo.nextRequestSerialNumber(),
|
||||
"NextRequestSerialNumber doesn't match!");
|
||||
NS_WARNING_ASSERTION(
|
||||
aLoggingInfo.nextTransactionSerialNumber() ==
|
||||
loggingInfo->mLoggingInfo.nextTransactionSerialNumber(),
|
||||
"NextTransactionSerialNumber doesn't match!");
|
||||
NS_WARNING_ASSERTION(
|
||||
aLoggingInfo.nextVersionChangeTransactionSerialNumber() ==
|
||||
loggingInfo->mLoggingInfo.
|
||||
nextVersionChangeTransactionSerialNumber(),
|
||||
"NextVersionChangeTransactionSerialNumber doesn't match!");
|
||||
NS_WARNING_ASSERTION(
|
||||
aLoggingInfo.nextRequestSerialNumber() ==
|
||||
loggingInfo->mLoggingInfo.nextRequestSerialNumber(),
|
||||
"NextRequestSerialNumber doesn't match!");
|
||||
#endif // !DISABLE_ASSERTS_FOR_FUZZING
|
||||
} else {
|
||||
loggingInfo = new DatabaseLoggingInfo(aLoggingInfo);
|
||||
@ -23089,19 +23092,20 @@ CommitOp::Run()
|
||||
if (NS_SUCCEEDED(mResultCode)) {
|
||||
if (fileRefcountFunction) {
|
||||
mResultCode = fileRefcountFunction->WillCommit();
|
||||
NS_WARN_IF_FALSE(NS_SUCCEEDED(mResultCode), "WillCommit() failed!");
|
||||
NS_WARNING_ASSERTION(NS_SUCCEEDED(mResultCode),
|
||||
"WillCommit() failed!");
|
||||
}
|
||||
|
||||
if (NS_SUCCEEDED(mResultCode)) {
|
||||
mResultCode = WriteAutoIncrementCounts();
|
||||
NS_WARN_IF_FALSE(NS_SUCCEEDED(mResultCode),
|
||||
"WriteAutoIncrementCounts() failed!");
|
||||
NS_WARNING_ASSERTION(NS_SUCCEEDED(mResultCode),
|
||||
"WriteAutoIncrementCounts() failed!");
|
||||
|
||||
if (NS_SUCCEEDED(mResultCode)) {
|
||||
AssertForeignKeyConsistency(connection);
|
||||
|
||||
mResultCode = connection->CommitWriteTransaction();
|
||||
NS_WARN_IF_FALSE(NS_SUCCEEDED(mResultCode), "Commit failed!");
|
||||
NS_WARNING_ASSERTION(NS_SUCCEEDED(mResultCode), "Commit failed!");
|
||||
|
||||
if (NS_SUCCEEDED(mResultCode) &&
|
||||
mTransaction->GetMode() == IDBTransaction::READ_WRITE_FLUSH) {
|
||||
|
@ -1604,7 +1604,8 @@ private:
|
||||
nsCOMPtr<nsIThread> ioTarget;
|
||||
mIOTarget.swap(ioTarget);
|
||||
|
||||
NS_WARN_IF_FALSE(NS_SUCCEEDED(stream->Close()), "Failed to close stream!");
|
||||
DebugOnly<nsresult> rv = stream->Close();
|
||||
NS_WARNING_ASSERTION(NS_SUCCEEDED(rv), "Failed to close stream!");
|
||||
|
||||
MOZ_ALWAYS_SUCCEEDS(NS_DispatchToMainThread(NewRunnableMethod(ioTarget, &nsIThread::Shutdown)));
|
||||
|
||||
|
@ -32,6 +32,7 @@
|
||||
#include "mozilla/dom/GetFilesHelper.h"
|
||||
#include "mozilla/dom/PCrashReporterChild.h"
|
||||
#include "mozilla/dom/ProcessGlobal.h"
|
||||
#include "mozilla/dom/PushNotifier.h"
|
||||
#include "mozilla/dom/workers/ServiceWorkerManager.h"
|
||||
#include "mozilla/dom/nsIContentChild.h"
|
||||
#include "mozilla/gfx/gfxVars.h"
|
||||
@ -167,10 +168,6 @@
|
||||
#include "nsAccessibilityService.h"
|
||||
#endif
|
||||
|
||||
#ifndef MOZ_SIMPLEPUSH
|
||||
#include "mozilla/dom/PushNotifier.h"
|
||||
#endif
|
||||
|
||||
#include "mozilla/dom/File.h"
|
||||
#include "mozilla/dom/cellbroadcast/CellBroadcastIPCService.h"
|
||||
#include "mozilla/dom/icc/IccChild.h"
|
||||
@ -575,7 +572,7 @@ ContentChild::Init(MessageLoop* aIOLoop,
|
||||
// Once we start sending IPC messages, we need the thread manager to be
|
||||
// initialized so we can deal with the responses. Do that here before we
|
||||
// try to construct the crash reporter.
|
||||
nsresult rv = nsThreadManager::get()->Init();
|
||||
nsresult rv = nsThreadManager::get().Init();
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return false;
|
||||
}
|
||||
@ -3255,10 +3252,8 @@ ContentChild::RecvPush(const nsCString& aScope,
|
||||
const IPC::Principal& aPrincipal,
|
||||
const nsString& aMessageId)
|
||||
{
|
||||
#ifndef MOZ_SIMPLEPUSH
|
||||
PushMessageDispatcher dispatcher(aScope, aPrincipal, aMessageId, Nothing());
|
||||
Unused << NS_WARN_IF(NS_FAILED(dispatcher.NotifyObserversAndWorkers()));
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -3268,10 +3263,8 @@ ContentChild::RecvPushWithData(const nsCString& aScope,
|
||||
const nsString& aMessageId,
|
||||
InfallibleTArray<uint8_t>&& aData)
|
||||
{
|
||||
#ifndef MOZ_SIMPLEPUSH
|
||||
PushMessageDispatcher dispatcher(aScope, aPrincipal, aMessageId, Some(aData));
|
||||
Unused << NS_WARN_IF(NS_FAILED(dispatcher.NotifyObserversAndWorkers()));
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -3279,10 +3272,8 @@ bool
|
||||
ContentChild::RecvPushSubscriptionChange(const nsCString& aScope,
|
||||
const IPC::Principal& aPrincipal)
|
||||
{
|
||||
#ifndef MOZ_SIMPLEPUSH
|
||||
PushSubscriptionChangeDispatcher dispatcher(aScope, aPrincipal);
|
||||
Unused << NS_WARN_IF(NS_FAILED(dispatcher.NotifyObserversAndWorkers()));
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -3290,10 +3281,8 @@ bool
|
||||
ContentChild::RecvPushError(const nsCString& aScope, const IPC::Principal& aPrincipal,
|
||||
const nsString& aMessage, const uint32_t& aFlags)
|
||||
{
|
||||
#ifndef MOZ_SIMPLEPUSH
|
||||
PushErrorDispatcher dispatcher(aScope, aPrincipal, aMessage, aFlags);
|
||||
Unused << NS_WARN_IF(NS_FAILED(dispatcher.NotifyObserversAndWorkers()));
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -3301,10 +3290,8 @@ bool
|
||||
ContentChild::RecvNotifyPushSubscriptionModifiedObservers(const nsCString& aScope,
|
||||
const IPC::Principal& aPrincipal)
|
||||
{
|
||||
#ifndef MOZ_SIMPLEPUSH
|
||||
PushSubscriptionModifiedDispatcher dispatcher(aScope, aPrincipal);
|
||||
Unused << NS_WARN_IF(NS_FAILED(dispatcher.NotifyObservers()));
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -66,6 +66,7 @@
|
||||
#include "mozilla/dom/Permissions.h"
|
||||
#include "mozilla/dom/PresentationParent.h"
|
||||
#include "mozilla/dom/PPresentationParent.h"
|
||||
#include "mozilla/dom/PushNotifier.h"
|
||||
#include "mozilla/dom/FlyWebPublishedServerIPC.h"
|
||||
#include "mozilla/dom/quota/QuotaManagerService.h"
|
||||
#include "mozilla/dom/telephony/TelephonyParent.h"
|
||||
@ -263,10 +264,6 @@ using namespace mozilla::system;
|
||||
#include "nsIProfileSaveEvent.h"
|
||||
#endif
|
||||
|
||||
#ifndef MOZ_SIMPLEPUSH
|
||||
#include "mozilla/dom/PushNotifier.h"
|
||||
#endif
|
||||
|
||||
#ifdef XP_WIN
|
||||
#include "mozilla/widget/AudioSession.h"
|
||||
#endif
|
||||
@ -5226,10 +5223,8 @@ ContentParent::RecvNotifyPushObservers(const nsCString& aScope,
|
||||
const IPC::Principal& aPrincipal,
|
||||
const nsString& aMessageId)
|
||||
{
|
||||
#ifndef MOZ_SIMPLEPUSH
|
||||
PushMessageDispatcher dispatcher(aScope, aPrincipal, aMessageId, Nothing());
|
||||
Unused << NS_WARN_IF(NS_FAILED(dispatcher.NotifyObservers()));
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -5239,10 +5234,8 @@ ContentParent::RecvNotifyPushObserversWithData(const nsCString& aScope,
|
||||
const nsString& aMessageId,
|
||||
InfallibleTArray<uint8_t>&& aData)
|
||||
{
|
||||
#ifndef MOZ_SIMPLEPUSH
|
||||
PushMessageDispatcher dispatcher(aScope, aPrincipal, aMessageId, Some(aData));
|
||||
Unused << NS_WARN_IF(NS_FAILED(dispatcher.NotifyObservers()));
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -5250,10 +5243,8 @@ bool
|
||||
ContentParent::RecvNotifyPushSubscriptionChangeObservers(const nsCString& aScope,
|
||||
const IPC::Principal& aPrincipal)
|
||||
{
|
||||
#ifndef MOZ_SIMPLEPUSH
|
||||
PushSubscriptionChangeDispatcher dispatcher(aScope, aPrincipal);
|
||||
Unused << NS_WARN_IF(NS_FAILED(dispatcher.NotifyObservers()));
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -5261,10 +5252,8 @@ bool
|
||||
ContentParent::RecvNotifyPushSubscriptionModifiedObservers(const nsCString& aScope,
|
||||
const IPC::Principal& aPrincipal)
|
||||
{
|
||||
#ifndef MOZ_SIMPLEPUSH
|
||||
PushSubscriptionModifiedDispatcher dispatcher(aScope, aPrincipal);
|
||||
Unused << NS_WARN_IF(NS_FAILED(dispatcher.NotifyObservers()));
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -1088,7 +1088,8 @@ nsJSChannel::SetExecuteAsync(bool aIsAsync)
|
||||
mIsAsync = aIsAsync;
|
||||
}
|
||||
// else ignore this call
|
||||
NS_WARN_IF_FALSE(!mIsActive, "Calling SetExecuteAsync on active channel?");
|
||||
NS_WARNING_ASSERTION(!mIsActive,
|
||||
"Calling SetExecuteAsync on active channel?");
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -83,8 +83,9 @@ public:
|
||||
// all the streams were ended (no mixer callback occured).
|
||||
// XXX Remove this warning, or find a way to avoid it if the mixer callback
|
||||
// isn't called.
|
||||
NS_WARN_IF_FALSE(Available() == 0 || mSampleWriteOffset == 0,
|
||||
"Audio Buffer is not full by the end of the callback.");
|
||||
NS_WARNING_ASSERTION(
|
||||
Available() == 0 || mSampleWriteOffset == 0,
|
||||
"Audio Buffer is not full by the end of the callback.");
|
||||
// Make sure the data returned is always set and not random!
|
||||
if (Available()) {
|
||||
PodZero(mBuffer + mSampleWriteOffset, FramesToSamples(CHANNELS, Available()));
|
||||
|
@ -365,8 +365,9 @@ public:
|
||||
void Mix(AudioMixer& aMixer, uint32_t aChannelCount, uint32_t aSampleRate);
|
||||
|
||||
int ChannelCount() {
|
||||
NS_WARN_IF_FALSE(!mChunks.IsEmpty(),
|
||||
"Cannot query channel count on a AudioSegment with no chunks.");
|
||||
NS_WARNING_ASSERTION(
|
||||
!mChunks.IsEmpty(),
|
||||
"Cannot query channel count on a AudioSegment with no chunks.");
|
||||
// Find the first chunk that has non-zero channels. A chunk that hs zero
|
||||
// channels is just silence and we can simply discard it.
|
||||
for (ChunkIterator ci(*this); !ci.IsEnded(); ci.Next()) {
|
||||
|
@ -149,8 +149,8 @@ void InitBrandName()
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
rv = brandBundle->GetStringFromName(u"brandShortName",
|
||||
getter_Copies(brandName));
|
||||
NS_WARN_IF_FALSE(NS_SUCCEEDED(rv),
|
||||
"Could not get the program name for a cubeb stream.");
|
||||
NS_WARNING_ASSERTION(
|
||||
NS_SUCCEEDED(rv), "Could not get the program name for a cubeb stream.");
|
||||
}
|
||||
}
|
||||
/* cubeb expects a c-string. */
|
||||
@ -170,12 +170,12 @@ cubeb* GetCubebContextUnlocked()
|
||||
if (!sBrandName && NS_IsMainThread()) {
|
||||
InitBrandName();
|
||||
} else {
|
||||
NS_WARN_IF_FALSE(sBrandName,
|
||||
"Did not initialize sbrandName, and not on the main thread?");
|
||||
NS_WARNING_ASSERTION(
|
||||
sBrandName, "Did not initialize sbrandName, and not on the main thread?");
|
||||
}
|
||||
|
||||
DebugOnly<int> rv = cubeb_init(&sCubebContext, sBrandName);
|
||||
NS_WARN_IF_FALSE(rv == CUBEB_OK, "Could not get a cubeb context.");
|
||||
NS_WARNING_ASSERTION(rv == CUBEB_OK, "Could not get a cubeb context.");
|
||||
|
||||
return sCubebContext;
|
||||
}
|
||||
|
@ -153,11 +153,11 @@ public:
|
||||
}
|
||||
|
||||
// Track had not been created on main thread before, create it now.
|
||||
NS_WARN_IF_FALSE(!mStream->mTracks.IsEmpty(),
|
||||
"A new track was detected on the input stream; creating "
|
||||
"a corresponding MediaStreamTrack. Initial tracks "
|
||||
"should be added manually to immediately and "
|
||||
"synchronously be available to JS.");
|
||||
NS_WARNING_ASSERTION(
|
||||
!mStream->mTracks.IsEmpty(),
|
||||
"A new track was detected on the input stream; creating a corresponding "
|
||||
"MediaStreamTrack. Initial tracks should be added manually to "
|
||||
"immediately and synchronously be available to JS.");
|
||||
RefPtr<MediaStreamTrackSource> source;
|
||||
if (mStream->mTrackSourceGetter) {
|
||||
source = mStream->mTrackSourceGetter->GetMediaStreamTrackSource(aTrackID);
|
||||
|
@ -486,7 +486,8 @@ AsyncCubebTask::AsyncCubebTask(AudioCallbackDriver* aDriver, AsyncCubebOperation
|
||||
mOperation(aOperation),
|
||||
mShutdownGrip(aDriver->GraphImpl())
|
||||
{
|
||||
NS_WARN_IF_FALSE(mDriver->mAudioStream || aOperation == INIT, "No audio stream !");
|
||||
NS_WARNING_ASSERTION(mDriver->mAudioStream || aOperation == INIT,
|
||||
"No audio stream!");
|
||||
}
|
||||
|
||||
AsyncCubebTask::~AsyncCubebTask()
|
||||
@ -658,8 +659,9 @@ AudioCallbackDriver::Init()
|
||||
DataCallback_s, StateCallback_s, this) == CUBEB_OK) {
|
||||
mAudioStream.own(stream);
|
||||
DebugOnly<int> rv = cubeb_stream_set_volume(mAudioStream, CubebUtils::GetVolumeScale());
|
||||
NS_WARN_IF_FALSE(rv == CUBEB_OK,
|
||||
"Could not set the audio stream volume in GraphDriver.cpp");
|
||||
NS_WARNING_ASSERTION(
|
||||
rv == CUBEB_OK,
|
||||
"Could not set the audio stream volume in GraphDriver.cpp");
|
||||
CubebUtils::ReportCubebBackendUsed();
|
||||
} else {
|
||||
#ifdef MOZ_WEBRTC
|
||||
@ -1008,7 +1010,7 @@ AudioCallbackDriver::MixerCallback(AudioDataValue* aMixedBuffer,
|
||||
MOZ_ASSERT(mBuffer.Available() == 0, "Missing frames to fill audio callback's buffer.");
|
||||
|
||||
DebugOnly<uint32_t> written = mScratchBuffer.Fill(aMixedBuffer + toWrite * aChannels, aFrames - toWrite);
|
||||
NS_WARN_IF_FALSE(written == aFrames - toWrite, "Dropping frames.");
|
||||
NS_WARNING_ASSERTION(written == aFrames - toWrite, "Dropping frames.");
|
||||
};
|
||||
|
||||
void AudioCallbackDriver::PanOutputIfNeeded(bool aMicrophoneActive)
|
||||
|
@ -1726,8 +1726,8 @@ MediaCacheStream::NotifyDataStarted(int64_t aOffset)
|
||||
NS_ASSERTION(NS_IsMainThread(), "Only call on main thread");
|
||||
|
||||
ReentrantMonitorAutoEnter mon(gMediaCache->GetReentrantMonitor());
|
||||
NS_WARN_IF_FALSE(aOffset == mChannelOffset,
|
||||
"Server is giving us unexpected offset");
|
||||
NS_WARNING_ASSERTION(aOffset == mChannelOffset,
|
||||
"Server is giving us unexpected offset");
|
||||
MOZ_ASSERT(aOffset >= 0);
|
||||
mChannelOffset = aOffset;
|
||||
if (mStreamLength >= 0) {
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user