Merge inbound to m-c a=merge

This commit is contained in:
Wes Kocher 2016-09-02 13:17:30 -07:00
commit ee92002ede
388 changed files with 3546 additions and 6714 deletions

View File

@ -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?

View File

@ -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

View File

@ -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(' '));

View File

@ -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.

View File

@ -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) {

View File

@ -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);

View File

@ -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

View File

@ -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

View File

@ -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");
}

View File

@ -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 &&

View File

@ -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);

View File

@ -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);
});
}
}

View File

@ -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"),

View File

@ -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

View File

@ -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);
}
});

View File

@ -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");

View File

@ -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]

View File

@ -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"),

View File

@ -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");
}

View File

@ -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);
}

View File

@ -743,3 +743,5 @@ decoder.noCodecsXP.message = To play video, you may need to enable Adobes 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 Microsofts Media Feature Pack.
decoder.noHWAccelerationVista.message = To improve video quality, you may need to install Microsofts Platform Update Supplement for Windows Vista.
permissions.remove.tooltip = Clear this permission and ask again

View File

@ -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>

View File

@ -1,6 +1,5 @@
amazondotcom
bing
eBay
google
twitter
wikipedia

View File

@ -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));
}
},

View File

@ -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

View File

@ -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.

View File

@ -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

View File

@ -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)

View File

@ -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;
}

View File

@ -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");
}
}
}

View File

@ -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";

View File

@ -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

View File

@ -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); \

View File

@ -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)
{
}

View File

@ -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;

View File

@ -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);

View File

@ -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) {

View File

@ -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;

View File

@ -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.");
}
}

View File

@ -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;
}

View File

@ -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;

View File

@ -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

View File

@ -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);
}

View File

@ -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();

View File

@ -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
}

View File

@ -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);
}

View File

@ -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;

View File

@ -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()));
}
}
}

View File

@ -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) {

View File

@ -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);

View File

@ -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;

View File

@ -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)

View File

@ -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);

View File

@ -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

View File

@ -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);
}
}
}

View File

@ -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;
}

View File

@ -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,

View File

@ -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));
}

View File

@ -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;
}

View File

@ -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

View File

@ -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:

View File

@ -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.")

View File

@ -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',
]

View File

@ -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

View File

@ -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.")

View File

@ -1,13 +0,0 @@
import WebIDL
def WebIDLTest(parser, harness):
parser.parse("""
interface A {
attribute long a;
};
interface B {
attribute A[] b;
};
""");
parser.finish()

View File

@ -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")

View File

@ -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:

View File

@ -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", [])

View File

@ -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)])])

View File

@ -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():

View File

@ -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 += """

View File

@ -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);

View File

@ -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;

View 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>

View File

@ -36,4 +36,5 @@ load 1288872-1.html
load 1290628-1.html
load 1283113-1.html
load 1286458-1.html
load 1299062-1.html

View File

@ -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()

View File

@ -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,

View File

@ -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);
}

View File

@ -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);

View File

@ -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;
}

View File

@ -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

View File

@ -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>

View File

@ -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>

View File

@ -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();
}

View File

@ -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;
}
}

View File

@ -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;
}

View File

@ -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);

View File

@ -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()

View File

@ -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) {

View File

@ -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)));

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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()));

View File

@ -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()) {

View File

@ -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;
}

View File

@ -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);

View File

@ -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)

View File

@ -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