mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-25 22:01:30 +00:00
merge mozilla-inbound to mozilla-central a=merge
--HG-- rename : browser/locales/en-US/chrome/browser/devtools/memory.properties => devtools/client/locales/en-US/memory.properties
This commit is contained in:
commit
bb068eacd7
@ -119,7 +119,7 @@
|
||||
accesskey="&bookmarkAllTabs.accesskey;"
|
||||
command="Browser:BookmarkAllTabs"/>
|
||||
<menuitem id="context_closeTabsToTheEnd" label="&closeTabsToTheEnd.label;" accesskey="&closeTabsToTheEnd.accesskey;"
|
||||
oncommand="gBrowser.removeTabsToTheEndFrom(TabContextMenu.contextTab);"/>
|
||||
oncommand="gBrowser.removeTabsToTheEndFrom(TabContextMenu.contextTab, {animate: true});"/>
|
||||
<menuitem id="context_closeOtherTabs" label="&closeOtherTabs.label;" accesskey="&closeOtherTabs.accesskey;"
|
||||
oncommand="gBrowser.removeAllTabsBut(TabContextMenu.contextTab);"/>
|
||||
<menuseparator/>
|
||||
|
@ -2049,12 +2049,13 @@
|
||||
|
||||
<method name="removeTabsToTheEndFrom">
|
||||
<parameter name="aTab"/>
|
||||
<parameter name="aParams"/>
|
||||
<body>
|
||||
<![CDATA[
|
||||
if (this.warnAboutClosingTabs(this.closingTabsEnum.TO_END, aTab)) {
|
||||
let tabs = this.getTabsToTheEndFrom(aTab);
|
||||
for (let i = tabs.length - 1; i >= 0; --i) {
|
||||
this.removeTab(tabs[i], {animate: true});
|
||||
this.removeTab(tabs[i], aParams);
|
||||
}
|
||||
}
|
||||
]]>
|
||||
|
@ -70,12 +70,8 @@ function loadTabInWindow(win, callback) {
|
||||
info("Loading tab");
|
||||
let url = "http://user:pass@example.com/";
|
||||
let tab = win.gBrowser.selectedTab = win.gBrowser.addTab(url);
|
||||
tab.linkedBrowser.addEventListener("load", function listener() {
|
||||
BrowserTestUtils.browserLoaded(tab.linkedBrowser, false, url).then(() => {
|
||||
info("Tab loaded");
|
||||
if (tab.linkedBrowser.currentURI.spec != url)
|
||||
return;
|
||||
tab.linkedBrowser.removeEventListener("load", listener, true);
|
||||
|
||||
is(win.gURLBar.textValue, "example.com", "URL bar had user/pass stripped initially");
|
||||
callback(tab);
|
||||
}, true);
|
||||
|
@ -2,9 +2,7 @@ function test () {
|
||||
|
||||
waitForExplicitFinish();
|
||||
gBrowser.selectedTab = gBrowser.addTab();
|
||||
gBrowser.selectedBrowser.addEventListener("load", function () {
|
||||
gBrowser.selectedBrowser.removeEventListener("load", arguments.callee, true);
|
||||
|
||||
BrowserTestUtils.browserLoaded(gBrowser.selectedBrowser).then(() => {
|
||||
let doc = gBrowser.contentDocument;
|
||||
let tooltip = document.getElementById("aHTMLTooltip");
|
||||
|
||||
@ -35,9 +33,10 @@ function test () {
|
||||
|
||||
gBrowser.removeCurrentTab();
|
||||
finish();
|
||||
}, true);
|
||||
});
|
||||
|
||||
content.location =
|
||||
"http://mochi.test:8888/browser/browser/base/content/test/general/title_test.svg";
|
||||
gBrowser.loadURI(
|
||||
"http://mochi.test:8888/browser/browser/base/content/test/general/title_test.svg"
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -4,9 +4,7 @@
|
||||
function test () {
|
||||
waitForExplicitFinish();
|
||||
gBrowser.selectedTab = gBrowser.addTab();
|
||||
gBrowser.selectedBrowser.addEventListener("load", function () {
|
||||
gBrowser.selectedBrowser.removeEventListener("load", arguments.callee, true);
|
||||
|
||||
BrowserTestUtils.browserLoaded(gBrowser.selectedBrowser).then(() => {
|
||||
let doc = gBrowser.contentDocument;
|
||||
let tooltip = document.getElementById("aHTMLTooltip");
|
||||
|
||||
@ -15,9 +13,10 @@ function test () {
|
||||
|
||||
gBrowser.removeCurrentTab();
|
||||
finish();
|
||||
}, true);
|
||||
});
|
||||
|
||||
content.location =
|
||||
"http://mochi.test:8888/browser/browser/base/content/test/general/xul_tooltiptext.xhtml";
|
||||
gBrowser.loadURI(
|
||||
"http://mochi.test:8888/browser/browser/base/content/test/general/xul_tooltiptext.xhtml"
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -22,7 +22,7 @@ function test() {
|
||||
function addTab(aURI, aIndex) {
|
||||
var tab = gBrowser.addTab(aURI);
|
||||
if (aIndex == 0)
|
||||
gBrowser.removeTab(gBrowser.tabs[0]);
|
||||
gBrowser.removeTab(gBrowser.tabs[0], {skipPermitUnload: true});
|
||||
|
||||
tab.linkedBrowser.addEventListener("load", function (event) {
|
||||
event.currentTarget.removeEventListener("load", arguments.callee, true);
|
||||
@ -41,14 +41,14 @@ function doTabsTest() {
|
||||
var scheme = closedTab.linkedBrowser.currentURI.scheme;
|
||||
Array.slice(gBrowser.tabs).forEach(function (aTab) {
|
||||
if (aTab != closedTab && aTab.linkedBrowser.currentURI.scheme == scheme)
|
||||
gBrowser.removeTab(aTab);
|
||||
gBrowser.removeTab(aTab, {skipPermitUnload: true});
|
||||
});
|
||||
}, true);
|
||||
|
||||
gBrowser.removeTab(gBrowser.tabs[0]);
|
||||
gBrowser.removeTab(gBrowser.tabs[0], {skipPermitUnload: true});
|
||||
is(gBrowser.tabs.length, 1, "Related tabs are not closed unexpectedly");
|
||||
|
||||
gBrowser.addTab("about:blank");
|
||||
gBrowser.removeTab(gBrowser.tabs[0]);
|
||||
gBrowser.removeTab(gBrowser.tabs[0], {skipPermitUnload: true});
|
||||
finish();
|
||||
}
|
||||
|
@ -1,42 +1,63 @@
|
||||
function test() {
|
||||
waitForExplicitFinish();
|
||||
|
||||
gBrowser.selectedTab = gBrowser.addTab();
|
||||
|
||||
// Navigate to a site with a broken cert
|
||||
window.addEventListener("DOMContentLoaded", testBrokenCert, true);
|
||||
content.location = "https://nocert.example.com/";
|
||||
function remote(task) {
|
||||
return ContentTask.spawn(gBrowser.selectedBrowser, null, task);
|
||||
}
|
||||
|
||||
function testBrokenCert() {
|
||||
if (gBrowser.contentDocument.documentURI === "about:blank")
|
||||
return;
|
||||
window.removeEventListener("DOMContentLoaded", testBrokenCert, true);
|
||||
add_task(function* () {
|
||||
gBrowser.selectedTab = gBrowser.addTab();
|
||||
|
||||
let promise = remote(function () {
|
||||
return ContentTaskUtils.waitForEvent(this, "DOMContentLoaded", true, event => {
|
||||
return content.document.documentURI != "about:blank";
|
||||
}).then(() => 0); // don't want to send the event to the chrome process
|
||||
});
|
||||
gBrowser.loadURI("https://nocert.example.com/");
|
||||
yield promise;
|
||||
|
||||
let uri = yield remote(() => {
|
||||
return content.document.documentURI;
|
||||
});
|
||||
|
||||
// Confirm that we are displaying the contributed error page, not the default
|
||||
ok(gBrowser.contentDocument.documentURI.startsWith("about:certerror"), "Broken page should go to about:certerror, not about:neterror");
|
||||
ok(uri.startsWith("about:certerror"), "Broken page should go to about:certerror, not about:neterror");
|
||||
|
||||
let advancedDiv, advancedDivVisibility, technicalDivCollapsed;
|
||||
|
||||
[advancedDiv, advancedDivVisibility] = yield remote(() => {
|
||||
let div = content.document.getElementById("advancedPanel");
|
||||
if (div) {
|
||||
return [true, div.ownerDocument.defaultView.getComputedStyle(div, "").visibility];
|
||||
} else {
|
||||
return [null, null];
|
||||
}
|
||||
});
|
||||
|
||||
// Confirm that the expert section is collapsed
|
||||
var advancedDiv = gBrowser.contentDocument.getElementById("advancedPanel");
|
||||
ok(advancedDiv, "Advanced content div should exist");
|
||||
is_element_hidden(advancedDiv, "Advanced content should not be visible by default");
|
||||
is(advancedDivVisibility, "hidden", "Advanced content should not be visible by default");
|
||||
|
||||
// Tweak the expert mode pref
|
||||
gPrefService.setBoolPref("browser.xul.error_pages.expert_bad_cert", true);
|
||||
|
||||
window.addEventListener("DOMContentLoaded", testExpertPref, true);
|
||||
promise = remote(function () {
|
||||
return ContentTaskUtils.waitForEvent(this, "DOMContentLoaded", true);
|
||||
});
|
||||
gBrowser.reload();
|
||||
}
|
||||
yield promise;
|
||||
|
||||
[advancedDiv, advancedDivVisibility] = yield remote(() => {
|
||||
let div = content.document.getElementById("advancedPanel");
|
||||
if (div) {
|
||||
return [true, div.ownerDocument.defaultView.getComputedStyle(div, "").visibility];
|
||||
} else {
|
||||
return [null, null];
|
||||
}
|
||||
});
|
||||
|
||||
function testExpertPref() {
|
||||
window.removeEventListener("DOMContentLoaded", testExpertPref, true);
|
||||
var advancedDiv = gBrowser.contentDocument.getElementById("advancedPanel");
|
||||
ok(advancedDiv, "Advanced content div should exist");
|
||||
is_element_visible(advancedDiv, "Advanced content should be visible by default");
|
||||
is(advancedDivVisibility, "visible", "Advanced content should be visible by default");
|
||||
|
||||
// Clean up
|
||||
gBrowser.removeCurrentTab();
|
||||
if (gPrefService.prefHasUserValue("browser.xul.error_pages.expert_bad_cert"))
|
||||
gPrefService.clearUserPref("browser.xul.error_pages.expert_bad_cert");
|
||||
finish();
|
||||
}
|
||||
});
|
||||
|
@ -99,7 +99,7 @@ function checkBookmarksPanel(invoker, phase)
|
||||
if (currentInvoker < invokers.length) {
|
||||
checkBookmarksPanel(invokers[currentInvoker], 1);
|
||||
} else {
|
||||
gBrowser.removeCurrentTab();
|
||||
gBrowser.removeTab(gBrowser.selectedTab, {skipPermitUnload: true});
|
||||
PlacesUtils.bookmarks.removeItem(bookmarkId);
|
||||
executeSoon(finish);
|
||||
}
|
||||
|
@ -2,15 +2,16 @@ function test() {
|
||||
waitForExplicitFinish();
|
||||
|
||||
gBrowser.selectedTab = gBrowser.addTab();
|
||||
gBrowser.selectedBrowser.addEventListener("load", function () {
|
||||
gBrowser.selectedBrowser.removeEventListener("load", arguments.callee, true);
|
||||
BrowserTestUtils.browserLoaded(gBrowser.selectedBrowser).then(() => {
|
||||
is(document.getElementById("identity-box").className,
|
||||
"unknownIdentity mixedDisplayContent",
|
||||
"identity box has class name for mixed content");
|
||||
|
||||
gBrowser.removeCurrentTab();
|
||||
finish();
|
||||
}, true);
|
||||
});
|
||||
|
||||
content.location = "https://example.com/browser/browser/base/content/test/general/test_bug435035.html";
|
||||
gBrowser.loadURI(
|
||||
"https://example.com/browser/browser/base/content/test/general/test_bug435035.html"
|
||||
);
|
||||
}
|
||||
|
@ -30,16 +30,16 @@ function test() {
|
||||
// Start the sub-document load.
|
||||
let deferred = Promise.defer();
|
||||
executeSoon(function () {
|
||||
testBrowser.addEventListener("load", function (e) {
|
||||
testBrowser.removeEventListener("load", arguments.callee, true);
|
||||
|
||||
is(e.target.defaultView.location, TEST_IFRAME_URL, "got the load event for the iframe");
|
||||
BrowserTestUtils.browserLoaded(testBrowser, true).then(url => {
|
||||
is(url, TEST_IFRAME_URL, "got the load event for the iframe");
|
||||
is(ZoomManager.zoom, zoomLevel, "zoom is retained after sub-document load");
|
||||
|
||||
FullZoomHelper.removeTabAndWaitForLocationChange().
|
||||
then(() => deferred.resolve());
|
||||
}, true);
|
||||
content.document.querySelector("iframe").src = TEST_IFRAME_URL;
|
||||
});
|
||||
ContentTask.spawn(testBrowser, TEST_IFRAME_URL, url => {
|
||||
content.document.querySelector("iframe").src = url;
|
||||
});
|
||||
});
|
||||
yield deferred.promise;
|
||||
}).then(finish, FullZoomHelper.failAndContinue(finish));
|
||||
|
@ -1,4 +1,4 @@
|
||||
function test() {
|
||||
add_task(function*() {
|
||||
is(gBrowser.tabs.length, 1, "one tab is open");
|
||||
|
||||
gBrowser.selectedBrowser.focus();
|
||||
@ -6,11 +6,15 @@ function test() {
|
||||
|
||||
var tab = gBrowser.selectedTab;
|
||||
gPrefService.setBoolPref("browser.tabs.closeWindowWithLastTab", false);
|
||||
|
||||
let tabClosedPromise = BrowserTestUtils.removeTab(tab, {dontRemove: true});
|
||||
EventUtils.synthesizeKey("w", { accelKey: true });
|
||||
yield tabClosedPromise;
|
||||
|
||||
is(tab.parentNode, null, "ctrl+w removes the tab");
|
||||
is(gBrowser.tabs.length, 1, "a new tab has been opened");
|
||||
is(document.activeElement, gURLBar.inputField, "location bar is focused for the new tab");
|
||||
|
||||
if (gPrefService.prefHasUserValue("browser.tabs.closeWindowWithLastTab"))
|
||||
gPrefService.clearUserPref("browser.tabs.closeWindowWithLastTab");
|
||||
}
|
||||
});
|
||||
|
@ -18,10 +18,13 @@ function record(aName) {
|
||||
if (actual.length == expected.length) {
|
||||
is(actual.toString(), expected.toString(),
|
||||
"got events and progress notifications in expected order");
|
||||
|
||||
executeSoon(function(tab) {
|
||||
gBrowser.removeTab(tab);
|
||||
gBrowser.removeTabsProgressListener(progressListener);
|
||||
gBrowser.tabContainer.removeEventListener("TabOpen", TabOpen, false);
|
||||
finish();
|
||||
}.bind(null, tab));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -6,14 +6,14 @@ function test() {
|
||||
|
||||
childTab1 = gBrowser.addTab("about:blank", { relatedToCurrent: true });
|
||||
gBrowser.selectedTab = childTab1;
|
||||
gBrowser.removeCurrentTab();
|
||||
gBrowser.removeTab(gBrowser.selectedTab, { skipPermitUnload: true });
|
||||
is(idx(gBrowser.selectedTab), idx(tab1),
|
||||
"closing a tab next to its parent selects the parent");
|
||||
|
||||
childTab1 = gBrowser.addTab("about:blank", { relatedToCurrent: true });
|
||||
gBrowser.selectedTab = tab2;
|
||||
gBrowser.selectedTab = childTab1;
|
||||
gBrowser.removeCurrentTab();
|
||||
gBrowser.removeTab(gBrowser.selectedTab, { skipPermitUnload: true });
|
||||
is(idx(gBrowser.selectedTab), idx(tab2),
|
||||
"closing a tab next to its parent doesn't select the parent if another tab had been selected ad interim");
|
||||
|
||||
@ -21,14 +21,14 @@ function test() {
|
||||
childTab1 = gBrowser.addTab("about:blank", { relatedToCurrent: true });
|
||||
childTab2 = gBrowser.addTab("about:blank", { relatedToCurrent: true });
|
||||
gBrowser.selectedTab = childTab1;
|
||||
gBrowser.removeCurrentTab();
|
||||
gBrowser.removeTab(gBrowser.selectedTab, { skipPermitUnload: true });
|
||||
is(idx(gBrowser.selectedTab), idx(childTab2),
|
||||
"closing a tab next to its parent selects the next tab with the same parent");
|
||||
gBrowser.removeCurrentTab();
|
||||
gBrowser.removeTab(gBrowser.selectedTab, { skipPermitUnload: true });
|
||||
is(idx(gBrowser.selectedTab), idx(tab2),
|
||||
"closing the last tab in a set of child tabs doesn't go back to the parent");
|
||||
|
||||
gBrowser.removeTab(tab2);
|
||||
gBrowser.removeTab(tab2, { skipPermitUnload: true });
|
||||
}
|
||||
|
||||
function idx(tab) {
|
||||
|
@ -803,12 +803,9 @@ function test_urlbar() {
|
||||
|
||||
function test_wronghost() {
|
||||
gBrowser.selectedTab = gBrowser.addTab();
|
||||
gBrowser.addEventListener("load", function() {
|
||||
if (gBrowser.currentURI.spec != TESTROOT2 + "enabled.html")
|
||||
return;
|
||||
|
||||
gBrowser.removeEventListener("load", arguments.callee, true);
|
||||
|
||||
let requestedUrl = TESTROOT2 + "enabled.html";
|
||||
BrowserTestUtils.browserLoaded(gBrowser.selectedBrowser, false, requestedUrl).then(() => {
|
||||
// Wait for the progress notification
|
||||
wait_for_progress_notification(function(aPanel) {
|
||||
// Wait for the complete notification
|
||||
@ -825,7 +822,7 @@ function test_wronghost() {
|
||||
});
|
||||
|
||||
gBrowser.loadURI(TESTROOT + "corrupt.xpi");
|
||||
}, true);
|
||||
});
|
||||
gBrowser.loadURI(TESTROOT2 + "enabled.html");
|
||||
},
|
||||
|
||||
@ -848,12 +845,8 @@ function test_reload() {
|
||||
|
||||
PopupNotifications.panel.addEventListener("popuphiding", test_fail, false);
|
||||
|
||||
gBrowser.addEventListener("load", function() {
|
||||
if (gBrowser.currentURI.spec != TESTROOT2 + "enabled.html")
|
||||
return;
|
||||
|
||||
gBrowser.removeEventListener("load", arguments.callee, true);
|
||||
|
||||
let requestedUrl = TESTROOT2 + "enabled.html";
|
||||
BrowserTestUtils.browserLoaded(gBrowser.selectedBrowser, false, requestedUrl).then(() => {
|
||||
PopupNotifications.panel.removeEventListener("popuphiding", test_fail, false);
|
||||
|
||||
AddonManager.getAllInstalls(function(aInstalls) {
|
||||
@ -864,7 +857,7 @@ function test_reload() {
|
||||
wait_for_notification_close(runNextTest);
|
||||
gBrowser.removeTab(gBrowser.selectedTab);
|
||||
});
|
||||
}, true);
|
||||
});
|
||||
gBrowser.loadURI(TESTROOT2 + "enabled.html");
|
||||
});
|
||||
|
||||
|
@ -1,9 +1,7 @@
|
||||
function test() {
|
||||
waitForExplicitFinish();
|
||||
gBrowser.selectedTab = gBrowser.addTab();
|
||||
gBrowser.selectedBrowser.addEventListener("load", function () {
|
||||
gBrowser.selectedBrowser.removeEventListener("load", arguments.callee, true);
|
||||
|
||||
BrowserTestUtils.browserLoaded(gBrowser.selectedBrowser).then(() => {
|
||||
let doc = gBrowser.contentDocument;
|
||||
let tooltip = document.getElementById("aHTMLTooltip");
|
||||
let i = doc.getElementById("i");
|
||||
@ -21,9 +19,10 @@ function test() {
|
||||
|
||||
gBrowser.removeCurrentTab();
|
||||
finish();
|
||||
}, true);
|
||||
});
|
||||
|
||||
content.location =
|
||||
"data:text/html,<!DOCTYPE html><html><body><input id='i'></body></html>";
|
||||
gBrowser.loadURI(
|
||||
"data:text/html,<!DOCTYPE html><html><body><input id='i'></body></html>"
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -14,13 +14,11 @@ function test() {
|
||||
is(gURLBar.value, URI, "location bar value matches test URI after switching tabs");
|
||||
|
||||
waitForExplicitFinish();
|
||||
gBrowser.selectedBrowser.addEventListener("load", function () {
|
||||
gBrowser.selectedBrowser.removeEventListener("load", arguments.callee, true);
|
||||
|
||||
BrowserTestUtils.browserLoaded(gBrowser.selectedBrowser).then(() => {
|
||||
is(gBrowser.userTypedValue, null, "userTypedValue is null as the page has loaded");
|
||||
is(gURLBar.value, URI, "location bar value matches test URI as the page has loaded");
|
||||
|
||||
gBrowser.removeCurrentTab();
|
||||
finish();
|
||||
}, true);
|
||||
});
|
||||
}
|
||||
|
@ -14,13 +14,12 @@ function test() {
|
||||
cp.setAccess(uriObj, cp.ACCESS_ALLOW);
|
||||
gBrowser.selectedTab = gBrowser.addTab(uriString);
|
||||
waitForExplicitFinish();
|
||||
gBrowser.selectedBrowser.addEventListener("load", onTabLoaded, true);
|
||||
BrowserTestUtils.browserLoaded(gBrowser.selectedBrowser).then(onTabLoaded);
|
||||
|
||||
function onTabLoaded() {
|
||||
is(gBrowser.selectedBrowser.contentWindow.navigator.cookieEnabled, true,
|
||||
"navigator.cookieEnabled should be true");
|
||||
// Clean up
|
||||
gBrowser.selectedBrowser.removeEventListener("load", onTabLoaded, true);
|
||||
gBrowser.removeTab(gBrowser.selectedTab);
|
||||
Services.prefs.setIntPref(cookieBehavior, 0);
|
||||
cp.setAccess(uriObj, cp.ACCESS_DEFAULT);
|
||||
|
@ -5,7 +5,7 @@
|
||||
function test() {
|
||||
let newTab = gBrowser.addTab();
|
||||
waitForExplicitFinish();
|
||||
newTab.linkedBrowser.addEventListener("load", mainPart, true);
|
||||
BrowserTestUtils.browserLoaded(newTab.linkedBrowser).then(mainPart);
|
||||
|
||||
function mainPart() {
|
||||
gBrowser.pinTab(newTab);
|
||||
@ -20,7 +20,6 @@ function test() {
|
||||
openUILinkIn("http://example.org/", "current");
|
||||
is(gBrowser.tabs.length, 3, "Should open in new tab");
|
||||
|
||||
newTab.removeEventListener("load", mainPart, true);
|
||||
gBrowser.removeTab(newTab);
|
||||
gBrowser.removeTab(gBrowser.tabs[1]); // example.org tab
|
||||
finish();
|
||||
|
@ -17,12 +17,10 @@ function test() {
|
||||
|
||||
var tab = gBrowser.addTab("http://mochi.test:8888/");
|
||||
var browser = gBrowser.getBrowserForTab(tab);
|
||||
browser.addEventListener("load", function() {
|
||||
browser.removeEventListener("load", arguments.callee, true);
|
||||
|
||||
BrowserTestUtils.browserLoaded(browser).then(() => {
|
||||
BrowserTestUtils.removeTab(tab).then(() => {
|
||||
ok(isUndoCloseEnabled(), "Undo Close Tab should be enabled.");
|
||||
finish();
|
||||
});
|
||||
}, true);
|
||||
});
|
||||
}
|
||||
|
@ -58,9 +58,7 @@ function todo_check(aElementName, aBarred) {
|
||||
function test () {
|
||||
waitForExplicitFinish();
|
||||
gBrowser.selectedTab = gBrowser.addTab();
|
||||
gBrowser.selectedBrowser.addEventListener("load", function () {
|
||||
gBrowser.selectedBrowser.removeEventListener("load", arguments.callee, true);
|
||||
|
||||
BrowserTestUtils.browserLoaded(gBrowser.selectedBrowser).then(() => {
|
||||
let testData = [
|
||||
/* element name, barred */
|
||||
[ 'input', false, null],
|
||||
@ -87,9 +85,10 @@ function test () {
|
||||
|
||||
gBrowser.removeCurrentTab();
|
||||
finish();
|
||||
}, true);
|
||||
});
|
||||
|
||||
content.location =
|
||||
"data:text/html,<!DOCTYPE html><html><body><form id='content'></form></body></html>";
|
||||
gBrowser.loadURI(
|
||||
"data:text/html,<!DOCTYPE html><html><body><form id='content'></form></body></html>"
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -14,6 +14,13 @@ function testAttrib(elem, attrib, attribValue, msg) {
|
||||
|
||||
function test() {
|
||||
waitForExplicitFinish();
|
||||
|
||||
// Ensure TabView has been initialized already. Otherwise it could
|
||||
// activate at an unexpected time and show/hide tabs.
|
||||
TabView._initFrame(runTest);
|
||||
}
|
||||
|
||||
function runTest() {
|
||||
is(gBrowser.tabs.length, 1, "one tab is open initially");
|
||||
|
||||
// Add several new tabs in sequence, hiding some, to ensure that the
|
||||
|
@ -5,11 +5,9 @@
|
||||
function test() {
|
||||
let newTab = gBrowser.addTab("http://example.com");
|
||||
waitForExplicitFinish();
|
||||
newTab.linkedBrowser.addEventListener("load", mainPart, true);
|
||||
BrowserTestUtils.browserLoaded(newTab.linkedBrowser).then(mainPart);
|
||||
|
||||
function mainPart() {
|
||||
newTab.linkedBrowser.removeEventListener("load", mainPart, true);
|
||||
|
||||
gBrowser.pinTab(newTab);
|
||||
gBrowser.selectedTab = newTab;
|
||||
|
||||
|
@ -5,6 +5,12 @@
|
||||
function test() {
|
||||
waitForExplicitFinish();
|
||||
|
||||
// Ensure TabView has been initialized already. Otherwise it could
|
||||
// activate at an unexpected time and show/hide tabs.
|
||||
TabView._initFrame(runTest);
|
||||
}
|
||||
|
||||
function runTest() {
|
||||
// establish initial state
|
||||
is(gBrowser.tabs.length, 1, "we start with one tab");
|
||||
|
||||
|
@ -17,15 +17,13 @@ function test() {
|
||||
waitForExplicitFinish();
|
||||
|
||||
let tab = gBrowser.selectedTab = gBrowser.addTab();
|
||||
tab.linkedBrowser.addEventListener("load", (function(event) {
|
||||
tab.linkedBrowser.removeEventListener("load", arguments.callee, true);
|
||||
|
||||
BrowserTestUtils.browserLoaded(tab.linkedBrowser).then(() => {
|
||||
if (BookmarkingUI.status == BookmarkingUI.STATUS_UPDATING) {
|
||||
waitForCondition(() => BookmarkingUI.status != BookmarkingUI.STATUS_UPDATING, finishTest, "BookmarkingUI was updating for too long");
|
||||
} else {
|
||||
finishTest();
|
||||
}
|
||||
}), true);
|
||||
});
|
||||
|
||||
tab.linkedBrowser.loadURI("http://example.com/browser/browser/base/content/test/general/dummy_page.html");
|
||||
}
|
||||
|
@ -4,17 +4,12 @@
|
||||
|
||||
function test() {
|
||||
waitForExplicitFinish();
|
||||
gBrowser.selectedTab = gBrowser.addTab();
|
||||
gBrowser.selectedTab = gBrowser.addTab("data:text/html,<iframe width='700' height='700' src='about:certerror'></iframe>");
|
||||
// Open a html page with about:certerror in an iframe
|
||||
gBrowser.selectedBrowser.addEventListener("load", testIframeCert, true);
|
||||
content.location = "data:text/html,<iframe width='700' height='700' src='about:certerror'></iframe>";
|
||||
BrowserTestUtils.browserLoaded(gBrowser.selectedBrowser).then(testIframeCert);
|
||||
}
|
||||
|
||||
function testIframeCert(e) {
|
||||
if (e.target.location.href == "about:blank") {
|
||||
return;
|
||||
}
|
||||
gBrowser.selectedBrowser.removeEventListener("load", testIframeCert, true);
|
||||
// Confirm that the expert section is hidden
|
||||
var doc = gBrowser.contentDocument.getElementsByTagName('iframe')[0].contentDocument;
|
||||
var aP = doc.getElementById("advancedPanel");
|
||||
|
@ -1,16 +1,10 @@
|
||||
function test () {
|
||||
requestLongerTimeout(2);
|
||||
waitForExplicitFinish();
|
||||
|
||||
var isHTTPS = false;
|
||||
|
||||
gBrowser.selectedTab = gBrowser.addTab();
|
||||
gBrowser.selectedBrowser.addEventListener("load", function () {
|
||||
if (isHTTPS) {
|
||||
gBrowser.selectedBrowser.removeEventListener("load", arguments.callee, true);
|
||||
}
|
||||
let doc = gBrowser.contentDocument;
|
||||
|
||||
|
||||
function loadListener() {
|
||||
function testLocation(link, url, next) {
|
||||
var tabOpenListener = new TabOpenListener(url, function () {
|
||||
gBrowser.removeTab(this.tab);
|
||||
@ -18,18 +12,26 @@ function test () {
|
||||
next();
|
||||
});
|
||||
|
||||
doc.getElementById(link).click();
|
||||
ContentTask.spawn(gBrowser.selectedBrowser, link, link => {
|
||||
content.document.getElementById(link).click();
|
||||
});
|
||||
}
|
||||
|
||||
function testLink(link, name, next) {
|
||||
addWindowListener("chrome://mozapps/content/downloads/unknownContentType.xul", function (win) {
|
||||
is(doc.getElementById("unload-flag").textContent, "Okay", "beforeunload shouldn't have fired");
|
||||
ContentTask.spawn(gBrowser.selectedBrowser, null, () => {
|
||||
return content.document.getElementById("unload-flag").textContent;
|
||||
}).then(unloadFlag => {
|
||||
is(unloadFlag, "Okay", "beforeunload shouldn't have fired");
|
||||
is(win.document.getElementById("location").value, name, "file name should match");
|
||||
win.close();
|
||||
next();
|
||||
});
|
||||
});
|
||||
|
||||
doc.getElementById(link).click();
|
||||
ContentTask.spawn(gBrowser.selectedBrowser, link, link => {
|
||||
content.document.getElementById(link).click();
|
||||
});
|
||||
}
|
||||
|
||||
testLink("link1", "test.txt",
|
||||
@ -41,18 +43,22 @@ function test () {
|
||||
testLocation.bind(null, "link7", "http://example.com/",
|
||||
function () {
|
||||
if (isHTTPS) {
|
||||
gBrowser.removeCurrentTab();
|
||||
finish();
|
||||
} else {
|
||||
// same test again with https:
|
||||
isHTTPS = true;
|
||||
content.location = "https://example.com:443/browser/browser/base/content/test/general/download_page.html";
|
||||
gBrowser.loadURI("https://example.com:443/browser/browser/base/content/test/general/download_page.html");
|
||||
}
|
||||
})))))));
|
||||
|
||||
}, true);
|
||||
}
|
||||
|
||||
content.location = "http://mochi.test:8888/browser/browser/base/content/test/general/download_page.html";
|
||||
BrowserTestUtils.browserLoaded(gBrowser.selectedBrowser).then(() => {
|
||||
loadListener();
|
||||
BrowserTestUtils.browserLoaded(gBrowser.selectedBrowser).then(loadListener);
|
||||
});
|
||||
|
||||
gBrowser.loadURI("http://mochi.test:8888/browser/browser/base/content/test/general/download_page.html");
|
||||
}
|
||||
|
||||
|
||||
@ -97,15 +103,12 @@ TabOpenListener.prototype = {
|
||||
gBrowser.tabContainer.removeEventListener("TabOpen", this, false);
|
||||
this.tab = event.originalTarget;
|
||||
this.browser = this.tab.linkedBrowser;
|
||||
gBrowser.addEventListener("pageshow", this, false);
|
||||
} else if (event.type == "pageshow") {
|
||||
if (event.target.location.href != this.url)
|
||||
return;
|
||||
gBrowser.removeEventListener("pageshow", this, false);
|
||||
BrowserTestUtils.browserLoaded(this.browser, false, this.url).then(() => {
|
||||
this.tab.addEventListener("TabClose", this, false);
|
||||
var url = this.browser.contentDocument.location.href;
|
||||
var url = this.browser.currentURI.spec;
|
||||
is(url, this.url, "Should have opened the correct tab");
|
||||
this.opencallback(this.tab, this.browser.contentWindow);
|
||||
this.opencallback();
|
||||
});
|
||||
} else if (event.type == "TabClose") {
|
||||
if (event.originalTarget != this.tab)
|
||||
return;
|
||||
|
@ -45,10 +45,7 @@ function cleanUpAfterTests() {
|
||||
//------------------------ Test 1 ------------------------------
|
||||
|
||||
function test1A() {
|
||||
// Removing EventListener because we have to register a new
|
||||
// one once the page is loaded with mixed content blocker disabled
|
||||
gTestBrowser.removeEventListener("load", test1A, true);
|
||||
gTestBrowser.addEventListener("load", test1B, true);
|
||||
BrowserTestUtils.browserLoaded(gTestBrowser).then(test1B);
|
||||
|
||||
assertMixedContentBlockingState(gTestBrowser, {activeLoaded: false, activeBlocked: true, passiveLoaded: false});
|
||||
|
||||
@ -65,21 +62,18 @@ function test1B() {
|
||||
}
|
||||
|
||||
function test1C() {
|
||||
gTestBrowser.removeEventListener("load", test1B, true);
|
||||
var actual = content.document.getElementById('mctestdiv').innerHTML;
|
||||
is(actual, "Mixed Content Blocker disabled", "OK: Executed mixed script in Test 1C");
|
||||
|
||||
// The Script loaded after we disabled the page, now we are going to reload the
|
||||
// page and see if our decision is persistent
|
||||
gTestBrowser.addEventListener("load", test1D, true);
|
||||
BrowserTestUtils.browserLoaded(gTestBrowser).then(test1D);
|
||||
|
||||
var url = gHttpTestRoot1 + "file_bug902156_2.html";
|
||||
gTestBrowser.contentWindow.location = url;
|
||||
gTestBrowser.loadURI(url);
|
||||
}
|
||||
|
||||
function test1D() {
|
||||
gTestBrowser.removeEventListener("load", test1D, true);
|
||||
|
||||
// The Control Center button should appear but isMixedContentBlocked should be NOT true,
|
||||
// because our decision of disabling the mixed content blocker is persistent.
|
||||
assertMixedContentBlockingState(gTestBrowser, {activeLoaded: true, activeBlocked: false, passiveLoaded: false});
|
||||
@ -94,16 +88,13 @@ function test1D() {
|
||||
//------------------------ Test 2 ------------------------------
|
||||
|
||||
function test2() {
|
||||
gTestBrowser.addEventListener("load", test2A, true);
|
||||
BrowserTestUtils.browserLoaded(gTestBrowser).then(test2A);
|
||||
var url = gHttpTestRoot2 + "file_bug902156_2.html";
|
||||
gTestBrowser.contentWindow.location = url;
|
||||
gTestBrowser.loadURI(url);
|
||||
}
|
||||
|
||||
function test2A() {
|
||||
// Removing EventListener because we have to register a new
|
||||
// one once the page is loaded with mixed content blocker disabled
|
||||
gTestBrowser.removeEventListener("load", test2A, true);
|
||||
gTestBrowser.addEventListener("load", test2B, true);
|
||||
BrowserTestUtils.browserLoaded(gTestBrowser).then(test2B);
|
||||
|
||||
assertMixedContentBlockingState(gTestBrowser, {activeLoaded: false, activeBlocked: true, passiveLoaded: false});
|
||||
|
||||
@ -120,13 +111,12 @@ function test2B() {
|
||||
}
|
||||
|
||||
function test2C() {
|
||||
gTestBrowser.removeEventListener("load", test2B, true);
|
||||
var actual = content.document.getElementById('mctestdiv').innerHTML;
|
||||
is(actual, "Mixed Content Blocker disabled", "OK: Executed mixed script in Test 2C");
|
||||
|
||||
// The Script loaded after we disabled the page, now we are going to reload the
|
||||
// page and see if our decision is persistent
|
||||
gTestBrowser.addEventListener("load", test2D, true);
|
||||
BrowserTestUtils.browserLoaded(gTestBrowser).then(test2D);
|
||||
|
||||
// reload the page using the provided link in the html file
|
||||
var mctestlink = content.document.getElementById("mctestlink");
|
||||
@ -134,8 +124,6 @@ function test2C() {
|
||||
}
|
||||
|
||||
function test2D() {
|
||||
gTestBrowser.removeEventListener("load", test2D, true);
|
||||
|
||||
// The Control Center button should appear but isMixedContentBlocked should be NOT true,
|
||||
// because our decision of disabling the mixed content blocker is persistent.
|
||||
assertMixedContentBlockingState(gTestBrowser, {activeLoaded: true, activeBlocked: false, passiveLoaded: false});
|
||||
@ -150,16 +138,12 @@ function test2D() {
|
||||
//------------------------ Test 3 ------------------------------
|
||||
|
||||
function test3() {
|
||||
gTestBrowser.addEventListener("load", test3A, true);
|
||||
BrowserTestUtils.browserLoaded(gTestBrowser).then(test3A);
|
||||
var url = gHttpTestRoot1 + "file_bug902156_3.html";
|
||||
gTestBrowser.contentWindow.location = url;
|
||||
gTestBrowser.loadURI(url);
|
||||
}
|
||||
|
||||
function test3A() {
|
||||
// Removing EventListener because we have to register a new
|
||||
// one once the page is loaded with mixed content blocker disabled
|
||||
gTestBrowser.removeEventListener("load", test3A, true);
|
||||
|
||||
assertMixedContentBlockingState(gTestBrowser, {activeLoaded: false, activeBlocked: true, passiveLoaded: false});
|
||||
|
||||
// We are done with tests, clean up
|
||||
@ -184,7 +168,7 @@ function test() {
|
||||
newTab.linkedBrowser.stop()
|
||||
|
||||
// Starting Test Number 1:
|
||||
gTestBrowser.addEventListener("load", test1A, true);
|
||||
BrowserTestUtils.browserLoaded(gTestBrowser).then(test1A);
|
||||
var url = gHttpTestRoot1 + "file_bug902156_1.html";
|
||||
gTestBrowser.contentWindow.location = url;
|
||||
gTestBrowser.loadURI(url);
|
||||
}
|
||||
|
@ -3,32 +3,27 @@
|
||||
|
||||
// Tests find bar auto-close behavior
|
||||
|
||||
var newTab, iframe;
|
||||
var newTab;
|
||||
|
||||
function test() {
|
||||
add_task(function* findbar_test() {
|
||||
waitForExplicitFinish();
|
||||
newTab = gBrowser.addTab("about:blank");
|
||||
newTab.linkedBrowser.addEventListener("DOMContentLoaded",
|
||||
prepareTestFindBarStaysOpenOnSubdocumentLocationChange, false);
|
||||
newTab.linkedBrowser.contentWindow.location = "http://example.com/browser/" +
|
||||
"browser/base/content/test/general/test_bug628179.html";
|
||||
}
|
||||
|
||||
function prepareTestFindBarStaysOpenOnSubdocumentLocationChange() {
|
||||
newTab.linkedBrowser.removeEventListener("DOMContentLoaded",
|
||||
prepareTestFindBarStaysOpenOnSubdocumentLocationChange, false);
|
||||
let promise = ContentTask.spawn(newTab.linkedBrowser, null, function* () {
|
||||
yield ContentTaskUtils.waitForEvent(this, "DOMContentLoaded", false);
|
||||
});
|
||||
newTab.linkedBrowser.loadURI("http://example.com/browser/" +
|
||||
"browser/base/content/test/general/test_bug628179.html");
|
||||
yield promise;
|
||||
|
||||
gFindBar.open();
|
||||
|
||||
iframe = newTab.linkedBrowser.contentDocument.getElementById("iframe");
|
||||
iframe.addEventListener("load",
|
||||
testFindBarStaysOpenOnSubdocumentLocationChange, false);
|
||||
yield new ContentTask.spawn(newTab.linkedBrowser, null, function* () {
|
||||
let iframe = content.document.getElementById("iframe");
|
||||
let promise = ContentTaskUtils.waitForEvent(iframe, "load", false);
|
||||
iframe.src = "http://example.org/";
|
||||
}
|
||||
|
||||
function testFindBarStaysOpenOnSubdocumentLocationChange() {
|
||||
iframe.removeEventListener("load",
|
||||
testFindBarStaysOpenOnSubdocumentLocationChange, false);
|
||||
yield promise;
|
||||
});
|
||||
|
||||
ok(!gFindBar.hidden, "the Find bar isn't hidden after the location of a " +
|
||||
"subdocument changes");
|
||||
@ -36,5 +31,5 @@ function testFindBarStaysOpenOnSubdocumentLocationChange() {
|
||||
gFindBar.close();
|
||||
gBrowser.removeTab(newTab);
|
||||
finish();
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -7,6 +7,12 @@
|
||||
function test() {
|
||||
waitForExplicitFinish();
|
||||
|
||||
// Ensure TabView has been initialized already. Otherwise it could
|
||||
// activate at an unexpected time and show/hide tabs.
|
||||
TabView._initFrame(runTest);
|
||||
}
|
||||
|
||||
function runTest() {
|
||||
// Add a tab that will get removed and hidden
|
||||
let testTab = gBrowser.addTab("about:blank", {skipAnimation: true});
|
||||
is(gBrowser.visibleTabs.length, 2, "just added a tab, so 2 tabs");
|
||||
|
@ -3,17 +3,16 @@ function test() {
|
||||
gPrefService.setBoolPref("dom.disable_open_during_load", false);
|
||||
|
||||
var browser = gBrowser.selectedBrowser;
|
||||
browser.addEventListener("load", function () {
|
||||
browser.removeEventListener("load", arguments.callee, true);
|
||||
|
||||
BrowserTestUtils.browserLoaded(browser).then(() => {
|
||||
if (gPrefService.prefHasUserValue("dom.disable_open_during_load"))
|
||||
gPrefService.clearUserPref("dom.disable_open_during_load");
|
||||
|
||||
findPopup();
|
||||
}, true);
|
||||
});
|
||||
|
||||
content.location =
|
||||
"data:text/html,<html><script>popup=open('about:blank','','width=300,height=200')</script>";
|
||||
browser.loadURI(
|
||||
"data:text/html,<html><script>popup=open('about:blank','','width=300,height=200')</script>"
|
||||
);
|
||||
}
|
||||
|
||||
function findPopup() {
|
||||
|
@ -2,7 +2,7 @@
|
||||
* 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/. */
|
||||
|
||||
function test() {
|
||||
add_task(function*() {
|
||||
is(gBrowser.tabs.length, 1, "one tab is open initially");
|
||||
|
||||
// Add several new tabs in sequence, interrupted by selecting a
|
||||
@ -10,26 +10,29 @@ function test() {
|
||||
// returning a list of opened tabs for verifying the expected order.
|
||||
// The new tab behaviour is documented in bug 465673
|
||||
let tabs = [];
|
||||
let promises = [];
|
||||
function addTab(aURL, aReferrer) {
|
||||
tabs.push(gBrowser.addTab(aURL, {referrerURI: aReferrer}));
|
||||
let tab = gBrowser.addTab(aURL, {referrerURI: aReferrer});
|
||||
tabs.push(tab);
|
||||
return BrowserTestUtils.browserLoaded(tab.linkedBrowser);
|
||||
}
|
||||
|
||||
addTab("http://mochi.test:8888/#0");
|
||||
yield addTab("http://mochi.test:8888/#0");
|
||||
gBrowser.selectedTab = tabs[0];
|
||||
addTab("http://mochi.test:8888/#1");
|
||||
addTab("http://mochi.test:8888/#2", gBrowser.currentURI);
|
||||
addTab("http://mochi.test:8888/#3", gBrowser.currentURI);
|
||||
yield addTab("http://mochi.test:8888/#1");
|
||||
yield addTab("http://mochi.test:8888/#2", gBrowser.currentURI);
|
||||
yield addTab("http://mochi.test:8888/#3", gBrowser.currentURI);
|
||||
gBrowser.selectedTab = tabs[tabs.length - 1];
|
||||
gBrowser.selectedTab = tabs[0];
|
||||
addTab("http://mochi.test:8888/#4", gBrowser.currentURI);
|
||||
yield addTab("http://mochi.test:8888/#4", gBrowser.currentURI);
|
||||
gBrowser.selectedTab = tabs[3];
|
||||
addTab("http://mochi.test:8888/#5", gBrowser.currentURI);
|
||||
yield addTab("http://mochi.test:8888/#5", gBrowser.currentURI);
|
||||
gBrowser.removeTab(tabs.pop());
|
||||
addTab("about:blank", gBrowser.currentURI);
|
||||
yield addTab("about:blank", gBrowser.currentURI);
|
||||
gBrowser.moveTabTo(gBrowser.selectedTab, 1);
|
||||
addTab("http://mochi.test:8888/#6", gBrowser.currentURI);
|
||||
addTab();
|
||||
addTab("http://mochi.test:8888/#7");
|
||||
yield addTab("http://mochi.test:8888/#6", gBrowser.currentURI);
|
||||
yield addTab();
|
||||
yield addTab("http://mochi.test:8888/#7");
|
||||
|
||||
function testPosition(tabNum, expectedPosition, msg) {
|
||||
is(Array.indexOf(gBrowser.tabs, tabs[tabNum]), expectedPosition, msg);
|
||||
@ -46,4 +49,4 @@ function test() {
|
||||
testPosition(8, 9, "tab without referrer opens at the end");
|
||||
|
||||
tabs.forEach(gBrowser.removeTab, gBrowser);
|
||||
}
|
||||
});
|
||||
|
@ -18,5 +18,5 @@ function test() {
|
||||
"gBrowser.selectTabAtIndex(-3) selects expected tab");
|
||||
|
||||
for (let i = 0; i < 9; i++)
|
||||
gBrowser.removeCurrentTab();
|
||||
gBrowser.removeTab(gBrowser.selectedTab, {skipPermitUnload: true});
|
||||
}
|
||||
|
@ -41,22 +41,20 @@ function test_getBoolPref() {
|
||||
function test_openNewTabWith() {
|
||||
openNewTabWith("http://example.com/");
|
||||
let tab = gBrowser.selectedTab = gBrowser.tabs[1];
|
||||
tab.linkedBrowser.addEventListener("load", function onLoad(event) {
|
||||
tab.linkedBrowser.removeEventListener("load", onLoad, true);
|
||||
BrowserTestUtils.browserLoaded(tab.linkedBrowser).then(() => {
|
||||
is(tab.linkedBrowser.currentURI.spec, "http://example.com/", "example.com loaded");
|
||||
gBrowser.removeCurrentTab();
|
||||
runNextTest();
|
||||
}, true);
|
||||
});
|
||||
}
|
||||
|
||||
function test_openUILink() {
|
||||
let tab = gBrowser.selectedTab = gBrowser.addTab("about:blank");
|
||||
tab.linkedBrowser.addEventListener("load", function onLoad(event) {
|
||||
tab.linkedBrowser.removeEventListener("load", onLoad, true);
|
||||
BrowserTestUtils.browserLoaded(tab.linkedBrowser).then(() => {
|
||||
is(tab.linkedBrowser.currentURI.spec, "http://example.org/", "example.org loaded");
|
||||
gBrowser.removeCurrentTab();
|
||||
runNextTest();
|
||||
}, true);
|
||||
});
|
||||
|
||||
openUILink("http://example.org/"); // defaults to "current"
|
||||
}
|
||||
|
@ -2,7 +2,11 @@
|
||||
* 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/. */
|
||||
|
||||
function test() {
|
||||
add_task(function* () {
|
||||
// Ensure TabView has been initialized already. Otherwise it could
|
||||
// activate at an unexpected time and show/hide tabs.
|
||||
yield new Promise(resolve => TabView._initFrame(resolve));
|
||||
|
||||
// There should be one tab when we start the test
|
||||
let [origTab] = gBrowser.visibleTabs;
|
||||
|
||||
@ -100,4 +104,5 @@ function test() {
|
||||
|
||||
if (tabViewWindow)
|
||||
tabViewWindow.GroupItems.groupItems[0].close();
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -5,6 +5,12 @@
|
||||
function test() {
|
||||
waitForExplicitFinish();
|
||||
|
||||
// Ensure TabView has been initialized already. Otherwise it could
|
||||
// activate at an unexpected time and show/hide tabs.
|
||||
TabView._initFrame(runTest);
|
||||
}
|
||||
|
||||
function runTest() {
|
||||
let tabOne = gBrowser.addTab("about:blank");
|
||||
let tabTwo = gBrowser.addTab("http://mochi.test:8888/");
|
||||
gBrowser.selectedTab = tabTwo;
|
||||
|
@ -5,6 +5,12 @@
|
||||
function test() {
|
||||
waitForExplicitFinish();
|
||||
|
||||
// Ensure TabView has been initialized already. Otherwise it could
|
||||
// activate at an unexpected time and show/hide tabs.
|
||||
TabView._initFrame(runTest);
|
||||
}
|
||||
|
||||
function runTest() {
|
||||
// There should be one tab when we start the test
|
||||
let [origTab] = gBrowser.visibleTabs;
|
||||
is(gBrowser.visibleTabs.length, 1, "1 tab should be open");
|
||||
|
@ -2,7 +2,11 @@
|
||||
* 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/. */
|
||||
|
||||
function test() {
|
||||
add_task(function* test() {
|
||||
// Ensure TabView has been initialized already. Otherwise it could
|
||||
// activate at an unexpected time and show/hide tabs.
|
||||
yield new Promise(resolve => TabView._initFrame(resolve));
|
||||
|
||||
// There should be one tab when we start the test
|
||||
let [origTab] = gBrowser.visibleTabs;
|
||||
is(gBrowser.visibleTabs.length, 1, "there is one visible tab");
|
||||
@ -51,4 +55,5 @@ function test() {
|
||||
|
||||
gBrowser.removeTab(testTab);
|
||||
gBrowser.removeTab(pinned);
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -2,7 +2,11 @@
|
||||
* 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/. */
|
||||
|
||||
function test() {
|
||||
add_task(function* test() {
|
||||
// Ensure TabView has been initialized already. Otherwise it could
|
||||
// activate at an unexpected time and show/hide tabs.
|
||||
yield new Promise(resolve => TabView._initFrame(resolve));
|
||||
|
||||
gPrefService.setBoolPref("browser.ctrlTab.previews", true);
|
||||
|
||||
let [origTab] = gBrowser.visibleTabs;
|
||||
@ -30,7 +34,7 @@ function test() {
|
||||
|
||||
if (gPrefService.prefHasUserValue("browser.ctrlTab.previews"))
|
||||
gPrefService.clearUserPref("browser.ctrlTab.previews");
|
||||
}
|
||||
});
|
||||
|
||||
function pressCtrlTab(aShiftKey) {
|
||||
EventUtils.synthesizeKey("VK_TAB", { ctrlKey: true, shiftKey: !!aShiftKey });
|
||||
|
@ -416,7 +416,7 @@ function loadIntoTab(tab, url, callback) {
|
||||
|
||||
function ensureBrowserTabClosed(tab) {
|
||||
let promise = ensureEventFired(gBrowser.tabContainer, "TabClose");
|
||||
gBrowser.removeTab(tab);
|
||||
gBrowser.removeTab(tab, {skipPermitUnload: true});
|
||||
return promise;
|
||||
}
|
||||
|
||||
|
@ -6,7 +6,7 @@ function test() {
|
||||
/** Test for Bug 522545 **/
|
||||
|
||||
waitForExplicitFinish();
|
||||
requestLongerTimeout(2);
|
||||
requestLongerTimeout(3);
|
||||
|
||||
// This tests the following use case:
|
||||
// User opens a new tab which gets focus. The user types something into the
|
||||
@ -159,12 +159,10 @@ function test() {
|
||||
|
||||
ok(hasUTV, "At least one tab has a userTypedValue with userTypedClear with no loaded URL");
|
||||
|
||||
gBrowser.addEventListener("load", firstLoad, true);
|
||||
BrowserTestUtils.browserLoaded(gBrowser.selectedBrowser).then(firstLoad);
|
||||
}
|
||||
|
||||
function firstLoad() {
|
||||
gBrowser.removeEventListener("load", firstLoad, true);
|
||||
|
||||
let state = JSON.parse(ss.getBrowserState());
|
||||
let hasSH = state.windows[0].tabs.some(function(aTab) {
|
||||
return !("userTypedValue" in aTab) && aTab.entries[0].url;
|
||||
|
@ -6,6 +6,10 @@ add_task(function* () {
|
||||
/** Bug 607016 - If a tab is never restored, attributes (eg. hidden) aren't updated correctly **/
|
||||
ignoreAllUncaughtExceptions();
|
||||
|
||||
// Ensure TabView has been initialized already. Otherwise it could
|
||||
// activate at an unexpected time and show/hide tabs.
|
||||
yield new Promise(resolve => TabView._initFrame(resolve));
|
||||
|
||||
// Set the pref to true so we know exactly how many tabs should be restoring at
|
||||
// any given time. This guarantees that a finishing load won't start another.
|
||||
Services.prefs.setBoolPref("browser.sessionstore.restore_on_demand", true);
|
||||
|
@ -7,6 +7,12 @@
|
||||
|
||||
function test() {
|
||||
waitForExplicitFinish();
|
||||
// Ensure TabView has been initialized already. Otherwise it could
|
||||
// activate at an unexpected time and show/hide tabs.
|
||||
TabView._initFrame(runTest);
|
||||
}
|
||||
|
||||
function runTest() {
|
||||
// We speed up the interval between session saves to ensure that the test
|
||||
// runs quickly.
|
||||
Services.prefs.setIntPref("browser.sessionstore.interval", 2000);
|
||||
|
@ -39,11 +39,18 @@ var RemotePrompt = {
|
||||
let tabPrompt = window.gBrowser.getTabModalPromptBox(browser)
|
||||
let callbackInvoked = false;
|
||||
let newPrompt;
|
||||
let needRemove = false;
|
||||
let promptId = args._remoteId;
|
||||
|
||||
function onPromptClose(forceCleanup) {
|
||||
// It's possible that we removed the prompt during the
|
||||
// appendPrompt call below. In that case, newPrompt will be
|
||||
// undefined. We set the needRemove flag to remember to remove
|
||||
// it right after we've finished adding it.
|
||||
if (newPrompt)
|
||||
tabPrompt.removePrompt(newPrompt);
|
||||
else
|
||||
needRemove = true;
|
||||
|
||||
PromptUtils.fireDialogEvent(window, "DOMModalDialogClosed", browser);
|
||||
browser.messageManager.sendAsyncMessage("Prompt:Close", args);
|
||||
@ -74,6 +81,10 @@ var RemotePrompt = {
|
||||
|
||||
newPrompt = tabPrompt.appendPrompt(args, onPromptClose);
|
||||
|
||||
if (needRemove) {
|
||||
tabPrompt.removePrompt(newPrompt);
|
||||
}
|
||||
|
||||
// TODO since we don't actually open a window, need to check if
|
||||
// there's other stuff in nsWindowWatcher::OpenWindowInternal
|
||||
// that we might need to do here as well.
|
||||
|
@ -9,12 +9,10 @@ function test()
|
||||
waitForExplicitFinish();
|
||||
|
||||
gBrowser.selectedTab = gBrowser.addTab();
|
||||
gBrowser.selectedBrowser.addEventListener("load", onLoad, true);
|
||||
BrowserTestUtils.browserLoaded(gBrowser.selectedBrowser).then(onLoad);
|
||||
}
|
||||
|
||||
function onLoad(evt) {
|
||||
gBrowser.selectedBrowser.removeEventListener(evt.type, onLoad, true);
|
||||
|
||||
function onLoad() {
|
||||
target = TargetFactory.forTab(gBrowser.selectedTab);
|
||||
|
||||
is(target.tab, gBrowser.selectedTab, "Target linked to the right tab.");
|
||||
|
@ -61,6 +61,11 @@ viewsourceindebugger=View source in Debugger → %S
|
||||
# that represents a row broken down by allocation stack when no stack was available.
|
||||
tree-item.nostack=(no stack available)
|
||||
|
||||
# LOCALIZATION NOTE (tree-item.nofilename): The label describing the row in the
|
||||
# heap tree that represents a row broken down by filename when no filename was
|
||||
# available.
|
||||
tree-item.nofilename=(no filename available)
|
||||
|
||||
# LOCALIZATION NOTE (tree-item.root): The label describing the row in the heap tree
|
||||
# that represents the root of the tree when inverted.
|
||||
tree-item.root=(root)
|
||||
|
@ -59,9 +59,22 @@ const TreeItem = module.exports = createClass({
|
||||
},
|
||||
|
||||
toLabel(name, toolbox) {
|
||||
return isSavedFrame(name) ? FrameView({ frame: name, toolbox }) :
|
||||
name === "noStack" ? L10N.getStr("tree-item.nostack") :
|
||||
name === null ? L10N.getStr("tree-item.root") :
|
||||
String(name);
|
||||
if (isSavedFrame(name)) {
|
||||
return FrameView({ frame: name, toolbox });
|
||||
}
|
||||
|
||||
if (name === null) {
|
||||
return L10N.getStr("tree-item.root");
|
||||
}
|
||||
|
||||
if (name === "noStack") {
|
||||
return L10N.getStr("tree-item.nostack");
|
||||
}
|
||||
|
||||
if (name === "noFilename") {
|
||||
return L10N.getStr("tree-item.nofilename");
|
||||
}
|
||||
|
||||
return String(name);
|
||||
},
|
||||
});
|
||||
|
@ -56,7 +56,11 @@ const breakdowns = exports.breakdowns = {
|
||||
by: "coarseType",
|
||||
objects: OBJECT_CLASS,
|
||||
strings: COUNT,
|
||||
scripts: INTERNAL_TYPE,
|
||||
scripts: {
|
||||
by: "filename",
|
||||
then: INTERNAL_TYPE,
|
||||
noFilename: INTERNAL_TYPE
|
||||
},
|
||||
other: INTERNAL_TYPE,
|
||||
}
|
||||
},
|
||||
|
@ -107,7 +107,8 @@ function removeTab(aTab, aWindow) {
|
||||
let targetWindow = aWindow || window;
|
||||
let targetBrowser = targetWindow.gBrowser;
|
||||
|
||||
targetBrowser.removeTab(aTab);
|
||||
// browser_net_pane-toggle.js relies on synchronous removeTab behavior.
|
||||
targetBrowser.removeTab(aTab, {skipPermitUnload: true});
|
||||
}
|
||||
|
||||
function waitForNavigation(aTarget) {
|
||||
|
@ -131,26 +131,22 @@ function* testTheBasics(widget) {
|
||||
*/
|
||||
function checkLinkClick(link) {
|
||||
|
||||
function loadListener(e) {
|
||||
let tab = e.target;
|
||||
function loadListener(tab) {
|
||||
var browser = getBrowser().getBrowserForTab(tab);
|
||||
var uri = browser.currentURI.spec;
|
||||
// this is horrible, and it's because when we open a new tab
|
||||
// "about:blank: is first loaded into it, before the actual
|
||||
// document we want to load.
|
||||
if (uri != "about:blank") {
|
||||
|
||||
info("New browser tab has loaded");
|
||||
tab.removeEventListener("load", loadListener);
|
||||
gBrowser.removeTab(tab);
|
||||
info("Resolve promise with new tab URI");
|
||||
deferred.resolve(uri);
|
||||
}
|
||||
}
|
||||
|
||||
function newTabListener(e) {
|
||||
gBrowser.tabContainer.removeEventListener("TabOpen", newTabListener);
|
||||
var tab = e.target;
|
||||
tab.addEventListener("load", loadListener, false);
|
||||
BrowserTestUtils.browserLoaded(tab.linkedBrowser, false,
|
||||
url => { return url != "about:blank"; })
|
||||
.then(url => loadListener(tab));
|
||||
}
|
||||
|
||||
let deferred = promise.defer();
|
||||
|
@ -27,17 +27,16 @@ function addTab(aURL, aCallback)
|
||||
waitForExplicitFinish();
|
||||
|
||||
gBrowser.selectedTab = gBrowser.addTab();
|
||||
content.location = aURL;
|
||||
|
||||
let tab = gBrowser.selectedTab;
|
||||
let browser = gBrowser.getBrowserForTab(tab);
|
||||
|
||||
function onTabLoad() {
|
||||
browser.removeEventListener("load", onTabLoad, true);
|
||||
aCallback(browser, tab, browser.contentDocument);
|
||||
}
|
||||
let url = encodeURI(aURL);
|
||||
|
||||
browser.addEventListener("load", onTabLoad, true);
|
||||
BrowserTestUtils.browserLoaded(browser, false, url).then(() => {
|
||||
aCallback(browser, tab, browser.contentDocument);
|
||||
});
|
||||
|
||||
browser.loadURI(url);
|
||||
}
|
||||
|
||||
function promiseTab(aURL) {
|
||||
|
@ -123,12 +123,11 @@ var doc = null;
|
||||
function test() {
|
||||
waitForExplicitFinish();
|
||||
gBrowser.selectedTab = gBrowser.addTab();
|
||||
gBrowser.selectedBrowser.addEventListener("load", function onload() {
|
||||
gBrowser.selectedBrowser.removeEventListener("load", onload, true);
|
||||
BrowserTestUtils.browserLoaded(gBrowser.selectedBrowser).then(() => {
|
||||
doc = content.document;
|
||||
runTests();
|
||||
}, true);
|
||||
content.location = TEST_URI;
|
||||
});
|
||||
gBrowser.loadURI(TEST_URI);
|
||||
}
|
||||
|
||||
function runTests() {
|
||||
|
@ -58,13 +58,11 @@ const TEST_URI = "data:text/html;charset=UTF-8," + encodeURIComponent(
|
||||
var doc = null;
|
||||
function test() {
|
||||
waitForExplicitFinish();
|
||||
gBrowser.selectedTab = gBrowser.addTab();
|
||||
gBrowser.selectedBrowser.addEventListener("load", function onload() {
|
||||
gBrowser.selectedBrowser.removeEventListener("load", onload, true);
|
||||
gBrowser.selectedTab = gBrowser.addTab(TEST_URI);
|
||||
BrowserTestUtils.browserLoaded(gBrowser.selectedBrowser).then(() => {
|
||||
doc = content.document;
|
||||
runTests();
|
||||
}, true);
|
||||
content.location = TEST_URI;
|
||||
});
|
||||
}
|
||||
|
||||
function runTests() {
|
||||
|
@ -28,7 +28,7 @@ function runCodeMirrorTest(browser) {
|
||||
'function check() { ' +
|
||||
' var doc = content.document; var out = doc.getElementById("status"); ' +
|
||||
' if (!out || !out.classList.contains("done")) { return setTimeout(check, 100); }' +
|
||||
' sendSyncMessage("done", { failed: content.wrappedJSObject.failed });' +
|
||||
' sendAsyncMessage("done", { failed: content.wrappedJSObject.failed });' +
|
||||
'}' +
|
||||
'check();'
|
||||
, true);
|
||||
|
@ -97,11 +97,19 @@ EDGES.allocationStack = function (breakdown, report) {
|
||||
edge: key,
|
||||
referent: value,
|
||||
breakdown: key === "noStack" ? breakdown.noStack : breakdown.then
|
||||
})
|
||||
});
|
||||
});
|
||||
return edges;
|
||||
};
|
||||
|
||||
EDGES.filename = function (breakdown, report) {
|
||||
return Object.keys(report).map(key => ({
|
||||
edge: key,
|
||||
referent: report[key],
|
||||
breakdown: key === "noFilename" ? breakdown.noFilename : breakdown.then
|
||||
}));
|
||||
};
|
||||
|
||||
/**
|
||||
* Get the set of outgoing edges from `report` as specified by the given
|
||||
* breakdown.
|
||||
|
@ -49,6 +49,8 @@ struct NodeOneofInstance {
|
||||
::google::protobuf::uint64 typenameref_;
|
||||
const ::std::string* jsobjectclassname_;
|
||||
::google::protobuf::uint64 jsobjectclassnameref_;
|
||||
const ::std::string* scriptfilename_;
|
||||
::google::protobuf::uint64 scriptfilenameref_;
|
||||
}* Node_default_oneof_instance_ = NULL;
|
||||
const ::google::protobuf::Descriptor* Edge_descriptor_ = NULL;
|
||||
const ::google::protobuf::internal::GeneratedMessageReflection*
|
||||
@ -130,7 +132,7 @@ void protobuf_AssignDesc_CoreDump_2eproto() {
|
||||
::google::protobuf::MessageFactory::generated_factory(),
|
||||
sizeof(StackFrame_Data));
|
||||
Node_descriptor_ = file->message_type(2);
|
||||
static const int Node_offsets_[11] = {
|
||||
static const int Node_offsets_[14] = {
|
||||
GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Node, id_),
|
||||
PROTO2_GENERATED_DEFAULT_ONEOF_FIELD_OFFSET(Node_default_oneof_instance_, typename__),
|
||||
PROTO2_GENERATED_DEFAULT_ONEOF_FIELD_OFFSET(Node_default_oneof_instance_, typenameref_),
|
||||
@ -140,8 +142,11 @@ void protobuf_AssignDesc_CoreDump_2eproto() {
|
||||
PROTO2_GENERATED_DEFAULT_ONEOF_FIELD_OFFSET(Node_default_oneof_instance_, jsobjectclassname_),
|
||||
PROTO2_GENERATED_DEFAULT_ONEOF_FIELD_OFFSET(Node_default_oneof_instance_, jsobjectclassnameref_),
|
||||
GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Node, coarsetype_),
|
||||
PROTO2_GENERATED_DEFAULT_ONEOF_FIELD_OFFSET(Node_default_oneof_instance_, scriptfilename_),
|
||||
PROTO2_GENERATED_DEFAULT_ONEOF_FIELD_OFFSET(Node_default_oneof_instance_, scriptfilenameref_),
|
||||
GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Node, TypeNameOrRef_),
|
||||
GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Node, JSObjectClassNameOrRef_),
|
||||
GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Node, ScriptFilenameOrRef_),
|
||||
};
|
||||
Node_reflection_ =
|
||||
new ::google::protobuf::internal::GeneratedMessageReflection(
|
||||
@ -237,17 +242,19 @@ void protobuf_AddDesc_CoreDump_2eproto() {
|
||||
"nDisplayName\030\007 \001(\014H\001\022 \n\026functionDisplayN"
|
||||
"ameRef\030\010 \001(\004H\001\022\020\n\010isSystem\030\t \001(\010\022\024\n\014isSe"
|
||||
"lfHosted\030\n \001(\010B\r\n\013SourceOrRefB\032\n\030Functio"
|
||||
"nDisplayNameOrRefB\020\n\016StackFrameType\"\272\002\n\004"
|
||||
"nDisplayNameOrRefB\020\n\016StackFrameType\"\210\003\n\004"
|
||||
"Node\022\n\n\002id\030\001 \001(\004\022\022\n\010typeName\030\002 \001(\014H\000\022\025\n\013"
|
||||
"typeNameRef\030\003 \001(\004H\000\022\014\n\004size\030\004 \001(\004\022.\n\005edg"
|
||||
"es\030\005 \003(\0132\037.mozilla.devtools.protobuf.Edg"
|
||||
"e\022>\n\017allocationStack\030\006 \001(\0132%.mozilla.dev"
|
||||
"tools.protobuf.StackFrame\022\033\n\021jsObjectCla"
|
||||
"ssName\030\007 \001(\014H\001\022\036\n\024jsObjectClassNameRef\030\010"
|
||||
" \001(\004H\001\022\025\n\ncoarseType\030\t \001(\r:\0010B\017\n\rTypeNam"
|
||||
"eOrRefB\030\n\026JSObjectClassNameOrRef\"L\n\004Edge"
|
||||
"\022\020\n\010referent\030\001 \001(\004\022\016\n\004name\030\002 \001(\014H\000\022\021\n\007na"
|
||||
"meRef\030\003 \001(\004H\000B\017\n\rEdgeNameOrRef", 870);
|
||||
" \001(\004H\001\022\025\n\ncoarseType\030\t \001(\r:\0010\022\030\n\016scriptF"
|
||||
"ilename\030\n \001(\014H\002\022\033\n\021scriptFilenameRef\030\013 \001"
|
||||
"(\004H\002B\017\n\rTypeNameOrRefB\030\n\026JSObjectClassNa"
|
||||
"meOrRefB\025\n\023ScriptFilenameOrRef\"L\n\004Edge\022\020"
|
||||
"\n\010referent\030\001 \001(\004\022\016\n\004name\030\002 \001(\014H\000\022\021\n\007name"
|
||||
"Ref\030\003 \001(\004H\000B\017\n\rEdgeNameOrRef", 948);
|
||||
::google::protobuf::MessageFactory::InternalRegisterGeneratedFile(
|
||||
"CoreDump.proto", &protobuf_RegisterTypes);
|
||||
Metadata::default_instance_ = new Metadata();
|
||||
@ -1462,6 +1469,8 @@ const int Node::kAllocationStackFieldNumber;
|
||||
const int Node::kJsObjectClassNameFieldNumber;
|
||||
const int Node::kJsObjectClassNameRefFieldNumber;
|
||||
const int Node::kCoarseTypeFieldNumber;
|
||||
const int Node::kScriptFilenameFieldNumber;
|
||||
const int Node::kScriptFilenameRefFieldNumber;
|
||||
#endif // !_MSC_VER
|
||||
|
||||
Node::Node()
|
||||
@ -1476,6 +1485,8 @@ void Node::InitAsDefaultInstance() {
|
||||
allocationstack_ = const_cast< ::mozilla::devtools::protobuf::StackFrame*>(&::mozilla::devtools::protobuf::StackFrame::default_instance());
|
||||
Node_default_oneof_instance_->jsobjectclassname_ = &::google::protobuf::internal::GetEmptyStringAlreadyInited();
|
||||
Node_default_oneof_instance_->jsobjectclassnameref_ = GOOGLE_ULONGLONG(0);
|
||||
Node_default_oneof_instance_->scriptfilename_ = &::google::protobuf::internal::GetEmptyStringAlreadyInited();
|
||||
Node_default_oneof_instance_->scriptfilenameref_ = GOOGLE_ULONGLONG(0);
|
||||
}
|
||||
|
||||
Node::Node(const Node& from)
|
||||
@ -1495,6 +1506,7 @@ void Node::SharedCtor() {
|
||||
::memset(_has_bits_, 0, sizeof(_has_bits_));
|
||||
clear_has_TypeNameOrRef();
|
||||
clear_has_JSObjectClassNameOrRef();
|
||||
clear_has_ScriptFilenameOrRef();
|
||||
}
|
||||
|
||||
Node::~Node() {
|
||||
@ -1509,6 +1521,9 @@ void Node::SharedDtor() {
|
||||
if (has_JSObjectClassNameOrRef()) {
|
||||
clear_JSObjectClassNameOrRef();
|
||||
}
|
||||
if (has_ScriptFilenameOrRef()) {
|
||||
clear_ScriptFilenameOrRef();
|
||||
}
|
||||
if (this != default_instance_) {
|
||||
delete allocationstack_;
|
||||
}
|
||||
@ -1569,6 +1584,23 @@ void Node::clear_JSObjectClassNameOrRef() {
|
||||
_oneof_case_[1] = JSOBJECTCLASSNAMEORREF_NOT_SET;
|
||||
}
|
||||
|
||||
void Node::clear_ScriptFilenameOrRef() {
|
||||
switch(ScriptFilenameOrRef_case()) {
|
||||
case kScriptFilename: {
|
||||
delete ScriptFilenameOrRef_.scriptfilename_;
|
||||
break;
|
||||
}
|
||||
case kScriptFilenameRef: {
|
||||
// No need to clear
|
||||
break;
|
||||
}
|
||||
case SCRIPTFILENAMEORREF_NOT_SET: {
|
||||
break;
|
||||
}
|
||||
}
|
||||
_oneof_case_[2] = SCRIPTFILENAMEORREF_NOT_SET;
|
||||
}
|
||||
|
||||
|
||||
void Node::Clear() {
|
||||
#define OFFSET_OF_FIELD_(f) (reinterpret_cast<char*>( \
|
||||
@ -1595,6 +1627,7 @@ void Node::Clear() {
|
||||
edges_.Clear();
|
||||
clear_TypeNameOrRef();
|
||||
clear_JSObjectClassNameOrRef();
|
||||
clear_ScriptFilenameOrRef();
|
||||
::memset(_has_bits_, 0, sizeof(_has_bits_));
|
||||
mutable_unknown_fields()->Clear();
|
||||
}
|
||||
@ -1734,6 +1767,35 @@ bool Node::MergePartialFromCodedStream(
|
||||
} else {
|
||||
goto handle_unusual;
|
||||
}
|
||||
if (input->ExpectTag(82)) goto parse_scriptFilename;
|
||||
break;
|
||||
}
|
||||
|
||||
// optional bytes scriptFilename = 10;
|
||||
case 10: {
|
||||
if (tag == 82) {
|
||||
parse_scriptFilename:
|
||||
DO_(::google::protobuf::internal::WireFormatLite::ReadBytes(
|
||||
input, this->mutable_scriptfilename()));
|
||||
} else {
|
||||
goto handle_unusual;
|
||||
}
|
||||
if (input->ExpectTag(88)) goto parse_scriptFilenameRef;
|
||||
break;
|
||||
}
|
||||
|
||||
// optional uint64 scriptFilenameRef = 11;
|
||||
case 11: {
|
||||
if (tag == 88) {
|
||||
parse_scriptFilenameRef:
|
||||
clear_ScriptFilenameOrRef();
|
||||
DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
|
||||
::google::protobuf::uint64, ::google::protobuf::internal::WireFormatLite::TYPE_UINT64>(
|
||||
input, &ScriptFilenameOrRef_.scriptfilenameref_)));
|
||||
set_has_scriptfilenameref();
|
||||
} else {
|
||||
goto handle_unusual;
|
||||
}
|
||||
if (input->ExpectAtEnd()) goto success;
|
||||
break;
|
||||
}
|
||||
@ -1812,6 +1874,17 @@ void Node::SerializeWithCachedSizes(
|
||||
::google::protobuf::internal::WireFormatLite::WriteUInt32(9, this->coarsetype(), output);
|
||||
}
|
||||
|
||||
// optional bytes scriptFilename = 10;
|
||||
if (has_scriptfilename()) {
|
||||
::google::protobuf::internal::WireFormatLite::WriteBytesMaybeAliased(
|
||||
10, this->scriptfilename(), output);
|
||||
}
|
||||
|
||||
// optional uint64 scriptFilenameRef = 11;
|
||||
if (has_scriptfilenameref()) {
|
||||
::google::protobuf::internal::WireFormatLite::WriteUInt64(11, this->scriptfilenameref(), output);
|
||||
}
|
||||
|
||||
if (!unknown_fields().empty()) {
|
||||
::google::protobuf::internal::WireFormat::SerializeUnknownFields(
|
||||
unknown_fields(), output);
|
||||
@ -1875,6 +1948,18 @@ void Node::SerializeWithCachedSizes(
|
||||
target = ::google::protobuf::internal::WireFormatLite::WriteUInt32ToArray(9, this->coarsetype(), target);
|
||||
}
|
||||
|
||||
// optional bytes scriptFilename = 10;
|
||||
if (has_scriptfilename()) {
|
||||
target =
|
||||
::google::protobuf::internal::WireFormatLite::WriteBytesToArray(
|
||||
10, this->scriptfilename(), target);
|
||||
}
|
||||
|
||||
// optional uint64 scriptFilenameRef = 11;
|
||||
if (has_scriptfilenameref()) {
|
||||
target = ::google::protobuf::internal::WireFormatLite::WriteUInt64ToArray(11, this->scriptfilenameref(), target);
|
||||
}
|
||||
|
||||
if (!unknown_fields().empty()) {
|
||||
target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(
|
||||
unknown_fields(), target);
|
||||
@ -1964,6 +2049,25 @@ int Node::ByteSize() const {
|
||||
break;
|
||||
}
|
||||
}
|
||||
switch (ScriptFilenameOrRef_case()) {
|
||||
// optional bytes scriptFilename = 10;
|
||||
case kScriptFilename: {
|
||||
total_size += 1 +
|
||||
::google::protobuf::internal::WireFormatLite::BytesSize(
|
||||
this->scriptfilename());
|
||||
break;
|
||||
}
|
||||
// optional uint64 scriptFilenameRef = 11;
|
||||
case kScriptFilenameRef: {
|
||||
total_size += 1 +
|
||||
::google::protobuf::internal::WireFormatLite::UInt64Size(
|
||||
this->scriptfilenameref());
|
||||
break;
|
||||
}
|
||||
case SCRIPTFILENAMEORREF_NOT_SET: {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!unknown_fields().empty()) {
|
||||
total_size +=
|
||||
::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
|
||||
@ -2016,6 +2120,19 @@ void Node::MergeFrom(const Node& from) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
switch (from.ScriptFilenameOrRef_case()) {
|
||||
case kScriptFilename: {
|
||||
set_scriptfilename(from.scriptfilename());
|
||||
break;
|
||||
}
|
||||
case kScriptFilenameRef: {
|
||||
set_scriptfilenameref(from.scriptfilenameref());
|
||||
break;
|
||||
}
|
||||
case SCRIPTFILENAMEORREF_NOT_SET: {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) {
|
||||
if (from.has_id()) {
|
||||
set_id(from.id());
|
||||
@ -2063,6 +2180,8 @@ void Node::Swap(Node* other) {
|
||||
std::swap(_oneof_case_[0], other->_oneof_case_[0]);
|
||||
std::swap(JSObjectClassNameOrRef_, other->JSObjectClassNameOrRef_);
|
||||
std::swap(_oneof_case_[1], other->_oneof_case_[1]);
|
||||
std::swap(ScriptFilenameOrRef_, other->ScriptFilenameOrRef_);
|
||||
std::swap(_oneof_case_[2], other->_oneof_case_[2]);
|
||||
std::swap(_has_bits_[0], other->_has_bits_[0]);
|
||||
_unknown_fields_.Swap(&other->_unknown_fields_);
|
||||
std::swap(_cached_size_, other->_cached_size_);
|
||||
|
@ -468,6 +468,12 @@ class Node : public ::google::protobuf::Message {
|
||||
JSOBJECTCLASSNAMEORREF_NOT_SET = 0,
|
||||
};
|
||||
|
||||
enum ScriptFilenameOrRefCase {
|
||||
kScriptFilename = 10,
|
||||
kScriptFilenameRef = 11,
|
||||
SCRIPTFILENAMEORREF_NOT_SET = 0,
|
||||
};
|
||||
|
||||
void Swap(Node* other);
|
||||
|
||||
// implements Message ----------------------------------------------
|
||||
@ -578,8 +584,28 @@ class Node : public ::google::protobuf::Message {
|
||||
inline ::google::protobuf::uint32 coarsetype() const;
|
||||
inline void set_coarsetype(::google::protobuf::uint32 value);
|
||||
|
||||
// optional bytes scriptFilename = 10;
|
||||
inline bool has_scriptfilename() const;
|
||||
inline void clear_scriptfilename();
|
||||
static const int kScriptFilenameFieldNumber = 10;
|
||||
inline const ::std::string& scriptfilename() const;
|
||||
inline void set_scriptfilename(const ::std::string& value);
|
||||
inline void set_scriptfilename(const char* value);
|
||||
inline void set_scriptfilename(const void* value, size_t size);
|
||||
inline ::std::string* mutable_scriptfilename();
|
||||
inline ::std::string* release_scriptfilename();
|
||||
inline void set_allocated_scriptfilename(::std::string* scriptfilename);
|
||||
|
||||
// optional uint64 scriptFilenameRef = 11;
|
||||
inline bool has_scriptfilenameref() const;
|
||||
inline void clear_scriptfilenameref();
|
||||
static const int kScriptFilenameRefFieldNumber = 11;
|
||||
inline ::google::protobuf::uint64 scriptfilenameref() const;
|
||||
inline void set_scriptfilenameref(::google::protobuf::uint64 value);
|
||||
|
||||
inline TypeNameOrRefCase TypeNameOrRef_case() const;
|
||||
inline JSObjectClassNameOrRefCase JSObjectClassNameOrRef_case() const;
|
||||
inline ScriptFilenameOrRefCase ScriptFilenameOrRef_case() const;
|
||||
// @@protoc_insertion_point(class_scope:mozilla.devtools.protobuf.Node)
|
||||
private:
|
||||
inline void set_has_id();
|
||||
@ -594,6 +620,8 @@ class Node : public ::google::protobuf::Message {
|
||||
inline void set_has_jsobjectclassnameref();
|
||||
inline void set_has_coarsetype();
|
||||
inline void clear_has_coarsetype();
|
||||
inline void set_has_scriptfilename();
|
||||
inline void set_has_scriptfilenameref();
|
||||
|
||||
inline bool has_TypeNameOrRef();
|
||||
void clear_TypeNameOrRef();
|
||||
@ -603,6 +631,10 @@ class Node : public ::google::protobuf::Message {
|
||||
void clear_JSObjectClassNameOrRef();
|
||||
inline void clear_has_JSObjectClassNameOrRef();
|
||||
|
||||
inline bool has_ScriptFilenameOrRef();
|
||||
void clear_ScriptFilenameOrRef();
|
||||
inline void clear_has_ScriptFilenameOrRef();
|
||||
|
||||
::google::protobuf::UnknownFieldSet _unknown_fields_;
|
||||
|
||||
::google::protobuf::uint32 _has_bits_[1];
|
||||
@ -620,7 +652,11 @@ class Node : public ::google::protobuf::Message {
|
||||
::std::string* jsobjectclassname_;
|
||||
::google::protobuf::uint64 jsobjectclassnameref_;
|
||||
} JSObjectClassNameOrRef_;
|
||||
::google::protobuf::uint32 _oneof_case_[2];
|
||||
union ScriptFilenameOrRefUnion {
|
||||
::std::string* scriptfilename_;
|
||||
::google::protobuf::uint64 scriptfilenameref_;
|
||||
} ScriptFilenameOrRef_;
|
||||
::google::protobuf::uint32 _oneof_case_[3];
|
||||
|
||||
friend void protobuf_AddDesc_CoreDump_2eproto();
|
||||
friend void protobuf_AssignDesc_CoreDump_2eproto();
|
||||
@ -1578,6 +1614,103 @@ inline void Node::set_coarsetype(::google::protobuf::uint32 value) {
|
||||
// @@protoc_insertion_point(field_set:mozilla.devtools.protobuf.Node.coarseType)
|
||||
}
|
||||
|
||||
// optional bytes scriptFilename = 10;
|
||||
inline bool Node::has_scriptfilename() const {
|
||||
return ScriptFilenameOrRef_case() == kScriptFilename;
|
||||
}
|
||||
inline void Node::set_has_scriptfilename() {
|
||||
_oneof_case_[2] = kScriptFilename;
|
||||
}
|
||||
inline void Node::clear_scriptfilename() {
|
||||
if (has_scriptfilename()) {
|
||||
delete ScriptFilenameOrRef_.scriptfilename_;
|
||||
clear_has_ScriptFilenameOrRef();
|
||||
}
|
||||
}
|
||||
inline const ::std::string& Node::scriptfilename() const {
|
||||
if (has_scriptfilename()) {
|
||||
return *ScriptFilenameOrRef_.scriptfilename_;
|
||||
}
|
||||
return ::google::protobuf::internal::GetEmptyStringAlreadyInited();
|
||||
}
|
||||
inline void Node::set_scriptfilename(const ::std::string& value) {
|
||||
if (!has_scriptfilename()) {
|
||||
clear_ScriptFilenameOrRef();
|
||||
set_has_scriptfilename();
|
||||
ScriptFilenameOrRef_.scriptfilename_ = new ::std::string;
|
||||
}
|
||||
ScriptFilenameOrRef_.scriptfilename_->assign(value);
|
||||
}
|
||||
inline void Node::set_scriptfilename(const char* value) {
|
||||
if (!has_scriptfilename()) {
|
||||
clear_ScriptFilenameOrRef();
|
||||
set_has_scriptfilename();
|
||||
ScriptFilenameOrRef_.scriptfilename_ = new ::std::string;
|
||||
}
|
||||
ScriptFilenameOrRef_.scriptfilename_->assign(value);
|
||||
}
|
||||
inline void Node::set_scriptfilename(const void* value, size_t size) {
|
||||
if (!has_scriptfilename()) {
|
||||
clear_ScriptFilenameOrRef();
|
||||
set_has_scriptfilename();
|
||||
ScriptFilenameOrRef_.scriptfilename_ = new ::std::string;
|
||||
}
|
||||
ScriptFilenameOrRef_.scriptfilename_->assign(
|
||||
reinterpret_cast<const char*>(value), size);
|
||||
}
|
||||
inline ::std::string* Node::mutable_scriptfilename() {
|
||||
if (!has_scriptfilename()) {
|
||||
clear_ScriptFilenameOrRef();
|
||||
set_has_scriptfilename();
|
||||
ScriptFilenameOrRef_.scriptfilename_ = new ::std::string;
|
||||
}
|
||||
return ScriptFilenameOrRef_.scriptfilename_;
|
||||
}
|
||||
inline ::std::string* Node::release_scriptfilename() {
|
||||
if (has_scriptfilename()) {
|
||||
clear_has_ScriptFilenameOrRef();
|
||||
::std::string* temp = ScriptFilenameOrRef_.scriptfilename_;
|
||||
ScriptFilenameOrRef_.scriptfilename_ = NULL;
|
||||
return temp;
|
||||
} else {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
inline void Node::set_allocated_scriptfilename(::std::string* scriptfilename) {
|
||||
clear_ScriptFilenameOrRef();
|
||||
if (scriptfilename) {
|
||||
set_has_scriptfilename();
|
||||
ScriptFilenameOrRef_.scriptfilename_ = scriptfilename;
|
||||
}
|
||||
}
|
||||
|
||||
// optional uint64 scriptFilenameRef = 11;
|
||||
inline bool Node::has_scriptfilenameref() const {
|
||||
return ScriptFilenameOrRef_case() == kScriptFilenameRef;
|
||||
}
|
||||
inline void Node::set_has_scriptfilenameref() {
|
||||
_oneof_case_[2] = kScriptFilenameRef;
|
||||
}
|
||||
inline void Node::clear_scriptfilenameref() {
|
||||
if (has_scriptfilenameref()) {
|
||||
ScriptFilenameOrRef_.scriptfilenameref_ = GOOGLE_ULONGLONG(0);
|
||||
clear_has_ScriptFilenameOrRef();
|
||||
}
|
||||
}
|
||||
inline ::google::protobuf::uint64 Node::scriptfilenameref() const {
|
||||
if (has_scriptfilenameref()) {
|
||||
return ScriptFilenameOrRef_.scriptfilenameref_;
|
||||
}
|
||||
return GOOGLE_ULONGLONG(0);
|
||||
}
|
||||
inline void Node::set_scriptfilenameref(::google::protobuf::uint64 value) {
|
||||
if (!has_scriptfilenameref()) {
|
||||
clear_ScriptFilenameOrRef();
|
||||
set_has_scriptfilenameref();
|
||||
}
|
||||
ScriptFilenameOrRef_.scriptfilenameref_ = value;
|
||||
}
|
||||
|
||||
inline bool Node::has_TypeNameOrRef() {
|
||||
return TypeNameOrRef_case() != TYPENAMEORREF_NOT_SET;
|
||||
}
|
||||
@ -1590,12 +1723,21 @@ inline bool Node::has_JSObjectClassNameOrRef() {
|
||||
inline void Node::clear_has_JSObjectClassNameOrRef() {
|
||||
_oneof_case_[1] = JSOBJECTCLASSNAMEORREF_NOT_SET;
|
||||
}
|
||||
inline bool Node::has_ScriptFilenameOrRef() {
|
||||
return ScriptFilenameOrRef_case() != SCRIPTFILENAMEORREF_NOT_SET;
|
||||
}
|
||||
inline void Node::clear_has_ScriptFilenameOrRef() {
|
||||
_oneof_case_[2] = SCRIPTFILENAMEORREF_NOT_SET;
|
||||
}
|
||||
inline Node::TypeNameOrRefCase Node::TypeNameOrRef_case() const {
|
||||
return Node::TypeNameOrRefCase(_oneof_case_[0]);
|
||||
}
|
||||
inline Node::JSObjectClassNameOrRefCase Node::JSObjectClassNameOrRef_case() const {
|
||||
return Node::JSObjectClassNameOrRefCase(_oneof_case_[1]);
|
||||
}
|
||||
inline Node::ScriptFilenameOrRefCase Node::ScriptFilenameOrRef_case() const {
|
||||
return Node::ScriptFilenameOrRefCase(_oneof_case_[2]);
|
||||
}
|
||||
// -------------------------------------------------------------------
|
||||
|
||||
// Edge
|
||||
|
@ -123,6 +123,12 @@ message Node {
|
||||
|
||||
// JS::ubi::CoarseType. Defaults to Other.
|
||||
optional uint32 coarseType = 9 [default = 0];
|
||||
|
||||
// De-duplicated one-byte string.
|
||||
oneof ScriptFilenameOrRef {
|
||||
bytes scriptFilename = 10;
|
||||
uint64 scriptFilenameRef = 11;
|
||||
}
|
||||
}
|
||||
|
||||
// A serialized edge from the heap graph.
|
||||
|
@ -67,6 +67,8 @@ struct DeserializedNode {
|
||||
Maybe<StackFrameId> allocationStack;
|
||||
// A borrowed reference to a string owned by this node's owning HeapSnapshot.
|
||||
const char* jsObjectClassName;
|
||||
// A borrowed reference to a string owned by this node's owning HeapSnapshot.
|
||||
const char* scriptFilename;
|
||||
// A weak pointer to this node's owning `HeapSnapshot`. Safe without
|
||||
// AddRef'ing because this node's lifetime is equal to that of its owner.
|
||||
HeapSnapshot* owner;
|
||||
@ -78,6 +80,7 @@ struct DeserializedNode {
|
||||
EdgeVector&& edges,
|
||||
Maybe<StackFrameId> allocationStack,
|
||||
const char* className,
|
||||
const char* filename,
|
||||
HeapSnapshot& owner)
|
||||
: id(id)
|
||||
, coarseType(coarseType)
|
||||
@ -86,6 +89,7 @@ struct DeserializedNode {
|
||||
, edges(Move(edges))
|
||||
, allocationStack(allocationStack)
|
||||
, jsObjectClassName(className)
|
||||
, scriptFilename(filename)
|
||||
, owner(&owner)
|
||||
{ }
|
||||
virtual ~DeserializedNode() { }
|
||||
@ -98,6 +102,7 @@ struct DeserializedNode {
|
||||
, edges(Move(rhs.edges))
|
||||
, allocationStack(rhs.allocationStack)
|
||||
, jsObjectClassName(rhs.jsObjectClassName)
|
||||
, scriptFilename(rhs.scriptFilename)
|
||||
, owner(rhs.owner)
|
||||
{ }
|
||||
|
||||
@ -125,6 +130,7 @@ protected:
|
||||
, edges()
|
||||
, allocationStack(Nothing())
|
||||
, jsObjectClassName(nullptr)
|
||||
, scriptFilename(nullptr)
|
||||
, owner(nullptr)
|
||||
{ }
|
||||
|
||||
@ -260,6 +266,7 @@ public:
|
||||
const char16_t* typeName() const override;
|
||||
Node::Size size(mozilla::MallocSizeOf mallocSizeof) const override;
|
||||
const char* jsObjectClassName() const override { return get().jsObjectClassName; }
|
||||
const char* scriptFilename() const final { return get().scriptFilename; }
|
||||
|
||||
bool hasAllocationStack() const override { return get().allocationStack.isSome(); }
|
||||
StackFrame allocationStack() const override;
|
||||
|
@ -276,10 +276,19 @@ HeapSnapshot::saveNode(const protobuf::Node& node)
|
||||
return false;
|
||||
}
|
||||
|
||||
const char* scriptFilename = nullptr;
|
||||
if (node.ScriptFilenameOrRef_case() != protobuf::Node::SCRIPTFILENAMEORREF_NOT_SET) {
|
||||
Maybe<StringOrRef> scriptFilenameOrRef = GET_STRING_OR_REF(node, scriptfilename);
|
||||
scriptFilename = getOrInternString<char>(internedOneByteStrings, scriptFilenameOrRef);
|
||||
if (NS_WARN_IF(!scriptFilename))
|
||||
return false;
|
||||
}
|
||||
|
||||
if (NS_WARN_IF(!nodes.putNew(id, DeserializedNode(id, coarseType, typeName,
|
||||
size, Move(edges),
|
||||
allocationStack,
|
||||
jsObjectClassName, *this))))
|
||||
jsObjectClassName,
|
||||
scriptFilename, *this))))
|
||||
{
|
||||
return false;
|
||||
};
|
||||
@ -1079,6 +1088,15 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
if (auto scriptFilename = ubiNode.scriptFilename()) {
|
||||
if (NS_WARN_IF(!attachOneByteString(scriptFilename,
|
||||
[&] (std::string* name) { protobufNode.set_allocated_scriptfilename(name); },
|
||||
[&] (uint64_t ref) { protobufNode.set_scriptfilenameref(ref); })))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return writeMessage(protobufNode);
|
||||
}
|
||||
};
|
||||
|
@ -39,12 +39,14 @@ size_t fakeMallocSizeOf(const void*) {
|
||||
DEF_TEST(DeserializedNodeUbiNodes, {
|
||||
const char16_t* typeName = MOZ_UTF16("TestTypeName");
|
||||
const char* className = "MyObjectClassName";
|
||||
const char* filename = "my-cool-filename.js";
|
||||
|
||||
NodeId id = uint64_t(1) << 33;
|
||||
uint64_t size = uint64_t(1) << 60;
|
||||
MockDeserializedNode mocked(id, typeName, size);
|
||||
mocked.coarseType = JS::ubi::CoarseType::Script;
|
||||
mocked.jsObjectClassName = className;
|
||||
mocked.scriptFilename = filename;
|
||||
|
||||
DeserializedNode& deserialized = mocked;
|
||||
JS::ubi::Node ubi(&deserialized);
|
||||
@ -57,6 +59,7 @@ DEF_TEST(DeserializedNodeUbiNodes, {
|
||||
EXPECT_EQ(id, ubi.identifier());
|
||||
EXPECT_FALSE(ubi.isLive());
|
||||
EXPECT_EQ(ubi.jsObjectClassName(), className);
|
||||
EXPECT_EQ(ubi.scriptFilename(), filename);
|
||||
|
||||
// Test the ubi::Node's edges.
|
||||
|
||||
|
@ -0,0 +1,133 @@
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
/**
|
||||
* Test inverting CensusTreeNode with a non-allocation stack breakdown.
|
||||
*/
|
||||
|
||||
function run_test() {
|
||||
const BREAKDOWN = {
|
||||
by: "filename",
|
||||
then: {
|
||||
by: "internalType",
|
||||
then: { by: "count", count: true, bytes: true }
|
||||
},
|
||||
noFilename: {
|
||||
by: "internalType",
|
||||
then: { by: "count", count: true, bytes: true }
|
||||
},
|
||||
};
|
||||
|
||||
const REPORT = {
|
||||
"http://example.com/app.js": {
|
||||
JSScript: { count: 10, bytes: 100 }
|
||||
},
|
||||
"http://example.com/ads.js": {
|
||||
"js::LazyScript": { count: 20, bytes: 200 }
|
||||
},
|
||||
"http://example.com/trackers.js": {
|
||||
JSScript: { count: 30, bytes: 300 }
|
||||
},
|
||||
noFilename: {
|
||||
"js::jit::JitCode": { count: 40, bytes: 400 }
|
||||
}
|
||||
};
|
||||
|
||||
const EXPECTED = {
|
||||
name: null,
|
||||
bytes: 0,
|
||||
totalBytes: 1000,
|
||||
count: 0,
|
||||
totalCount: 100,
|
||||
children: [
|
||||
{
|
||||
name: "noFilename",
|
||||
bytes: 0,
|
||||
totalBytes: 400,
|
||||
count: 0,
|
||||
totalCount: 40,
|
||||
children: [
|
||||
{
|
||||
name: "js::jit::JitCode",
|
||||
bytes: 400,
|
||||
totalBytes: 400,
|
||||
count: 40,
|
||||
totalCount: 40,
|
||||
children: undefined,
|
||||
id: 9,
|
||||
parent: 8
|
||||
}
|
||||
],
|
||||
id: 8,
|
||||
parent: 1
|
||||
},
|
||||
{
|
||||
name: "http://example.com/trackers.js",
|
||||
bytes: 0,
|
||||
totalBytes: 300,
|
||||
count: 0,
|
||||
totalCount: 30,
|
||||
children: [
|
||||
{
|
||||
name: "JSScript",
|
||||
bytes: 300,
|
||||
totalBytes: 300,
|
||||
count: 30,
|
||||
totalCount: 30,
|
||||
children: undefined,
|
||||
id: 7,
|
||||
parent: 6
|
||||
}
|
||||
],
|
||||
id: 6,
|
||||
parent: 1
|
||||
},
|
||||
{
|
||||
name: "http://example.com/ads.js",
|
||||
bytes: 0,
|
||||
totalBytes: 200,
|
||||
count: 0,
|
||||
totalCount: 20,
|
||||
children: [
|
||||
{
|
||||
name: "js::LazyScript",
|
||||
bytes: 200,
|
||||
totalBytes: 200,
|
||||
count: 20,
|
||||
totalCount: 20,
|
||||
children: undefined,
|
||||
id: 5,
|
||||
parent: 4
|
||||
}
|
||||
],
|
||||
id: 4,
|
||||
parent: 1
|
||||
},
|
||||
{
|
||||
name: "http://example.com/app.js",
|
||||
bytes: 0,
|
||||
totalBytes: 100,
|
||||
count: 0,
|
||||
totalCount: 10,
|
||||
children: [
|
||||
{
|
||||
name: "JSScript",
|
||||
bytes: 100,
|
||||
totalBytes: 100,
|
||||
count: 10,
|
||||
totalCount: 10,
|
||||
children: undefined,
|
||||
id: 3,
|
||||
parent: 2
|
||||
}
|
||||
],
|
||||
id: 2,
|
||||
parent: 1
|
||||
}
|
||||
],
|
||||
id: 1,
|
||||
parent: undefined,
|
||||
};
|
||||
|
||||
compareCensusViewData(BREAKDOWN, REPORT, EXPECTED);
|
||||
}
|
@ -26,6 +26,7 @@ support-files =
|
||||
[test_census-tree-node-05.js]
|
||||
[test_census-tree-node-06.js]
|
||||
[test_census-tree-node-07.js]
|
||||
[test_census-tree-node-08.js]
|
||||
[test_HeapAnalyses_getCreationTime_01.js]
|
||||
[test_HeapAnalyses_readHeapSnapshot_01.js]
|
||||
[test_HeapAnalyses_takeCensusDiff_01.js]
|
||||
|
@ -1,10 +1,27 @@
|
||||
/* Make sure that netError won't allow HTML injection through badcert parameters. See bug 441169. */
|
||||
var newBrowser
|
||||
|
||||
// An edited version of the standard neterror url which attempts to
|
||||
// insert a <span id="test_span"> tag into the text. We will navigate to this page
|
||||
// and ensure that the span tag is not parsed as HTML.
|
||||
var chromeURL = "about:neterror?e=nssBadCert&u=https%3A//test.kuix.de/&c=UTF-8&d=This%20sentence%20should%20not%20be%20parsed%20to%20include%20a%20%3Cspan%20id=%22test_span%22%3Enamed%3C/span%3E%20span%20tag.%0A%0AThe%20certificate%20is%20only%20valid%20for%20%3Ca%20id=%22cert_domain_link%22%20title=%22kuix.de%22%3Ekuix.de%3C/a%3E%0A%0A(Error%20code%3A%20ssl_error_bad_cert_domain)";
|
||||
function task() {
|
||||
let resolve;
|
||||
let promise = new Promise(r => { resolve = r; });
|
||||
|
||||
addEventListener("DOMContentLoaded", checkPage, false);
|
||||
|
||||
function checkPage(event) {
|
||||
if (event.target != content.document) {
|
||||
return;
|
||||
}
|
||||
removeEventListener("DOMContentLoaded", checkPage, false);
|
||||
|
||||
is(content.document.getElementById("test_span"), null, "Error message should not be parsed as HTML, and hence shouldn't include the 'test_span' element.");
|
||||
resolve();
|
||||
}
|
||||
|
||||
var chromeURL = "about:neterror?e=nssBadCert&u=https%3A//test.kuix.de/&c=UTF-8&d=This%20sentence%20should%20not%20be%20parsed%20to%20include%20a%20%3Cspan%20id=%22test_span%22%3Enamed%3C/span%3E%20span%20tag.%0A%0AThe%20certificate%20is%20only%20valid%20for%20%3Ca%20id=%22cert_domain_link%22%20title=%22kuix.de%22%3Ekuix.de%3C/a%3E%0A%0A(Error%20code%3A%20ssl_error_bad_cert_domain)";
|
||||
content.location = chromeURL;
|
||||
|
||||
return promise;
|
||||
}
|
||||
|
||||
function test() {
|
||||
waitForExplicitFinish();
|
||||
@ -13,19 +30,8 @@ function test() {
|
||||
gBrowser.selectedTab = newTab;
|
||||
newBrowser = gBrowser.getBrowserForTab(newTab);
|
||||
|
||||
window.addEventListener("DOMContentLoaded", checkPage, false);
|
||||
newBrowser.contentWindow.location = chromeURL;
|
||||
}
|
||||
|
||||
function checkPage(event) {
|
||||
if (event.target != gBrowser.selectedBrowser.contentDocument) {
|
||||
return;
|
||||
}
|
||||
|
||||
window.removeEventListener("DOMContentLoaded", checkPage, false);
|
||||
|
||||
is(newBrowser.contentDocument.getElementById("test_span"), null, "Error message should not be parsed as HTML, and hence shouldn't include the 'test_span' element.");
|
||||
|
||||
ContentTask.spawn(newBrowser, null, task).then(() => {
|
||||
gBrowser.removeCurrentTab();
|
||||
finish();
|
||||
});
|
||||
}
|
||||
|
@ -14,9 +14,7 @@ function test() {
|
||||
let tab = gBrowser.addTab('http://example.com');
|
||||
let tabBrowser = tab.linkedBrowser;
|
||||
|
||||
tabBrowser.addEventListener('load', function(aEvent) {
|
||||
tabBrowser.removeEventListener('load', arguments.callee, true);
|
||||
|
||||
BrowserTestUtils.browserLoaded(tab.linkedBrowser).then(() => {
|
||||
let cw = tabBrowser.contentWindow;
|
||||
let oldTitle = cw.document.title;
|
||||
ok(oldTitle, 'Content window should initially have a title.');
|
||||
@ -31,5 +29,5 @@ function test() {
|
||||
|
||||
gBrowser.removeTab(tab);
|
||||
finish();
|
||||
}, true);
|
||||
});
|
||||
}
|
||||
|
@ -10,6 +10,7 @@ SpecialPowers.pushPrefEnv({"set": [["dom.require_user_interaction_for_beforeunlo
|
||||
|
||||
var loadExpected = TEST_PAGE;
|
||||
var testTab;
|
||||
var testsLength;
|
||||
|
||||
var loadStarted = false;
|
||||
var tabStateListener = {
|
||||
@ -40,6 +41,10 @@ function onTabLoaded(event) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!testsLength) {
|
||||
testsLength = testTab.linkedBrowser.contentWindow.wrappedJSObject.testFns.length;
|
||||
}
|
||||
|
||||
is(loadedPage, loadExpected, "Loaded the expected page");
|
||||
if (contentWindow) {
|
||||
is(contentWindow.document, event.target, "Same doc");
|
||||
@ -102,47 +107,9 @@ function onTabModalDialogLoaded(node) {
|
||||
// Listen for the dialog being created
|
||||
Services.obs.addObserver(onTabModalDialogLoaded, "tabmodal-dialog-loaded", false);
|
||||
|
||||
var testFns = [
|
||||
function(e) {
|
||||
e.target.location.href = 'otherpage-href-set.html';
|
||||
return "stop";
|
||||
},
|
||||
function(e) {
|
||||
e.target.location.reload();
|
||||
return "stop";
|
||||
},
|
||||
function(e) {
|
||||
e.target.location.replace('otherpage-location-replaced.html');
|
||||
return "stop";
|
||||
},
|
||||
function(e) {
|
||||
var link = e.target.createElement('a');
|
||||
link.href = "otherpage.html";
|
||||
e.target.body.appendChild(link);
|
||||
link.click();
|
||||
return "stop";
|
||||
},
|
||||
function(e) {
|
||||
var link = e.target.createElement('a');
|
||||
link.href = "otherpage.html";
|
||||
link.setAttribute("target", "_blank");
|
||||
e.target.body.appendChild(link);
|
||||
link.click();
|
||||
return "stop";
|
||||
},
|
||||
function(e) {
|
||||
var link = e.target.createElement('a');
|
||||
link.href = e.target.location.href;
|
||||
e.target.body.appendChild(link);
|
||||
link.setAttribute("target", "somearbitrarywindow");
|
||||
link.click();
|
||||
return "stop";
|
||||
},
|
||||
];
|
||||
|
||||
function runNextTest() {
|
||||
currentTest++;
|
||||
if (currentTest >= testFns.length) {
|
||||
if (currentTest >= testsLength) {
|
||||
if (!stayingOnPage) {
|
||||
finish();
|
||||
return;
|
||||
@ -171,10 +138,10 @@ function runCurrentTest() {
|
||||
contentWindow.dialogWasInvoked = false;
|
||||
originalLocation = contentWindow.location.href;
|
||||
// And run this test:
|
||||
info("Running test with onbeforeunload " + testFns[currentTest].toSource());
|
||||
contentWindow.onbeforeunload = testFns[currentTest];
|
||||
info("Running test with onbeforeunload " + contentWindow.wrappedJSObject.testFns[currentTest].toSource());
|
||||
contentWindow.onbeforeunload = contentWindow.wrappedJSObject.testFns[currentTest];
|
||||
loadStarted = false;
|
||||
contentWindow.location.href = TARGETED_PAGE;
|
||||
testTab.linkedBrowser.loadURI(TARGETED_PAGE);
|
||||
}
|
||||
|
||||
var onAfterPageLoad = runNextTest;
|
||||
|
@ -7,4 +7,44 @@
|
||||
<body>
|
||||
Waiting for onbeforeunload to hit...
|
||||
</body>
|
||||
|
||||
<script>
|
||||
var testFns = [
|
||||
function(e) {
|
||||
e.target.location.href = 'otherpage-href-set.html';
|
||||
return "stop";
|
||||
},
|
||||
function(e) {
|
||||
e.target.location.reload();
|
||||
return "stop";
|
||||
},
|
||||
function(e) {
|
||||
e.target.location.replace('otherpage-location-replaced.html');
|
||||
return "stop";
|
||||
},
|
||||
function(e) {
|
||||
var link = e.target.createElement('a');
|
||||
link.href = "otherpage.html";
|
||||
e.target.body.appendChild(link);
|
||||
link.click();
|
||||
return "stop";
|
||||
},
|
||||
function(e) {
|
||||
var link = e.target.createElement('a');
|
||||
link.href = "otherpage.html";
|
||||
link.setAttribute("target", "_blank");
|
||||
e.target.body.appendChild(link);
|
||||
link.click();
|
||||
return "stop";
|
||||
},
|
||||
function(e) {
|
||||
var link = e.target.createElement('a');
|
||||
link.href = e.target.location.href;
|
||||
e.target.body.appendChild(link);
|
||||
link.setAttribute("target", "somearbitrarywindow");
|
||||
link.click();
|
||||
return "stop";
|
||||
},
|
||||
];
|
||||
</script>
|
||||
</html>
|
||||
|
@ -31,8 +31,8 @@ function makeTimelineTest(frameScriptName, url) {
|
||||
info(message.data.message);
|
||||
});
|
||||
mm.addMessageListener("browser:test:finish", function(ignore) {
|
||||
finish();
|
||||
gBrowser.removeCurrentTab();
|
||||
finish();
|
||||
});
|
||||
});
|
||||
}
|
||||
|
@ -186,7 +186,8 @@ function runNextTest()
|
||||
gCurrentTest = gTests[gNextTest++];
|
||||
gNumPokes = 0;
|
||||
|
||||
SpecialPowers.pushPrefEnv({"set": [["network.jar.open-unsafe-types", gCurrentTest['pref']]]}, function() {
|
||||
SpecialPowers.pushPrefEnv({"set": [["network.jar.block-remote-files", false],
|
||||
["network.jar.open-unsafe-types", gCurrentTest['pref']]]}, function() {
|
||||
|
||||
// Create a new frame each time, so our restictions on loads in a
|
||||
// jar:-loaded iframe don't interfere with the test.
|
||||
|
99
dom/animation/ComputedTimingFunction.cpp
Normal file
99
dom/animation/ComputedTimingFunction.cpp
Normal file
@ -0,0 +1,99 @@
|
||||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||
* You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "ComputedTimingFunction.h"
|
||||
#include "nsStyleUtil.h"
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
void
|
||||
ComputedTimingFunction::Init(const nsTimingFunction &aFunction)
|
||||
{
|
||||
mType = aFunction.mType;
|
||||
if (nsTimingFunction::IsSplineType(mType)) {
|
||||
mTimingFunction.Init(aFunction.mFunc.mX1, aFunction.mFunc.mY1,
|
||||
aFunction.mFunc.mX2, aFunction.mFunc.mY2);
|
||||
} else {
|
||||
mSteps = aFunction.mSteps;
|
||||
mStepSyntax = aFunction.mStepSyntax;
|
||||
}
|
||||
}
|
||||
|
||||
static inline double
|
||||
StepEnd(uint32_t aSteps, double aPortion)
|
||||
{
|
||||
MOZ_ASSERT(0.0 <= aPortion && aPortion <= 1.0, "out of range");
|
||||
uint32_t step = uint32_t(aPortion * aSteps); // floor
|
||||
return double(step) / double(aSteps);
|
||||
}
|
||||
|
||||
double
|
||||
ComputedTimingFunction::GetValue(double aPortion) const
|
||||
{
|
||||
if (HasSpline()) {
|
||||
return mTimingFunction.GetSplineValue(aPortion);
|
||||
}
|
||||
if (mType == nsTimingFunction::Type::StepStart) {
|
||||
// There are diagrams in the spec that seem to suggest this check
|
||||
// and the bounds point should not be symmetric with StepEnd, but
|
||||
// should actually step up at rather than immediately after the
|
||||
// fraction points. However, we rely on rounding negative values
|
||||
// up to zero, so we can't do that. And it's not clear the spec
|
||||
// really meant it.
|
||||
return 1.0 - StepEnd(mSteps, 1.0 - aPortion);
|
||||
}
|
||||
MOZ_ASSERT(mType == nsTimingFunction::Type::StepEnd, "bad type");
|
||||
return StepEnd(mSteps, aPortion);
|
||||
}
|
||||
|
||||
int32_t
|
||||
ComputedTimingFunction::Compare(const ComputedTimingFunction& aRhs) const
|
||||
{
|
||||
if (mType != aRhs.mType) {
|
||||
return int32_t(mType) - int32_t(aRhs.mType);
|
||||
}
|
||||
|
||||
if (mType == nsTimingFunction::Type::CubicBezier) {
|
||||
int32_t order = mTimingFunction.Compare(aRhs.mTimingFunction);
|
||||
if (order != 0) {
|
||||
return order;
|
||||
}
|
||||
} else if (mType == nsTimingFunction::Type::StepStart ||
|
||||
mType == nsTimingFunction::Type::StepEnd) {
|
||||
if (mSteps != aRhs.mSteps) {
|
||||
return int32_t(mSteps) - int32_t(aRhs.mSteps);
|
||||
}
|
||||
if (mStepSyntax != aRhs.mStepSyntax) {
|
||||
return int32_t(mStepSyntax) - int32_t(aRhs.mStepSyntax);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
ComputedTimingFunction::AppendToString(nsAString& aResult) const
|
||||
{
|
||||
switch (mType) {
|
||||
case nsTimingFunction::Type::CubicBezier:
|
||||
nsStyleUtil::AppendCubicBezierTimingFunction(mTimingFunction.X1(),
|
||||
mTimingFunction.Y1(),
|
||||
mTimingFunction.X2(),
|
||||
mTimingFunction.Y2(),
|
||||
aResult);
|
||||
break;
|
||||
case nsTimingFunction::Type::StepStart:
|
||||
case nsTimingFunction::Type::StepEnd:
|
||||
nsStyleUtil::AppendStepsTimingFunction(mType, mSteps, mStepSyntax,
|
||||
aResult);
|
||||
break;
|
||||
default:
|
||||
nsStyleUtil::AppendCubicBezierKeywordTimingFunction(mType, aResult);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace mozilla
|
53
dom/animation/ComputedTimingFunction.h
Normal file
53
dom/animation/ComputedTimingFunction.h
Normal file
@ -0,0 +1,53 @@
|
||||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||
* You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifndef mozilla_ComputedTimingFunction_h
|
||||
#define mozilla_ComputedTimingFunction_h
|
||||
|
||||
#include "nsSMILKeySpline.h" // nsSMILKeySpline
|
||||
#include "nsStyleStruct.h" // nsTimingFunction
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
class ComputedTimingFunction
|
||||
{
|
||||
public:
|
||||
void Init(const nsTimingFunction &aFunction);
|
||||
double GetValue(double aPortion) const;
|
||||
const nsSMILKeySpline* GetFunction() const
|
||||
{
|
||||
NS_ASSERTION(HasSpline(), "Type mismatch");
|
||||
return &mTimingFunction;
|
||||
}
|
||||
nsTimingFunction::Type GetType() const { return mType; }
|
||||
bool HasSpline() const { return nsTimingFunction::IsSplineType(mType); }
|
||||
uint32_t GetSteps() const { return mSteps; }
|
||||
nsTimingFunction::StepSyntax GetStepSyntax() const { return mStepSyntax; }
|
||||
bool operator==(const ComputedTimingFunction& aOther) const
|
||||
{
|
||||
return mType == aOther.mType &&
|
||||
(HasSpline() ?
|
||||
mTimingFunction == aOther.mTimingFunction :
|
||||
(mSteps == aOther.mSteps &&
|
||||
mStepSyntax == aOther.mStepSyntax));
|
||||
}
|
||||
bool operator!=(const ComputedTimingFunction& aOther) const
|
||||
{
|
||||
return !(*this == aOther);
|
||||
}
|
||||
int32_t Compare(const ComputedTimingFunction& aRhs) const;
|
||||
void AppendToString(nsAString& aResult) const;
|
||||
|
||||
private:
|
||||
nsTimingFunction::Type mType;
|
||||
nsSMILKeySpline mTimingFunction;
|
||||
uint32_t mSteps;
|
||||
nsTimingFunction::StepSyntax mStepSyntax;
|
||||
};
|
||||
|
||||
} // namespace mozilla
|
||||
|
||||
#endif // mozilla_dom_AnimationEffectReadOnly_h
|
@ -86,94 +86,6 @@ GetComputedTimingDictionary(const ComputedTiming& aComputedTiming,
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
ComputedTimingFunction::Init(const nsTimingFunction &aFunction)
|
||||
{
|
||||
mType = aFunction.mType;
|
||||
if (nsTimingFunction::IsSplineType(mType)) {
|
||||
mTimingFunction.Init(aFunction.mFunc.mX1, aFunction.mFunc.mY1,
|
||||
aFunction.mFunc.mX2, aFunction.mFunc.mY2);
|
||||
} else {
|
||||
mSteps = aFunction.mSteps;
|
||||
mStepSyntax = aFunction.mStepSyntax;
|
||||
}
|
||||
}
|
||||
|
||||
static inline double
|
||||
StepEnd(uint32_t aSteps, double aPortion)
|
||||
{
|
||||
MOZ_ASSERT(0.0 <= aPortion && aPortion <= 1.0, "out of range");
|
||||
uint32_t step = uint32_t(aPortion * aSteps); // floor
|
||||
return double(step) / double(aSteps);
|
||||
}
|
||||
|
||||
double
|
||||
ComputedTimingFunction::GetValue(double aPortion) const
|
||||
{
|
||||
if (HasSpline()) {
|
||||
return mTimingFunction.GetSplineValue(aPortion);
|
||||
}
|
||||
if (mType == nsTimingFunction::Type::StepStart) {
|
||||
// There are diagrams in the spec that seem to suggest this check
|
||||
// and the bounds point should not be symmetric with StepEnd, but
|
||||
// should actually step up at rather than immediately after the
|
||||
// fraction points. However, we rely on rounding negative values
|
||||
// up to zero, so we can't do that. And it's not clear the spec
|
||||
// really meant it.
|
||||
return 1.0 - StepEnd(mSteps, 1.0 - aPortion);
|
||||
}
|
||||
MOZ_ASSERT(mType == nsTimingFunction::Type::StepEnd, "bad type");
|
||||
return StepEnd(mSteps, aPortion);
|
||||
}
|
||||
|
||||
int32_t
|
||||
ComputedTimingFunction::Compare(const ComputedTimingFunction& aRhs) const
|
||||
{
|
||||
if (mType != aRhs.mType) {
|
||||
return int32_t(mType) - int32_t(aRhs.mType);
|
||||
}
|
||||
|
||||
if (mType == nsTimingFunction::Type::CubicBezier) {
|
||||
int32_t order = mTimingFunction.Compare(aRhs.mTimingFunction);
|
||||
if (order != 0) {
|
||||
return order;
|
||||
}
|
||||
} else if (mType == nsTimingFunction::Type::StepStart ||
|
||||
mType == nsTimingFunction::Type::StepEnd) {
|
||||
if (mSteps != aRhs.mSteps) {
|
||||
return int32_t(mSteps) - int32_t(aRhs.mSteps);
|
||||
}
|
||||
if (mStepSyntax != aRhs.mStepSyntax) {
|
||||
return int32_t(mStepSyntax) - int32_t(aRhs.mStepSyntax);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
ComputedTimingFunction::AppendToString(nsAString& aResult) const
|
||||
{
|
||||
switch (mType) {
|
||||
case nsTimingFunction::Type::CubicBezier:
|
||||
nsStyleUtil::AppendCubicBezierTimingFunction(mTimingFunction.X1(),
|
||||
mTimingFunction.Y1(),
|
||||
mTimingFunction.X2(),
|
||||
mTimingFunction.Y2(),
|
||||
aResult);
|
||||
break;
|
||||
case nsTimingFunction::Type::StepStart:
|
||||
case nsTimingFunction::Type::StepEnd:
|
||||
nsStyleUtil::AppendStepsTimingFunction(mType, mSteps, mStepSyntax,
|
||||
aResult);
|
||||
break;
|
||||
default:
|
||||
nsStyleUtil::AppendCubicBezierKeywordTimingFunction(mType, aResult);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
namespace dom {
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_INHERITED(KeyframeEffectReadOnly,
|
||||
|
@ -13,6 +13,7 @@
|
||||
#include "nsIDocument.h"
|
||||
#include "nsWrapperCache.h"
|
||||
#include "mozilla/Attributes.h"
|
||||
#include "mozilla/ComputedTimingFunction.h" // ComputedTimingFunction
|
||||
#include "mozilla/LayerAnimationInfo.h" // LayerAnimations::kRecords
|
||||
#include "mozilla/StickyTimeDuration.h"
|
||||
#include "mozilla/StyleAnimationValue.h"
|
||||
@ -21,8 +22,6 @@
|
||||
#include "mozilla/dom/Element.h"
|
||||
#include "mozilla/dom/KeyframeBinding.h"
|
||||
#include "mozilla/dom/Nullable.h"
|
||||
#include "nsSMILKeySpline.h"
|
||||
#include "nsStyleStruct.h" // for nsTimingFunction
|
||||
|
||||
struct JSContext;
|
||||
class nsCSSPropertySet;
|
||||
@ -97,41 +96,6 @@ struct ComputedTiming
|
||||
AnimationPhase mPhase = AnimationPhase::Null;
|
||||
};
|
||||
|
||||
class ComputedTimingFunction
|
||||
{
|
||||
public:
|
||||
typedef nsTimingFunction::Type Type;
|
||||
typedef nsTimingFunction::StepSyntax StepSyntax;
|
||||
void Init(const nsTimingFunction &aFunction);
|
||||
double GetValue(double aPortion) const;
|
||||
const nsSMILKeySpline* GetFunction() const {
|
||||
NS_ASSERTION(HasSpline(), "Type mismatch");
|
||||
return &mTimingFunction;
|
||||
}
|
||||
Type GetType() const { return mType; }
|
||||
bool HasSpline() const { return nsTimingFunction::IsSplineType(mType); }
|
||||
uint32_t GetSteps() const { return mSteps; }
|
||||
StepSyntax GetStepSyntax() const { return mStepSyntax; }
|
||||
bool operator==(const ComputedTimingFunction& aOther) const {
|
||||
return mType == aOther.mType &&
|
||||
(HasSpline() ?
|
||||
mTimingFunction == aOther.mTimingFunction :
|
||||
(mSteps == aOther.mSteps &&
|
||||
mStepSyntax == aOther.mStepSyntax));
|
||||
}
|
||||
bool operator!=(const ComputedTimingFunction& aOther) const {
|
||||
return !(*this == aOther);
|
||||
}
|
||||
int32_t Compare(const ComputedTimingFunction& aRhs) const;
|
||||
void AppendToString(nsAString& aResult) const;
|
||||
|
||||
private:
|
||||
Type mType;
|
||||
nsSMILKeySpline mTimingFunction;
|
||||
uint32_t mSteps;
|
||||
StepSyntax mStepSyntax;
|
||||
};
|
||||
|
||||
struct AnimationPropertySegment
|
||||
{
|
||||
float mFromKey, mToKey;
|
||||
|
@ -18,6 +18,7 @@ EXPORTS.mozilla.dom += [
|
||||
EXPORTS.mozilla += [
|
||||
'AnimationComparator.h',
|
||||
'AnimationUtils.h',
|
||||
'ComputedTimingFunction.h',
|
||||
'PendingAnimationTracker.h',
|
||||
]
|
||||
|
||||
@ -25,6 +26,7 @@ UNIFIED_SOURCES += [
|
||||
'Animation.cpp',
|
||||
'AnimationEffectReadOnly.cpp',
|
||||
'AnimationTimeline.cpp',
|
||||
'ComputedTimingFunction.cpp',
|
||||
'DocumentTimeline.cpp',
|
||||
'KeyframeEffect.cpp',
|
||||
'PendingAnimationTracker.cpp',
|
||||
|
@ -106,7 +106,6 @@ class nsIWindowProvider;
|
||||
|
||||
struct JSPropertyDescriptor;
|
||||
struct JSRuntime;
|
||||
struct nsIntMargin;
|
||||
|
||||
template<class E> class nsCOMArray;
|
||||
template<class K, class V> class nsDataHashtable;
|
||||
|
@ -8894,16 +8894,6 @@ nsDocument::Destroy()
|
||||
|
||||
mRegistry = nullptr;
|
||||
|
||||
using mozilla::dom::workers::ServiceWorkerManager;
|
||||
RefPtr<ServiceWorkerManager> swm = ServiceWorkerManager::GetInstance();
|
||||
if (swm) {
|
||||
ErrorResult error;
|
||||
if (swm->IsControlled(this, error)) {
|
||||
nsContentUtils::GetImgLoaderForDocument(this)->ClearCacheForControlledDocument(this);
|
||||
}
|
||||
swm->MaybeStopControlling(this);
|
||||
}
|
||||
|
||||
// XXX We really should let cycle collection do this, but that currently still
|
||||
// leaks (see https://bugzilla.mozilla.org/show_bug.cgi?id=406684).
|
||||
ReleaseWrapper(static_cast<nsINode*>(this));
|
||||
@ -8915,6 +8905,19 @@ nsDocument::RemovedFromDocShell()
|
||||
if (mRemovedFromDocShell)
|
||||
return;
|
||||
|
||||
using mozilla::dom::workers::ServiceWorkerManager;
|
||||
RefPtr<ServiceWorkerManager> swm = ServiceWorkerManager::GetInstance();
|
||||
if (swm) {
|
||||
ErrorResult error;
|
||||
if (swm->IsControlled(this, error)) {
|
||||
imgLoader* loader = nsContentUtils::GetImgLoaderForDocument(this);
|
||||
if (loader) {
|
||||
loader->ClearCacheForControlledDocument(this);
|
||||
}
|
||||
}
|
||||
swm->MaybeStopControlling(this);
|
||||
}
|
||||
|
||||
mRemovedFromDocShell = true;
|
||||
EnumerateActivityObservers(NotifyActivityChanged, nullptr);
|
||||
|
||||
|
@ -64,7 +64,9 @@ function runTests() {
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
|
||||
addLoadEvent(function() {
|
||||
SpecialPowers.pushPrefEnv({"set": [["network.jar.block-remote-files", false]]}, function() {
|
||||
SpecialPowers.pushPermissions([{'type': 'systemXHR', 'allow': true, 'context': document}], runTests);
|
||||
});
|
||||
});
|
||||
</script>
|
||||
</pre>
|
||||
|
@ -502,8 +502,7 @@ BluetoothMapSmsManager::ReplyToConnect()
|
||||
|
||||
req[3] = 0x10; // version=1.0
|
||||
req[4] = 0x00; // flag=0x00
|
||||
req[5] = BluetoothMapSmsManager::MAX_PACKET_LENGTH >> 8;
|
||||
req[6] = (uint8_t)BluetoothMapSmsManager::MAX_PACKET_LENGTH;
|
||||
BigEndian::writeUint16(&req[5], BluetoothMapSmsManager::MAX_PACKET_LENGTH);
|
||||
|
||||
// Section 6.4 "Establishing an OBEX Session", MapSms 1.2
|
||||
// Headers: [Who:16][Connection ID]
|
||||
|
@ -866,8 +866,7 @@ BluetoothOppManager::ComposePacket(uint8_t aOpCode, UnixSocketBuffer* aMessage)
|
||||
// [opcode:1][length:2][Headers:var]
|
||||
frameHeaderLength = 3;
|
||||
|
||||
mPacketLength = ((static_cast<int>(data[1]) << 8) | data[2]) -
|
||||
frameHeaderLength;
|
||||
mPacketLength = BigEndian::readUint16(&data[1]) - frameHeaderLength;
|
||||
|
||||
/**
|
||||
* A PUT request from remote devices may be divided into multiple parts.
|
||||
@ -1119,7 +1118,7 @@ BluetoothOppManager::ClientDataHandler(UnixSocketBuffer* aMessage)
|
||||
// Keep remote information
|
||||
mRemoteObexVersion = data[3];
|
||||
mRemoteConnectionFlags = data[4];
|
||||
mRemoteMaxPacketLength = ((static_cast<int>(data[5]) << 8) | data[6]);
|
||||
mRemoteMaxPacketLength = BigEndian::readUint16(&data[5]);
|
||||
|
||||
// The length of file name exceeds maximum length.
|
||||
int fileNameByteLen = (mFileName.Length() + 1) * 2;
|
||||
|
@ -242,7 +242,7 @@ BluetoothPbapManager::ReceiveSocketData(BluetoothSocket* aSocket,
|
||||
}
|
||||
|
||||
// Save the max packet length from remote information
|
||||
mRemoteMaxPacketLength = ((static_cast<int>(data[5]) << 8) | data[6]);
|
||||
mRemoteMaxPacketLength = BigEndian::readUint16(&data[5]);
|
||||
|
||||
if (mRemoteMaxPacketLength < kObexLeastMaxSize) {
|
||||
BT_LOGR("Remote maximum packet length %d is smaller than %d bytes",
|
||||
|
@ -842,8 +842,7 @@ BluetoothOppManager::ComposePacket(uint8_t aOpCode, UnixSocketBuffer* aMessage)
|
||||
// [opcode:1][length:2][Headers:var]
|
||||
frameHeaderLength = 3;
|
||||
|
||||
mPacketLength = ((static_cast<int>(data[1]) << 8) | data[2]) -
|
||||
frameHeaderLength;
|
||||
mPacketLength = BigEndian::readUint16(&data[1]) - frameHeaderLength;
|
||||
/**
|
||||
* A PUT request from remote devices may be divided into multiple parts.
|
||||
* In other words, one request may need to be received multiple times,
|
||||
@ -1094,7 +1093,7 @@ BluetoothOppManager::ClientDataHandler(UnixSocketBuffer* aMessage)
|
||||
// Keep remote information
|
||||
mRemoteObexVersion = data[3];
|
||||
mRemoteConnectionFlags = data[4];
|
||||
mRemoteMaxPacketLength = (static_cast<int>(data[5]) << 8) | data[6];
|
||||
mRemoteMaxPacketLength = BigEndian::readUint16(&data[5]);
|
||||
|
||||
// The length of file name exceeds maximum length.
|
||||
int fileNameByteLen = (mFileName.Length() + 1) * 2;
|
||||
|
@ -9,6 +9,7 @@
|
||||
|
||||
#include <algorithm>
|
||||
#include "mozilla/Compiler.h"
|
||||
#include "mozilla/Endian.h"
|
||||
#include "mozilla/Observer.h"
|
||||
#include "nsAutoPtr.h"
|
||||
#include "nsPrintfCString.h"
|
||||
@ -496,14 +497,12 @@ struct BluetoothAddress {
|
||||
|
||||
uint16_t GetNAP() const
|
||||
{
|
||||
return (static_cast<uint16_t>(mAddr[4])) |
|
||||
(static_cast<uint16_t>(mAddr[5]) << 8);
|
||||
return LittleEndian::readUint16(&mAddr[4]);
|
||||
}
|
||||
|
||||
void SetNAP(uint16_t aNAP)
|
||||
{
|
||||
mAddr[4] = aNAP;
|
||||
mAddr[5] = aNAP >> 8;
|
||||
LittleEndian::writeUint16(&mAddr[4], aNAP);
|
||||
}
|
||||
|
||||
};
|
||||
@ -635,10 +634,7 @@ struct BluetoothUuid {
|
||||
|
||||
void SetUuid32(uint32_t aUuid32)
|
||||
{
|
||||
mUuid[0] = static_cast<uint8_t>(0xff & (aUuid32 >> 24));
|
||||
mUuid[1] = static_cast<uint8_t>(0xff & (aUuid32 >> 16));
|
||||
mUuid[2] = static_cast<uint8_t>(0xff & (aUuid32 >> 8));
|
||||
mUuid[3] = static_cast<uint8_t>(0xff & (aUuid32));
|
||||
BigEndian::writeUint32(&mUuid[0], aUuid32);
|
||||
mUuid[4] = 0x00;
|
||||
mUuid[5] = 0x00;
|
||||
mUuid[6] = 0x10;
|
||||
@ -655,10 +651,7 @@ struct BluetoothUuid {
|
||||
|
||||
uint32_t GetUuid32() const
|
||||
{
|
||||
return (static_cast<uint32_t>(mUuid[0]) << 24) |
|
||||
(static_cast<uint32_t>(mUuid[1]) << 16) |
|
||||
(static_cast<uint32_t>(mUuid[2]) << 8) |
|
||||
(static_cast<uint32_t>(mUuid[3]));
|
||||
return BigEndian::readUint32(&mUuid[0]);
|
||||
}
|
||||
|
||||
void SetUuid16(uint16_t aUuid16)
|
||||
@ -668,8 +661,7 @@ struct BluetoothUuid {
|
||||
|
||||
uint16_t GetUuid16() const
|
||||
{
|
||||
return (static_cast<uint16_t>(mUuid[2]) << 8) |
|
||||
(static_cast<uint16_t>(mUuid[3]));
|
||||
return BigEndian::readUint16(&mUuid[2]);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -23,8 +23,7 @@ AppendHeader(uint8_t aHeaderId, uint8_t* aRetBuf, int aBufferSize,
|
||||
int writtenLength = (headerLength < aBufferSize) ? headerLength : aBufferSize;
|
||||
|
||||
aRetBuf[0] = aHeaderId;
|
||||
aRetBuf[1] = (headerLength & 0xFF00) >> 8;
|
||||
aRetBuf[2] = headerLength & 0x00FF;
|
||||
BigEndian::writeUint16(&aRetBuf[1], headerLength);
|
||||
memcpy(&aRetBuf[3], aData, writtenLength - 3);
|
||||
|
||||
return writtenLength;
|
||||
@ -37,10 +36,7 @@ int
|
||||
AppendHeader(uint8_t aHeaderId, uint8_t* aRetBuf, int aValue)
|
||||
{
|
||||
aRetBuf[0] = aHeaderId;
|
||||
aRetBuf[1] = (aValue & 0xFF000000) >> 24;
|
||||
aRetBuf[2] = (aValue & 0x00FF0000) >> 16;
|
||||
aRetBuf[3] = (aValue & 0x0000FF00) >> 8;
|
||||
aRetBuf[4] = aValue & 0x000000FF;
|
||||
BigEndian::writeInt32(&aRetBuf[1], aValue);
|
||||
|
||||
return 5;
|
||||
}
|
||||
@ -135,8 +131,7 @@ void
|
||||
SetObexPacketInfo(uint8_t* aRetBuf, uint8_t aOpcode, int aPacketLength)
|
||||
{
|
||||
aRetBuf[0] = aOpcode;
|
||||
aRetBuf[1] = (aPacketLength & 0xFF00) >> 8;
|
||||
aRetBuf[2] = aPacketLength & 0x00FF;
|
||||
BigEndian::writeUint16(&aRetBuf[1], aPacketLength);
|
||||
}
|
||||
|
||||
bool
|
||||
@ -150,7 +145,6 @@ ParseHeaders(const uint8_t* aHeaderStart,
|
||||
ObexHeaderId headerId = (ObexHeaderId)*ptr++;
|
||||
|
||||
uint16_t contentLength = 0;
|
||||
uint8_t highByte, lowByte;
|
||||
|
||||
// Defined in 2.1 OBEX Headers, IrOBEX 1.2
|
||||
switch (headerId >> 6)
|
||||
@ -160,9 +154,8 @@ ParseHeaders(const uint8_t* aHeaderStart,
|
||||
// unsigned integer.
|
||||
case 0x01:
|
||||
// byte sequence, length prefixed with 2 byte unsigned integer.
|
||||
highByte = *ptr++;
|
||||
lowByte = *ptr++;
|
||||
contentLength = (((uint16_t)highByte << 8) | lowByte) - 3;
|
||||
contentLength = BigEndian::readUint16(ptr) - 3;
|
||||
ptr += 2;
|
||||
break;
|
||||
|
||||
case 0x02:
|
||||
|
@ -8,6 +8,7 @@
|
||||
#define mozilla_dom_bluetooth_ObexBase_h
|
||||
|
||||
#include "BluetoothCommon.h"
|
||||
#include "mozilla/Endian.h"
|
||||
#include "nsAutoPtr.h"
|
||||
#include "nsTArray.h"
|
||||
|
||||
@ -178,7 +179,7 @@ public:
|
||||
uint8_t* ptr = mHeaders[i]->mData.get();
|
||||
|
||||
for (int j = 0; j < nameLength; ++j) {
|
||||
char16_t c = ((((uint32_t)ptr[j * 2]) << 8) | ptr[j * 2 + 1]);
|
||||
char16_t c = BigEndian::readUint16(&ptr[j * 2]);
|
||||
aRetName += c;
|
||||
}
|
||||
|
||||
@ -211,10 +212,7 @@ public:
|
||||
for (int i = 0; i < length; ++i) {
|
||||
if (mHeaders[i]->mId == ObexHeaderId::Length) {
|
||||
uint8_t* ptr = mHeaders[i]->mData.get();
|
||||
*aRetLength = ((uint32_t)ptr[0] << 24) |
|
||||
((uint32_t)ptr[1] << 16) |
|
||||
((uint32_t)ptr[2] << 8) |
|
||||
((uint32_t)ptr[3]);
|
||||
*aRetLength = BigEndian::readUint32(&ptr[0]);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -19,6 +19,11 @@ Cu.import("resource://gre/modules/ExtensionContent.jsm");
|
||||
XPCOMUtils.defineLazyServiceGetter(this, "acs",
|
||||
"@mozilla.org/audiochannel/service;1",
|
||||
"nsIAudioChannelService");
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "ManifestFinder",
|
||||
"resource://gre/modules/ManifestFinder.jsm");
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "ManifestObtainer",
|
||||
"resource://gre/modules/ManifestObtainer.jsm");
|
||||
|
||||
|
||||
var kLongestReturnedString = 128;
|
||||
|
||||
@ -289,7 +294,8 @@ BrowserElementChild.prototype = {
|
||||
"get-audio-channel-muted": this._recvGetAudioChannelMuted,
|
||||
"set-audio-channel-muted": this._recvSetAudioChannelMuted,
|
||||
"get-is-audio-channel-active": this._recvIsAudioChannelActive,
|
||||
"get-structured-data": this._recvGetStructuredData
|
||||
"get-structured-data": this._recvGetStructuredData,
|
||||
"get-web-manifest": this._recvGetWebManifest,
|
||||
}
|
||||
|
||||
addMessageListener("browser-element-api:call", function(aMessage) {
|
||||
@ -1527,7 +1533,26 @@ BrowserElementChild.prototype = {
|
||||
id: data.json.id, successRv: active
|
||||
});
|
||||
},
|
||||
|
||||
_recvGetWebManifest: Task.async(function* (data) {
|
||||
debug(`Received GetWebManifest message: (${data.json.id})`);
|
||||
let manifest = null;
|
||||
let hasManifest = ManifestFinder.contentHasManifestLink(content);
|
||||
if (hasManifest) {
|
||||
try {
|
||||
manifest = yield ManifestObtainer.contentObtainManifest(content);
|
||||
} catch (e) {
|
||||
sendAsyncMsg('got-web-manifest', {
|
||||
id: data.json.id,
|
||||
errorMsg: `Error fetching web manifest: ${e}.`,
|
||||
});
|
||||
return;
|
||||
}
|
||||
}
|
||||
sendAsyncMsg('got-web-manifest', {
|
||||
id: data.json.id,
|
||||
successRv: manifest
|
||||
});
|
||||
}),
|
||||
_initFinder: function() {
|
||||
if (!this._finder) {
|
||||
try {
|
||||
|
@ -386,7 +386,8 @@ BrowserElementParent.prototype = {
|
||||
"got-audio-channel-muted": this._gotDOMRequestResult,
|
||||
"got-set-audio-channel-muted": this._gotDOMRequestResult,
|
||||
"got-is-audio-channel-active": this._gotDOMRequestResult,
|
||||
"got-structured-data": this._gotDOMRequestResult
|
||||
"got-structured-data": this._gotDOMRequestResult,
|
||||
"got-web-manifest": this._gotDOMRequestResult,
|
||||
};
|
||||
|
||||
let mmSecuritySensitiveCalls = {
|
||||
@ -1210,6 +1211,7 @@ BrowserElementParent.prototype = {
|
||||
|
||||
getStructuredData: defineDOMRequestMethod('get-structured-data'),
|
||||
|
||||
getWebManifest: defineDOMRequestMethod('get-web-manifest'),
|
||||
/**
|
||||
* Called when the visibility of the window which owns this iframe changes.
|
||||
*/
|
||||
|
@ -0,0 +1,65 @@
|
||||
/* Any copyright is dedicated to the public domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
/*globals async, ok, is, SimpleTest, browserElementTestHelpers*/
|
||||
|
||||
// Bug 1169633 - getWebManifest tests
|
||||
'use strict';
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
browserElementTestHelpers.setEnabledPref(true);
|
||||
browserElementTestHelpers.addPermission();
|
||||
|
||||
// request to load a manifest from a page that doesn't have a manifest.
|
||||
// The expected result to be null.
|
||||
var test1 = async(function* () {
|
||||
var manifest = yield requestManifest('file_empty.html');
|
||||
is(manifest, null, 'it should be null.');
|
||||
});
|
||||
|
||||
// request to load a manifest from a page that has a manifest.
|
||||
// The expected manifest to have a property name whose value is 'pass'.
|
||||
var test2 = async(function* () {
|
||||
var manifest = yield requestManifest('file_web_manifest.html');
|
||||
is(manifest && manifest.name, 'pass', 'it should return a manifest with name pass.');
|
||||
});
|
||||
|
||||
// Cause an exception by attempting to fetch a file URL,
|
||||
// expect onerror to be called.
|
||||
var test3 = async(function* () {
|
||||
var gotError = false;
|
||||
try {
|
||||
yield requestManifest('file_illegal_web_manifest.html');
|
||||
} catch (err) {
|
||||
gotError = true;
|
||||
}
|
||||
ok(gotError, 'onerror was called on the DOMRequest.');
|
||||
});
|
||||
|
||||
// Run the tests
|
||||
addEventListener('testready', () => {
|
||||
Promise
|
||||
.all([test1(), test2(), test3()])
|
||||
.then(SimpleTest.finish);
|
||||
});
|
||||
|
||||
function requestManifest(url) {
|
||||
var iframe = document.createElement('iframe');
|
||||
iframe.setAttribute('mozbrowser', 'true');
|
||||
iframe.src = url;
|
||||
document.body.appendChild(iframe);
|
||||
return new Promise((resolve, reject) => {
|
||||
iframe.addEventListener('mozbrowserloadend', function loadend() {
|
||||
iframe.removeEventListener('mozbrowserloadend', loadend);
|
||||
SimpleTest.executeSoon(() => {
|
||||
var req = iframe.getWebManifest();
|
||||
req.onsuccess = () => {
|
||||
document.body.removeChild(iframe);
|
||||
resolve(req.result);
|
||||
};
|
||||
req.onerror = () => {
|
||||
document.body.removeChild(iframe);
|
||||
reject(new Error(req.error));
|
||||
};
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
@ -0,0 +1,6 @@
|
||||
<!doctype html>
|
||||
<meta charset=utf-8>
|
||||
<head>
|
||||
<link rel="manifest" href="file://this_is_not_allowed!">
|
||||
</head>
|
||||
<h1>Support Page for Web Manifest Tests</h1>
|
6
dom/browser-element/mochitest/file_web_manifest.html
Normal file
6
dom/browser-element/mochitest/file_web_manifest.html
Normal file
@ -0,0 +1,6 @@
|
||||
<!doctype html>
|
||||
<meta charset=utf-8>
|
||||
<head>
|
||||
<link rel="manifest" href="file_web_manifest.json">
|
||||
</head>
|
||||
<h1>Support Page for Web Manifest Tests</h1>
|
1
dom/browser-element/mochitest/file_web_manifest.json
Normal file
1
dom/browser-element/mochitest/file_web_manifest.json
Normal file
@ -0,0 +1 @@
|
||||
{"name": "pass"}
|
@ -119,3 +119,4 @@ disabled = bug 924771
|
||||
[test_browserElement_oop_GetContentDimensions.html]
|
||||
[test_browserElement_oop_AudioChannel.html]
|
||||
[test_browserElement_oop_SetNFCFocus.html]
|
||||
[test_browserElement_oop_getWebManifest.html]
|
||||
|
@ -39,6 +39,7 @@ support-files =
|
||||
browserElement_GetScreenshot.js
|
||||
browserElement_GetScreenshotDppx.js
|
||||
browserElement_getStructuredData.js
|
||||
browserElement_getWebManifest.js
|
||||
browserElement_Iconchange.js
|
||||
browserElement_LoadEvents.js
|
||||
browserElement_Manifestchange.js
|
||||
@ -136,10 +137,14 @@ support-files =
|
||||
file_wyciwyg.html
|
||||
file_audio.html
|
||||
iframe_file_audio.html
|
||||
file_web_manifest.html
|
||||
file_web_manifest.json
|
||||
file_illegal_web_manifest.html
|
||||
|
||||
# Note: browserElementTestHelpers.js looks at the test's filename to determine
|
||||
# whether the test should be OOP. "_oop_" signals OOP, "_inproc_" signals in
|
||||
# process. Default is OOP.
|
||||
[test_browserElement_inproc_getWebManifest.html]
|
||||
[test_browserElement_NoAttr.html]
|
||||
[test_browserElement_NoPref.html]
|
||||
[test_browserElement_NoPermission.html]
|
||||
|
@ -0,0 +1,17 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head>
|
||||
<title>Test for Bug 1169633</title>
|
||||
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<script type="application/javascript" src="/tests/dom/browser-element/mochitest/browserElementTestHelpers.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
|
||||
</head>
|
||||
<body>
|
||||
<script type="application/javascript;version=1.8"
|
||||
src="async.js">
|
||||
</script>
|
||||
<script type="application/javascript;version=1.8"
|
||||
src="browserElement_getWebManifest.js">
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
@ -0,0 +1,16 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head>
|
||||
<title>Test for Bug 1169633</title>
|
||||
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<script type="application/javascript" src="/tests/dom/browser-element/mochitest/browserElementTestHelpers.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
|
||||
</head>
|
||||
<body>
|
||||
<script type="application/javascript;version=1.8"
|
||||
src="async.js"></script>
|
||||
<script type="application/javascript;version=1.8"
|
||||
src="browserElement_getWebManifest.js">
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
@ -9,7 +9,7 @@
|
||||
interface nsIDOMDOMRequest;
|
||||
interface nsIFrameLoader;
|
||||
|
||||
[scriptable, function, uuid(c0c2dd9b-41ef-42dd-a4c1-e456619c1941)]
|
||||
[scriptable, function, uuid(00d0e19d-bd67-491f-8e85-b9905224d3bb)]
|
||||
interface nsIBrowserElementNextPaintListener : nsISupports
|
||||
{
|
||||
void recvNextPaint();
|
||||
@ -26,7 +26,7 @@ interface nsIBrowserElementNextPaintListener : nsISupports
|
||||
* Interface to the BrowserElementParent implementation. All methods
|
||||
* but setFrameLoader throw when the remote process is dead.
|
||||
*/
|
||||
[scriptable, uuid(9946695c-1ed3-4abb-bc60-6f8947fd5641)]
|
||||
[scriptable, uuid(1e098c3a-7d65-452d-a2b2-9ffd1b6e04bb)]
|
||||
interface nsIBrowserElementAPI : nsISupports
|
||||
{
|
||||
const long FIND_CASE_SENSITIVE = 0;
|
||||
@ -101,6 +101,12 @@ interface nsIBrowserElementAPI : nsISupports
|
||||
|
||||
nsIDOMDOMRequest executeScript(in DOMString script, in jsval options);
|
||||
|
||||
/**
|
||||
* Returns an object that represents a Web Manifest:
|
||||
* http://w3c.github.io/manifest/
|
||||
*/
|
||||
nsIDOMDOMRequest getWebManifest();
|
||||
|
||||
/**
|
||||
* Returns a JSON string representing Microdata objects on the page.
|
||||
* Format is described at:
|
||||
|
@ -312,22 +312,7 @@ WebGL2Context::GetUniformIndices(WebGLProgram* program,
|
||||
if (!uniformNames.Length())
|
||||
return;
|
||||
|
||||
GLuint progname = program->mGLName;
|
||||
size_t count = uniformNames.Length();
|
||||
nsTArray<GLuint>& arr = retval.SetValue();
|
||||
|
||||
MakeContextCurrent();
|
||||
|
||||
for (size_t n = 0; n < count; n++) {
|
||||
NS_LossyConvertUTF16toASCII name(uniformNames[n]);
|
||||
// const GLchar* glname = name.get();
|
||||
const GLchar* glname = nullptr;
|
||||
name.BeginReading(glname);
|
||||
|
||||
GLuint index = 0;
|
||||
gl->fGetUniformIndices(progname, 1, &glname, &index);
|
||||
arr.AppendElement(index);
|
||||
}
|
||||
program->GetUniformIndices(uniformNames, retval);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -758,6 +758,51 @@ WebGLProgram::GetUniformLocation(const nsAString& userName_wide) const
|
||||
return locObj.forget();
|
||||
}
|
||||
|
||||
void
|
||||
WebGLProgram::GetUniformIndices(const dom::Sequence<nsString>& uniformNames,
|
||||
dom::Nullable< nsTArray<GLuint> >& retval) const
|
||||
{
|
||||
size_t count = uniformNames.Length();
|
||||
nsTArray<GLuint>& arr = retval.SetValue();
|
||||
|
||||
gl::GLContext* gl = mContext->GL();
|
||||
gl->MakeCurrent();
|
||||
|
||||
for (size_t i = 0; i < count; i++) {
|
||||
const NS_LossyConvertUTF16toASCII userName(uniformNames[i]);
|
||||
|
||||
nsDependentCString baseUserName;
|
||||
bool isArray;
|
||||
size_t arrayIndex;
|
||||
if (!ParseName(userName, &baseUserName, &isArray, &arrayIndex)) {
|
||||
arr.AppendElement(LOCAL_GL_INVALID_INDEX);
|
||||
continue;
|
||||
}
|
||||
|
||||
const WebGLActiveInfo* activeInfo;
|
||||
if (!LinkInfo()->FindUniform(baseUserName, &activeInfo)) {
|
||||
arr.AppendElement(LOCAL_GL_INVALID_INDEX);
|
||||
continue;
|
||||
}
|
||||
|
||||
const nsCString& baseMappedName = activeInfo->mBaseMappedName;
|
||||
|
||||
nsAutoCString mappedName(baseMappedName);
|
||||
if (isArray) {
|
||||
mappedName.AppendLiteral("[");
|
||||
mappedName.AppendInt(uint32_t(arrayIndex));
|
||||
mappedName.AppendLiteral("]");
|
||||
}
|
||||
|
||||
const GLchar* mappedNameBytes = mappedName.BeginReading();
|
||||
|
||||
GLuint index = 0;
|
||||
gl->fGetUniformIndices(mGLName, 1, &mappedNameBytes, &index);
|
||||
arr.AppendElement(index);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
WebGLProgram::UniformBlockBinding(GLuint uniformBlockIndex, GLuint uniformBlockBinding) const
|
||||
{
|
||||
|
@ -161,6 +161,8 @@ public:
|
||||
dom::Nullable<dom::OwningUnsignedLongOrUint32ArrayOrBoolean>& retval,
|
||||
ErrorResult& rv) const;
|
||||
already_AddRefed<WebGLUniformLocation> GetUniformLocation(const nsAString& name) const;
|
||||
void GetUniformIndices(const dom::Sequence<nsString>& uniformNames,
|
||||
dom::Nullable< nsTArray<GLuint> >& retval) const;
|
||||
void UniformBlockBinding(GLuint uniformBlockIndex, GLuint uniformBlockBinding) const;
|
||||
|
||||
bool LinkProgram();
|
||||
|
@ -357,8 +357,16 @@ WebGLShader::FindUniformBlockByMappedName(const nsACString& mappedName,
|
||||
nsCString* const out_userName,
|
||||
bool* const out_isArray) const
|
||||
{
|
||||
// TODO: Extract block information from shader validator.
|
||||
if (!mValidator)
|
||||
return false;
|
||||
|
||||
const std::string mappedNameStr(mappedName.BeginReading(), mappedName.Length());
|
||||
std::string userNameStr;
|
||||
if (!mValidator->FindUniformBlockByMappedName(mappedNameStr, &userNameStr))
|
||||
return false;
|
||||
|
||||
*out_userName = userNameStr.c_str();
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
@ -379,9 +387,8 @@ WebGLShader::ApplyTransformFeedbackVaryings(GLuint prog,
|
||||
std::string userNameStr(userName.BeginReading());
|
||||
|
||||
const std::string* mappedNameStr = &userNameStr;
|
||||
// TODO: Are vertex->fragment shader varyings listed under attribs?
|
||||
if (mValidator)
|
||||
mValidator->FindAttribMappedNameByUserName(userNameStr, &mappedNameStr);
|
||||
mValidator->FindVaryingMappedNameByUserName(userNameStr, &mappedNameStr);
|
||||
|
||||
mappedVaryings.push_back(*mappedNameStr);
|
||||
}
|
||||
|
@ -361,6 +361,21 @@ ShaderValidator::FindAttribMappedNameByUserName(const std::string& userName,
|
||||
return false;
|
||||
}
|
||||
|
||||
bool
|
||||
ShaderValidator::FindVaryingMappedNameByUserName(const std::string& userName,
|
||||
const std::string** const out_mappedName) const
|
||||
{
|
||||
const std::vector<sh::Varying>& attribs = *ShGetVaryings(mHandle);
|
||||
for (auto itr = attribs.begin(); itr != attribs.end(); ++itr) {
|
||||
if (itr->name == userName) {
|
||||
*out_mappedName = &(itr->mappedName);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// This must handle names like "foo.bar[0]".
|
||||
bool
|
||||
ShaderValidator::FindUniformByMappedName(const std::string& mappedName,
|
||||
@ -377,6 +392,22 @@ ShaderValidator::FindUniformByMappedName(const std::string& mappedName,
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool
|
||||
ShaderValidator::FindUniformBlockByMappedName(const std::string& mappedName,
|
||||
std::string* const out_userName) const
|
||||
{
|
||||
const std::vector<sh::InterfaceBlock>& interfaces = *ShGetInterfaceBlocks(mHandle);
|
||||
for (const auto& interface : interfaces) {
|
||||
if (mappedName == interface.mappedName) {
|
||||
*out_userName = interface.name;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -50,9 +50,15 @@ public:
|
||||
bool FindAttribMappedNameByUserName(const std::string& userName,
|
||||
const std::string** const out_mappedName) const;
|
||||
|
||||
bool FindVaryingMappedNameByUserName(const std::string& userName,
|
||||
const std::string** const out_mappedName) const;
|
||||
|
||||
bool FindUniformByMappedName(const std::string& mappedName,
|
||||
std::string* const out_userName,
|
||||
bool* const out_isArray) const;
|
||||
bool FindUniformBlockByMappedName(const std::string& mappedName,
|
||||
std::string* const out_userName) const;
|
||||
|
||||
};
|
||||
|
||||
} // namespace webgl
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user