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

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

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

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

@ -93,6 +93,7 @@
<command id="Browser:OpenLocation" oncommand="openLocation();"/>
<command id="Browser:RestoreLastSession" oncommand="restoreLastSession();" disabled="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:Downloads" oncommand="BrowserDownloadsUI();"/>

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

@ -119,6 +119,16 @@ tabbrowser {
visibility: hidden; /* temporary space to keep a tab's close button under the cursor */
}
.tabs-newtab-button > .toolbarbutton-menu-dropmarker,
#new-tab-button > .toolbarbutton-menu-dropmarker {
display: none;
}
/* override drop marker image padding */
.tabs-newtab-button > .toolbarbutton-icon {
margin-inline-end: 0;
}
.tabbrowser-tab {
-moz-binding: url("chrome://browser/content/tabbrowser.xml#tabbrowser-tab");
}
@ -177,6 +187,7 @@ tabbrowser {
transition: transform 200ms ease-out;
}
.new-tab-popup,
#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?
*/
function SetClickAndHoldHandlers() {
var timer;
function openMenu(aButton) {
cancelHold(aButton);
aButton.firstChild.hidden = false;
aButton.open = true;
}
function mousedownHandler(aEvent) {
if (aEvent.button != 0 ||
aEvent.currentTarget.open ||
aEvent.currentTarget.disabled)
return;
// Prevent the menupopup from opening immediately
aEvent.currentTarget.firstChild.hidden = true;
aEvent.currentTarget.addEventListener("mouseout", mouseoutHandler, false);
aEvent.currentTarget.addEventListener("mouseup", mouseupHandler, false);
timer = setTimeout(openMenu, 500, aEvent.currentTarget);
}
function mouseoutHandler(aEvent) {
let buttonRect = aEvent.currentTarget.getBoundingClientRect();
if (aEvent.clientX >= buttonRect.left &&
aEvent.clientX <= buttonRect.right &&
aEvent.clientY >= buttonRect.bottom)
openMenu(aEvent.currentTarget);
else
cancelHold(aEvent.currentTarget);
}
function mouseupHandler(aEvent) {
cancelHold(aEvent.currentTarget);
}
function cancelHold(aButton) {
clearTimeout(timer);
aButton.removeEventListener("mouseout", mouseoutHandler, false);
aButton.removeEventListener("mouseup", mouseupHandler, false);
}
function clickHandler(aEvent) {
if (aEvent.button == 0 &&
aEvent.target == aEvent.currentTarget &&
!aEvent.currentTarget.open &&
!aEvent.currentTarget.disabled) {
let cmdEvent = document.createEvent("xulcommandevent");
cmdEvent.initCommandEvent("command", true, true, window, 0,
aEvent.ctrlKey, aEvent.altKey, aEvent.shiftKey,
aEvent.metaKey, null);
aEvent.currentTarget.dispatchEvent(cmdEvent);
}
}
function _addClickAndHoldListenersOnElement(aElm) {
aElm.addEventListener("mousedown", mousedownHandler, true);
aElm.addEventListener("click", clickHandler, true);
}
// Bug 414797: Clone the back/forward buttons' context menu into both buttons.
let popup = document.getElementById("backForwardMenu").cloneNode(true);
popup.removeAttribute("id");
@ -338,15 +278,107 @@ function SetClickAndHoldHandlers() {
let backButton = document.getElementById("back-button");
backButton.setAttribute("type", "menu");
backButton.appendChild(popup);
_addClickAndHoldListenersOnElement(backButton);
gClickAndHoldListenersOnElement.add(backButton);
let forwardButton = document.getElementById("forward-button");
popup = popup.cloneNode(true);
forwardButton.setAttribute("type", "menu");
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 = {
observe: function(subject, topic, data)
{
@ -4100,22 +4132,25 @@ function updateUserContextUIIndicator()
let userContextId = gBrowser.selectedBrowser.getAttribute("usercontextid");
if (!userContextId) {
hbox.setAttribute("data-identity-color", "");
hbox.hidden = true;
return;
}
let identity = ContextualIdentityService.getIdentityFromId(userContextId);
if (!identity) {
hbox.setAttribute("data-identity-color", "");
hbox.hidden = true;
return;
}
hbox.setAttribute("data-identity-color", identity.color);
let label = document.getElementById("userContext-label");
label.setAttribute('value', ContextualIdentityService.getUserContextLabel(userContextId));
label.style.color = identity.color;
label.setAttribute("value", ContextualIdentityService.getUserContextLabel(userContextId));
let indicator = document.getElementById("userContext-indicator");
indicator.style.listStyleImage = "url(" + identity.icon + ")";
indicator.setAttribute("data-identity-icon", identity.icon);
hbox.hidden = false;
}

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

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

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

@ -529,7 +529,7 @@ function openCacheEntry(key, cb)
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;
var url = docInfo.location;

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

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

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

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

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

@ -534,3 +534,4 @@ skip-if = !e10s
tags = mcb
[browser_newwindow_focus.js]
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_multi_allow.js]
[browser_CTP_nonplugins.js]
skip-if = true # Bug 1315042
[browser_CTP_notificationBar.js]
[browser_CTP_outsideScrollArea.js]
[browser_CTP_remove_navigate.js]

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

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

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

@ -83,5 +83,11 @@ function* testProbe(aProbe) {
`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_LONG_MS"));

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

@ -1,6 +1,12 @@
const kURL1 = "data:text/html,Should I stay or should I go?";
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
* 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_in_frame.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;
if (showNotification) {
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");
if (previousDate < date) {
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
// by onpopupshowing passing the event as first argument. addCommandAttribute
// param is used to set the 'command' attribute in the new menuitem elements.
function createUserContextMenu(event, addCommandAttribute = true, excludeUserContextId = 0) {
// by onpopupshowing passing the event as first argument.
function createUserContextMenu(event, isContextMenu = false, excludeUserContextId = 0) {
while (event.target.hasChildNodes()) {
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("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
// addCommandAttribute will be false.
// isContextMenu will be true.
docfrag.appendChild(menuitem);
@ -479,16 +478,29 @@ function createUserContextMenu(event, addCommandAttribute = true, excludeUserCon
}
menuitem.classList.add("menuitem-iconic");
menuitem.setAttribute("data-identity-color", identity.color);
if (addCommandAttribute) {
if (!isContextMenu) {
menuitem.setAttribute("command", "Browser:NewUserContextTab");
}
menuitem.setAttribute("image", identity.icon);
menuitem.setAttribute("data-identity-icon", identity.icon);
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);
return true;
}

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

@ -165,6 +165,7 @@ browser.jar:
content/browser/tabbrowser.xml (content/tabbrowser.xml)
content/browser/urlbarBindings.xml (content/urlbarBindings.xml)
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.xul (content/web-panels.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 {
height: 16px;
width: 16px;
@ -5,9 +65,27 @@
#userContext-label {
margin-inline-end: 3px;
color: #909090;
color: var(--identity-tab-color);
}
#userContext-icons {
-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_EME_forgetThisSite.js]
[browser_forgetAPI_quota_clearStoragesForPrincipal.js]
[browser_newtabButton.js]
[browser_usercontext.js]
[browser_usercontextid_tabdrop.js]
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.
yield new Promise(resolve => {
SpecialPowers.pushPrefEnv({"set": [
["privacy.userContext.enabled", true]
["privacy.userContext.enabled", true],
["dom.ipc.processCount", 1]
]}, resolve);
});
});

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

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

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

@ -1108,8 +1108,10 @@ const CustomizableWidgets = [
let onItemCommand = function (aEvent) {
let item = aEvent.target;
let userContextId = parseInt(item.getAttribute("usercontextid"));
win.openUILinkIn(win.BROWSER_NEW_TAB_URL, "tab", {userContextId});
if (item.hasAttribute("usercontextid")) {
let userContextId = parseInt(item.getAttribute("usercontextid"));
win.openUILinkIn(win.BROWSER_NEW_TAB_URL, "tab", {userContextId});
}
};
items.addEventListener("command", onItemCommand);
@ -1134,20 +1136,29 @@ const CustomizableWidgets = [
}
let fragment = doc.createDocumentFragment();
let bundle = doc.getElementById("bundle_browser");
ContextualIdentityService.getIdentities().forEach(identity => {
let bundle = doc.getElementById("bundle_browser");
let label = ContextualIdentityService.getUserContextLabel(identity.userContextId);
let item = doc.createElementNS(kNSXUL, "toolbarbutton");
item.setAttribute("label", label);
item.setAttribute("usercontextid", identity.userContextId);
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(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);
},

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

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

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

@ -78,15 +78,6 @@ XPCOMUtils.defineLazyGetter(this, "standaloneStylesheets", () => {
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 {
constructor(extension, viewNode, popupURL, browserStyle, fixedWidth = false) {
this.extension = extension;
@ -97,6 +88,8 @@ class BasePopup {
this.destroyed = false;
this.fixedWidth = fixedWidth;
extension.callOnClose(this);
this.contentReady = new Promise(resolve => {
this._resolveContentReady = resolve;
});
@ -120,7 +113,13 @@ class BasePopup {
return BasePopup.instances.get(window).get(extension);
}
close() {
this.closePopup();
}
destroy() {
this.extension.forgetOnClose(this);
this.destroyed = true;
this.browserLoadedDeferred.reject(new Error("Popup destroyed"));
return this.browserReady.then(() => {

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

@ -53,6 +53,7 @@ tags = webextensions
[browser_ext_popup_api_injection.js]
[browser_ext_popup_background.js]
[browser_ext_popup_corners.js]
[browser_ext_popup_sendMessage.js]
[browser_ext_popup_shutdown.js]
[browser_ext_runtime_openOptionsPage.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
// and command events will be dispatched immediately after mouseup, and void
// 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.pendingPopupTimeout, null, "Have a pending popup timeout");
return true;
@ -291,3 +291,74 @@ add_task(function* testBrowserActionClickCanceled() {
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 new Promise(resolve => setTimeout(resolve, 0));
is(panel.parentNode, null, "Panel should be removed from the document");
});

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

@ -33,6 +33,7 @@ support-files =
worker_deblobify.js
[browser_broadcastChannel.js]
[browser_cookieIsolation.js]
[browser_favicon_firstParty.js]
[browser_favicon_userContextId.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");
}
#containersView > richlistitem {
-moz-binding: url("chrome://browser/content/preferences/handlers.xml#container");
}
/**
* Make the icons appear.
* Note: we display the icon box for every item whether or not it has an icon

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

@ -69,6 +69,29 @@
</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"
extends="chrome://global/content/bindings/listbox.xml#listitem">
<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/privacy.js
content/browser/preferences/in-content/containers.js
content/browser/preferences/in-content/advanced.js
content/browser/preferences/in-content/applications.js
content/browser/preferences/in-content/content.js

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

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

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

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

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

@ -178,6 +178,8 @@ var gPrivacyPane = {
gPrivacyPane.showBlockLists);
setEventListener("browserContainersCheckbox", "command",
gPrivacyPane._checkBrowserContainers);
setEventListener("browserContainersSettings", "command",
gPrivacyPane.showContainerSettings);
},
// TRACKING PROTECTION MODE
@ -475,6 +477,13 @@ var gPrivacyPane = {
null, params);
},
/**
* Displays container panel for customising and adding containers.
*/
showContainerSettings() {
gotoPref("containers");
},
/**
* Displays the available block lists for tracking protection.
*/
@ -678,6 +687,26 @@ var gPrivacyPane = {
var sanitizeOnShutdownPref = document.getElementById("privacy.sanitize.sanitizeOnShutdown");
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"
value="&browserContainersLearnMore.label;"/>
</label></caption>
<checkbox id="browserContainersCheckbox"
label="&browserContainersEnabled.label;"
accesskey="&browserContainersEnabled.accesskey;" />
<hbox align="start">
<vbox>
<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>
</groupbox>

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

@ -20,6 +20,8 @@ browser.jar:
* content/browser/preferences/languages.xul
content/browser/preferences/languages.js
content/browser/preferences/permissions.xul
content/browser/preferences/containers.xul
content/browser/preferences/containers.js
content/browser/preferences/permissions.js
content/browser/preferences/sanitize.xul
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 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() {
let prefix = 'http://mochi.test:8888/browser/browser/components/privatebrowsing/test/browser/browser_privatebrowsing_concurrent_page.html';

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

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

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

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

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

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

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

@ -6,7 +6,6 @@ pageInfo.page.title=Page Info - %S
pageInfo.frame.title=Frame Info - %S
noPageTitle=Untitled Page:
pageTitle=%S:
unknown=Unknown
notset=Not specified
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 paneApplications.title "Applications">
<!ENTITY panePrivacy.title "Privacy">
<!ENTITY paneContainers.title "Container Tabs">
<!ENTITY paneSecurity.title "Security">
<!ENTITY paneAdvanced.title "Advanced">

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

@ -109,3 +109,5 @@
<!ENTITY browserContainersLearnMore.label "Learn more">
<!ENTITY browserContainersEnabled.label "Enable Container Tabs">
<!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/preferences.dtd (%chrome/browser/preferences/preferences.dtd)
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/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/tabs.dtd (%chrome/browser/preferences/tabs.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 = {
init(aWindow) {
init: function(aWindow) {
// Register ourselves with the service so we know when the zoom prefs change.
Services.obs.addObserver(this, "browser-fullZoom:zoomChange", false);
Services.obs.addObserver(this, "browser-fullZoom:zoomReset", false);
Services.obs.addObserver(this, "browser-fullZoom:location-change", false);
Services.obs.addObserver(updateZoomButton, "browser-fullZoom:zoomChange", false);
Services.obs.addObserver(updateZoomButton, "browser-fullZoom:zoomReset", false);
Services.obs.addObserver(updateZoomButton, "browser-fullZoom:location-change", false);
},
}
observe(aSubject, aTopic) {
this.updateZoomButton(aSubject, aTopic);
},
function 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) {
// aSubject.ownerGlobal may no longer exist if a tab has been dragged to a
// new window. In this case, aSubject.ownerGlobal will be supplied by
// updateZoomButton() called in XULBrowserWindow.onLocationChange().
if (!aSubject.ownerGlobal) {
return;
// 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;
}
let win = aSubject.ownerGlobal;
let customizableZoomControls = win.document.getElementById("zoom-controls");
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]));
// Only allow pulse animation for zoom changes, not tab switching
if (aTopic != "browser-fullZoom:location-change") {
zoomResetButton.setAttribute("animate", "true");
} else {
// Hide button if zoom is at 100%
zoomResetButton.hidden = true;
zoomResetButton.removeAttribute("animate");
}
},
};
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/icons.svg (../shared/incontentprefs/icons.svg)
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/logo.png (../shared/fxa/logo.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/urlbar-star.svg (../shared/urlbar-star.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
fi
done
if test "$android_build_tools_version" == ""; then
if test "$android_build_tools_version" = ""; then
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)])
fi

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

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

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

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

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

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

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

@ -4,6 +4,12 @@
"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
// when a node with no animation is selected.
// 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_rule_view.js]
[browser_toolbox_swap_browsers.js]
skip-if = true # Bug 1315042
[browser_touch_simulation.js]
[browser_viewport_basics.js]
[browser_window_close.js]

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

@ -13,6 +13,12 @@ const TEST_DOC = "https://example.com/browser/devtools/client/webconsole/" +
"test/test_bug1092055_shouldwarn.html";
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* () {
let { browser } = yield loadTab(TEST_URI);

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

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

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

@ -4,6 +4,12 @@
"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
// multiple animations.

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

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

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

@ -16,7 +16,9 @@ DocGroup::GetKey(nsIPrincipal* aPrincipal, nsACString& aKey)
aKey.Truncate();
nsCOMPtr<nsIURI> 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 =
do_GetService(NS_EFFECTIVETLDSERVICE_CONTRACTID);
if (tldService) {

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

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

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

@ -271,15 +271,15 @@ public:
* Get the SMIL override style declaration for this element. If the
* 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
* aNotify is true, this method will notify the document's pres
* context, so that the style changes will be noticed.
*/
virtual nsresult SetSMILOverrideStyleDeclaration(css::Declaration* aDeclaration,
bool aNotify);
virtual nsresult SetSMILOverrideStyleDeclaration(
DeclarationBlock* aDeclaration, bool aNotify);
/**
* Returns a new nsISMILAttr that allows the caller to animate the given

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

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

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

@ -33,9 +33,7 @@ class nsDOMStringMap;
class nsIURI;
namespace mozilla {
namespace css {
class Declaration;
} // namespace css
class DeclarationBlock;
namespace dom {
class DOMIntersectionObserver;
class Element;
@ -284,7 +282,7 @@ public:
/**
* 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)

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

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

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

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

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

@ -20,6 +20,7 @@ tags = mcb
[browser_bug1011748.js]
[browser_bug1058164.js]
[browser_messagemanager_loadprocessscript.js]
skip-if = true # Bug 1315042
[browser_messagemanager_targetframeloader.js]
[browser_messagemanager_unload.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
disabled = Disabling some OOP tests for WebIDL scope changes
[test_browserElement_oop_PrivateBrowsing.html]
skip-if = true # Bug 1315042
[test_browserElement_oop_PromptCheck.html]
[test_browserElement_oop_PromptConfirm.html]
# 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
// the spec required font sizes be converted to pixels, but that no
// longer seems to be required.)
decl->GetValue(eCSSProperty_font, aOutUsedFont);
decl->GetPropertyValueByID(eCSSProperty_font, aOutUsedFont);
return sc.forget();
}

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

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

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

@ -18,8 +18,8 @@ class ErrorResult;
namespace dom {
class BlobCallback;
class EncodeCompleteCallback;
class FileCallback;
enum class CanvasContextType : uint8_t {
NoContext,
@ -55,7 +55,7 @@ protected:
nsAString& outParams,
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,
ErrorResult& aRv);

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

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

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

@ -5,8 +5,9 @@
* You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "CallbackRunnables.h"
#include "mozilla/dom/Directory.h"
#include "mozilla/dom/DirectoryBinding.h"
#include "mozilla/dom/DOMError.h"
#include "mozilla/dom/DOMException.h"
#include "mozilla/dom/File.h"
#include "mozilla/dom/FileBinding.h"
#include "mozilla/dom/FileSystemDirectoryReaderBinding.h"
@ -55,8 +56,8 @@ ErrorCallbackRunnable::Run()
return NS_ERROR_FAILURE;
}
RefPtr<DOMError> error = new DOMError(window, mError);
mCallback->HandleEvent(*error);
RefPtr<DOMException> exception = DOMException::Create(mError);
mCallback->HandleEvent(*exception);
return NS_OK;
}
@ -74,18 +75,24 @@ EmptyEntriesCallbackRunnable::Run()
return NS_OK;
}
GetEntryHelper::GetEntryHelper(nsIGlobalObject* aGlobalObject,
GetEntryHelper::GetEntryHelper(FileSystemDirectoryEntry* aParentEntry,
Directory* aDirectory,
nsTArray<nsString>& aParts,
FileSystem* aFileSystem,
FileSystemEntryCallback* aSuccessCallback,
ErrorCallback* aErrorCallback,
FileSystemDirectoryEntry::GetInternalType aType)
: mGlobal(aGlobalObject)
: mParentEntry(aParentEntry)
, mDirectory(aDirectory)
, mParts(aParts)
, mFileSystem(aFileSystem)
, mSuccessCallback(aSuccessCallback)
, mErrorCallback(aErrorCallback)
, mType(aType)
{
MOZ_ASSERT(aGlobalObject);
MOZ_ASSERT(aParentEntry);
MOZ_ASSERT(aDirectory);
MOZ_ASSERT(!aParts.IsEmpty());
MOZ_ASSERT(aFileSystem);
MOZ_ASSERT(aSuccessCallback || aErrorCallback);
}
@ -93,6 +100,23 @@ GetEntryHelper::GetEntryHelper(nsIGlobalObject* aGlobalObject,
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
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());
// 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) {
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);
return;
}
RefPtr<FileSystemFileEntry> entry =
new FileSystemFileEntry(mGlobal, file, mFileSystem);
new FileSystemFileEntry(mParentEntry->GetParentObject(), file,
mParentEntry, mFileSystem);
mSuccessCallback->HandleEvent(*entry);
return;
}
@ -118,16 +157,39 @@ GetEntryHelper::ResolvedCallback(JSContext* aCx, JS::Handle<JS::Value> aValue)
MOZ_ASSERT(mType == FileSystemDirectoryEntry::eGetDirectory);
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);
return;
}
RefPtr<FileSystemDirectoryEntry> entry =
new FileSystemDirectoryEntry(mGlobal, directory, mFileSystem);
new FileSystemDirectoryEntry(mParentEntry->GetParentObject(), directory,
mParentEntry, mFileSystem);
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
GetEntryHelper::RejectedCallback(JSContext* aCx, JS::Handle<JS::Value> aValue)
{
@ -141,7 +203,8 @@ GetEntryHelper::Error(nsresult aError)
if (mErrorCallback) {
RefPtr<ErrorCallbackRunnable> runnable =
new ErrorCallbackRunnable(mGlobal, mErrorCallback, aError);
new ErrorCallbackRunnable(mParentEntry->GetParentObject(),
mErrorCallback, aError);
DebugOnly<nsresult> rv = NS_DispatchToMainThread(runnable);
NS_WARNING_ASSERTION(NS_SUCCEEDED(rv), "NS_DispatchToMainThread failed");
}
@ -149,6 +212,21 @@ GetEntryHelper::Error(nsresult aError)
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
ErrorCallbackHelper::Call(nsIGlobalObject* aGlobal,
const Optional<OwningNonNull<ErrorCallback>>& aErrorCallback,

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

@ -65,12 +65,17 @@ class GetEntryHelper final : public PromiseNativeHandler
public:
NS_DECL_ISUPPORTS
GetEntryHelper(nsIGlobalObject* aGlobalObject,
GetEntryHelper(FileSystemDirectoryEntry* aParentEntry,
Directory* aDirectory,
nsTArray<nsString>& aParts,
FileSystem* aFileSystem,
FileSystemEntryCallback* aSuccessCallback,
ErrorCallback* aErrorCallback,
FileSystemDirectoryEntry::GetInternalType aType);
void
Run();
virtual void
ResolvedCallback(JSContext* aCx, JS::Handle<JS::Value> aValue) override;
@ -83,13 +88,31 @@ private:
void
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<FileSystemEntryCallback> mSuccessCallback;
RefPtr<ErrorCallback> mErrorCallback;
FileSystemDirectoryEntry::GetInternalType mType;
};
class FileSystemEntryCallbackHelper
{
public:
static void
Call(const Optional<OwningNonNull<FileSystemEntryCallback>>& aEntryCallback,
FileSystemEntry* aEntry);
};
class ErrorCallbackHelper
{
public:

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

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

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

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

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

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

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

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

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

@ -13,7 +13,8 @@
namespace mozilla {
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_RELEASE(FileSystemEntry)
@ -35,11 +36,13 @@ FileSystemEntry::Create(nsIGlobalObject* aGlobalObject,
if (aFileOrDirectory.IsFile()) {
entry = new FileSystemFileEntry(aGlobalObject,
aFileOrDirectory.GetAsFile(),
nullptr,
aFileSystem);
} else {
MOZ_ASSERT(aFileOrDirectory.IsDirectory());
entry = new FileSystemDirectoryEntry(aGlobalObject,
aFileOrDirectory.GetAsDirectory(),
nullptr,
aFileSystem);
}
@ -47,8 +50,10 @@ FileSystemEntry::Create(nsIGlobalObject* aGlobalObject,
}
FileSystemEntry::FileSystemEntry(nsIGlobalObject* aGlobal,
FileSystemEntry* aParentEntry,
FileSystem* aFileSystem)
: mParent(aGlobal)
, mParentEntry(aParentEntry)
, mFileSystem(aFileSystem)
{
MOZ_ASSERT(aGlobal);
@ -64,5 +69,21 @@ FileSystemEntry::WrapObject(JSContext* aCx, JS::Handle<JSObject*> 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
} // mozilla namespace

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

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

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

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

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

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

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

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

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

@ -29,7 +29,7 @@ public:
GetFullPath(nsAString& aFullPath, ErrorResult& aRv) const override;
virtual already_AddRefed<FileSystemDirectoryReader>
CreateReader() const override;
CreateReader() override;
private:
~FileSystemRootDirectoryEntry();
@ -38,7 +38,7 @@ private:
GetInternal(const nsAString& aPath, const FileSystemFlags& aFlag,
const Optional<OwningNonNull<FileSystemEntryCallback>>& aSuccessCallback,
const Optional<OwningNonNull<ErrorCallback>>& aErrorCallback,
GetInternalType aType) const override;
GetInternalType aType) override;
void
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_END_INHERITING(FileSystemDirectoryReader)
FileSystemRootDirectoryReader::FileSystemRootDirectoryReader(nsIGlobalObject* aGlobal,
FileSystemRootDirectoryReader::FileSystemRootDirectoryReader(FileSystemDirectoryEntry* aParentEntry,
FileSystem* aFileSystem,
const Sequence<RefPtr<FileSystemEntry>>& aEntries)
: FileSystemDirectoryReader(aGlobal, aFileSystem, nullptr)
: FileSystemDirectoryReader(aParentEntry, aFileSystem, nullptr)
, mEntries(aEntries)
, mAlreadyRead(false)
{
MOZ_ASSERT(aGlobal);
MOZ_ASSERT(aParentEntry);
MOZ_ASSERT(aFileSystem);
}

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