MozReview-Commit-ID: Hm1RxN6OaoZ
This commit is contained in:
Phil Ringnalda 2016-11-03 19:32:48 -07:00
Родитель 898435da51 9919073d9f
Коммит 0f32b67e2d
354 изменённых файлов: 10929 добавлений и 6299 удалений

Просмотреть файл

@ -90,6 +90,15 @@
); );
} else { } else {
SimpleTest.ok(true, "Testing Firefox tabbrowser UI."); SimpleTest.ok(true, "Testing Firefox tabbrowser UI.");
let newTabChildren = [];
if (SpecialPowers.getBoolPref("privacy.userContext.enabled")) {
newTabChildren = [
{
role: ROLE_MENUPOPUP,
children: []
}
];
}
// NB: The (3) buttons are not visible, unless manually hovered, // NB: The (3) buttons are not visible, unless manually hovered,
// probably due to size reduction in this test. // probably due to size reduction in this test.
@ -119,7 +128,7 @@
{ {
// xul:toolbarbutton ("Open a new tab") // xul:toolbarbutton ("Open a new tab")
role: ROLE_PUSHBUTTON, role: ROLE_PUSHBUTTON,
children: [] children: newTabChildren
} }
// "List all tabs" dropdown // "List all tabs" dropdown
// XXX: This child(?) is not present in this test. // XXX: This child(?) is not present in this test.

Просмотреть файл

@ -7,6 +7,7 @@ support-files =
invalid.json invalid.json
[browser_sdk_loader_sdk_modules.js] [browser_sdk_loader_sdk_modules.js]
[browser_sdk_loader_sdk_gui_modules.js] [browser_sdk_loader_sdk_gui_modules.js]
skip-if = true # Bug 1315042
[browser_sdk_loader_jsm_modules.js] [browser_sdk_loader_jsm_modules.js]
[browser_sdk_loader_js_modules.js] [browser_sdk_loader_js_modules.js]
[browser_sdk_loader_json.js] [browser_sdk_loader_json.js]

Просмотреть файл

@ -93,6 +93,7 @@
<command id="Browser:OpenLocation" oncommand="openLocation();"/> <command id="Browser:OpenLocation" oncommand="openLocation();"/>
<command id="Browser:RestoreLastSession" oncommand="restoreLastSession();" disabled="true"/> <command id="Browser:RestoreLastSession" oncommand="restoreLastSession();" disabled="true"/>
<command id="Browser:NewUserContextTab" oncommand="openNewUserContextTab(event.sourceEvent);" reserved="true"/> <command id="Browser:NewUserContextTab" oncommand="openNewUserContextTab(event.sourceEvent);" reserved="true"/>
<command id="Browser:OpenAboutContainers" oncommand="openPreferences('paneContainers');"/>
<command id="Tools:Search" oncommand="BrowserSearch.webSearch();"/> <command id="Tools:Search" oncommand="BrowserSearch.webSearch();"/>
<command id="Tools:Downloads" oncommand="BrowserDownloadsUI();"/> <command id="Tools:Downloads" oncommand="BrowserDownloadsUI();"/>

Просмотреть файл

@ -119,6 +119,16 @@ tabbrowser {
visibility: hidden; /* temporary space to keep a tab's close button under the cursor */ visibility: hidden; /* temporary space to keep a tab's close button under the cursor */
} }
.tabs-newtab-button > .toolbarbutton-menu-dropmarker,
#new-tab-button > .toolbarbutton-menu-dropmarker {
display: none;
}
/* override drop marker image padding */
.tabs-newtab-button > .toolbarbutton-icon {
margin-inline-end: 0;
}
.tabbrowser-tab { .tabbrowser-tab {
-moz-binding: url("chrome://browser/content/tabbrowser.xml#tabbrowser-tab"); -moz-binding: url("chrome://browser/content/tabbrowser.xml#tabbrowser-tab");
} }
@ -177,6 +187,7 @@ tabbrowser {
transition: transform 200ms ease-out; transition: transform 200ms ease-out;
} }
.new-tab-popup,
#alltabs-popup { #alltabs-popup {
-moz-binding: url("chrome://browser/content/tabbrowser.xml#tabbrowser-alltabs-popup"); -moz-binding: url("chrome://browser/content/tabbrowser.xml#tabbrowser-alltabs-popup");
} }

Просмотреть файл

@ -269,66 +269,6 @@ function UpdateBackForwardCommands(aWebNavigation) {
* XXXmano: should this live in toolbarbutton.xml? * XXXmano: should this live in toolbarbutton.xml?
*/ */
function SetClickAndHoldHandlers() { function SetClickAndHoldHandlers() {
var timer;
function openMenu(aButton) {
cancelHold(aButton);
aButton.firstChild.hidden = false;
aButton.open = true;
}
function mousedownHandler(aEvent) {
if (aEvent.button != 0 ||
aEvent.currentTarget.open ||
aEvent.currentTarget.disabled)
return;
// Prevent the menupopup from opening immediately
aEvent.currentTarget.firstChild.hidden = true;
aEvent.currentTarget.addEventListener("mouseout", mouseoutHandler, false);
aEvent.currentTarget.addEventListener("mouseup", mouseupHandler, false);
timer = setTimeout(openMenu, 500, aEvent.currentTarget);
}
function mouseoutHandler(aEvent) {
let buttonRect = aEvent.currentTarget.getBoundingClientRect();
if (aEvent.clientX >= buttonRect.left &&
aEvent.clientX <= buttonRect.right &&
aEvent.clientY >= buttonRect.bottom)
openMenu(aEvent.currentTarget);
else
cancelHold(aEvent.currentTarget);
}
function mouseupHandler(aEvent) {
cancelHold(aEvent.currentTarget);
}
function cancelHold(aButton) {
clearTimeout(timer);
aButton.removeEventListener("mouseout", mouseoutHandler, false);
aButton.removeEventListener("mouseup", mouseupHandler, false);
}
function clickHandler(aEvent) {
if (aEvent.button == 0 &&
aEvent.target == aEvent.currentTarget &&
!aEvent.currentTarget.open &&
!aEvent.currentTarget.disabled) {
let cmdEvent = document.createEvent("xulcommandevent");
cmdEvent.initCommandEvent("command", true, true, window, 0,
aEvent.ctrlKey, aEvent.altKey, aEvent.shiftKey,
aEvent.metaKey, null);
aEvent.currentTarget.dispatchEvent(cmdEvent);
}
}
function _addClickAndHoldListenersOnElement(aElm) {
aElm.addEventListener("mousedown", mousedownHandler, true);
aElm.addEventListener("click", clickHandler, true);
}
// Bug 414797: Clone the back/forward buttons' context menu into both buttons. // Bug 414797: Clone the back/forward buttons' context menu into both buttons.
let popup = document.getElementById("backForwardMenu").cloneNode(true); let popup = document.getElementById("backForwardMenu").cloneNode(true);
popup.removeAttribute("id"); popup.removeAttribute("id");
@ -338,15 +278,107 @@ function SetClickAndHoldHandlers() {
let backButton = document.getElementById("back-button"); let backButton = document.getElementById("back-button");
backButton.setAttribute("type", "menu"); backButton.setAttribute("type", "menu");
backButton.appendChild(popup); backButton.appendChild(popup);
_addClickAndHoldListenersOnElement(backButton); gClickAndHoldListenersOnElement.add(backButton);
let forwardButton = document.getElementById("forward-button"); let forwardButton = document.getElementById("forward-button");
popup = popup.cloneNode(true); popup = popup.cloneNode(true);
forwardButton.setAttribute("type", "menu"); forwardButton.setAttribute("type", "menu");
forwardButton.appendChild(popup); forwardButton.appendChild(popup);
_addClickAndHoldListenersOnElement(forwardButton); gClickAndHoldListenersOnElement.add(forwardButton);
} }
const gClickAndHoldListenersOnElement = {
_timers: new Map(),
_mousedownHandler(aEvent) {
if (aEvent.button != 0 ||
aEvent.currentTarget.open ||
aEvent.currentTarget.disabled)
return;
// Prevent the menupopup from opening immediately
aEvent.currentTarget.firstChild.hidden = true;
aEvent.currentTarget.addEventListener("mouseout", this, false);
aEvent.currentTarget.addEventListener("mouseup", this, false);
this._timers.set(aEvent.currentTarget, setTimeout((b) => this._openMenu(b), 500, aEvent.currentTarget));
},
_clickHandler(aEvent) {
if (aEvent.button == 0 &&
aEvent.target == aEvent.currentTarget &&
!aEvent.currentTarget.open &&
!aEvent.currentTarget.disabled) {
let cmdEvent = document.createEvent("xulcommandevent");
cmdEvent.initCommandEvent("command", true, true, window, 0,
aEvent.ctrlKey, aEvent.altKey, aEvent.shiftKey,
aEvent.metaKey, null);
aEvent.currentTarget.dispatchEvent(cmdEvent);
// This is here to cancel the XUL default event
// dom.click() triggers a command even if there is a click handler
// however this can now be prevented with preventDefault().
aEvent.preventDefault();
}
},
_openMenu(aButton) {
this._cancelHold(aButton);
aButton.firstChild.hidden = false;
aButton.open = true;
},
_mouseoutHandler(aEvent) {
let buttonRect = aEvent.currentTarget.getBoundingClientRect();
if (aEvent.clientX >= buttonRect.left &&
aEvent.clientX <= buttonRect.right &&
aEvent.clientY >= buttonRect.bottom)
this._openMenu(aEvent.currentTarget);
else
this._cancelHold(aEvent.currentTarget);
},
_mouseupHandler(aEvent) {
this._cancelHold(aEvent.currentTarget);
},
_cancelHold(aButton) {
clearTimeout(this._timers.get(aButton));
aButton.removeEventListener("mouseout", this, false);
aButton.removeEventListener("mouseup", this, false);
},
handleEvent(e) {
switch (e.type) {
case "mouseout":
this._mouseoutHandler(e);
break;
case "mousedown":
this._mousedownHandler(e);
break;
case "click":
this._clickHandler(e);
break;
case "mouseup":
this._mouseupHandler(e);
break;
}
},
remove(aButton) {
aButton.removeEventListener("mousedown", this, true);
aButton.removeEventListener("click", this, true);
},
add(aElm) {
this._timers.delete(aElm);
aElm.addEventListener("mousedown", this, true);
aElm.addEventListener("click", this, true);
}
};
const gSessionHistoryObserver = { const gSessionHistoryObserver = {
observe: function(subject, topic, data) observe: function(subject, topic, data)
{ {
@ -4100,22 +4132,25 @@ function updateUserContextUIIndicator()
let userContextId = gBrowser.selectedBrowser.getAttribute("usercontextid"); let userContextId = gBrowser.selectedBrowser.getAttribute("usercontextid");
if (!userContextId) { if (!userContextId) {
hbox.setAttribute("data-identity-color", "");
hbox.hidden = true; hbox.hidden = true;
return; return;
} }
let identity = ContextualIdentityService.getIdentityFromId(userContextId); let identity = ContextualIdentityService.getIdentityFromId(userContextId);
if (!identity) { if (!identity) {
hbox.setAttribute("data-identity-color", "");
hbox.hidden = true; hbox.hidden = true;
return; return;
} }
hbox.setAttribute("data-identity-color", identity.color);
let label = document.getElementById("userContext-label"); let label = document.getElementById("userContext-label");
label.setAttribute('value', ContextualIdentityService.getUserContextLabel(userContextId)); label.setAttribute("value", ContextualIdentityService.getUserContextLabel(userContextId));
label.style.color = identity.color;
let indicator = document.getElementById("userContext-indicator"); let indicator = document.getElementById("userContext-indicator");
indicator.style.listStyleImage = "url(" + identity.icon + ")"; indicator.setAttribute("data-identity-icon", identity.icon);
hbox.hidden = false; hbox.hidden = false;
} }

Просмотреть файл

@ -1867,7 +1867,7 @@ nsContextMenu.prototype = {
}, },
createContainerMenu: function(aEvent) { createContainerMenu: function(aEvent) {
return createUserContextMenu(aEvent, false, return createUserContextMenu(aEvent, true,
gContextMenuContentData.userContextId); gContextMenuContentData.userContextId);
}, },
}; };

Просмотреть файл

@ -529,7 +529,7 @@ function openCacheEntry(key, cb)
function makeGeneralTab(metaViewRows, docInfo) function makeGeneralTab(metaViewRows, docInfo)
{ {
var title = (docInfo.title) ? gBundle.getFormattedString("pageTitle", [docInfo.title]) : gBundle.getString("noPageTitle"); var title = (docInfo.title) ? docInfo.title : gBundle.getString("noPageTitle");
document.getElementById("titletext").value = title; document.getElementById("titletext").value = title;
var url = docInfo.location; var url = docInfo.location;

Просмотреть файл

@ -88,7 +88,6 @@
<deck id="mainDeck" flex="1"> <deck id="mainDeck" flex="1">
<!-- General page information --> <!-- General page information -->
<vbox id="generalPanel"> <vbox id="generalPanel">
<textbox class="header" readonly="true" id="titletext"/>
<grid id="generalGrid"> <grid id="generalGrid">
<columns> <columns>
<column/> <column/>
@ -96,6 +95,11 @@
<column flex="1"/> <column flex="1"/>
</columns> </columns>
<rows id="generalRows"> <rows id="generalRows">
<row id="generalTitle">
<label control="titletext" value="&generalTitle;"/>
<separator/>
<textbox readonly="true" id="titletext"/>
</row>
<row id="generalURLRow"> <row id="generalURLRow">
<label control="urltext" value="&generalURL;"/> <label control="urltext" value="&generalURL;"/>
<separator/> <separator/>

Просмотреть файл

@ -5236,7 +5236,7 @@
</xul:arrowscrollbox> </xul:arrowscrollbox>
</content> </content>
<implementation implements="nsIDOMEventListener"> <implementation implements="nsIDOMEventListener, nsIObserver">
<constructor> <constructor>
<![CDATA[ <![CDATA[
this.mTabClipWidth = Services.prefs.getIntPref("browser.tabs.tabClipWidth"); this.mTabClipWidth = Services.prefs.getIntPref("browser.tabs.tabClipWidth");
@ -5255,9 +5255,17 @@
this._tabAnimationLoggingEnabled = false; this._tabAnimationLoggingEnabled = false;
} }
this._browserNewtabpageEnabled = Services.prefs.getBoolPref("browser.newtabpage.enabled"); this._browserNewtabpageEnabled = Services.prefs.getBoolPref("browser.newtabpage.enabled");
this.observe(null, "nsPref:changed", "privacy.userContext.enabled");
Services.prefs.addObserver("privacy.userContext.enabled", this, false);
]]> ]]>
</constructor> </constructor>
<destructor>
<![CDATA[
Services.prefs.removeObserver("privacy.userContext.enabled", this);
]]>
</destructor>
<field name="tabbrowser" readonly="true"> <field name="tabbrowser" readonly="true">
document.getElementById(this.getAttribute("tabbrowser")); document.getElementById(this.getAttribute("tabbrowser"));
</field> </field>
@ -5283,6 +5291,53 @@
<field name="_afterHoveredTab">null</field> <field name="_afterHoveredTab">null</field>
<field name="_hoveredTab">null</field> <field name="_hoveredTab">null</field>
<method name="observe">
<parameter name="aSubject"/>
<parameter name="aTopic"/>
<parameter name="aData"/>
<body><![CDATA[
switch (aTopic) {
case "nsPref:changed":
// This is the only pref observed.
let containersEnabled = Services.prefs.getBoolPref("privacy.userContext.enabled");
const newTab = document.getElementById("new-tab-button");
const newTab2 = document.getAnonymousElementByAttribute(this, "anonid", "tabs-newtab-button")
if (containersEnabled) {
for (let parent of [newTab, newTab2]) {
if (!parent)
continue;
let popup = document.createElementNS(
"http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul",
"menupopup");
if (parent.id) {
popup.id = "newtab-popup";
} else {
popup.setAttribute("anonid", "newtab-popup");
}
popup.className = "new-tab-popup";
popup.setAttribute("position", "after_end");
parent.appendChild(popup);
gClickAndHoldListenersOnElement.add(parent);
parent.setAttribute("type", "menu");
}
} else {
for (let parent of [newTab, newTab2]) {
if (!parent)
continue;
gClickAndHoldListenersOnElement.remove(parent);
parent.removeAttribute("type");
parent.firstChild.remove();
}
}
break;
}
]]></body>
</method>
<property name="_isCustomizing" readonly="true"> <property name="_isCustomizing" readonly="true">
<getter> <getter>
let root = document.documentElement; let root = document.documentElement;
@ -6963,41 +7018,47 @@
<handlers> <handlers>
<handler event="popupshowing"> <handler event="popupshowing">
<![CDATA[ <![CDATA[
if (event.target.getAttribute('id') == "alltabs_containersMenuTab") { if (event.target.getAttribute("id") == "alltabs_containersMenuTab") {
createUserContextMenu(event); createUserContextMenu(event);
return; return;
} }
let containersEnabled = Services.prefs.getBoolPref("privacy.userContext.enabled"); let containersEnabled = Services.prefs.getBoolPref("privacy.userContext.enabled");
document.getElementById("alltabs-popup-separator-1").hidden = !containersEnabled;
let containersTab = document.getElementById("alltabs_containersTab");
containersTab.hidden = !containersEnabled; if (event.target.getAttribute("anonid") == "newtab-popup" ||
if (PrivateBrowsingUtils.isWindowPrivate(window)) { event.target.id == "newtab-popup") {
containersTab.setAttribute("disabled", "true"); createUserContextMenu(event);
} else {
document.getElementById("alltabs-popup-separator-1").hidden = !containersEnabled;
let containersTab = document.getElementById("alltabs_containersTab");
containersTab.hidden = !containersEnabled;
if (PrivateBrowsingUtils.isWindowPrivate(window)) {
containersTab.setAttribute("disabled", "true");
}
document.getElementById("alltabs_undoCloseTab").disabled =
SessionStore.getClosedTabCount(window) == 0;
var tabcontainer = gBrowser.tabContainer;
// Listen for changes in the tab bar.
tabcontainer.addEventListener("TabAttrModified", this, false);
tabcontainer.addEventListener("TabClose", this, false);
tabcontainer.mTabstrip.addEventListener("scroll", this, false);
let tabs = gBrowser.visibleTabs;
for (var i = 0; i < tabs.length; i++) {
if (!tabs[i].pinned)
this._createTabMenuItem(tabs[i]);
}
this._updateTabsVisibilityStatus();
} }
document.getElementById("alltabs_undoCloseTab").disabled =
SessionStore.getClosedTabCount(window) == 0;
var tabcontainer = gBrowser.tabContainer;
// Listen for changes in the tab bar.
tabcontainer.addEventListener("TabAttrModified", this, false);
tabcontainer.addEventListener("TabClose", this, false);
tabcontainer.mTabstrip.addEventListener("scroll", this, false);
let tabs = gBrowser.visibleTabs;
for (var i = 0; i < tabs.length; i++) {
if (!tabs[i].pinned)
this._createTabMenuItem(tabs[i]);
}
this._updateTabsVisibilityStatus();
]]></handler> ]]></handler>
<handler event="popuphidden"> <handler event="popuphidden">
<![CDATA[ <![CDATA[
if (event.target.getAttribute('id') == "alltabs_containersMenuTab") { if (event.target.getAttribute("id") == "alltabs_containersMenuTab") {
return; return;
} }
@ -7008,6 +7069,9 @@
menuItem.tab.mCorrespondingMenuitem = null; menuItem.tab.mCorrespondingMenuitem = null;
this.removeChild(menuItem); this.removeChild(menuItem);
} }
if (menuItem.hasAttribute("usercontextid")) {
this.removeChild(menuItem);
}
} }
var tabcontainer = gBrowser.tabContainer; var tabcontainer = gBrowser.tabContainer;
tabcontainer.mTabstrip.removeEventListener("scroll", this, false); tabcontainer.mTabstrip.removeEventListener("scroll", this, false);

Просмотреть файл

@ -534,3 +534,4 @@ skip-if = !e10s
tags = mcb tags = mcb
[browser_newwindow_focus.js] [browser_newwindow_focus.js]
skip-if = (os == "linux" && !e10s) # Bug 1263254 - Perma fails on Linux without e10s for some reason. skip-if = (os == "linux" && !e10s) # Bug 1263254 - Perma fails on Linux without e10s for some reason.
[browser_bug1299667.js]

Просмотреть файл

@ -0,0 +1,71 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
const { addObserver, removeObserver } = Cc["@mozilla.org/observer-service;1"].
getService(Ci.nsIObserverService);
function receive(topic) {
return new Promise((resolve, reject) => {
let timeout = setTimeout(() => {
reject(new Error("Timeout"));
}, 90000);
const observer = {
observe: subject => {
removeObserver(observer, topic);
clearTimeout(timeout);
resolve(subject);
}
};
addObserver(observer, topic, false);
});
}
add_task(function* () {
yield BrowserTestUtils.openNewForegroundTab(gBrowser, "http://example.com");
yield ContentTask.spawn(gBrowser.selectedBrowser, {}, function* () {
content.history.pushState({}, "2", "2.html");
});
yield receive("sessionstore-state-write-complete");
// Wait for the session data to be flushed before continuing the test
yield new Promise(resolve => SessionStore.getSessionHistory(gBrowser.selectedTab, resolve));
var backButton = document.getElementById("back-button");
var contextMenu = document.getElementById("backForwardMenu");
info("waiting for the history menu to open");
let popupShownPromise = BrowserTestUtils.waitForEvent(contextMenu, "popupshown");
EventUtils.synthesizeMouseAtCenter(backButton, {type: "contextmenu", button: 2});
let event = yield popupShownPromise;
ok(true, "history menu opened");
// Wait for the session data to be flushed before continuing the test
yield new Promise(resolve => SessionStore.getSessionHistory(gBrowser.selectedTab, resolve));
is(event.target.children.length, 2, "Two history items");
let node = event.target.firstChild;
is(node.getAttribute("uri"), "http://example.com/2.html", "first item uri");
is(node.getAttribute("index"), "1", "first item index");
is(node.getAttribute("historyindex"), "0", "first item historyindex");
node = event.target.lastChild;
is(node.getAttribute("uri"), "http://example.com/", "second item uri");
is(node.getAttribute("index"), "0", "second item index");
is(node.getAttribute("historyindex"), "-1", "second item historyindex");
let popupHiddenPromise = BrowserTestUtils.waitForEvent(contextMenu, "popuphidden");
event.target.hidePopup();
yield popupHiddenPromise;
info("Hidden popup");
let onClose = BrowserTestUtils.waitForEvent(gBrowser.tabContainer, "TabClose");
yield BrowserTestUtils.removeTab(gBrowser.selectedTab);
yield onClose;
info("Tab closed");
});

Просмотреть файл

@ -57,6 +57,7 @@ skip-if = !crashreporter
[browser_CTP_iframe.js] [browser_CTP_iframe.js]
[browser_CTP_multi_allow.js] [browser_CTP_multi_allow.js]
[browser_CTP_nonplugins.js] [browser_CTP_nonplugins.js]
skip-if = true # Bug 1315042
[browser_CTP_notificationBar.js] [browser_CTP_notificationBar.js]
[browser_CTP_outsideScrollArea.js] [browser_CTP_outsideScrollArea.js]
[browser_CTP_remove_navigate.js] [browser_CTP_remove_navigate.js]

Просмотреть файл

@ -6,6 +6,7 @@ support-files =
head.js head.js
[browser_referrer_middle_click.js] [browser_referrer_middle_click.js]
skip-if = true # Bug 1315042
[browser_referrer_middle_click_in_container.js] [browser_referrer_middle_click_in_container.js]
[browser_referrer_open_link_in_private.js] [browser_referrer_open_link_in_private.js]
skip-if = os == 'linux' # Bug 1145199 skip-if = os == 'linux' # Bug 1145199

Просмотреть файл

@ -83,5 +83,11 @@ function* testProbe(aProbe) {
`Spinner probe should now have a value in some bucket`); `Spinner probe should now have a value in some bucket`);
} }
add_task(function* setup() {
yield SpecialPowers.pushPrefEnv({
set: [["dom.ipc.processCount", 1]]
});
});
add_task(testProbe.bind(null, "FX_TAB_SWITCH_SPINNER_VISIBLE_MS")); add_task(testProbe.bind(null, "FX_TAB_SWITCH_SPINNER_VISIBLE_MS"));
add_task(testProbe.bind(null, "FX_TAB_SWITCH_SPINNER_VISIBLE_LONG_MS")); add_task(testProbe.bind(null, "FX_TAB_SWITCH_SPINNER_VISIBLE_LONG_MS"));

Просмотреть файл

@ -1,6 +1,12 @@
const kURL1 = "data:text/html,Should I stay or should I go?"; const kURL1 = "data:text/html,Should I stay or should I go?";
const kURL2 = "data:text/html,I shouldn't be here!"; const kURL2 = "data:text/html,I shouldn't be here!";
add_task(function* setup() {
yield SpecialPowers.pushPrefEnv({
set: [["dom.ipc.processCount", 1]]
});
});
/** /**
* Verify that if we open a new tab and try to make it the selected tab while * Verify that if we open a new tab and try to make it the selected tab while
* print preview is up, that doesn't happen. * print preview is up, that doesn't happen.

Просмотреть файл

@ -9,3 +9,4 @@ skip-if = buildapp == 'mulet' || (os == "linux" && debug) # linux: bug 976544
[browser_devices_get_user_media_anim.js] [browser_devices_get_user_media_anim.js]
[browser_devices_get_user_media_in_frame.js] [browser_devices_get_user_media_in_frame.js]
[browser_devices_get_user_media_tear_off_tab.js] [browser_devices_get_user_media_tear_off_tab.js]
skip-if = true # Bug 1315042

Просмотреть файл

@ -1539,7 +1539,8 @@ file, You can obtain one at http://mozilla.org/MPL/2.0/.
let showNotification = aInput.shouldShowSearchSuggestionsNotification; let showNotification = aInput.shouldShowSearchSuggestionsNotification;
if (showNotification) { if (showNotification) {
let prefs = aInput._prefs; let prefs = aInput._prefs;
let date = parseInt((new Date()).toLocaleFormat("%Y%m%d")); let now = new Date();
let date = now.getFullYear() * 10000 + (now.getMonth() + 1) * 100 + now.getDate();
let previousDate = prefs.getIntPref("lastSuggestionsPromptDate"); let previousDate = prefs.getIntPref("lastSuggestionsPromptDate");
if (previousDate < date) { if (previousDate < date) {
let remainingDays = let remainingDays =

Просмотреть файл

@ -0,0 +1,23 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- 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/. -->
<svg xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
width="32" height="32" viewBox="0 0 32 32">
<style>
path, circle {
fill: menutext;
}
path:not(:target),
circle:not(:target) {
display: none;
}
</style>
<path id="dollar" d="M17.3857868,14.0527919 C14.2304569,13.0862944 13.4913706,12.4609137 13.4913706,11.0964467 C13.4913706,9.61827411 14.7137056,8.85076142 16.4192893,8.85076142 C17.9827411,8.85076142 19.3187817,9.33401015 20.5979695,10.4994924 L22.4456853,8.42436548 C21.1664975,7.20203046 19.3187819,6.26535905 17,6.00952148 L17,2 L15,2 L15,6.00952148 C12.3827412,6.43591742 9.76751269,8.53807107 9.76751269,11.3238579 C9.76751269,14.1664975 11.4730964,15.786802 15.4812183,17.0091371 C18.4375635,17.9187817 19.2335025,18.6294416 19.2335025,20.2213198 C19.2335025,22.0690355 17.7553299,23.035533 15.7370558,23.035533 C13.7756345,23.035533 12.2406091,22.3248731 10.9329949,21.1025381 L9,23.2345178 C10.4213198,24.6274112 12.8659899,25.8324934 15,26.0030518 L15,30 L17,30 L17,26.0030518 C20.7116753,25.4060974 22.9857868,22.893401 22.9857868,20.022335 C22.9857868,16.4690355 20.7116751,15.1045685 17.3857868,14.0527919 Z"/>
<path id="briefcase" fill-rule="evenodd" d="M22,9.99887085 L21.635468,10 L29.0034652,10 C29.5538362,10 30,10.4449463 30,10.9933977 L30,27.0066023 C30,27.5552407 29.5601869,28 29.0034652,28 L2.99653482,28 C2.44616384,28 2,27.5550537 2,27.0066023 L2,10.9933977 C2,10.4447593 2.43981314,10 2.99653482,10 L8,10 L8,7.99922997 C8,5.79051625 10.0426627,4 12.5635454,4 L19.4364546,4 C21.9568311,4 24,5.79246765 24,7.99922997 L24,9.99267578 L22,9.99887085 L22,10 L10,10 L10,7.99922997 C10,6.89421235 11.0713286,6 12.3917227,6 L19.6082773,6 C20.9273761,6 22,6.89552665 22,7.99922997 L22,9.99887085 Z"/>
<path id="fingerprint" d="M7.17741905,12 C7.10965537,12 7.041327,11.9953181 6.97243393,11.985018 C6.33263187,11.8918489 5.90515601,11.3862071 6.01809547,10.8552833 C7.41798011,4.26321358 12.2613889,2.57493207 15.0238882,2.15590491 C19.6448063,1.45690206 24.3408291,3.21541158 25.8344535,5.29743816 C26.1664955,5.76047488 25.9835336,6.35881757 25.4244832,6.63364321 C24.8654329,6.9098734 24.1437497,6.75583996 23.8122724,6.29327142 C22.8923805,5.01043967 19.1749781,3.51130562 15.4479759,4.07406612 C12.8080159,4.474834 9.43056132,6.03623689 8.33561323,11.1942506 C8.23453242,11.666651 7.73816348,12 7.17741905,12 Z M16.63127,26 C16.1452186,26 15.6509104,25.9658335 15.147795,25.8938767 C10.637921,25.257137 6.71207921,21.8114952 6.01575422,17.8807924 C5.91171832,17.2932317 6.33391695,16.7382846 6.95813239,16.6404441 C7.58454965,16.5343208 8.17298555,16.9406954 8.27757192,17.5272206 C8.80876054,20.5255916 11.9766264,23.26409 15.4885263,23.7610576 C17.3975027,24.02766 20.959494,23.8221432 23.3220449,19.3789425 C24.4625867,17.2331815 23.0049831,11.881462 19.9521622,9.34692739 C18.2380468,7.92384005 16.4573263,7.76905536 14.6628445,8.89499751 C13.26469,9.77142052 11.8070864,12.2857658 11.8665355,14.6287608 C11.9127737,16.4835887 12.8386382,17.9325598 14.6171568,18.9363308 C15.2210054,19.2764429 16.9411759,19.4933486 17.9424527,18.8296898 C18.7257495,18.3104622 18.9591422,17.2761485 18.6365758,15.7583267 C18.3822659,14.5650869 17.2219077,12.4452096 16.6664991,12.3711821 C16.6692513,12.3722175 16.4666841,12.4312324 16.1276041,12.9095636 C15.8545786,13.2936782 15.58981,14.7297074 15.9476054,15.3581643 C16.0142104,15.4761941 16.0725586,15.5465978 16.3202632,15.5465978 C16.9532859,15.5465978 17.46686,16.0290705 17.46686,16.6249139 C17.46686,17.2207573 16.9543868,17.7042653 16.3213641,17.7042653 C15.2644914,17.7042653 14.4140391,17.2336992 13.9268868,16.3774655 C13.1083609,14.9388479 13.5536787,12.6548678 14.2202791,11.7137354 C15.2540327,10.2564816 16.3631986,10.1151564 17.1123672,10.2564816 C19.7066595,10.7389543 20.8763754,15.2908666 20.8857331,15.3359043 C21.5303153,18.3648181 20.3594985,19.8665919 19.264094,20.593407 C17.4151172,21.8192603 14.6920186,21.493643 13.4380832,20.7859819 C10.3280151,19.0310652 9.62013053,16.497566 9.5744428,14.6805283 C9.49022326,11.3643051 11.4779146,8.30018945 13.391845,7.10021984 C16.0417332,5.43848454 18.9877658,5.66781436 21.4714167,7.72919442 C25.1176276,10.7565552 27.0871539,17.1229168 25.3746898,20.3433702 C23.4326862,23.9950465 20.2983981,26 16.63127,26 Z M16.0845157,30 C14.9348455,30 13.9050564,29.8557557 13.0394288,29.6610017 C10.2114238,29.0257442 7.58700058,27.4599412 6.18892823,25.5735955 C5.84440518,25.1078371 5.98426642,24.4803503 6.50105099,24.1700066 C7.01675554,23.8596629 7.71552172,23.986423 8.06112477,24.4507244 C9.89498097,26.9252176 15.9397944,29.9781448 22.2508301,26.1937972 C22.7676147,25.8844249 23.4658409,26.0087566 23.8109039,26.474515 C24.155427,26.9397877 24.0161057,27.5672745 23.4993212,27.8776182 C20.7987573,29.4963593 18.2315746,30 16.0845157,30 Z"/>
<path id="cart" fill-rule="evenodd" d="M20.8195396,14 L15.1804604,14 L15.1804604,14 L15.8471271,18 L20.1528729,18 L20.8195396,14 Z M22.8471271,14 L27.6125741,14 L27.6125741,14 L26.2792408,18 L22.1804604,18 L22.8471271,14 Z M21.1528729,12 L14.8471271,12 L14.8471271,12 L14.1804604,8 L21.8195396,8 L21.1528729,12 Z M23.1804604,12 L28.2792408,12 L28.2792408,12 L29.6125741,8 L23.8471271,8 L23.1804604,12 Z M13.1528729,14 L8.47703296,14 L10.077033,18 L10.077033,18 L13.8195396,18 L13.1528729,14 Z M12.8195396,12 L7.67703296,12 L6.07703296,8 L12.1528729,8 L12.8195396,12 L12.8195396,12 Z M31.7207592,8 L32,8 L32,6 L31,6 L5.27703296,6 L5.27703296,6 L4,2.8074176 L4,2 L3,2 L1,2 L0,2 L0,4 L1,4 L2.32296704,4 L9.78931928,22.6658806 L9.78931928,22.6658806 C8.71085924,23.3823847 8,24.6081773 8,26 C8,28.209139 9.790861,30 12,30 C14.209139,30 16,28.209139 16,26 C16,25.2714257 15.8052114,24.5883467 15.4648712,24 L22.5351288,24 C22.1947886,24.5883467 22,25.2714257 22,26 C22,28.209139 23.790861,30 26,30 C28.209139,30 30,28.209139 30,26 C30,23.790861 28.209139,22 26,22 L11.677033,22 L10.877033,20 L27,20 L28,20 L28,19.1622777 L31.7207592,8 L31.7207592,8 Z M26,28 C27.1045695,28 28,27.1045695 28,26 C28,24.8954305 27.1045695,24 26,24 C24.8954305,24 24,24.8954305 24,26 C24,27.1045695 24.8954305,28 26,28 Z M12,28 C13.1045695,28 14,27.1045695 14,26 C14,24.8954305 13.1045695,24 12,24 C10.8954305,24 10,24.8954305 10,26 C10,27.1045695 10.8954305,28 12,28 Z"/>
<circle id="circle" r="16" cx="16" cy="16" fill-rule="evenodd" />
</svg>

После

Ширина:  |  Высота:  |  Размер: 6.5 KiB

Просмотреть файл

@ -438,9 +438,8 @@ function checkForMiddleClick(node, event) {
} }
// Populate a menu with user-context menu items. This method should be called // Populate a menu with user-context menu items. This method should be called
// by onpopupshowing passing the event as first argument. addCommandAttribute // by onpopupshowing passing the event as first argument.
// param is used to set the 'command' attribute in the new menuitem elements. function createUserContextMenu(event, isContextMenu = false, excludeUserContextId = 0) {
function createUserContextMenu(event, addCommandAttribute = true, excludeUserContextId = 0) {
while (event.target.hasChildNodes()) { while (event.target.hasChildNodes()) {
event.target.removeChild(event.target.firstChild); event.target.removeChild(event.target.firstChild);
} }
@ -455,9 +454,9 @@ function createUserContextMenu(event, addCommandAttribute = true, excludeUserCon
menuitem.setAttribute("label", bundle.getString("userContextNone.label")); menuitem.setAttribute("label", bundle.getString("userContextNone.label"));
menuitem.setAttribute("accesskey", bundle.getString("userContextNone.accesskey")); menuitem.setAttribute("accesskey", bundle.getString("userContextNone.accesskey"));
// We don't set an oncommand/command attribute attribute because if we have // We don't set an oncommand/command attribute because if we have
// to exclude a userContextId we are generating the contextMenu and // to exclude a userContextId we are generating the contextMenu and
// addCommandAttribute will be false. // isContextMenu will be true.
docfrag.appendChild(menuitem); docfrag.appendChild(menuitem);
@ -479,16 +478,29 @@ function createUserContextMenu(event, addCommandAttribute = true, excludeUserCon
} }
menuitem.classList.add("menuitem-iconic"); menuitem.classList.add("menuitem-iconic");
menuitem.setAttribute("data-identity-color", identity.color);
if (addCommandAttribute) { if (!isContextMenu) {
menuitem.setAttribute("command", "Browser:NewUserContextTab"); menuitem.setAttribute("command", "Browser:NewUserContextTab");
} }
menuitem.setAttribute("image", identity.icon); menuitem.setAttribute("data-identity-icon", identity.icon);
docfrag.appendChild(menuitem); docfrag.appendChild(menuitem);
}); });
if (!isContextMenu) {
docfrag.appendChild(document.createElement("menuseparator"));
let menuitem = document.createElement("menuitem");
menuitem.setAttribute("label",
bundle.getString("userContext.aboutPage.label"));
menuitem.setAttribute("accesskey",
bundle.getString("userContext.aboutPage.accesskey"));
menuitem.setAttribute("command", "Browser:OpenAboutContainers");
docfrag.appendChild(menuitem);
}
event.target.appendChild(docfrag); event.target.appendChild(docfrag);
return true; return true;
} }

Просмотреть файл

@ -165,6 +165,7 @@ browser.jar:
content/browser/tabbrowser.xml (content/tabbrowser.xml) content/browser/tabbrowser.xml (content/tabbrowser.xml)
content/browser/urlbarBindings.xml (content/urlbarBindings.xml) content/browser/urlbarBindings.xml (content/urlbarBindings.xml)
content/browser/utilityOverlay.js (content/utilityOverlay.js) content/browser/utilityOverlay.js (content/utilityOverlay.js)
content/browser/usercontext.svg (content/usercontext.svg)
content/browser/web-panels.js (content/web-panels.js) content/browser/web-panels.js (content/web-panels.js)
* content/browser/web-panels.xul (content/web-panels.xul) * content/browser/web-panels.xul (content/web-panels.xul)
* content/browser/baseMenuOverlay.xul (content/baseMenuOverlay.xul) * content/browser/baseMenuOverlay.xul (content/baseMenuOverlay.xul)

Просмотреть файл

@ -1,3 +1,63 @@
[data-identity-color="blue"] {
--identity-tab-color: #0996f8;
--identity-icon-color: #00a7e0;
}
[data-identity-color="turquoise"] {
--identity-tab-color: #01bdad;
--identity-icon-color: #01bdad;
}
[data-identity-color="green"] {
--identity-tab-color: #57bd35;
--identity-icon-color: #7dc14c;
}
[data-identity-color="yellow"] {
--identity-tab-color: #ffcb00;
--identity-icon-color: #ffcb00;
}
[data-identity-color="orange"] {
--identity-tab-color: #ff9216;
--identity-icon-color: #ff9216;
}
[data-identity-color="red"] {
--identity-tab-color: #d92215;
--identity-icon-color: #d92215;
}
[data-identity-color="pink"] {
--identity-tab-color: #ea385e;
--identity-icon-color: #ee5195;
}
[data-identity-color="purple"] {
--identity-tab-color: #7a2f7a;
--identity-icon-color: #7a2f7a;
}
[data-identity-icon="fingerprint"] {
--identity-icon: url("chrome://browser/content/usercontext.svg#fingerprint");
}
[data-identity-icon="briefcase"] {
--identity-icon: url("chrome://browser/content/usercontext.svg#briefcase");
}
[data-identity-icon="dollar"] {
--identity-icon: url("chrome://browser/content/usercontext.svg#dollar");
}
[data-identity-icon="cart"] {
--identity-icon: url("chrome://browser/content/usercontext.svg#cart");
}
[data-identity-icon="circle"] {
--identity-icon: url("chrome://browser/content/usercontext.svg#circle");
}
#userContext-indicator { #userContext-indicator {
height: 16px; height: 16px;
width: 16px; width: 16px;
@ -5,9 +65,27 @@
#userContext-label { #userContext-label {
margin-inline-end: 3px; margin-inline-end: 3px;
color: #909090; color: var(--identity-tab-color);
} }
#userContext-icons { #userContext-icons {
-moz-box-align: center; -moz-box-align: center;
} }
.tabbrowser-tab[usercontextid] {
background-image: linear-gradient(to right, transparent 20%, var(--identity-tab-color) 30%, var(--identity-tab-color) 70%, transparent 80%);
background-size: auto 2px;
background-repeat: no-repeat;
}
.userContext-icon,
.menuitem-iconic[data-usercontextid] > .menu-iconic-left > .menu-iconic-icon,
.subviewbutton[usercontextid] > .toolbarbutton-icon,
#userContext-indicator {
background-image: var(--identity-icon);
filter: url(chrome://browser/skin/filters.svg#fill);
fill: var(--identity-icon-color);
background-size: contain;
background-repeat: no-repeat;
background-position: center center;
}

Просмотреть файл

@ -15,6 +15,7 @@ support-files =
[browser_forgetAPI_cookie_getCookiesWithOriginAttributes.js] [browser_forgetAPI_cookie_getCookiesWithOriginAttributes.js]
[browser_forgetAPI_EME_forgetThisSite.js] [browser_forgetAPI_EME_forgetThisSite.js]
[browser_forgetAPI_quota_clearStoragesForPrincipal.js] [browser_forgetAPI_quota_clearStoragesForPrincipal.js]
[browser_newtabButton.js]
[browser_usercontext.js] [browser_usercontext.js]
[browser_usercontextid_tabdrop.js] [browser_usercontextid_tabdrop.js]
skip-if = os == "mac" || os == "win" # Intermittent failure - bug 1268276 skip-if = os == "mac" || os == "win" # Intermittent failure - bug 1268276

Просмотреть файл

@ -0,0 +1,34 @@
"use strict";
// Testing that when the user opens the add tab menu and clicks menu items
// the correct context id is opened
add_task(function* test() {
yield SpecialPowers.pushPrefEnv({"set": [
["privacy.userContext.enabled", true]
]});
let newTab = document.getElementById('tabbrowser-tabs');
let newTabButton = document.getAnonymousElementByAttribute(newTab, "anonid", "tabs-newtab-button");
ok(newTabButton, "New tab button exists");
ok(!newTabButton.hidden, "New tab button is visible");
let popup = document.getAnonymousElementByAttribute(newTab, "anonid", "newtab-popup");
for (let i = 1; i <= 4; i++) {
let popupShownPromise = BrowserTestUtils.waitForEvent(popup, "popupshown");
EventUtils.synthesizeMouseAtCenter(newTabButton, {type: "mousedown"});
yield popupShownPromise;
let contextIdItem = popup.querySelector(`menuitem[data-usercontextid="${i}"]`);
ok(contextIdItem, `User context id ${i} exists`);
let waitForTabPromise = BrowserTestUtils.waitForNewTab(gBrowser);
EventUtils.synthesizeMouseAtCenter(contextIdItem, {});
let tab = yield waitForTabPromise;
is(tab.getAttribute('usercontextid'), i, `New tab has UCI equal ${i}`);
yield BrowserTestUtils.removeTab(tab);
}
});

Просмотреть файл

@ -25,7 +25,8 @@ add_task(function* setup() {
// make sure userContext is enabled. // make sure userContext is enabled.
yield new Promise(resolve => { yield new Promise(resolve => {
SpecialPowers.pushPrefEnv({"set": [ SpecialPowers.pushPrefEnv({"set": [
["privacy.userContext.enabled", true] ["privacy.userContext.enabled", true],
["dom.ipc.processCount", 1]
]}, resolve); ]}, resolve);
}); });
}); });

Просмотреть файл

@ -29,7 +29,8 @@ add_task(function* setup() {
// make sure userContext is enabled. // make sure userContext is enabled.
yield new Promise(resolve => { yield new Promise(resolve => {
SpecialPowers.pushPrefEnv({"set": [ SpecialPowers.pushPrefEnv({"set": [
["privacy.userContext.enabled", true] ["privacy.userContext.enabled", true],
["dom.ipc.processCount", 1]
]}, resolve); ]}, resolve);
}); });
}); });

Просмотреть файл

@ -1108,8 +1108,10 @@ const CustomizableWidgets = [
let onItemCommand = function (aEvent) { let onItemCommand = function (aEvent) {
let item = aEvent.target; let item = aEvent.target;
let userContextId = parseInt(item.getAttribute("usercontextid")); if (item.hasAttribute("usercontextid")) {
win.openUILinkIn(win.BROWSER_NEW_TAB_URL, "tab", {userContextId}); let userContextId = parseInt(item.getAttribute("usercontextid"));
win.openUILinkIn(win.BROWSER_NEW_TAB_URL, "tab", {userContextId});
}
}; };
items.addEventListener("command", onItemCommand); items.addEventListener("command", onItemCommand);
@ -1134,20 +1136,29 @@ const CustomizableWidgets = [
} }
let fragment = doc.createDocumentFragment(); let fragment = doc.createDocumentFragment();
let bundle = doc.getElementById("bundle_browser");
ContextualIdentityService.getIdentities().forEach(identity => { ContextualIdentityService.getIdentities().forEach(identity => {
let bundle = doc.getElementById("bundle_browser");
let label = ContextualIdentityService.getUserContextLabel(identity.userContextId); let label = ContextualIdentityService.getUserContextLabel(identity.userContextId);
let item = doc.createElementNS(kNSXUL, "toolbarbutton"); let item = doc.createElementNS(kNSXUL, "toolbarbutton");
item.setAttribute("label", label); item.setAttribute("label", label);
item.setAttribute("usercontextid", identity.userContextId); item.setAttribute("usercontextid", identity.userContextId);
item.setAttribute("class", "subviewbutton"); item.setAttribute("class", "subviewbutton");
item.setAttribute("image", identity.icon); item.setAttribute("data-identity-color", identity.color);
item.setAttribute("data-identity-icon", identity.icon);
fragment.appendChild(item); fragment.appendChild(item);
}); });
fragment.appendChild(doc.createElementNS(kNSXUL, "menuseparator"));
let item = doc.createElementNS(kNSXUL, "toolbarbutton");
item.setAttribute("label", bundle.getString("userContext.aboutPage.label"));
item.setAttribute("command", "Browser:OpenAboutContainers");
item.setAttribute("class", "subviewbutton");
fragment.appendChild(item);
items.appendChild(fragment); items.appendChild(fragment);
}, },

Просмотреть файл

@ -193,8 +193,9 @@ BrowserAction.prototype = {
// be ready by the time we get a complete click. // be ready by the time we get a complete click.
let tab = window.gBrowser.selectedTab; let tab = window.gBrowser.selectedTab;
let popupURL = this.getProperty(tab, "popup"); let popupURL = this.getProperty(tab, "popup");
let enabled = this.getProperty(tab, "enabled");
if (popupURL) { if (popupURL && enabled) {
this.pendingPopup = this.getPopup(window, popupURL); this.pendingPopup = this.getPopup(window, popupURL);
window.addEventListener("mouseup", this, true); window.addEventListener("mouseup", this, true);
} else { } else {

Просмотреть файл

@ -78,15 +78,6 @@ XPCOMUtils.defineLazyGetter(this, "standaloneStylesheets", () => {
return stylesheets; return stylesheets;
}); });
/* eslint-disable mozilla/balanced-listeners */
extensions.on("page-shutdown", (type, context) => {
if (context.viewType == "popup" && context.active) {
// TODO(robwu): This is not webext-oop compatible.
context.xulBrowser.contentWindow.close();
}
});
/* eslint-enable mozilla/balanced-listeners */
class BasePopup { class BasePopup {
constructor(extension, viewNode, popupURL, browserStyle, fixedWidth = false) { constructor(extension, viewNode, popupURL, browserStyle, fixedWidth = false) {
this.extension = extension; this.extension = extension;
@ -97,6 +88,8 @@ class BasePopup {
this.destroyed = false; this.destroyed = false;
this.fixedWidth = fixedWidth; this.fixedWidth = fixedWidth;
extension.callOnClose(this);
this.contentReady = new Promise(resolve => { this.contentReady = new Promise(resolve => {
this._resolveContentReady = resolve; this._resolveContentReady = resolve;
}); });
@ -120,7 +113,13 @@ class BasePopup {
return BasePopup.instances.get(window).get(extension); return BasePopup.instances.get(window).get(extension);
} }
close() {
this.closePopup();
}
destroy() { destroy() {
this.extension.forgetOnClose(this);
this.destroyed = true; this.destroyed = true;
this.browserLoadedDeferred.reject(new Error("Popup destroyed")); this.browserLoadedDeferred.reject(new Error("Popup destroyed"));
return this.browserReady.then(() => { return this.browserReady.then(() => {

Просмотреть файл

@ -53,6 +53,7 @@ tags = webextensions
[browser_ext_popup_api_injection.js] [browser_ext_popup_api_injection.js]
[browser_ext_popup_background.js] [browser_ext_popup_background.js]
[browser_ext_popup_corners.js] [browser_ext_popup_corners.js]
[browser_ext_popup_sendMessage.js]
[browser_ext_popup_shutdown.js] [browser_ext_popup_shutdown.js]
[browser_ext_runtime_openOptionsPage.js] [browser_ext_runtime_openOptionsPage.js]
[browser_ext_runtime_openOptionsPage_uninstall.js] [browser_ext_runtime_openOptionsPage_uninstall.js]

Просмотреть файл

@ -273,7 +273,7 @@ add_task(function* testBrowserActionClickCanceled() {
// We need to do these tests during the mouseup event cycle, since the click // We need to do these tests during the mouseup event cycle, since the click
// and command events will be dispatched immediately after mouseup, and void // and command events will be dispatched immediately after mouseup, and void
// the results. // the results.
let mouseUpPromise = BrowserTestUtils.waitForEvent(widget.node, "mouseup", event => { let mouseUpPromise = BrowserTestUtils.waitForEvent(widget.node, "mouseup", false, event => {
isnot(browserAction.pendingPopup, null, "Pending popup was not cleared"); isnot(browserAction.pendingPopup, null, "Pending popup was not cleared");
isnot(browserAction.pendingPopupTimeout, null, "Have a pending popup timeout"); isnot(browserAction.pendingPopupTimeout, null, "Have a pending popup timeout");
return true; return true;
@ -291,3 +291,74 @@ add_task(function* testBrowserActionClickCanceled() {
yield extension.unload(); yield extension.unload();
}); });
add_task(function* testBrowserActionDisabled() {
let extension = ExtensionTestUtils.loadExtension({
manifest: {
"browser_action": {
"default_popup": "popup.html",
"browser_style": true,
},
},
background() {
browser.browserAction.disable();
},
files: {
"popup.html": `<!DOCTYPE html><html><head><meta charset="utf-8"><script src="popup.js"></script></head></html>`,
"popup.js"() {
browser.test.fail("Should not get here");
},
},
});
yield extension.startup();
const {GlobalManager, Management: {global: {browserActionFor}}} = Cu.import("resource://gre/modules/Extension.jsm", {});
let ext = GlobalManager.extensionMap.get(extension.id);
let browserAction = browserActionFor(ext);
let widget = getBrowserActionWidget(extension).forWindow(window);
// Test canceled click.
EventUtils.synthesizeMouseAtCenter(widget.node, {type: "mousedown", button: 0}, window);
is(browserAction.pendingPopup, null, "Have no pending popup");
is(browserAction.pendingPopupTimeout, null, "Have no pending popup timeout");
EventUtils.synthesizeMouseAtCenter(document.documentElement, {type: "mouseup", button: 0}, window);
is(browserAction.pendingPopup, null, "Have no pending popup");
is(browserAction.pendingPopupTimeout, null, "Have no pending popup timeout");
// Test completed click.
EventUtils.synthesizeMouseAtCenter(widget.node, {type: "mousedown", button: 0}, window);
is(browserAction.pendingPopup, null, "Have no pending popup");
is(browserAction.pendingPopupTimeout, null, "Have no pending popup timeout");
// We need to do these tests during the mouseup event cycle, since the click
// and command events will be dispatched immediately after mouseup, and void
// the results.
let mouseUpPromise = BrowserTestUtils.waitForEvent(widget.node, "mouseup", false, event => {
is(browserAction.pendingPopup, null, "Have no pending popup");
is(browserAction.pendingPopupTimeout, null, "Have no pending popup timeout");
return true;
});
EventUtils.synthesizeMouseAtCenter(widget.node, {type: "mouseup", button: 0}, window);
yield mouseUpPromise;
is(browserAction.pendingPopup, null, "Have no pending popup");
is(browserAction.pendingPopupTimeout, null, "Have no pending popup timeout");
// Give the popup a chance to load and trigger a failure, if it was
// erroneously opened.
yield new Promise(resolve => setTimeout(resolve, 250));
yield extension.unload();
});

Просмотреть файл

@ -0,0 +1,94 @@
/* -*- Mode: indent-tabs-mode: nil; js-indent-level: 2 -*- */
/* vim: set sts=2 sw=2 et tw=80: */
"use strict";
add_task(function* test_popup_sendMessage_reply() {
let scriptPage = url => `<html><head><meta charset="utf-8"><script src="${url}"></script></head><body>${url}</body></html>`;
let extension = ExtensionTestUtils.loadExtension({
manifest: {
"browser_action": {
"default_popup": "popup.html",
"browser_style": true,
},
"page_action": {
"default_popup": "popup.html",
"browser_style": true,
},
},
files: {
"popup.html": scriptPage("popup.js"),
"popup.js": function() {
browser.runtime.onMessage.addListener(msg => {
if (msg == "popup-ping") {
return Promise.resolve("popup-pong");
}
});
browser.runtime.sendMessage("background-ping").then(response => {
browser.test.sendMessage("background-ping-response", response);
});
},
},
background() {
browser.tabs.query({active: true, currentWindow: true}).then(([tab]) => {
return browser.pageAction.show(tab.id);
}).then(() => {
browser.test.sendMessage("page-action-ready");
});
browser.runtime.onMessage.addListener(msg => {
if (msg == "background-ping") {
browser.runtime.sendMessage("popup-ping").then(response => {
browser.test.sendMessage("popup-ping-response", response);
});
return new Promise(resolve => {
// Wait long enough that we're relatively sure the docShells have
// been swapped. Note that this value is fairly arbitrary. The load
// event that triggers the swap should happen almost immediately
// after the message is sent. The extra quarter of a second gives us
// enough leeway that we can expect to respond after the swap in the
// vast majority of cases.
setTimeout(resolve, 250);
}).then(() => {
return "background-pong";
});
}
});
},
});
yield extension.startup();
{
clickBrowserAction(extension);
let pong = yield extension.awaitMessage("background-ping-response");
is(pong, "background-pong", "Got pong");
pong = yield extension.awaitMessage("popup-ping-response");
is(pong, "popup-pong", "Got pong");
yield closeBrowserAction(extension);
}
yield extension.awaitMessage("page-action-ready");
{
clickPageAction(extension);
let pong = yield extension.awaitMessage("background-ping-response");
is(pong, "background-pong", "Got pong");
pong = yield extension.awaitMessage("popup-ping-response");
is(pong, "popup-pong", "Got pong");
yield closePageAction(extension);
}
yield extension.unload();
});

Просмотреть файл

@ -74,7 +74,5 @@ add_task(function* testPageAction() {
yield extension.unload(); yield extension.unload();
yield new Promise(resolve => setTimeout(resolve, 0));
is(panel.parentNode, null, "Panel should be removed from the document"); is(panel.parentNode, null, "Panel should be removed from the document");
}); });

Просмотреть файл

@ -33,6 +33,7 @@ support-files =
worker_deblobify.js worker_deblobify.js
[browser_broadcastChannel.js] [browser_broadcastChannel.js]
[browser_cookieIsolation.js]
[browser_favicon_firstParty.js] [browser_favicon_firstParty.js]
[browser_favicon_userContextId.js] [browser_favicon_userContextId.js]
[browser_firstPartyIsolation.js] [browser_firstPartyIsolation.js]

Просмотреть файл

@ -0,0 +1,31 @@
/**
* Bug 1312541 - A test case for document.cookie isolation.
*/
const TEST_PAGE = "http://mochi.test:8888/browser/browser/components/" +
"originattributes/test/browser/file_firstPartyBasic.html";
// Use a random key so we don't access it in later tests.
const key = "key" + Math.random().toString();
const re = new RegExp(key + "=([0-9\.]+)");
// Define the testing function
function* doTest(aBrowser) {
return yield ContentTask.spawn(aBrowser, {key, re},
function ({key, re}) {
let result = re.exec(content.document.cookie);
if (result) {
return result[1];
}
// No value is found, so we create one.
let value = Math.random().toString();
content.document.cookie = key + "=" + value;
return value;
});
}
registerCleanupFunction(() => {
Services.cookies.removeAll();
});
IsolationTestTools.runTests(TEST_PAGE, doTest);

Просмотреть файл

@ -0,0 +1,177 @@
/* 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/. */
Components.utils.import("resource://gre/modules/Services.jsm");
Components.utils.import("resource://gre/modules/ContextualIdentityService.jsm");
const containersBundle = Services.strings.createBundle("chrome://browser/locale/preferences/containers.properties");
const HTMLNS = "http://www.w3.org/1999/xhtml";
let gContainersManager = {
icons: [
"fingerprint",
"briefcase",
"dollar",
"cart",
"circle"
],
colors: [
"blue",
"turquoise",
"green",
"yellow",
"orange",
"red",
"pink",
"purple"
],
onLoad() {
let params = window.arguments[0] || {};
this.init(params);
},
init(aParams) {
this.userContextId = aParams.userContextId || null;
this.identity = aParams.identity;
if (aParams.windowTitle) {
document.title = aParams.windowTitle;
}
const iconWrapper = document.getElementById("iconWrapper");
iconWrapper.appendChild(this.createIconButtons());
const colorWrapper = document.getElementById("colorWrapper");
colorWrapper.appendChild(this.createColorSwatches());
if (this.identity.name) {
const name = document.getElementById("name");
name.value = this.identity.name;
this.checkForm();
}
this.setLabelsMinWidth();
// This is to prevent layout jank caused by the svgs and outlines rendering at different times
document.getElementById("containers-content").removeAttribute("hidden");
},
setLabelsMinWidth() {
const labelMinWidth = containersBundle.GetStringFromName("containers.labelMinWidth");
const labels = [
document.getElementById("nameLabel"),
document.getElementById("iconLabel"),
document.getElementById("colorLabel")
];
for (let label of labels) {
label.style.minWidth = labelMinWidth;
}
},
uninit() {
},
// Check if name string as to if the form can be submitted
checkForm() {
const name = document.getElementById("name");
let btnApplyChanges = document.getElementById("btnApplyChanges");
if (!name.value) {
btnApplyChanges.setAttribute("disabled", true);
} else {
btnApplyChanges.removeAttribute("disabled");
}
},
createIconButtons(defaultIcon) {
let radiogroup = document.createElement("radiogroup");
radiogroup.setAttribute("id", "icon");
radiogroup.className = "icon-buttons";
for (let icon of this.icons) {
let iconSwatch = document.createElement("radio");
iconSwatch.id = "iconbutton-" + icon;
iconSwatch.name = "icon";
iconSwatch.type = "radio";
iconSwatch.value = icon;
if (this.identity.icon && this.identity.icon == icon) {
iconSwatch.setAttribute("selected", true);
}
iconSwatch.setAttribute("label",
containersBundle.GetStringFromName(`containers.${icon}.label`));
let iconElement = document.createElement("hbox");
iconElement.className = 'userContext-icon';
iconElement.setAttribute("data-identity-icon", icon);
iconSwatch.appendChild(iconElement);
radiogroup.appendChild(iconSwatch);
}
return radiogroup;
},
createColorSwatches(defaultColor) {
let radiogroup = document.createElement("radiogroup");
radiogroup.setAttribute("id", "color");
for (let color of this.colors) {
let colorSwatch = document.createElement("radio");
colorSwatch.id = "colorswatch-" + color;
colorSwatch.name = "color";
colorSwatch.type = "radio";
colorSwatch.value = color;
if (this.identity.color && this.identity.color == color) {
colorSwatch.setAttribute("selected", true);
}
colorSwatch.setAttribute("label",
containersBundle.GetStringFromName(`containers.${color}.label`));
let iconElement = document.createElement("hbox");
iconElement.className = 'userContext-icon';
iconElement.setAttribute("data-identity-icon", "circle");
iconElement.setAttribute("data-identity-color", color);
colorSwatch.appendChild(iconElement);
radiogroup.appendChild(colorSwatch);
}
return radiogroup;
},
onApplyChanges() {
let icon = document.getElementById("icon").value;
let color = document.getElementById("color").value;
let name = document.getElementById("name").value;
let userContextId = false;
if (this.icons.indexOf(icon) == -1) {
throw "Internal error. The icon value doesn't match.";
}
if (this.colors.indexOf(color) == -1) {
throw "Internal error. The color value doesn't match.";
}
if (this.userContextId) {
ContextualIdentityService.update(this.userContextId,
name,
icon,
color);
} else {
ContextualIdentityService.create(name,
icon,
color);
}
window.parent.location.reload()
},
onWindowKeyPress(aEvent) {
if (aEvent.keyCode == KeyEvent.DOM_VK_ESCAPE)
window.close();
}
}

Просмотреть файл

@ -0,0 +1,52 @@
<?xml version="1.0"?>
<!-- This Source Code Form is subject to the terms of the Mozilla Public
- License, v. 2.0. If a copy of the MPL was not distributed with this
- file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
<?xml-stylesheet href="chrome://global/skin/" type="text/css"?>
<?xml-stylesheet href="chrome://browser/skin/preferences/containers.css" type="text/css"?>
<!DOCTYPE dialog SYSTEM "chrome://browser/locale/preferences/containers.dtd" >
<window id="ContainersDialog" class="windowDialog"
windowtype="Browser:Permissions"
title="&window.title;"
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
style="width: &window.width;;"
onload="gContainersManager.onLoad();"
onunload="gContainersManager.uninit();"
persist="screenX screenY width height"
onkeypress="gContainersManager.onWindowKeyPress(event);">
<script src="chrome://global/content/treeUtils.js"/>
<script src="chrome://browser/content/preferences/containers.js"/>
<stringbundle id="bundlePreferences"
src="chrome://browser/locale/preferences/preferences.properties"/>
<keyset>
<key key="&windowClose.key;" modifiers="accel" oncommand="window.close();"/>
</keyset>
<vbox class="contentPane largeDialogContainer" flex="1" hidden="true" id="containers-content">
<description id="permissionsText" control="url"/>
<separator class="thin"/>
<hbox align="start">
<label id="nameLabel" control="url" value="&name.label;" accesskey="&name.accesskey;"/>
<textbox id="name" flex="1" onkeyup="gContainersManager.checkForm();" />
</hbox>
<hbox align="center" id="iconWrapper">
<label id="iconLabel" control="url" value="&icon.label;" accesskey="&icon.accesskey;"/>
</hbox>
<hbox align="center" id="colorWrapper">
<label id="colorLabel" control="url" value="&color.label;" accesskey="&color.accesskey;"/>
</hbox>
</vbox>
<vbox>
<hbox class="actionButtons" align="right" flex="1">
<button id="btnApplyChanges" disabled="true" oncommand="gContainersManager.onApplyChanges();" icon="save"
label="&button.ok.label;" accesskey="&button.ok.accesskey;"/>
</hbox>
</vbox>
</window>

Просмотреть файл

@ -10,6 +10,10 @@
-moz-binding: url("chrome://browser/content/preferences/handlers.xml#handler-selected"); -moz-binding: url("chrome://browser/content/preferences/handlers.xml#handler-selected");
} }
#containersView > richlistitem {
-moz-binding: url("chrome://browser/content/preferences/handlers.xml#container");
}
/** /**
* Make the icons appear. * Make the icons appear.
* Note: we display the icon box for every item whether or not it has an icon * Note: we display the icon box for every item whether or not it has an icon

Просмотреть файл

@ -69,6 +69,29 @@
</binding> </binding>
<binding id="container">
<content>
<xul:hbox flex="1" equalsize="always">
<xul:hbox flex="1" align="center">
<xul:hbox xbl:inherits="data-identity-icon=containerIcon,data-identity-color=containerColor" height="24" width="24" class="userContext-icon"/>
<xul:label flex="1" crop="end" xbl:inherits="value=containerName"/>
</xul:hbox>
<xul:hbox flex="1" align="right">
<xul:button anonid="preferencesButton"
xbl:inherits="value=userContextId"
onclick="gContainersPane.onPeferenceClick(event.originalTarget)">
Preferences
</xul:button>
<xul:button anonid="removeButton"
xbl:inherits="value=userContextId"
onclick="gContainersPane.onRemoveClick(event.originalTarget)">
Remove
</xul:button>
</xul:hbox>
</xul:hbox>
</content>
</binding>
<binding id="offlineapp" <binding id="offlineapp"
extends="chrome://global/content/bindings/listbox.xml#listitem"> extends="chrome://global/content/bindings/listbox.xml#listitem">
<content> <content>

Просмотреть файл

@ -0,0 +1,73 @@
/* 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/. */
Components.utils.import("resource://gre/modules/AppConstants.jsm");
Components.utils.import("resource://gre/modules/ContextualIdentityService.jsm");
const containersBundle = Services.strings.createBundle("chrome://browser/locale/preferences/containers.properties");
const defaultContainerIcon = "fingerprint";
const defaultContainerColor = "blue";
let gContainersPane = {
init() {
this._list = document.getElementById("containersView");
document.getElementById("backContainersLink").addEventListener("click", function () {
gotoPref("privacy");
});
this._rebuildView();
},
_rebuildView() {
const containers = ContextualIdentityService.getIdentities();
while (this._list.firstChild) {
this._list.firstChild.remove();
}
for (let container of containers) {
let item = document.createElement("richlistitem");
item.setAttribute("containerName", ContextualIdentityService.getUserContextLabel(container.userContextId));
item.setAttribute("containerIcon", container.icon);
item.setAttribute("containerColor", container.color);
item.setAttribute("userContextId", container.userContextId);
this._list.appendChild(item);
}
},
onRemoveClick(button) {
let userContextId = button.getAttribute("value");
ContextualIdentityService.remove(userContextId);
this._rebuildView();
},
onPeferenceClick(button) {
this.openPreferenceDialog(button.getAttribute("value"));
},
onAddButtonClick(button) {
this.openPreferenceDialog(null);
},
openPreferenceDialog(userContextId) {
let identity = {
name: "",
icon: defaultContainerIcon,
color: defaultContainerColor
};
let title;
if (userContextId) {
identity = ContextualIdentityService.getIdentityFromId(userContextId);
// This is required to get the translation string from defaults
identity.name = ContextualIdentityService.getUserContextLabel(identity.userContextId);
title = containersBundle.formatStringFromName("containers.updateContainerTitle", [identity.name], 1);
}
const params = { userContextId, identity, windowTitle: title };
gSubDialog.open("chrome://browser/content/preferences/containers.xul",
null, params);
}
};

Просмотреть файл

@ -0,0 +1,54 @@
# 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/.
<!-- Containers panel -->
<script type="application/javascript"
src="chrome://browser/content/preferences/in-content/containers.js"/>
<preferences id="containerPreferences" hidden="true" data-category="paneContainer">
<!-- Containers -->
<preference id="privacy.userContext.enabled"
name="privacy.userContext.enabled"
type="bool"/>
</preferences>
<hbox hidden="true"
class="container-header-links"
data-category="paneContainers">
<label class="text-link" id="backContainersLink" value="&backLink.label;" />
</hbox>
<hbox id="header-containers"
class="header"
hidden="true"
data-category="paneContainers">
<label class="header-name" flex="1">&paneContainers.title;</label>
<button class="help-button"
aria-label="&helpButton.label;"/>
</hbox>
<!-- Containers -->
<groupbox id="browserContainersGroup" data-category="paneContainers" hidden="true">
<vbox id="browserContainersbox">
<richlistbox id="containersView" orient="vertical" persist="lastSelectedType"
flex="1">
<listheader equalsize="always">
<treecol id="typeColumn" label="&label.label;" value="type"
persist="sortDirection"
flex="1" sortDirection="ascending"/>
<treecol id="actionColumn" value="action"
persist="sortDirection"
flex="1"/>
</listheader>
</richlistbox>
</vbox>
<vbox>
<hbox flex="1">
<button onclick="gContainersPane.onAddButtonClick();" accesskey="&addButton.accesskey;" label="&addButton.label;"/>
</hbox>
</vbox>
</groupbox>

Просмотреть файл

@ -9,6 +9,7 @@ browser.jar:
content/browser/preferences/in-content/main.js content/browser/preferences/in-content/main.js
content/browser/preferences/in-content/privacy.js content/browser/preferences/in-content/privacy.js
content/browser/preferences/in-content/containers.js
content/browser/preferences/in-content/advanced.js content/browser/preferences/in-content/advanced.js
content/browser/preferences/in-content/applications.js content/browser/preferences/in-content/applications.js
content/browser/preferences/in-content/content.js content/browser/preferences/in-content/content.js

Просмотреть файл

@ -61,6 +61,7 @@ function init_all() {
register_module("paneGeneral", gMainPane); register_module("paneGeneral", gMainPane);
register_module("paneSearch", gSearchPane); register_module("paneSearch", gSearchPane);
register_module("panePrivacy", gPrivacyPane); register_module("panePrivacy", gPrivacyPane);
register_module("paneContainers", gContainersPane);
register_module("paneAdvanced", gAdvancedPane); register_module("paneAdvanced", gAdvancedPane);
register_module("paneApplications", gApplicationsPane); register_module("paneApplications", gApplicationsPane);
register_module("paneContent", gContentPane); register_module("paneContent", gContentPane);

Просмотреть файл

@ -13,6 +13,7 @@
href="chrome://browser/content/preferences/handlers.css"?> href="chrome://browser/content/preferences/handlers.css"?>
<?xml-stylesheet href="chrome://browser/skin/preferences/applications.css"?> <?xml-stylesheet href="chrome://browser/skin/preferences/applications.css"?>
<?xml-stylesheet href="chrome://browser/skin/preferences/in-content/search.css"?> <?xml-stylesheet href="chrome://browser/skin/preferences/in-content/search.css"?>
<?xml-stylesheet href="chrome://browser/skin/preferences/in-content/containers.css"?>
<!DOCTYPE page [ <!DOCTYPE page [
<!ENTITY % brandDTD SYSTEM "chrome://branding/locale/brand.dtd"> <!ENTITY % brandDTD SYSTEM "chrome://branding/locale/brand.dtd">
@ -26,6 +27,8 @@
<!ENTITY % syncDTD SYSTEM "chrome://browser/locale/preferences/sync.dtd"> <!ENTITY % syncDTD SYSTEM "chrome://browser/locale/preferences/sync.dtd">
<!ENTITY % securityDTD SYSTEM <!ENTITY % securityDTD SYSTEM
"chrome://browser/locale/preferences/security.dtd"> "chrome://browser/locale/preferences/security.dtd">
<!ENTITY % containersDTD SYSTEM
"chrome://browser/locale/preferences/containers.dtd">
<!ENTITY % sanitizeDTD SYSTEM "chrome://browser/locale/sanitize.dtd"> <!ENTITY % sanitizeDTD SYSTEM "chrome://browser/locale/sanitize.dtd">
<!ENTITY % mainDTD SYSTEM "chrome://browser/locale/preferences/main.dtd"> <!ENTITY % mainDTD SYSTEM "chrome://browser/locale/preferences/main.dtd">
<!ENTITY % aboutHomeDTD SYSTEM "chrome://browser/locale/aboutHome.dtd"> <!ENTITY % aboutHomeDTD SYSTEM "chrome://browser/locale/aboutHome.dtd">
@ -43,6 +46,7 @@
%syncBrandDTD; %syncBrandDTD;
%syncDTD; %syncDTD;
%securityDTD; %securityDTD;
%containersDTD;
%sanitizeDTD; %sanitizeDTD;
%mainDTD; %mainDTD;
%aboutHomeDTD; %aboutHomeDTD;
@ -137,6 +141,12 @@
<label class="category-name" flex="1">&panePrivacy.title;</label> <label class="category-name" flex="1">&panePrivacy.title;</label>
</richlistitem> </richlistitem>
<richlistitem id="category-containers"
class="category"
value="paneContainers"
helpTopic="prefs-containers"
hidden="true"/>
<richlistitem id="category-security" <richlistitem id="category-security"
class="category" class="category"
value="paneSecurity" value="paneSecurity"
@ -173,6 +183,7 @@
#include main.xul #include main.xul
#include search.xul #include search.xul
#include privacy.xul #include privacy.xul
#include containers.xul
#include advanced.xul #include advanced.xul
#include applications.xul #include applications.xul
#include content.xul #include content.xul

Просмотреть файл

@ -178,6 +178,8 @@ var gPrivacyPane = {
gPrivacyPane.showBlockLists); gPrivacyPane.showBlockLists);
setEventListener("browserContainersCheckbox", "command", setEventListener("browserContainersCheckbox", "command",
gPrivacyPane._checkBrowserContainers); gPrivacyPane._checkBrowserContainers);
setEventListener("browserContainersSettings", "command",
gPrivacyPane.showContainerSettings);
}, },
// TRACKING PROTECTION MODE // TRACKING PROTECTION MODE
@ -475,6 +477,13 @@ var gPrivacyPane = {
null, params); null, params);
}, },
/**
* Displays container panel for customising and adding containers.
*/
showContainerSettings() {
gotoPref("containers");
},
/** /**
* Displays the available block lists for tracking protection. * Displays the available block lists for tracking protection.
*/ */
@ -678,6 +687,26 @@ var gPrivacyPane = {
var sanitizeOnShutdownPref = document.getElementById("privacy.sanitize.sanitizeOnShutdown"); var sanitizeOnShutdownPref = document.getElementById("privacy.sanitize.sanitizeOnShutdown");
settingsButton.disabled = !sanitizeOnShutdownPref.value; settingsButton.disabled = !sanitizeOnShutdownPref.value;
},
// CONTAINERS
/*
* preferences:
*
* privacy.userContext.enabled
* - true if containers is enabled
*/
/**
* Enables/disables the Settings button used to configure containers
*/
readBrowserContainersCheckbox: function ()
{
var pref = document.getElementById("privacy.userContext.enabled");
var settings = document.getElementById("browserContainersSettings");
settings.disabled = !pref.value;
} }
}; };

Просмотреть файл

@ -289,8 +289,20 @@
<label id="browserContainersLearnMore" class="text-link" <label id="browserContainersLearnMore" class="text-link"
value="&browserContainersLearnMore.label;"/> value="&browserContainersLearnMore.label;"/>
</label></caption> </label></caption>
<checkbox id="browserContainersCheckbox" <hbox align="start">
label="&browserContainersEnabled.label;" <vbox>
accesskey="&browserContainersEnabled.accesskey;" /> <checkbox id="browserContainersCheckbox"
label="&browserContainersEnabled.label;"
accesskey="&browserContainersEnabled.accesskey;"
preference="privacy.userContext.enabled"
onsyncfrompreference="return gPrivacyPane.readBrowserContainersCheckbox();"/>
</vbox>
<spacer flex="1"/>
<vbox>
<button id="browserContainersSettings"
label="&browserContainersSettings.label;"
accesskey="&browserContainersSettings.accesskey;"/>
</vbox>
</hbox>
</vbox> </vbox>
</groupbox> </groupbox>

Просмотреть файл

@ -20,6 +20,8 @@ browser.jar:
* content/browser/preferences/languages.xul * content/browser/preferences/languages.xul
content/browser/preferences/languages.js content/browser/preferences/languages.js
content/browser/preferences/permissions.xul content/browser/preferences/permissions.xul
content/browser/preferences/containers.xul
content/browser/preferences/containers.js
content/browser/preferences/permissions.js content/browser/preferences/permissions.js
content/browser/preferences/sanitize.xul content/browser/preferences/sanitize.xul
content/browser/preferences/sanitize.js content/browser/preferences/sanitize.js

Просмотреть файл

@ -11,6 +11,12 @@
// Step 3: load a page in the tab from step 1 that checks the value of test2 is value2 and the total count in non-private storage is 1 // Step 3: load a page in the tab from step 1 that checks the value of test2 is value2 and the total count in non-private storage is 1
// Step 4: load a page in the tab from step 2 that checks the value of test is value and the total count in private storage is 1 // Step 4: load a page in the tab from step 2 that checks the value of test is value and the total count in private storage is 1
add_task(function* setup() {
yield SpecialPowers.pushPrefEnv({
set: [["dom.ipc.processCount", 1]]
});
});
add_task(function test() { add_task(function test() {
let prefix = 'http://mochi.test:8888/browser/browser/components/privatebrowsing/test/browser/browser_privatebrowsing_concurrent_page.html'; let prefix = 'http://mochi.test:8888/browser/browser/components/privatebrowsing/test/browser/browser_privatebrowsing_concurrent_page.html';

Просмотреть файл

@ -2,6 +2,12 @@
requestLongerTimeout(2); requestLongerTimeout(2);
add_task(function* setup() {
yield SpecialPowers.pushPrefEnv({
set: [["dom.ipc.processCount", 1]]
});
});
add_task(function* () { add_task(function* () {
let win = yield BrowserTestUtils.openNewBrowserWindow(); let win = yield BrowserTestUtils.openNewBrowserWindow();

Просмотреть файл

@ -691,6 +691,9 @@ userContextBanking.accesskey = B
userContextShopping.accesskey = S userContextShopping.accesskey = S
userContextNone.accesskey = N userContextNone.accesskey = N
userContext.aboutPage.label = Manage containers
userContext.aboutPage.accesskey = O
userContextOpenLink.label = Open Link in New %S Tab userContextOpenLink.label = Open Link in New %S Tab
muteTab.label = Mute Tab muteTab.label = Mute Tab

Просмотреть файл

@ -15,6 +15,7 @@
<!ENTITY generalTab "General"> <!ENTITY generalTab "General">
<!ENTITY generalTab.accesskey "G"> <!ENTITY generalTab.accesskey "G">
<!ENTITY generalTitle "Title:">
<!ENTITY generalURL "Address:"> <!ENTITY generalURL "Address:">
<!ENTITY generalType "Type:"> <!ENTITY generalType "Type:">
<!ENTITY generalMode "Render Mode:"> <!ENTITY generalMode "Render Mode:">

Просмотреть файл

@ -6,7 +6,6 @@ pageInfo.page.title=Page Info - %S
pageInfo.frame.title=Frame Info - %S pageInfo.frame.title=Frame Info - %S
noPageTitle=Untitled Page: noPageTitle=Untitled Page:
pageTitle=%S:
unknown=Unknown unknown=Unknown
notset=Not specified notset=Not specified
yes=Yes yes=Yes

Просмотреть файл

@ -0,0 +1,24 @@
<!-- 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/. -->
<!ENTITY label.label "Name">
<!ENTITY addButton.label "Add New Container">
<!ENTITY addButton.accesskey "A">
<!-- &#171; is &laquo; however it's not defined in XML -->
<!ENTITY backLink.label "&#171; Go Back to Privacy">
<!ENTITY window.title "Add New Container">
<!ENTITY window.width "45em">
<!ENTITY name.label "Name:">
<!ENTITY name.accesskey "N">
<!ENTITY icon.label "Icon:">
<!ENTITY icon.accesskey "I">
<!ENTITY color.label "Color:">
<!ENTITY color.accesskey "o">
<!ENTITY windowClose.key "w">
<!ENTITY button.ok.label "Done">
<!ENTITY button.ok.accesskey "D">

Просмотреть файл

@ -0,0 +1,31 @@
# 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/.
containers.removeButton = Remove
containers.preferencesButton = Preferences
containers.colorHeading = Color:
containers.labelMinWidth = 4rem
containers.nameLabel = Name:
containers.namePlaceholder = Enter a container name
containers.submitButton = Done
containers.iconHeading = Icon:
containers.updateContainerTitle = %S Container Preferences
containers.blue.label = Blue
containers.turquoise.label = Turquoise
containers.green.label = Green
containers.yellow.label = Yellow
containers.orange.label = Orange
containers.red.label = Red
containers.pink.label = Pink
containers.purple.label = Purple
containers.fingerprint.label = Fingerprint
containers.briefcase.label = Briefcase
# LOCALIZATION NOTE (containers.dollar.label)
# String represents a money sign but currently uses a dollar sign so don't change to local currency
# See Bug 1291672
containers.dollar.label = Dollar sign
containers.cart.label = Shopping cart
containers.circle.label = Dot

Просмотреть файл

@ -19,6 +19,7 @@
<!ENTITY paneContent.title "Content"> <!ENTITY paneContent.title "Content">
<!ENTITY paneApplications.title "Applications"> <!ENTITY paneApplications.title "Applications">
<!ENTITY panePrivacy.title "Privacy"> <!ENTITY panePrivacy.title "Privacy">
<!ENTITY paneContainers.title "Container Tabs">
<!ENTITY paneSecurity.title "Security"> <!ENTITY paneSecurity.title "Security">
<!ENTITY paneAdvanced.title "Advanced"> <!ENTITY paneAdvanced.title "Advanced">

Просмотреть файл

@ -109,3 +109,5 @@
<!ENTITY browserContainersLearnMore.label "Learn more"> <!ENTITY browserContainersLearnMore.label "Learn more">
<!ENTITY browserContainersEnabled.label "Enable Container Tabs"> <!ENTITY browserContainersEnabled.label "Enable Container Tabs">
<!ENTITY browserContainersEnabled.accesskey "n"> <!ENTITY browserContainersEnabled.accesskey "n">
<!ENTITY browserContainersSettings.label "Settings…">
<!ENTITY browserContainersSettings.accesskey "i">

Просмотреть файл

@ -75,8 +75,10 @@
locale/browser/preferences/permissions.dtd (%chrome/browser/preferences/permissions.dtd) locale/browser/preferences/permissions.dtd (%chrome/browser/preferences/permissions.dtd)
locale/browser/preferences/preferences.dtd (%chrome/browser/preferences/preferences.dtd) locale/browser/preferences/preferences.dtd (%chrome/browser/preferences/preferences.dtd)
locale/browser/preferences/preferences.properties (%chrome/browser/preferences/preferences.properties) locale/browser/preferences/preferences.properties (%chrome/browser/preferences/preferences.properties)
locale/browser/preferences/containers.properties (%chrome/browser/preferences/containers.properties)
locale/browser/preferences/privacy.dtd (%chrome/browser/preferences/privacy.dtd) locale/browser/preferences/privacy.dtd (%chrome/browser/preferences/privacy.dtd)
locale/browser/preferences/security.dtd (%chrome/browser/preferences/security.dtd) locale/browser/preferences/security.dtd (%chrome/browser/preferences/security.dtd)
locale/browser/preferences/containers.dtd (%chrome/browser/preferences/containers.dtd)
locale/browser/preferences/sync.dtd (%chrome/browser/preferences/sync.dtd) locale/browser/preferences/sync.dtd (%chrome/browser/preferences/sync.dtd)
locale/browser/preferences/tabs.dtd (%chrome/browser/preferences/tabs.dtd) locale/browser/preferences/tabs.dtd (%chrome/browser/preferences/tabs.dtd)
locale/browser/preferences/search.dtd (%chrome/browser/preferences/search.dtd) locale/browser/preferences/search.dtd (%chrome/browser/preferences/search.dtd)

Просмотреть файл

@ -11,52 +11,41 @@ Components.utils.import("resource://gre/modules/Services.jsm");
var URLBarZoom = { var URLBarZoom = {
init(aWindow) { init: function(aWindow) {
// Register ourselves with the service so we know when the zoom prefs change. // Register ourselves with the service so we know when the zoom prefs change.
Services.obs.addObserver(this, "browser-fullZoom:zoomChange", false); Services.obs.addObserver(updateZoomButton, "browser-fullZoom:zoomChange", false);
Services.obs.addObserver(this, "browser-fullZoom:zoomReset", false); Services.obs.addObserver(updateZoomButton, "browser-fullZoom:zoomReset", false);
Services.obs.addObserver(this, "browser-fullZoom:location-change", false); Services.obs.addObserver(updateZoomButton, "browser-fullZoom:location-change", false);
}, },
}
observe(aSubject, aTopic) { function updateZoomButton(aSubject, aTopic) {
this.updateZoomButton(aSubject, aTopic); let win = aSubject.ownerDocument.defaultView;
}, let customizableZoomControls = win.document.getElementById("zoom-controls");
let zoomResetButton = win.document.getElementById("urlbar-zoom-button");
let zoomFactor = Math.round(win.ZoomManager.zoom * 100);
updateZoomButton(aSubject, aTopic) { // Ensure that zoom controls haven't already been added to browser in Customize Mode
// aSubject.ownerGlobal may no longer exist if a tab has been dragged to a if (customizableZoomControls &&
// new window. In this case, aSubject.ownerGlobal will be supplied by customizableZoomControls.getAttribute("cui-areatype") == "toolbar") {
// updateZoomButton() called in XULBrowserWindow.onLocationChange(). zoomResetButton.hidden = true;
if (!aSubject.ownerGlobal) { return;
return; }
if (zoomFactor != 100) {
// Check if zoom button is visible and update label if it is
if (zoomResetButton.hidden) {
zoomResetButton.hidden = false;
} }
// Only allow pulse animation for zoom changes, not tab switching
let win = aSubject.ownerGlobal; if (aTopic != "browser-fullZoom:location-change") {
let customizableZoomControls = win.document.getElementById("zoom-controls"); zoomResetButton.setAttribute("animate", "true");
let zoomResetButton = win.document.getElementById("urlbar-zoom-button");
let zoomFactor = Math.round(win.ZoomManager.zoom * 100);
// Ensure that zoom controls haven't already been added to browser in Customize Mode
if (customizableZoomControls &&
customizableZoomControls.getAttribute("cui-areatype") == "toolbar") {
zoomResetButton.hidden = true;
return;
}
if (zoomFactor != 100) {
// Check if zoom button is visible and update label if it is
if (zoomResetButton.hidden) {
zoomResetButton.hidden = false;
}
// Only allow pulse animation for zoom changes, not tab switching
if (aTopic != "browser-fullZoom:location-change") {
zoomResetButton.setAttribute("animate", "true");
} else {
zoomResetButton.removeAttribute("animate");
}
zoomResetButton.setAttribute("label",
win.gNavigatorBundle.getFormattedString("urlbar-zoom-button.label", [zoomFactor]));
} else { } else {
// Hide button if zoom is at 100% zoomResetButton.removeAttribute("animate");
zoomResetButton.hidden = true;
} }
}, zoomResetButton.setAttribute("label",
}; win.gNavigatorBundle.getFormattedString("urlbar-zoom-button.label", [zoomFactor]));
// Hide button if zoom is at 100%
} else {
zoomResetButton.hidden = true;
}
}

Просмотреть файл

@ -0,0 +1,32 @@
/* 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 ../../../components/contextualidentity/content/usercontext.css
.container-header-links {
margin-block-end: 15px;
}
[data-identity-icon] {
margin: 0;
margin-inline-end: 16px;
}
#containersView {
border: 0 none;
background: transparent;
}
#containersView richlistitem {
margin: 0px;
margin-inline-end: 8px;
padding: 0;
padding-block-end: 8px;
border-block-end: 1px solid var(--in-content-header-border-color);
}
#containersView richlistitem:last-of-type {
border-block-end: 0 none;
margin-block-end: 8px;
}

Просмотреть файл

@ -77,6 +77,8 @@
skin/classic/browser/preferences/in-content/favicon.ico (../shared/incontentprefs/favicon.ico) skin/classic/browser/preferences/in-content/favicon.ico (../shared/incontentprefs/favicon.ico)
skin/classic/browser/preferences/in-content/icons.svg (../shared/incontentprefs/icons.svg) skin/classic/browser/preferences/in-content/icons.svg (../shared/incontentprefs/icons.svg)
skin/classic/browser/preferences/in-content/search.css (../shared/incontentprefs/search.css) skin/classic/browser/preferences/in-content/search.css (../shared/incontentprefs/search.css)
* skin/classic/browser/preferences/in-content/containers.css (../shared/incontentprefs/containers.css)
* skin/classic/browser/preferences/containers.css (../shared/preferences/containers.css)
skin/classic/browser/fxa/default-avatar.svg (../shared/fxa/default-avatar.svg) skin/classic/browser/fxa/default-avatar.svg (../shared/fxa/default-avatar.svg)
skin/classic/browser/fxa/logo.png (../shared/fxa/logo.png) skin/classic/browser/fxa/logo.png (../shared/fxa/logo.png)
skin/classic/browser/fxa/logo@2x.png (../shared/fxa/logo@2x.png) skin/classic/browser/fxa/logo@2x.png (../shared/fxa/logo@2x.png)
@ -148,7 +150,3 @@
skin/classic/browser/devedition/urlbar-history-dropmarker.svg (../shared/devedition/urlbar-history-dropmarker.svg) skin/classic/browser/devedition/urlbar-history-dropmarker.svg (../shared/devedition/urlbar-history-dropmarker.svg)
skin/classic/browser/urlbar-star.svg (../shared/urlbar-star.svg) skin/classic/browser/urlbar-star.svg (../shared/urlbar-star.svg)
skin/classic/browser/urlbar-tab.svg (../shared/urlbar-tab.svg) skin/classic/browser/urlbar-tab.svg (../shared/urlbar-tab.svg)
skin/classic/browser/usercontext/personal.svg (../shared/usercontext/personal.svg)
skin/classic/browser/usercontext/work.svg (../shared/usercontext/work.svg)
skin/classic/browser/usercontext/banking.svg (../shared/usercontext/banking.svg)
skin/classic/browser/usercontext/shopping.svg (../shared/usercontext/shopping.svg)

Просмотреть файл

@ -0,0 +1,53 @@
/* 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 ../../../components/contextualidentity/content/usercontext.css
:root {
--preference-selected-color: #0996f8;
--preference-unselected-color: #333;
--preference-active-color: #858585;
}
radiogroup {
display: flex;
margin-inline-start: 0.35rem;
}
radio {
flex: auto;
display: flex;
align-items: center;
justify-content: center;
-moz-user-select: none;
outline: 2px solid transparent;
outline-offset: 4px;
-moz-outline-radius: 100%;
min-block-size: 24px;
min-inline-size: 24px;
border-radius: 50%;
padding: 2px;
margin: 10px;
}
.icon-buttons > radio > [data-identity-icon] {
fill: #4d4d4d;
}
radio > [data-identity-icon] {
inline-size: 22px;
block-size: 22px;
}
radio[selected=true] {
outline-color: var(--preference-unselected-color);
}
radio[focused=true] {
outline-color: var(--preference-selected-color);
}
radio:hover:active {
outline-color: var(--preference-active-color);
}

Просмотреть файл

@ -1,8 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- 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/. -->
<svg xmlns="http://www.w3.org/2000/svg"
width="32" height="32" viewBox="0 0 32 32">
<path fill="#7dc14c" d="M17.3857868,14.0527919 C14.2304569,13.0862944 13.4913706,12.4609137 13.4913706,11.0964467 C13.4913706,9.61827411 14.7137056,8.85076142 16.4192893,8.85076142 C17.9827411,8.85076142 19.3187817,9.33401015 20.5979695,10.4994924 L22.4456853,8.42436548 C21.1664975,7.20203046 19.3187819,6.26535905 17,6.00952148 L17,2 L15,2 L15,6.00952148 C12.3827412,6.43591742 9.76751269,8.53807107 9.76751269,11.3238579 C9.76751269,14.1664975 11.4730964,15.786802 15.4812183,17.0091371 C18.4375635,17.9187817 19.2335025,18.6294416 19.2335025,20.2213198 C19.2335025,22.0690355 17.7553299,23.035533 15.7370558,23.035533 C13.7756345,23.035533 12.2406091,22.3248731 10.9329949,21.1025381 L9,23.2345178 C10.4213198,24.6274112 12.8659899,25.8324934 15,26.0030518 L15,30 L17,30 L17,26.0030518 C20.7116753,25.4060974 22.9857868,22.893401 22.9857868,20.022335 C22.9857868,16.4690355 20.7116751,15.1045685 17.3857868,14.0527919 Z"/>
</svg>

До

Ширина:  |  Высота:  |  Размер: 1.2 KiB

Просмотреть файл

@ -1,8 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- 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/. -->
<svg xmlns="http://www.w3.org/2000/svg"
width="32" height="32" viewBox="0 0 32 32">
<path fill="#00a7e0" d="M7.17741905,12 C7.10965537,12 7.041327,11.9953181 6.97243393,11.985018 C6.33263187,11.8918489 5.90515601,11.3862071 6.01809547,10.8552833 C7.41798011,4.26321358 12.2613889,2.57493207 15.0238882,2.15590491 C19.6448063,1.45690206 24.3408291,3.21541158 25.8344535,5.29743816 C26.1664955,5.76047488 25.9835336,6.35881757 25.4244832,6.63364321 C24.8654329,6.9098734 24.1437497,6.75583996 23.8122724,6.29327142 C22.8923805,5.01043967 19.1749781,3.51130562 15.4479759,4.07406612 C12.8080159,4.474834 9.43056132,6.03623689 8.33561323,11.1942506 C8.23453242,11.666651 7.73816348,12 7.17741905,12 Z M16.63127,26 C16.1452186,26 15.6509104,25.9658335 15.147795,25.8938767 C10.637921,25.257137 6.71207921,21.8114952 6.01575422,17.8807924 C5.91171832,17.2932317 6.33391695,16.7382846 6.95813239,16.6404441 C7.58454965,16.5343208 8.17298555,16.9406954 8.27757192,17.5272206 C8.80876054,20.5255916 11.9766264,23.26409 15.4885263,23.7610576 C17.3975027,24.02766 20.959494,23.8221432 23.3220449,19.3789425 C24.4625867,17.2331815 23.0049831,11.881462 19.9521622,9.34692739 C18.2380468,7.92384005 16.4573263,7.76905536 14.6628445,8.89499751 C13.26469,9.77142052 11.8070864,12.2857658 11.8665355,14.6287608 C11.9127737,16.4835887 12.8386382,17.9325598 14.6171568,18.9363308 C15.2210054,19.2764429 16.9411759,19.4933486 17.9424527,18.8296898 C18.7257495,18.3104622 18.9591422,17.2761485 18.6365758,15.7583267 C18.3822659,14.5650869 17.2219077,12.4452096 16.6664991,12.3711821 C16.6692513,12.3722175 16.4666841,12.4312324 16.1276041,12.9095636 C15.8545786,13.2936782 15.58981,14.7297074 15.9476054,15.3581643 C16.0142104,15.4761941 16.0725586,15.5465978 16.3202632,15.5465978 C16.9532859,15.5465978 17.46686,16.0290705 17.46686,16.6249139 C17.46686,17.2207573 16.9543868,17.7042653 16.3213641,17.7042653 C15.2644914,17.7042653 14.4140391,17.2336992 13.9268868,16.3774655 C13.1083609,14.9388479 13.5536787,12.6548678 14.2202791,11.7137354 C15.2540327,10.2564816 16.3631986,10.1151564 17.1123672,10.2564816 C19.7066595,10.7389543 20.8763754,15.2908666 20.8857331,15.3359043 C21.5303153,18.3648181 20.3594985,19.8665919 19.264094,20.593407 C17.4151172,21.8192603 14.6920186,21.493643 13.4380832,20.7859819 C10.3280151,19.0310652 9.62013053,16.497566 9.5744428,14.6805283 C9.49022326,11.3643051 11.4779146,8.30018945 13.391845,7.10021984 C16.0417332,5.43848454 18.9877658,5.66781436 21.4714167,7.72919442 C25.1176276,10.7565552 27.0871539,17.1229168 25.3746898,20.3433702 C23.4326862,23.9950465 20.2983981,26 16.63127,26 Z M16.0845157,30 C14.9348455,30 13.9050564,29.8557557 13.0394288,29.6610017 C10.2114238,29.0257442 7.58700058,27.4599412 6.18892823,25.5735955 C5.84440518,25.1078371 5.98426642,24.4803503 6.50105099,24.1700066 C7.01675554,23.8596629 7.71552172,23.986423 8.06112477,24.4507244 C9.89498097,26.9252176 15.9397944,29.9781448 22.2508301,26.1937972 C22.7676147,25.8844249 23.4658409,26.0087566 23.8109039,26.474515 C24.155427,26.9397877 24.0161057,27.5672745 23.4993212,27.8776182 C20.7987573,29.4963593 18.2315746,30 16.0845157,30 Z"/>
</svg>

До

Ширина:  |  Высота:  |  Размер: 3.3 KiB

Просмотреть файл

@ -1,8 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- 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/. -->
<svg xmlns="http://www.w3.org/2000/svg"
width="32" height="32" viewBox="0 0 32 32">
<path fill="#ee5195" fill-rule="evenodd" d="M20.8195396,14 L15.1804604,14 L15.1804604,14 L15.8471271,18 L20.1528729,18 L20.8195396,14 Z M22.8471271,14 L27.6125741,14 L27.6125741,14 L26.2792408,18 L22.1804604,18 L22.8471271,14 Z M21.1528729,12 L14.8471271,12 L14.8471271,12 L14.1804604,8 L21.8195396,8 L21.1528729,12 Z M23.1804604,12 L28.2792408,12 L28.2792408,12 L29.6125741,8 L23.8471271,8 L23.1804604,12 Z M13.1528729,14 L8.47703296,14 L10.077033,18 L10.077033,18 L13.8195396,18 L13.1528729,14 Z M12.8195396,12 L7.67703296,12 L6.07703296,8 L12.1528729,8 L12.8195396,12 L12.8195396,12 Z M31.7207592,8 L32,8 L32,6 L31,6 L5.27703296,6 L5.27703296,6 L4,2.8074176 L4,2 L3,2 L1,2 L0,2 L0,4 L1,4 L2.32296704,4 L9.78931928,22.6658806 L9.78931928,22.6658806 C8.71085924,23.3823847 8,24.6081773 8,26 C8,28.209139 9.790861,30 12,30 C14.209139,30 16,28.209139 16,26 C16,25.2714257 15.8052114,24.5883467 15.4648712,24 L22.5351288,24 C22.1947886,24.5883467 22,25.2714257 22,26 C22,28.209139 23.790861,30 26,30 C28.209139,30 30,28.209139 30,26 C30,23.790861 28.209139,22 26,22 L11.677033,22 L10.877033,20 L27,20 L28,20 L28,19.1622777 L31.7207592,8 L31.7207592,8 Z M26,28 C27.1045695,28 28,27.1045695 28,26 C28,24.8954305 27.1045695,24 26,24 C24.8954305,24 24,24.8954305 24,26 C24,27.1045695 24.8954305,28 26,28 Z M12,28 C13.1045695,28 14,27.1045695 14,26 C14,24.8954305 13.1045695,24 12,24 C10.8954305,24 10,24.8954305 10,26 C10,27.1045695 10.8954305,28 12,28 Z"/>
</svg>

До

Ширина:  |  Высота:  |  Размер: 1.8 KiB

Просмотреть файл

@ -1,8 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- 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/. -->
<svg xmlns="http://www.w3.org/2000/svg"
width="32" height="32" viewBox="0 0 32 32">
<path fill="#f89c24" fill-rule="evenodd" d="M22,9.99887085 L21.635468,10 L29.0034652,10 C29.5538362,10 30,10.4449463 30,10.9933977 L30,27.0066023 C30,27.5552407 29.5601869,28 29.0034652,28 L2.99653482,28 C2.44616384,28 2,27.5550537 2,27.0066023 L2,10.9933977 C2,10.4447593 2.43981314,10 2.99653482,10 L8,10 L8,7.99922997 C8,5.79051625 10.0426627,4 12.5635454,4 L19.4364546,4 C21.9568311,4 24,5.79246765 24,7.99922997 L24,9.99267578 L22,9.99887085 L22,10 L10,10 L10,7.99922997 C10,6.89421235 11.0713286,6 12.3917227,6 L19.6082773,6 C20.9273761,6 22,6.89552665 22,7.99922997 L22,9.99887085 Z"/>
</svg>

До

Ширина:  |  Высота:  |  Размер: 941 B

Просмотреть файл

@ -263,7 +263,7 @@ case "$target" in
break break
fi fi
done done
if test "$android_build_tools_version" == ""; then if test "$android_build_tools_version" = ""; then
version=$(echo $2 | cut -d" " -f1) version=$(echo $2 | cut -d" " -f1)
AC_MSG_ERROR([You must install the Android build-tools version $version. Try |mach bootstrap|. (Looked for "$android_build_tools_base"/$version)]) AC_MSG_ERROR([You must install the Android build-tools version $version. Try |mach bootstrap|. (Looked for "$android_build_tools_base"/$version)])
fi fi

Просмотреть файл

@ -18,6 +18,7 @@ add_task(function* () {
["dom.serviceWorkers.testing.enabled", true], ["dom.serviceWorkers.testing.enabled", true],
["dom.serviceWorkers.idle_timeout", SW_TIMEOUT], ["dom.serviceWorkers.idle_timeout", SW_TIMEOUT],
["dom.serviceWorkers.idle_extended_timeout", SW_TIMEOUT], ["dom.serviceWorkers.idle_extended_timeout", SW_TIMEOUT],
["dom.ipc.processCount", 1],
] ]
}); });

Просмотреть файл

@ -20,6 +20,7 @@ add_task(function* () {
let options = { "set": [ let options = { "set": [
// Accept workers from mochitest's http. // Accept workers from mochitest's http.
["dom.serviceWorkers.testing.enabled", true], ["dom.serviceWorkers.testing.enabled", true],
["dom.ipc.processCount", 1],
]}; ]};
SpecialPowers.pushPrefEnv(options, done); SpecialPowers.pushPrefEnv(options, done);
}); });

Просмотреть файл

@ -5,6 +5,12 @@
const TAB_URL = "data:text/html,<title>foo</title>"; const TAB_URL = "data:text/html,<title>foo</title>";
add_task(function* setup() {
yield SpecialPowers.pushPrefEnv({
set: [["dom.ipc.processCount", 1]]
});
});
add_task(function* () { add_task(function* () {
let { tab, document } = yield openAboutDebugging("tabs"); let { tab, document } = yield openAboutDebugging("tabs");

Просмотреть файл

@ -4,6 +4,12 @@
"use strict"; "use strict";
add_task(function* setup() {
yield SpecialPowers.pushPrefEnv({
set: [["dom.ipc.processCount", 1]]
});
});
// Test that the spacebar key press toggles the toggleAll button state // Test that the spacebar key press toggles the toggleAll button state
// when a node with no animation is selected. // when a node with no animation is selected.
// This test doesn't need to test if animations actually pause/resume // This test doesn't need to test if animations actually pause/resume

Просмотреть файл

@ -37,6 +37,7 @@ support-files =
[browser_toolbox_computed_view.js] [browser_toolbox_computed_view.js]
[browser_toolbox_rule_view.js] [browser_toolbox_rule_view.js]
[browser_toolbox_swap_browsers.js] [browser_toolbox_swap_browsers.js]
skip-if = true # Bug 1315042
[browser_touch_simulation.js] [browser_touch_simulation.js]
[browser_viewport_basics.js] [browser_viewport_basics.js]
[browser_window_close.js] [browser_window_close.js]

Просмотреть файл

@ -13,6 +13,12 @@ const TEST_DOC = "https://example.com/browser/devtools/client/webconsole/" +
"test/test_bug1092055_shouldwarn.html"; "test/test_bug1092055_shouldwarn.html";
const SAMPLE_MSG = "specified a header that could not be parsed successfully."; const SAMPLE_MSG = "specified a header that could not be parsed successfully.";
add_task(function* setup() {
yield SpecialPowers.pushPrefEnv({
set: [["dom.ipc.processCount", 1]]
});
});
add_task(function* () { add_task(function* () {
let { browser } = yield loadTab(TEST_URI); let { browser } = yield loadTab(TEST_URI);

Просмотреть файл

@ -8,6 +8,11 @@
const TEST_URI = "data:text/html;charset=utf-8,Web Console test for splitting"; const TEST_URI = "data:text/html;charset=utf-8,Web Console test for splitting";
function test() { function test() {
waitForExplicitFinish();
SpecialPowers.pushPrefEnv({"set": [["dom.ipc.processCount", 1]]}, runTest);
}
function runTest() {
// Test is slow on Linux EC2 instances - Bug 962931 // Test is slow on Linux EC2 instances - Bug 962931
requestLongerTimeout(2); requestLongerTimeout(2);

Просмотреть файл

@ -4,6 +4,12 @@
"use strict"; "use strict";
add_task(function* setup() {
yield SpecialPowers.pushPrefEnv({
set: [["dom.ipc.processCount", 1]]
});
});
// Check that the duration, iterationCount and delay are retrieved correctly for // Check that the duration, iterationCount and delay are retrieved correctly for
// multiple animations. // multiple animations.

Просмотреть файл

@ -241,8 +241,8 @@ EdgeInclusiveIntersection(const nsRect& aRect, const nsRect& aOtherRect)
void void
DOMIntersectionObserver::Update(nsIDocument* aDocument, DOMHighResTimeStamp time) DOMIntersectionObserver::Update(nsIDocument* aDocument, DOMHighResTimeStamp time)
{ {
Element* root; Element* root = nullptr;
nsIFrame* rootFrame; nsIFrame* rootFrame = nullptr;
nsRect rootRect; nsRect rootRect;
if (mRoot) { if (mRoot) {

Просмотреть файл

@ -16,7 +16,9 @@ DocGroup::GetKey(nsIPrincipal* aPrincipal, nsACString& aKey)
aKey.Truncate(); aKey.Truncate();
nsCOMPtr<nsIURI> uri; nsCOMPtr<nsIURI> uri;
nsresult rv = aPrincipal->GetURI(getter_AddRefs(uri)); nsresult rv = aPrincipal->GetURI(getter_AddRefs(uri));
if (NS_SUCCEEDED(rv)) { // GetBaseDomain works fine if |uri| is null, but it outputs a warning
// which ends up cluttering the logs.
if (NS_SUCCEEDED(rv) && uri) {
nsCOMPtr<nsIEffectiveTLDService> tldService = nsCOMPtr<nsIEffectiveTLDService> tldService =
do_GetService(NS_EFFECTIVETLDSERVICE_CONTRACTID); do_GetService(NS_EFFECTIVETLDSERVICE_CONTRACTID);
if (tldService) { if (tldService) {

Просмотреть файл

@ -57,6 +57,7 @@
#include "mozilla/AnimationComparator.h" #include "mozilla/AnimationComparator.h"
#include "mozilla/AsyncEventDispatcher.h" #include "mozilla/AsyncEventDispatcher.h"
#include "mozilla/ContentEvents.h" #include "mozilla/ContentEvents.h"
#include "mozilla/DeclarationBlockInlines.h"
#include "mozilla/EffectSet.h" #include "mozilla/EffectSet.h"
#include "mozilla/EventDispatcher.h" #include "mozilla/EventDispatcher.h"
#include "mozilla/EventListenerManager.h" #include "mozilla/EventListenerManager.h"
@ -1967,7 +1968,7 @@ Element::GetSMILOverrideStyle()
return slots->mSMILOverrideStyle; return slots->mSMILOverrideStyle;
} }
css::Declaration* DeclarationBlock*
Element::GetSMILOverrideStyleDeclaration() Element::GetSMILOverrideStyleDeclaration()
{ {
Element::nsDOMSlots *slots = GetExistingDOMSlots(); Element::nsDOMSlots *slots = GetExistingDOMSlots();
@ -1975,7 +1976,7 @@ Element::GetSMILOverrideStyleDeclaration()
} }
nsresult nsresult
Element::SetSMILOverrideStyleDeclaration(css::Declaration* aDeclaration, Element::SetSMILOverrideStyleDeclaration(DeclarationBlock* aDeclaration,
bool aNotify) bool aNotify)
{ {
Element::nsDOMSlots *slots = DOMSlots(); Element::nsDOMSlots *slots = DOMSlots();

Просмотреть файл

@ -271,15 +271,15 @@ public:
* Get the SMIL override style declaration for this element. If the * Get the SMIL override style declaration for this element. If the
* rule hasn't been created, this method simply returns null. * rule hasn't been created, this method simply returns null.
*/ */
virtual css::Declaration* GetSMILOverrideStyleDeclaration(); virtual DeclarationBlock* GetSMILOverrideStyleDeclaration();
/** /**
* Set the SMIL override style declaration for this element. If * Set the SMIL override style declaration for this element. If
* aNotify is true, this method will notify the document's pres * aNotify is true, this method will notify the document's pres
* context, so that the style changes will be noticed. * context, so that the style changes will be noticed.
*/ */
virtual nsresult SetSMILOverrideStyleDeclaration(css::Declaration* aDeclaration, virtual nsresult SetSMILOverrideStyleDeclaration(
bool aNotify); DeclarationBlock* aDeclaration, bool aNotify);
/** /**
* Returns a new nsISMILAttr that allows the caller to animate the given * Returns a new nsISMILAttr that allows the caller to animate the given

Просмотреть файл

@ -18,6 +18,7 @@
#include "mozilla/dom/FragmentOrElement.h" #include "mozilla/dom/FragmentOrElement.h"
#include "mozilla/AsyncEventDispatcher.h" #include "mozilla/AsyncEventDispatcher.h"
#include "mozilla/DeclarationBlockInlines.h"
#include "mozilla/EffectSet.h" #include "mozilla/EffectSet.h"
#include "mozilla/EventDispatcher.h" #include "mozilla/EventDispatcher.h"
#include "mozilla/EventListenerManager.h" #include "mozilla/EventListenerManager.h"

Просмотреть файл

@ -33,9 +33,7 @@ class nsDOMStringMap;
class nsIURI; class nsIURI;
namespace mozilla { namespace mozilla {
namespace css { class DeclarationBlock;
class Declaration;
} // namespace css
namespace dom { namespace dom {
class DOMIntersectionObserver; class DOMIntersectionObserver;
class Element; class Element;
@ -284,7 +282,7 @@ public:
/** /**
* Holds any SMIL override style declaration for this element. * Holds any SMIL override style declaration for this element.
*/ */
RefPtr<mozilla::css::Declaration> mSMILOverrideStyleDeclaration; RefPtr<mozilla::DeclarationBlock> mSMILOverrideStyleDeclaration;
/** /**
* An object implementing nsIDOMMozNamedAttrMap for this content (attributes) * An object implementing nsIDOMMozNamedAttrMap for this content (attributes)

Просмотреть файл

@ -1720,7 +1720,7 @@ nsAttrValue::ParseStyleAttribute(const nsAString& aString,
RefPtr<DeclarationBlock> decl; RefPtr<DeclarationBlock> decl;
if (ownerDoc->GetStyleBackendType() == StyleBackendType::Servo) { if (ownerDoc->GetStyleBackendType() == StyleBackendType::Servo) {
decl = ServoDeclarationBlock::FromStyleAttribute(aString); decl = ServoDeclarationBlock::FromCssText(aString);
} else { } else {
css::Loader* cssLoader = ownerDoc->CSSLoader(); css::Loader* cssLoader = ownerDoc->CSSLoader();
nsCSSParser cssParser(cssLoader); nsCSSParser cssParser(cssLoader);

Просмотреть файл

@ -1068,7 +1068,7 @@ nsTreeSanitizer::SanitizeStyleDeclaration(mozilla::css::Declaration* aDeclaratio
nsAutoString& aRuleText) nsAutoString& aRuleText)
{ {
bool didSanitize = aDeclaration->HasProperty(eCSSProperty_binding); bool didSanitize = aDeclaration->HasProperty(eCSSProperty_binding);
aDeclaration->RemoveProperty(eCSSProperty_binding); aDeclaration->RemovePropertyByID(eCSSProperty_binding);
aDeclaration->ToString(aRuleText); aDeclaration->ToString(aRuleText);
return didSanitize; return didSanitize;
} }

Просмотреть файл

@ -20,6 +20,7 @@ tags = mcb
[browser_bug1011748.js] [browser_bug1011748.js]
[browser_bug1058164.js] [browser_bug1058164.js]
[browser_messagemanager_loadprocessscript.js] [browser_messagemanager_loadprocessscript.js]
skip-if = true # Bug 1315042
[browser_messagemanager_targetframeloader.js] [browser_messagemanager_targetframeloader.js]
[browser_messagemanager_unload.js] [browser_messagemanager_unload.js]
[browser_pagehide_on_tab_close.js] [browser_pagehide_on_tab_close.js]

Просмотреть файл

@ -83,6 +83,7 @@ skip-if = (toolkit == 'gonk' && !debug)
# skip-if = (toolkit == 'gonk') # Disabled on emulator. See bug 1144015 comment 8 # skip-if = (toolkit == 'gonk') # Disabled on emulator. See bug 1144015 comment 8
disabled = Disabling some OOP tests for WebIDL scope changes disabled = Disabling some OOP tests for WebIDL scope changes
[test_browserElement_oop_PrivateBrowsing.html] [test_browserElement_oop_PrivateBrowsing.html]
skip-if = true # Bug 1315042
[test_browserElement_oop_PromptCheck.html] [test_browserElement_oop_PromptCheck.html]
[test_browserElement_oop_PromptConfirm.html] [test_browserElement_oop_PromptConfirm.html]
# Disabled on B2G Emulator because permission cannot be asserted in content process, # Disabled on B2G Emulator because permission cannot be asserted in content process,

Просмотреть файл

@ -2686,7 +2686,7 @@ GetFontStyleContext(Element* aElement, const nsAString& aFont,
// parsed (including having line-height removed). (Older drafts of // parsed (including having line-height removed). (Older drafts of
// the spec required font sizes be converted to pixels, but that no // the spec required font sizes be converted to pixels, but that no
// longer seems to be required.) // longer seems to be required.)
decl->GetValue(eCSSProperty_font, aOutUsedFont); decl->GetPropertyValueByID(eCSSProperty_font, aOutUsedFont);
return sc.forget(); return sc.forget();
} }

Просмотреть файл

@ -22,7 +22,7 @@ namespace dom {
void void
CanvasRenderingContextHelper::ToBlob(JSContext* aCx, CanvasRenderingContextHelper::ToBlob(JSContext* aCx,
nsIGlobalObject* aGlobal, nsIGlobalObject* aGlobal,
FileCallback& aCallback, BlobCallback& aCallback,
const nsAString& aType, const nsAString& aType,
JS::Handle<JS::Value> aParams, JS::Handle<JS::Value> aParams,
ErrorResult& aRv) ErrorResult& aRv)
@ -31,9 +31,9 @@ CanvasRenderingContextHelper::ToBlob(JSContext* aCx,
class EncodeCallback : public EncodeCompleteCallback class EncodeCallback : public EncodeCompleteCallback
{ {
public: public:
EncodeCallback(nsIGlobalObject* aGlobal, FileCallback* aCallback) EncodeCallback(nsIGlobalObject* aGlobal, BlobCallback* aCallback)
: mGlobal(aGlobal) : mGlobal(aGlobal)
, mFileCallback(aCallback) {} , mBlobCallback(aCallback) {}
// This is called on main thread. // This is called on main thread.
nsresult ReceiveBlob(already_AddRefed<Blob> aBlob) nsresult ReceiveBlob(already_AddRefed<Blob> aBlob)
@ -53,16 +53,16 @@ CanvasRenderingContextHelper::ToBlob(JSContext* aCx,
RefPtr<Blob> newBlob = Blob::Create(mGlobal, blob->Impl()); RefPtr<Blob> newBlob = Blob::Create(mGlobal, blob->Impl());
mFileCallback->Call(*newBlob, rv); mBlobCallback->Call(*newBlob, rv);
mGlobal = nullptr; mGlobal = nullptr;
mFileCallback = nullptr; mBlobCallback = nullptr;
return rv.StealNSResult(); return rv.StealNSResult();
} }
nsCOMPtr<nsIGlobalObject> mGlobal; nsCOMPtr<nsIGlobalObject> mGlobal;
RefPtr<FileCallback> mFileCallback; RefPtr<BlobCallback> mBlobCallback;
}; };
RefPtr<EncodeCompleteCallback> callback = RefPtr<EncodeCompleteCallback> callback =

Просмотреть файл

@ -18,8 +18,8 @@ class ErrorResult;
namespace dom { namespace dom {
class BlobCallback;
class EncodeCompleteCallback; class EncodeCompleteCallback;
class FileCallback;
enum class CanvasContextType : uint8_t { enum class CanvasContextType : uint8_t {
NoContext, NoContext,
@ -55,7 +55,7 @@ protected:
nsAString& outParams, nsAString& outParams,
bool* const outCustomParseOptions); bool* const outCustomParseOptions);
void ToBlob(JSContext* aCx, nsIGlobalObject* global, FileCallback& aCallback, void ToBlob(JSContext* aCx, nsIGlobalObject* global, BlobCallback& aCallback,
const nsAString& aType, JS::Handle<JS::Value> aParams, const nsAString& aType, JS::Handle<JS::Value> aParams,
ErrorResult& aRv); ErrorResult& aRv);

Просмотреть файл

@ -326,9 +326,9 @@ DataTransferItem::GetAsEntry(nsIPrincipal& aSubjectPrincipal,
} }
RefPtr<Directory> directory = Directory::Create(global, directoryFile); RefPtr<Directory> directory = Directory::Create(global, directoryFile);
entry = new FileSystemDirectoryEntry(global, directory, fs); entry = new FileSystemDirectoryEntry(global, directory, nullptr, fs);
} else { } else {
entry = new FileSystemFileEntry(global, file, fs); entry = new FileSystemFileEntry(global, file, nullptr, fs);
} }
Sequence<RefPtr<FileSystemEntry>> entries; Sequence<RefPtr<FileSystemEntry>> entries;

Просмотреть файл

@ -5,8 +5,9 @@
* You can obtain one at http://mozilla.org/MPL/2.0/. */ * You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "CallbackRunnables.h" #include "CallbackRunnables.h"
#include "mozilla/dom/Directory.h"
#include "mozilla/dom/DirectoryBinding.h" #include "mozilla/dom/DirectoryBinding.h"
#include "mozilla/dom/DOMError.h" #include "mozilla/dom/DOMException.h"
#include "mozilla/dom/File.h" #include "mozilla/dom/File.h"
#include "mozilla/dom/FileBinding.h" #include "mozilla/dom/FileBinding.h"
#include "mozilla/dom/FileSystemDirectoryReaderBinding.h" #include "mozilla/dom/FileSystemDirectoryReaderBinding.h"
@ -55,8 +56,8 @@ ErrorCallbackRunnable::Run()
return NS_ERROR_FAILURE; return NS_ERROR_FAILURE;
} }
RefPtr<DOMError> error = new DOMError(window, mError); RefPtr<DOMException> exception = DOMException::Create(mError);
mCallback->HandleEvent(*error); mCallback->HandleEvent(*exception);
return NS_OK; return NS_OK;
} }
@ -74,18 +75,24 @@ EmptyEntriesCallbackRunnable::Run()
return NS_OK; return NS_OK;
} }
GetEntryHelper::GetEntryHelper(nsIGlobalObject* aGlobalObject, GetEntryHelper::GetEntryHelper(FileSystemDirectoryEntry* aParentEntry,
Directory* aDirectory,
nsTArray<nsString>& aParts,
FileSystem* aFileSystem, FileSystem* aFileSystem,
FileSystemEntryCallback* aSuccessCallback, FileSystemEntryCallback* aSuccessCallback,
ErrorCallback* aErrorCallback, ErrorCallback* aErrorCallback,
FileSystemDirectoryEntry::GetInternalType aType) FileSystemDirectoryEntry::GetInternalType aType)
: mGlobal(aGlobalObject) : mParentEntry(aParentEntry)
, mDirectory(aDirectory)
, mParts(aParts)
, mFileSystem(aFileSystem) , mFileSystem(aFileSystem)
, mSuccessCallback(aSuccessCallback) , mSuccessCallback(aSuccessCallback)
, mErrorCallback(aErrorCallback) , mErrorCallback(aErrorCallback)
, mType(aType) , mType(aType)
{ {
MOZ_ASSERT(aGlobalObject); MOZ_ASSERT(aParentEntry);
MOZ_ASSERT(aDirectory);
MOZ_ASSERT(!aParts.IsEmpty());
MOZ_ASSERT(aFileSystem); MOZ_ASSERT(aFileSystem);
MOZ_ASSERT(aSuccessCallback || aErrorCallback); MOZ_ASSERT(aSuccessCallback || aErrorCallback);
} }
@ -93,6 +100,23 @@ GetEntryHelper::GetEntryHelper(nsIGlobalObject* aGlobalObject,
GetEntryHelper::~GetEntryHelper() GetEntryHelper::~GetEntryHelper()
{} {}
void
GetEntryHelper::Run()
{
MOZ_ASSERT(!mParts.IsEmpty());
ErrorResult rv;
RefPtr<Promise> promise = mDirectory->Get(mParts[0], rv);
if (NS_WARN_IF(rv.Failed())) {
rv.SuppressException();
Error(NS_ERROR_DOM_INVALID_STATE_ERR);
return;
}
mParts.RemoveElementAt(0);
promise->AppendNativeHandler(this);
}
void void
GetEntryHelper::ResolvedCallback(JSContext* aCx, JS::Handle<JS::Value> aValue) GetEntryHelper::ResolvedCallback(JSContext* aCx, JS::Handle<JS::Value> aValue)
{ {
@ -102,15 +126,30 @@ GetEntryHelper::ResolvedCallback(JSContext* aCx, JS::Handle<JS::Value> aValue)
JS::Rooted<JSObject*> obj(aCx, &aValue.toObject()); JS::Rooted<JSObject*> obj(aCx, &aValue.toObject());
// This is not the last part of the path.
if (!mParts.IsEmpty()) {
ContinueRunning(obj);
return;
}
CompleteOperation(obj);
}
void
GetEntryHelper::CompleteOperation(JSObject* aObj)
{
MOZ_ASSERT(mParts.IsEmpty());
if (mType == FileSystemDirectoryEntry::eGetFile) { if (mType == FileSystemDirectoryEntry::eGetFile) {
RefPtr<File> file; RefPtr<File> file;
if (NS_FAILED(UNWRAP_OBJECT(File, obj, file))) { if (NS_FAILED(UNWRAP_OBJECT(File, aObj, file))) {
Error(NS_ERROR_DOM_TYPE_MISMATCH_ERR); Error(NS_ERROR_DOM_TYPE_MISMATCH_ERR);
return; return;
} }
RefPtr<FileSystemFileEntry> entry = RefPtr<FileSystemFileEntry> entry =
new FileSystemFileEntry(mGlobal, file, mFileSystem); new FileSystemFileEntry(mParentEntry->GetParentObject(), file,
mParentEntry, mFileSystem);
mSuccessCallback->HandleEvent(*entry); mSuccessCallback->HandleEvent(*entry);
return; return;
} }
@ -118,16 +157,39 @@ GetEntryHelper::ResolvedCallback(JSContext* aCx, JS::Handle<JS::Value> aValue)
MOZ_ASSERT(mType == FileSystemDirectoryEntry::eGetDirectory); MOZ_ASSERT(mType == FileSystemDirectoryEntry::eGetDirectory);
RefPtr<Directory> directory; RefPtr<Directory> directory;
if (NS_FAILED(UNWRAP_OBJECT(Directory, obj, directory))) { if (NS_FAILED(UNWRAP_OBJECT(Directory, aObj, directory))) {
Error(NS_ERROR_DOM_TYPE_MISMATCH_ERR); Error(NS_ERROR_DOM_TYPE_MISMATCH_ERR);
return; return;
} }
RefPtr<FileSystemDirectoryEntry> entry = RefPtr<FileSystemDirectoryEntry> entry =
new FileSystemDirectoryEntry(mGlobal, directory, mFileSystem); new FileSystemDirectoryEntry(mParentEntry->GetParentObject(), directory,
mParentEntry, mFileSystem);
mSuccessCallback->HandleEvent(*entry); mSuccessCallback->HandleEvent(*entry);
} }
void
GetEntryHelper::ContinueRunning(JSObject* aObj)
{
MOZ_ASSERT(!mParts.IsEmpty());
RefPtr<Directory> directory;
if (NS_FAILED(UNWRAP_OBJECT(Directory, aObj, directory))) {
Error(NS_ERROR_DOM_TYPE_MISMATCH_ERR);
return;
}
RefPtr<FileSystemDirectoryEntry> entry =
new FileSystemDirectoryEntry(mParentEntry->GetParentObject(), directory,
mParentEntry, mFileSystem);
// Update the internal values.
mParentEntry = entry;
mDirectory = directory;
Run();
}
void void
GetEntryHelper::RejectedCallback(JSContext* aCx, JS::Handle<JS::Value> aValue) GetEntryHelper::RejectedCallback(JSContext* aCx, JS::Handle<JS::Value> aValue)
{ {
@ -141,7 +203,8 @@ GetEntryHelper::Error(nsresult aError)
if (mErrorCallback) { if (mErrorCallback) {
RefPtr<ErrorCallbackRunnable> runnable = RefPtr<ErrorCallbackRunnable> runnable =
new ErrorCallbackRunnable(mGlobal, mErrorCallback, aError); new ErrorCallbackRunnable(mParentEntry->GetParentObject(),
mErrorCallback, aError);
DebugOnly<nsresult> rv = NS_DispatchToMainThread(runnable); DebugOnly<nsresult> rv = NS_DispatchToMainThread(runnable);
NS_WARNING_ASSERTION(NS_SUCCEEDED(rv), "NS_DispatchToMainThread failed"); NS_WARNING_ASSERTION(NS_SUCCEEDED(rv), "NS_DispatchToMainThread failed");
} }
@ -149,6 +212,21 @@ GetEntryHelper::Error(nsresult aError)
NS_IMPL_ISUPPORTS0(GetEntryHelper); NS_IMPL_ISUPPORTS0(GetEntryHelper);
/* static */ void
FileSystemEntryCallbackHelper::Call(const Optional<OwningNonNull<FileSystemEntryCallback>>& aEntryCallback,
FileSystemEntry* aEntry)
{
MOZ_ASSERT(aEntry);
if (aEntryCallback.WasPassed()) {
RefPtr<EntryCallbackRunnable> runnable =
new EntryCallbackRunnable(&aEntryCallback.Value(), aEntry);
DebugOnly<nsresult> rv = NS_DispatchToMainThread(runnable);
NS_WARNING_ASSERTION(NS_SUCCEEDED(rv), "NS_DispatchToMainThread failed");
}
}
/* static */ void /* static */ void
ErrorCallbackHelper::Call(nsIGlobalObject* aGlobal, ErrorCallbackHelper::Call(nsIGlobalObject* aGlobal,
const Optional<OwningNonNull<ErrorCallback>>& aErrorCallback, const Optional<OwningNonNull<ErrorCallback>>& aErrorCallback,

Просмотреть файл

@ -65,12 +65,17 @@ class GetEntryHelper final : public PromiseNativeHandler
public: public:
NS_DECL_ISUPPORTS NS_DECL_ISUPPORTS
GetEntryHelper(nsIGlobalObject* aGlobalObject, GetEntryHelper(FileSystemDirectoryEntry* aParentEntry,
Directory* aDirectory,
nsTArray<nsString>& aParts,
FileSystem* aFileSystem, FileSystem* aFileSystem,
FileSystemEntryCallback* aSuccessCallback, FileSystemEntryCallback* aSuccessCallback,
ErrorCallback* aErrorCallback, ErrorCallback* aErrorCallback,
FileSystemDirectoryEntry::GetInternalType aType); FileSystemDirectoryEntry::GetInternalType aType);
void
Run();
virtual void virtual void
ResolvedCallback(JSContext* aCx, JS::Handle<JS::Value> aValue) override; ResolvedCallback(JSContext* aCx, JS::Handle<JS::Value> aValue) override;
@ -83,13 +88,31 @@ private:
void void
Error(nsresult aError); Error(nsresult aError);
nsCOMPtr<nsIGlobalObject> mGlobal; void
ContinueRunning(JSObject* aObj);
void
CompleteOperation(JSObject* aObj);
RefPtr<FileSystemDirectoryEntry> mParentEntry;
RefPtr<Directory> mDirectory;
nsTArray<nsString> mParts;
RefPtr<FileSystem> mFileSystem; RefPtr<FileSystem> mFileSystem;
RefPtr<FileSystemEntryCallback> mSuccessCallback; RefPtr<FileSystemEntryCallback> mSuccessCallback;
RefPtr<ErrorCallback> mErrorCallback; RefPtr<ErrorCallback> mErrorCallback;
FileSystemDirectoryEntry::GetInternalType mType; FileSystemDirectoryEntry::GetInternalType mType;
}; };
class FileSystemEntryCallbackHelper
{
public:
static void
Call(const Optional<OwningNonNull<FileSystemEntryCallback>>& aEntryCallback,
FileSystemEntry* aEntry);
};
class ErrorCallbackHelper class ErrorCallbackHelper
{ {
public: public:

Просмотреть файл

@ -25,8 +25,9 @@ NS_INTERFACE_MAP_END_INHERITING(FileSystemEntry)
FileSystemDirectoryEntry::FileSystemDirectoryEntry(nsIGlobalObject* aGlobal, FileSystemDirectoryEntry::FileSystemDirectoryEntry(nsIGlobalObject* aGlobal,
Directory* aDirectory, Directory* aDirectory,
FileSystemDirectoryEntry* aParentEntry,
FileSystem* aFileSystem) FileSystem* aFileSystem)
: FileSystemEntry(aGlobal, aFileSystem) : FileSystemEntry(aGlobal, aParentEntry, aFileSystem)
, mDirectory(aDirectory) , mDirectory(aDirectory)
{ {
MOZ_ASSERT(aGlobal); MOZ_ASSERT(aGlobal);
@ -57,12 +58,12 @@ FileSystemDirectoryEntry::GetFullPath(nsAString& aPath, ErrorResult& aRv) const
} }
already_AddRefed<FileSystemDirectoryReader> already_AddRefed<FileSystemDirectoryReader>
FileSystemDirectoryEntry::CreateReader() const FileSystemDirectoryEntry::CreateReader()
{ {
MOZ_ASSERT(mDirectory); MOZ_ASSERT(mDirectory);
RefPtr<FileSystemDirectoryReader> reader = RefPtr<FileSystemDirectoryReader> reader =
new FileSystemDirectoryReader(GetParentObject(), Filesystem(), mDirectory); new FileSystemDirectoryReader(this, Filesystem(), mDirectory);
return reader.forget(); return reader.forget();
} }
@ -71,7 +72,7 @@ FileSystemDirectoryEntry::GetInternal(const nsAString& aPath,
const FileSystemFlags& aFlag, const FileSystemFlags& aFlag,
const Optional<OwningNonNull<FileSystemEntryCallback>>& aSuccessCallback, const Optional<OwningNonNull<FileSystemEntryCallback>>& aSuccessCallback,
const Optional<OwningNonNull<ErrorCallback>>& aErrorCallback, const Optional<OwningNonNull<ErrorCallback>>& aErrorCallback,
GetInternalType aType) const GetInternalType aType)
{ {
MOZ_ASSERT(mDirectory); MOZ_ASSERT(mDirectory);
@ -92,30 +93,14 @@ FileSystemDirectoryEntry::GetInternal(const nsAString& aPath,
return; return;
} }
ErrorResult error; RefPtr<GetEntryHelper> helper =
RefPtr<Promise> promise = mDirectory->Get(aPath, error); new GetEntryHelper(this, mDirectory, parts, Filesystem(),
if (NS_WARN_IF(error.Failed())) {
ErrorCallbackHelper::Call(GetParentObject(), aErrorCallback,
error.StealNSResult());
return;
}
RefPtr<GetEntryHelper> handler =
new GetEntryHelper(GetParentObject(), Filesystem(),
aSuccessCallback.WasPassed() aSuccessCallback.WasPassed()
? &aSuccessCallback.Value() : nullptr, ? &aSuccessCallback.Value() : nullptr,
aErrorCallback.WasPassed() aErrorCallback.WasPassed()
? &aErrorCallback.Value() : nullptr, ? &aErrorCallback.Value() : nullptr,
aType); aType);
promise->AppendNativeHandler(handler); helper->Run();
}
void
FileSystemDirectoryEntry::RemoveRecursively(VoidCallback& aSuccessCallback,
const Optional<OwningNonNull<ErrorCallback>>& aErrorCallback) const
{
ErrorCallbackHelper::Call(GetParentObject(), aErrorCallback,
NS_ERROR_DOM_SECURITY_ERR);
} }
} // dom namespace } // dom namespace

Просмотреть файл

@ -7,7 +7,6 @@
#ifndef mozilla_dom_FileSystemDirectoryEntry_h #ifndef mozilla_dom_FileSystemDirectoryEntry_h
#define mozilla_dom_FileSystemDirectoryEntry_h #define mozilla_dom_FileSystemDirectoryEntry_h
#include "mozilla/dom/FileSystemBinding.h"
#include "mozilla/dom/FileSystemEntry.h" #include "mozilla/dom/FileSystemEntry.h"
namespace mozilla { namespace mozilla {
@ -25,6 +24,7 @@ public:
FileSystemDirectoryEntry(nsIGlobalObject* aGlobalObject, FileSystemDirectoryEntry(nsIGlobalObject* aGlobalObject,
Directory* aDirectory, Directory* aDirectory,
FileSystemDirectoryEntry* aParentEntry,
FileSystem* aFileSystem); FileSystem* aFileSystem);
virtual JSObject* virtual JSObject*
@ -43,35 +43,33 @@ public:
GetFullPath(nsAString& aFullPath, ErrorResult& aRv) const override; GetFullPath(nsAString& aFullPath, ErrorResult& aRv) const override;
virtual already_AddRefed<FileSystemDirectoryReader> virtual already_AddRefed<FileSystemDirectoryReader>
CreateReader() const; CreateReader();
void void
GetFile(const nsAString& aPath, const FileSystemFlags& aFlag, GetFile(const Optional<nsAString>& aPath, const FileSystemFlags& aFlag,
const Optional<OwningNonNull<FileSystemEntryCallback>>& aSuccessCallback, const Optional<OwningNonNull<FileSystemEntryCallback>>& aSuccessCallback,
const Optional<OwningNonNull<ErrorCallback>>& aErrorCallback) const const Optional<OwningNonNull<ErrorCallback>>& aErrorCallback)
{ {
GetInternal(aPath, aFlag, aSuccessCallback, aErrorCallback, eGetFile); GetInternal(aPath.WasPassed() ? aPath.Value() : EmptyString(),
aFlag, aSuccessCallback, aErrorCallback, eGetFile);
} }
void void
GetDirectory(const nsAString& aPath, const FileSystemFlags& aFlag, GetDirectory(const Optional<nsAString>& aPath, const FileSystemFlags& aFlag,
const Optional<OwningNonNull<FileSystemEntryCallback>>& aSuccessCallback, const Optional<OwningNonNull<FileSystemEntryCallback>>& aSuccessCallback,
const Optional<OwningNonNull<ErrorCallback>>& aErrorCallback) const const Optional<OwningNonNull<ErrorCallback>>& aErrorCallback)
{ {
GetInternal(aPath, aFlag, aSuccessCallback, aErrorCallback, eGetDirectory); GetInternal(aPath.WasPassed() ? aPath.Value() : EmptyString(),
aFlag, aSuccessCallback, aErrorCallback, eGetDirectory);
} }
void
RemoveRecursively(VoidCallback& aSuccessCallback,
const Optional<OwningNonNull<ErrorCallback>>& aErrorCallback) const;
enum GetInternalType { eGetFile, eGetDirectory }; enum GetInternalType { eGetFile, eGetDirectory };
virtual void virtual void
GetInternal(const nsAString& aPath, const FileSystemFlags& aFlag, GetInternal(const nsAString& aPath, const FileSystemFlags& aFlag,
const Optional<OwningNonNull<FileSystemEntryCallback>>& aSuccessCallback, const Optional<OwningNonNull<FileSystemEntryCallback>>& aSuccessCallback,
const Optional<OwningNonNull<ErrorCallback>>& aErrorCallback, const Optional<OwningNonNull<ErrorCallback>>& aErrorCallback,
GetInternalType aType) const; GetInternalType aType);
protected: protected:
virtual ~FileSystemDirectoryEntry(); virtual ~FileSystemDirectoryEntry();

Просмотреть файл

@ -12,7 +12,6 @@
#include "mozilla/dom/DirectoryBinding.h" #include "mozilla/dom/DirectoryBinding.h"
#include "mozilla/dom/Promise.h" #include "mozilla/dom/Promise.h"
#include "mozilla/dom/PromiseNativeHandler.h" #include "mozilla/dom/PromiseNativeHandler.h"
#include "nsIGlobalObject.h"
namespace mozilla { namespace mozilla {
namespace dom { namespace dom {
@ -24,16 +23,16 @@ class PromiseHandler final : public PromiseNativeHandler
public: public:
NS_DECL_ISUPPORTS NS_DECL_ISUPPORTS
PromiseHandler(nsIGlobalObject* aGlobalObject, PromiseHandler(FileSystemDirectoryEntry* aParentEntry,
FileSystem* aFileSystem, FileSystem* aFileSystem,
FileSystemEntriesCallback* aSuccessCallback, FileSystemEntriesCallback* aSuccessCallback,
ErrorCallback* aErrorCallback) ErrorCallback* aErrorCallback)
: mGlobal(aGlobalObject) : mParentEntry(aParentEntry)
, mFileSystem(aFileSystem) , mFileSystem(aFileSystem)
, mSuccessCallback(aSuccessCallback) , mSuccessCallback(aSuccessCallback)
, mErrorCallback(aErrorCallback) , mErrorCallback(aErrorCallback)
{ {
MOZ_ASSERT(aGlobalObject); MOZ_ASSERT(aParentEntry);
MOZ_ASSERT(aFileSystem); MOZ_ASSERT(aFileSystem);
MOZ_ASSERT(aSuccessCallback); MOZ_ASSERT(aSuccessCallback);
} }
@ -72,7 +71,8 @@ public:
RefPtr<File> file; RefPtr<File> file;
if (NS_SUCCEEDED(UNWRAP_OBJECT(File, valueObj, file))) { if (NS_SUCCEEDED(UNWRAP_OBJECT(File, valueObj, file))) {
RefPtr<FileSystemFileEntry> entry = RefPtr<FileSystemFileEntry> entry =
new FileSystemFileEntry(mGlobal, file, mFileSystem); new FileSystemFileEntry(mParentEntry->GetParentObject(), file,
mParentEntry, mFileSystem);
sequence[i] = entry; sequence[i] = entry;
continue; continue;
} }
@ -84,7 +84,8 @@ public:
} }
RefPtr<FileSystemDirectoryEntry> entry = RefPtr<FileSystemDirectoryEntry> entry =
new FileSystemDirectoryEntry(mGlobal, directory, mFileSystem); new FileSystemDirectoryEntry(mParentEntry->GetParentObject(), directory,
mParentEntry, mFileSystem);
sequence[i] = entry; sequence[i] = entry;
} }
@ -96,7 +97,8 @@ public:
{ {
if (mErrorCallback) { if (mErrorCallback) {
RefPtr<ErrorCallbackRunnable> runnable = RefPtr<ErrorCallbackRunnable> runnable =
new ErrorCallbackRunnable(mGlobal, mErrorCallback, new ErrorCallbackRunnable(mParentEntry->GetParentObject(),
mErrorCallback,
NS_ERROR_DOM_INVALID_STATE_ERR); NS_ERROR_DOM_INVALID_STATE_ERR);
DebugOnly<nsresult> rv = NS_DispatchToMainThread(runnable); DebugOnly<nsresult> rv = NS_DispatchToMainThread(runnable);
NS_WARNING_ASSERTION(NS_SUCCEEDED(rv), "NS_DispatchToMainThread failed"); NS_WARNING_ASSERTION(NS_SUCCEEDED(rv), "NS_DispatchToMainThread failed");
@ -106,7 +108,7 @@ public:
private: private:
~PromiseHandler() {} ~PromiseHandler() {}
nsCOMPtr<nsIGlobalObject> mGlobal; RefPtr<FileSystemDirectoryEntry> mParentEntry;
RefPtr<FileSystem> mFileSystem; RefPtr<FileSystem> mFileSystem;
RefPtr<FileSystemEntriesCallback> mSuccessCallback; RefPtr<FileSystemEntriesCallback> mSuccessCallback;
RefPtr<ErrorCallback> mErrorCallback; RefPtr<ErrorCallback> mErrorCallback;
@ -116,7 +118,7 @@ NS_IMPL_ISUPPORTS0(PromiseHandler);
} // anonymous namespace } // anonymous namespace
NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(FileSystemDirectoryReader, mParent, NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(FileSystemDirectoryReader, mParentEntry,
mDirectory, mFileSystem) mDirectory, mFileSystem)
NS_IMPL_CYCLE_COLLECTING_ADDREF(FileSystemDirectoryReader) NS_IMPL_CYCLE_COLLECTING_ADDREF(FileSystemDirectoryReader)
@ -127,15 +129,15 @@ NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(FileSystemDirectoryReader)
NS_INTERFACE_MAP_ENTRY(nsISupports) NS_INTERFACE_MAP_ENTRY(nsISupports)
NS_INTERFACE_MAP_END NS_INTERFACE_MAP_END
FileSystemDirectoryReader::FileSystemDirectoryReader(nsIGlobalObject* aGlobal, FileSystemDirectoryReader::FileSystemDirectoryReader(FileSystemDirectoryEntry* aParentEntry,
FileSystem* aFileSystem, FileSystem* aFileSystem,
Directory* aDirectory) Directory* aDirectory)
: mParent(aGlobal) : mParentEntry(aParentEntry)
, mFileSystem(aFileSystem) , mFileSystem(aFileSystem)
, mDirectory(aDirectory) , mDirectory(aDirectory)
, mAlreadyRead(false) , mAlreadyRead(false)
{ {
MOZ_ASSERT(aGlobal); MOZ_ASSERT(aParentEntry);
MOZ_ASSERT(aFileSystem); MOZ_ASSERT(aFileSystem);
} }
@ -176,7 +178,7 @@ FileSystemDirectoryReader::ReadEntries(FileSystemEntriesCallback& aSuccessCallba
} }
RefPtr<PromiseHandler> handler = RefPtr<PromiseHandler> handler =
new PromiseHandler(GetParentObject(), mFileSystem, &aSuccessCallback, new PromiseHandler(mParentEntry, mFileSystem, &aSuccessCallback,
aErrorCallback.WasPassed() aErrorCallback.WasPassed()
? &aErrorCallback.Value() : nullptr); ? &aErrorCallback.Value() : nullptr);
promise->AppendNativeHandler(handler); promise->AppendNativeHandler(handler);

Просмотреть файл

@ -13,8 +13,6 @@
#include "nsCycleCollectionParticipant.h" #include "nsCycleCollectionParticipant.h"
#include "nsWrapperCache.h" #include "nsWrapperCache.h"
class nsIGlobalObject;
namespace mozilla { namespace mozilla {
namespace dom { namespace dom {
@ -30,14 +28,14 @@ public:
NS_DECL_CYCLE_COLLECTING_ISUPPORTS NS_DECL_CYCLE_COLLECTING_ISUPPORTS
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(FileSystemDirectoryReader) NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(FileSystemDirectoryReader)
explicit FileSystemDirectoryReader(nsIGlobalObject* aGlobalObject, explicit FileSystemDirectoryReader(FileSystemDirectoryEntry* aDirectoryEntry,
FileSystem* aFileSystem, FileSystem* aFileSystem,
Directory* aDirectory); Directory* aDirectory);
nsIGlobalObject* nsIGlobalObject*
GetParentObject() const GetParentObject() const
{ {
return mParent; return mParentEntry->GetParentObject();
} }
virtual JSObject* virtual JSObject*
@ -52,7 +50,7 @@ protected:
virtual ~FileSystemDirectoryReader(); virtual ~FileSystemDirectoryReader();
private: private:
nsCOMPtr<nsIGlobalObject> mParent; RefPtr<FileSystemDirectoryEntry> mParentEntry;
RefPtr<FileSystem> mFileSystem; RefPtr<FileSystem> mFileSystem;
RefPtr<Directory> mDirectory; RefPtr<Directory> mDirectory;

Просмотреть файл

@ -13,7 +13,8 @@
namespace mozilla { namespace mozilla {
namespace dom { namespace dom {
NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(FileSystemEntry, mParent, mFileSystem) NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(FileSystemEntry, mParent, mParentEntry,
mFileSystem)
NS_IMPL_CYCLE_COLLECTING_ADDREF(FileSystemEntry) NS_IMPL_CYCLE_COLLECTING_ADDREF(FileSystemEntry)
NS_IMPL_CYCLE_COLLECTING_RELEASE(FileSystemEntry) NS_IMPL_CYCLE_COLLECTING_RELEASE(FileSystemEntry)
@ -35,11 +36,13 @@ FileSystemEntry::Create(nsIGlobalObject* aGlobalObject,
if (aFileOrDirectory.IsFile()) { if (aFileOrDirectory.IsFile()) {
entry = new FileSystemFileEntry(aGlobalObject, entry = new FileSystemFileEntry(aGlobalObject,
aFileOrDirectory.GetAsFile(), aFileOrDirectory.GetAsFile(),
nullptr,
aFileSystem); aFileSystem);
} else { } else {
MOZ_ASSERT(aFileOrDirectory.IsDirectory()); MOZ_ASSERT(aFileOrDirectory.IsDirectory());
entry = new FileSystemDirectoryEntry(aGlobalObject, entry = new FileSystemDirectoryEntry(aGlobalObject,
aFileOrDirectory.GetAsDirectory(), aFileOrDirectory.GetAsDirectory(),
nullptr,
aFileSystem); aFileSystem);
} }
@ -47,8 +50,10 @@ FileSystemEntry::Create(nsIGlobalObject* aGlobalObject,
} }
FileSystemEntry::FileSystemEntry(nsIGlobalObject* aGlobal, FileSystemEntry::FileSystemEntry(nsIGlobalObject* aGlobal,
FileSystemEntry* aParentEntry,
FileSystem* aFileSystem) FileSystem* aFileSystem)
: mParent(aGlobal) : mParent(aGlobal)
, mParentEntry(aParentEntry)
, mFileSystem(aFileSystem) , mFileSystem(aFileSystem)
{ {
MOZ_ASSERT(aGlobal); MOZ_ASSERT(aGlobal);
@ -64,5 +69,21 @@ FileSystemEntry::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
return FileSystemEntryBinding::Wrap(aCx, this, aGivenProto); return FileSystemEntryBinding::Wrap(aCx, this, aGivenProto);
} }
void
FileSystemEntry::GetParent(const Optional<OwningNonNull<FileSystemEntryCallback>>& aSuccessCallback,
const Optional<OwningNonNull<ErrorCallback>>& aErrorCallback)
{
if (!aSuccessCallback.WasPassed() && !aErrorCallback.WasPassed()) {
return;
}
if (mParentEntry) {
FileSystemEntryCallbackHelper::Call(aSuccessCallback, mParentEntry);
return;
}
FileSystemEntryCallbackHelper::Call(aSuccessCallback, this);
}
} // dom namespace } // dom namespace
} // mozilla namespace } // mozilla namespace

Просмотреть файл

@ -10,6 +10,7 @@
#include "mozilla/Attributes.h" #include "mozilla/Attributes.h"
#include "mozilla/ErrorResult.h" #include "mozilla/ErrorResult.h"
#include "mozilla/dom/BindingDeclarations.h" #include "mozilla/dom/BindingDeclarations.h"
#include "mozilla/dom/FileSystemBinding.h"
#include "nsCycleCollectionParticipant.h" #include "nsCycleCollectionParticipant.h"
#include "nsIGlobalObject.h" #include "nsIGlobalObject.h"
#include "nsWrapperCache.h" #include "nsWrapperCache.h"
@ -60,6 +61,10 @@ public:
virtual void virtual void
GetFullPath(nsAString& aFullPath, ErrorResult& aRv) const = 0; GetFullPath(nsAString& aFullPath, ErrorResult& aRv) const = 0;
void
GetParent(const Optional<OwningNonNull<FileSystemEntryCallback>>& aSuccessCallback,
const Optional<OwningNonNull<ErrorCallback>>& aErrorCallback);
FileSystem* FileSystem*
Filesystem() const Filesystem() const
{ {
@ -68,11 +73,13 @@ public:
protected: protected:
FileSystemEntry(nsIGlobalObject* aGlobalObject, FileSystemEntry(nsIGlobalObject* aGlobalObject,
FileSystemEntry* aParentEntry,
FileSystem* aFileSystem); FileSystem* aFileSystem);
virtual ~FileSystemEntry(); virtual ~FileSystemEntry();
private: private:
nsCOMPtr<nsIGlobalObject> mParent; nsCOMPtr<nsIGlobalObject> mParent;
RefPtr<FileSystemEntry> mParentEntry;
RefPtr<FileSystem> mFileSystem; RefPtr<FileSystem> mFileSystem;
}; };

Просмотреть файл

@ -14,10 +14,10 @@ namespace dom {
namespace { namespace {
class BlobCallbackRunnable final : public Runnable class FileCallbackRunnable final : public Runnable
{ {
public: public:
BlobCallbackRunnable(BlobCallback* aCallback, File* aFile) FileCallbackRunnable(FileCallback* aCallback, File* aFile)
: mCallback(aCallback) : mCallback(aCallback)
, mFile(aFile) , mFile(aFile)
{ {
@ -28,12 +28,12 @@ public:
NS_IMETHOD NS_IMETHOD
Run() override Run() override
{ {
mCallback->HandleEvent(mFile); mCallback->HandleEvent(*mFile);
return NS_OK; return NS_OK;
} }
private: private:
RefPtr<BlobCallback> mCallback; RefPtr<FileCallback> mCallback;
RefPtr<File> mFile; RefPtr<File> mFile;
}; };
@ -49,8 +49,9 @@ NS_INTERFACE_MAP_END_INHERITING(FileSystemEntry)
FileSystemFileEntry::FileSystemFileEntry(nsIGlobalObject* aGlobal, FileSystemFileEntry::FileSystemFileEntry(nsIGlobalObject* aGlobal,
File* aFile, File* aFile,
FileSystemDirectoryEntry* aParentEntry,
FileSystem* aFileSystem) FileSystem* aFileSystem)
: FileSystemEntry(aGlobal, aFileSystem) : FileSystemEntry(aGlobal, aParentEntry, aFileSystem)
, mFile(aFile) , mFile(aFile)
{ {
MOZ_ASSERT(aGlobal); MOZ_ASSERT(aGlobal);
@ -98,11 +99,11 @@ FileSystemFileEntry::CreateWriter(VoidCallback& aSuccessCallback,
} }
void void
FileSystemFileEntry::GetFile(BlobCallback& aSuccessCallback, FileSystemFileEntry::GetFile(FileCallback& aSuccessCallback,
const Optional<OwningNonNull<ErrorCallback>>& aErrorCallback) const const Optional<OwningNonNull<ErrorCallback>>& aErrorCallback) const
{ {
RefPtr<BlobCallbackRunnable> runnable = RefPtr<FileCallbackRunnable> runnable =
new BlobCallbackRunnable(&aSuccessCallback, mFile); new FileCallbackRunnable(&aSuccessCallback, mFile);
DebugOnly<nsresult> rv = NS_DispatchToMainThread(runnable); DebugOnly<nsresult> rv = NS_DispatchToMainThread(runnable);
NS_WARNING_ASSERTION(NS_SUCCEEDED(rv), "NS_DispatchToMainThread failed"); NS_WARNING_ASSERTION(NS_SUCCEEDED(rv), "NS_DispatchToMainThread failed");
} }

Просмотреть файл

@ -13,7 +13,8 @@ namespace mozilla {
namespace dom { namespace dom {
class File; class File;
class BlobCallback; class FileCallback;
class FileSystemDirectoryEntry;
class FileSystemFileEntry final : public FileSystemEntry class FileSystemFileEntry final : public FileSystemEntry
{ {
@ -22,6 +23,7 @@ public:
NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(FileSystemFileEntry, FileSystemEntry) NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(FileSystemFileEntry, FileSystemEntry)
FileSystemFileEntry(nsIGlobalObject* aGlobalObject, File* aFile, FileSystemFileEntry(nsIGlobalObject* aGlobalObject, File* aFile,
FileSystemDirectoryEntry* aParentEntry,
FileSystem* aFileSystem); FileSystem* aFileSystem);
virtual JSObject* virtual JSObject*
@ -44,7 +46,7 @@ public:
const Optional<OwningNonNull<ErrorCallback>>& aErrorCallback) const; const Optional<OwningNonNull<ErrorCallback>>& aErrorCallback) const;
void void
GetFile(BlobCallback& aSuccessCallback, GetFile(FileCallback& aSuccessCallback,
const Optional<OwningNonNull<ErrorCallback>>& aErrorCallback) const; const Optional<OwningNonNull<ErrorCallback>>& aErrorCallback) const;
private: private:

Просмотреть файл

@ -23,7 +23,7 @@ NS_INTERFACE_MAP_END_INHERITING(FileSystemDirectoryEntry)
FileSystemRootDirectoryEntry::FileSystemRootDirectoryEntry(nsIGlobalObject* aGlobal, FileSystemRootDirectoryEntry::FileSystemRootDirectoryEntry(nsIGlobalObject* aGlobal,
const Sequence<RefPtr<FileSystemEntry>>& aEntries, const Sequence<RefPtr<FileSystemEntry>>& aEntries,
FileSystem* aFileSystem) FileSystem* aFileSystem)
: FileSystemDirectoryEntry(aGlobal, nullptr, aFileSystem) : FileSystemDirectoryEntry(aGlobal, nullptr, nullptr, aFileSystem)
, mEntries(aEntries) , mEntries(aEntries)
{ {
MOZ_ASSERT(aGlobal); MOZ_ASSERT(aGlobal);
@ -45,11 +45,10 @@ FileSystemRootDirectoryEntry::GetFullPath(nsAString& aPath, ErrorResult& aRv) co
} }
already_AddRefed<FileSystemDirectoryReader> already_AddRefed<FileSystemDirectoryReader>
FileSystemRootDirectoryEntry::CreateReader() const FileSystemRootDirectoryEntry::CreateReader()
{ {
RefPtr<FileSystemDirectoryReader> reader = RefPtr<FileSystemDirectoryReader> reader =
new FileSystemRootDirectoryReader(GetParentObject(), Filesystem(), new FileSystemRootDirectoryReader(this, Filesystem(), mEntries);
mEntries);
return reader.forget(); return reader.forget();
} }
@ -58,7 +57,7 @@ FileSystemRootDirectoryEntry::GetInternal(const nsAString& aPath,
const FileSystemFlags& aFlag, const FileSystemFlags& aFlag,
const Optional<OwningNonNull<FileSystemEntryCallback>>& aSuccessCallback, const Optional<OwningNonNull<FileSystemEntryCallback>>& aSuccessCallback,
const Optional<OwningNonNull<ErrorCallback>>& aErrorCallback, const Optional<OwningNonNull<ErrorCallback>>& aErrorCallback,
GetInternalType aType) const GetInternalType aType)
{ {
if (!aSuccessCallback.WasPassed() && !aErrorCallback.WasPassed()) { if (!aSuccessCallback.WasPassed() && !aErrorCallback.WasPassed()) {
return; return;

Просмотреть файл

@ -29,7 +29,7 @@ public:
GetFullPath(nsAString& aFullPath, ErrorResult& aRv) const override; GetFullPath(nsAString& aFullPath, ErrorResult& aRv) const override;
virtual already_AddRefed<FileSystemDirectoryReader> virtual already_AddRefed<FileSystemDirectoryReader>
CreateReader() const override; CreateReader() override;
private: private:
~FileSystemRootDirectoryEntry(); ~FileSystemRootDirectoryEntry();
@ -38,7 +38,7 @@ private:
GetInternal(const nsAString& aPath, const FileSystemFlags& aFlag, GetInternal(const nsAString& aPath, const FileSystemFlags& aFlag,
const Optional<OwningNonNull<FileSystemEntryCallback>>& aSuccessCallback, const Optional<OwningNonNull<FileSystemEntryCallback>>& aSuccessCallback,
const Optional<OwningNonNull<ErrorCallback>>& aErrorCallback, const Optional<OwningNonNull<ErrorCallback>>& aErrorCallback,
GetInternalType aType) const override; GetInternalType aType) override;
void void
Error(const Optional<OwningNonNull<ErrorCallback>>& aErrorCallback, Error(const Optional<OwningNonNull<ErrorCallback>>& aErrorCallback,

Просмотреть файл

@ -56,14 +56,14 @@ NS_IMPL_RELEASE_INHERITED(FileSystemRootDirectoryReader,
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(FileSystemRootDirectoryReader) NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(FileSystemRootDirectoryReader)
NS_INTERFACE_MAP_END_INHERITING(FileSystemDirectoryReader) NS_INTERFACE_MAP_END_INHERITING(FileSystemDirectoryReader)
FileSystemRootDirectoryReader::FileSystemRootDirectoryReader(nsIGlobalObject* aGlobal, FileSystemRootDirectoryReader::FileSystemRootDirectoryReader(FileSystemDirectoryEntry* aParentEntry,
FileSystem* aFileSystem, FileSystem* aFileSystem,
const Sequence<RefPtr<FileSystemEntry>>& aEntries) const Sequence<RefPtr<FileSystemEntry>>& aEntries)
: FileSystemDirectoryReader(aGlobal, aFileSystem, nullptr) : FileSystemDirectoryReader(aParentEntry, aFileSystem, nullptr)
, mEntries(aEntries) , mEntries(aEntries)
, mAlreadyRead(false) , mAlreadyRead(false)
{ {
MOZ_ASSERT(aGlobal); MOZ_ASSERT(aParentEntry);
MOZ_ASSERT(aFileSystem); MOZ_ASSERT(aFileSystem);
} }

Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше