зеркало из https://github.com/mozilla/gecko-dev.git
Merge mozilla-central to inbound. a=merge CLOSED TREE
This commit is contained in:
Коммит
f7ac77cf17
|
@ -77,7 +77,7 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "audioipc"
|
||||
version = "0.2.3"
|
||||
version = "0.2.4"
|
||||
dependencies = [
|
||||
"bincode 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"bytes 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
|
@ -100,7 +100,7 @@ dependencies = [
|
|||
name = "audioipc-client"
|
||||
version = "0.4.0"
|
||||
dependencies = [
|
||||
"audioipc 0.2.3",
|
||||
"audioipc 0.2.4",
|
||||
"cubeb-backend 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"foreign-types 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"futures 0.1.18 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
|
@ -113,11 +113,11 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "audioipc-server"
|
||||
version = "0.2.2"
|
||||
version = "0.2.3"
|
||||
dependencies = [
|
||||
"audioipc 0.2.3",
|
||||
"audioipc 0.2.4",
|
||||
"bytes 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"cubeb 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"cubeb-core 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"error-chain 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"futures 0.1.18 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"lazycell 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
|
@ -822,7 +822,7 @@ name = "gkrust-shared"
|
|||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"audioipc-client 0.4.0",
|
||||
"audioipc-server 0.2.2",
|
||||
"audioipc-server 0.2.3",
|
||||
"cose-c 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"cubeb-pulse 0.2.0",
|
||||
"cubeb-sys 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
|
|
|
@ -1,18 +1,49 @@
|
|||
add_task(async function test_reserved_shortcuts() {
|
||||
/* eslint-disable no-unsanitized/property */
|
||||
let keyset = `<keyset>
|
||||
<key id='kt_reserved' modifiers='shift' key='O' reserved='true' count='0'
|
||||
oncommand='this.setAttribute("count", Number(this.getAttribute("count")) + 1)'/>
|
||||
<key id='kt_notreserved' modifiers='shift' key='P' reserved='false' count='0'
|
||||
oncommand='this.setAttribute("count", Number(this.getAttribute("count")) + 1)'/>
|
||||
<key id='kt_reserveddefault' modifiers='shift' key='Q' count='0'
|
||||
oncommand='this.setAttribute("count", Number(this.getAttribute("count")) + 1)'/>
|
||||
</keyset>`;
|
||||
let keyset = document.createElement("keyset");
|
||||
let key1 = document.createElement("key");
|
||||
key1.setAttribute("id", "kt_reserved");
|
||||
key1.setAttribute("modifiers", "shift");
|
||||
key1.setAttribute("key", "O");
|
||||
key1.setAttribute("reserved", "true");
|
||||
key1.setAttribute("count", "0");
|
||||
// We need to have the attribute "oncommand" for the "command" listener to fire
|
||||
key1.setAttribute("oncommand", "//");
|
||||
key1.addEventListener("command", () => {
|
||||
let attribute = key1.getAttribute("count");
|
||||
key1.setAttribute("count", Number(attribute) + 1);
|
||||
});
|
||||
|
||||
let key2 = document.createElement("key");
|
||||
key2.setAttribute("id", "kt_notreserved");
|
||||
key2.setAttribute("modifiers", "shift");
|
||||
key2.setAttribute("key", "P");
|
||||
key2.setAttribute("reserved", "false");
|
||||
key2.setAttribute("count", "0");
|
||||
// We need to have the attribute "oncommand" for the "command" listener to fire
|
||||
key2.setAttribute("oncommand", "//");
|
||||
key2.addEventListener("command", () => {
|
||||
let attribute = key2.getAttribute("count");
|
||||
key2.setAttribute("count", Number(attribute) + 1);
|
||||
});
|
||||
|
||||
let key3 = document.createElement("key");
|
||||
key3.setAttribute("id", "kt_reserveddefault");
|
||||
key3.setAttribute("modifiers", "shift");
|
||||
key3.setAttribute("key", "Q");
|
||||
key3.setAttribute("count", "0");
|
||||
// We need to have the attribute "oncommand" for the "command" listener to fire
|
||||
key3.setAttribute("oncommand", "//");
|
||||
key3.addEventListener("command", () => {
|
||||
let attribute = key3.getAttribute("count");
|
||||
key3.setAttribute("count", Number(attribute) + 1);
|
||||
});
|
||||
|
||||
keyset.appendChild(key1);
|
||||
keyset.appendChild(key2);
|
||||
keyset.appendChild(key3);
|
||||
let container = document.createElement("box");
|
||||
container.unsafeSetInnerHTML(keyset);
|
||||
container.appendChild(keyset);
|
||||
document.documentElement.appendChild(container);
|
||||
/* eslint-enable no-unsanitized/property */
|
||||
|
||||
const pageUrl = "data:text/html,<body onload='document.body.firstChild.focus();'><div onkeydown='event.preventDefault();' tabindex=0>Test</div></body>";
|
||||
let tab = await BrowserTestUtils.openNewForegroundTab(gBrowser, pageUrl);
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
onkeypress="gContainersManager.onWindowKeyPress(event);">
|
||||
|
||||
<link rel="localization" href="browser/preferences/containers.ftl"/>
|
||||
<script type="text/javascript" src="chrome://global/content/l10n.js"></script>
|
||||
<script type="application/javascript" src="chrome://global/content/l10n.js"></script>
|
||||
|
||||
<script src="chrome://global/content/treeUtils.js"/>
|
||||
<script src="chrome://browser/content/preferences/containers.js"/>
|
||||
|
|
|
@ -320,12 +320,11 @@
|
|||
onsyncfrompreference="return gMainPane.updateButtons('translateButton',
|
||||
'browser.translation.detectLanguage');"/>
|
||||
<hbox id="bingAttribution" hidden="true" align="center">
|
||||
<label>&translation.options.attribution.beforeLogo;</label>
|
||||
<separator orient="vertical" class="thin"/>
|
||||
<image id="translationAttributionImage" aria-label="Microsoft Translator"
|
||||
src="chrome://browser/content/microsoft-translator-attribution.png"/>
|
||||
<separator orient="vertical" class="thin"/>
|
||||
<label>&translation.options.attribution.afterLogo;</label>
|
||||
<label data-l10n-id="translate-attribution">
|
||||
<html:img id="translationAttributionImage" aria-label="Microsoft Translator"
|
||||
src="chrome://browser/content/microsoft-translator-attribution.png"
|
||||
data-l10n-name="logo"/>
|
||||
</label>
|
||||
</hbox>
|
||||
</hbox>
|
||||
<button id="translateButton"
|
||||
|
|
|
@ -18,35 +18,19 @@
|
|||
|
||||
<!DOCTYPE page [
|
||||
<!ENTITY % brandDTD SYSTEM "chrome://branding/locale/brand.dtd">
|
||||
<!ENTITY % passwordManagerDTD SYSTEM "chrome://passwordmgr/locale/passwordManager.dtd">
|
||||
<!ENTITY % historyDTD SYSTEM "chrome://mozapps/locale/update/history.dtd">
|
||||
<!ENTITY % certManagerDTD SYSTEM "chrome://pippki/locale/certManager.dtd">
|
||||
<!ENTITY % deviceManangerDTD SYSTEM "chrome://pippki/locale/deviceManager.dtd">
|
||||
<!ENTITY % privacyDTD SYSTEM "chrome://browser/locale/preferences/privacy.dtd">
|
||||
<!ENTITY % syncBrandDTD SYSTEM "chrome://browser/locale/syncBrand.dtd">
|
||||
<!ENTITY % syncDTD SYSTEM "chrome://browser/locale/preferences/sync.dtd">
|
||||
<!ENTITY % sanitizeDTD SYSTEM "chrome://browser/locale/sanitize.dtd">
|
||||
<!ENTITY % aboutHomeDTD SYSTEM "chrome://browser/locale/aboutHome.dtd">
|
||||
<!ENTITY % contentDTD SYSTEM "chrome://browser/locale/preferences/content.dtd">
|
||||
<!ENTITY % aboutDialogDTD SYSTEM "chrome://browser/locale/aboutDialog.dtd" >
|
||||
%aboutDialogDTD;
|
||||
%brandDTD;
|
||||
%passwordManagerDTD;
|
||||
%historyDTD;
|
||||
%certManagerDTD;
|
||||
%deviceManangerDTD;
|
||||
%privacyDTD;
|
||||
%syncBrandDTD;
|
||||
%syncDTD;
|
||||
%sanitizeDTD;
|
||||
%aboutHomeDTD;
|
||||
%contentDTD;
|
||||
]>
|
||||
|
||||
#ifdef XP_WIN
|
||||
#define USE_WIN_TITLE_STYLE
|
||||
#endif
|
||||
|
||||
<page xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
|
||||
xmlns:html="http://www.w3.org/1999/xhtml"
|
||||
disablefastfind="true"
|
||||
|
|
|
@ -66,19 +66,18 @@
|
|||
<hbox align="center">
|
||||
<label id="historyModeLabel"
|
||||
control="historyMode"
|
||||
accesskey="&historyHeader2.pre.accesskey;">&historyHeader2.pre.label;
|
||||
</label>
|
||||
data-l10n-id="history-remember-label"/>
|
||||
<!-- Please don't remove the wrapping hbox/vbox/box for these elements. It's used to properly compute the search tooltip position. -->
|
||||
<hbox>
|
||||
<menulist id="historyMode">
|
||||
<menupopup>
|
||||
<menuitem label="&historyHeader.remember.label;"
|
||||
<menuitem data-l10n-id="history-remember-option-all"
|
||||
value="remember"
|
||||
search-l10n-ids="history-remember-description"/>
|
||||
<menuitem label="&historyHeader.dontremember.label;"
|
||||
<menuitem data-l10n-id="history-remember-option-never"
|
||||
value="dontremember"
|
||||
search-l10n-ids="history-dontremember-description"/>
|
||||
<menuitem label="&historyHeader.custom.label;"
|
||||
<menuitem data-l10n-id="history-remember-option-custom"
|
||||
value="custom"
|
||||
search-l10n-ids="
|
||||
history-private-browsing-permanent.label,
|
||||
|
@ -89,7 +88,6 @@
|
|||
</menupopup>
|
||||
</menulist>
|
||||
</hbox>
|
||||
<label>&historyHeader.post.label;</label>
|
||||
</hbox>
|
||||
<hbox>
|
||||
<deck id="historyPane" flex="1">
|
||||
|
|
|
@ -282,7 +282,16 @@ SubDialog.prototype = {
|
|||
let frameSizeDifference = (frameRect.top - boxRect.top) + (boxRect.bottom - frameRect.bottom);
|
||||
|
||||
// Then determine and set a bunch of width stuff:
|
||||
let frameMinWidth = docEl.style.width || docEl.scrollWidth + "px";
|
||||
let frameMinWidth = docEl.style.width;
|
||||
if (!frameMinWidth) {
|
||||
if (docEl.ownerDocument.body) {
|
||||
// HTML documents have a body but XUL documents don't
|
||||
frameMinWidth = docEl.ownerDocument.body.scrollWidth;
|
||||
} else {
|
||||
frameMinWidth = docEl.scrollWidth;
|
||||
}
|
||||
frameMinWidth += "px";
|
||||
}
|
||||
let frameWidth = docEl.getAttribute("width") ? docEl.getAttribute("width") + "px" :
|
||||
frameMinWidth;
|
||||
this._frame.style.width = frameWidth;
|
||||
|
|
|
@ -46,16 +46,23 @@
|
|||
</hbox>
|
||||
</vbox>
|
||||
</hbox>
|
||||
<label class="fxaMobilePromo">
|
||||
&mobilePromo3.start;<!-- We put these comments to avoid inserting white spaces
|
||||
--><image class="androidLink"></image><label id="fxaMobilePromo-android"
|
||||
class="text-link"><!--
|
||||
-->&mobilePromo3.androidLink;</label><!--
|
||||
-->&mobilePromo3.iOSBefore;<!--
|
||||
--><image class="iOSLink"></image><label id="fxaMobilePromo-ios"
|
||||
class="text-link"><!--
|
||||
-->&mobilePromo3.iOSLink;</label><!--
|
||||
-->&mobilePromo3.end;
|
||||
<label class="fxaMobilePromo" data-l10n-id="sync-mobile-promo">
|
||||
<html:img
|
||||
src="chrome://browser/skin/preferences/in-content/logo-android.svg"
|
||||
data-l10n-name="android-icon"
|
||||
class="androidIcon"/>
|
||||
<html:a
|
||||
id="fxaMobilePromo-android"
|
||||
data-l10n-name="android-link"
|
||||
class="text-link" target="_blank"/>
|
||||
<html:img
|
||||
src="chrome://browser/skin/preferences/in-content/logo-ios.svg"
|
||||
data-l10n-name="ios-icon"
|
||||
class="iOSIcon"/>
|
||||
<html:a
|
||||
id="fxaMobilePromo-ios"
|
||||
data-l10n-name="ios-link"
|
||||
class="text-link" target="_blank"/>
|
||||
</label>
|
||||
</groupbox>
|
||||
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
<!ENTITY % globalDTD SYSTEM "chrome://global/locale/global.dtd">
|
||||
%globalDTD;
|
||||
]>
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" width="620">
|
||||
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||
<head>
|
||||
<title data-localization="addNewAddressTitle"/>
|
||||
<link rel="stylesheet" href="chrome://formautofill-shared/skin/editDialog.css"/>
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
<!ENTITY % globalDTD SYSTEM "chrome://global/locale/global.dtd">
|
||||
%globalDTD;
|
||||
]>
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" width="500" style="width: 500px">
|
||||
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||
<head>
|
||||
<title data-localization="addNewCreditCardTitle"/>
|
||||
<link rel="stylesheet" href="chrome://formautofill-shared/skin/editDialog.css"/>
|
||||
|
|
|
@ -2,6 +2,9 @@
|
|||
* 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/. */
|
||||
|
||||
html {
|
||||
width: 620px;
|
||||
}
|
||||
|
||||
label > span {
|
||||
flex: 0 0 9.5em;
|
||||
|
|
|
@ -2,6 +2,10 @@
|
|||
* 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/. */
|
||||
|
||||
html {
|
||||
width: 500px;
|
||||
}
|
||||
|
||||
form {
|
||||
justify-content: center;
|
||||
}
|
||||
|
|
|
@ -19,9 +19,9 @@ XPCOMUtils.defineLazyGetter(this, "wcStrings", function() {
|
|||
// Gather values for prefs we want to appear in reports.
|
||||
let prefs = {};
|
||||
XPCOMUtils.defineLazyPreferenceGetter(prefs, "gfx.webrender.all", "gfx.webrender.all", false);
|
||||
XPCOMUtils.defineLazyPreferenceGetter(prefs, "gfx.webrender.blob-images", "gfx.webrender.blob-images", 1);
|
||||
XPCOMUtils.defineLazyPreferenceGetter(prefs, "gfx.webrender.blob-images", "gfx.webrender.blob-images", true);
|
||||
XPCOMUtils.defineLazyPreferenceGetter(prefs, "gfx.webrender.enabled", "gfx.webrender.enabled", false);
|
||||
XPCOMUtils.defineLazyPreferenceGetter(prefs, "image.mem.shared", "image.mem.shared", 2);
|
||||
XPCOMUtils.defineLazyPreferenceGetter(prefs, "image.mem.shared", "image.mem.shared", true);
|
||||
|
||||
if (AppConstants.platform == "linux") {
|
||||
XPCOMUtils.defineLazyPreferenceGetter(prefs, "layers.acceleration.force-enabled", "layers.acceleration.force-enabled", false);
|
||||
|
|
|
@ -220,6 +220,10 @@ translate-web-pages =
|
|||
.label = Translate web content
|
||||
.accesskey = T
|
||||
|
||||
# The <img> element is replaced by the logo of the provider
|
||||
# used to provide machine translations for web pages.
|
||||
translate-attribution = Translations by <img data-l10n-name="logo"/>
|
||||
|
||||
translate-exceptions =
|
||||
.label = Exceptions…
|
||||
.accesskey = x
|
||||
|
@ -498,6 +502,16 @@ sync-signedout-account-signin =
|
|||
.label = Sign In…
|
||||
.accesskey = I
|
||||
|
||||
# This message contains two links and two icon images.
|
||||
# `<img data-l10n-name="android-icon"/>` - Android logo icon
|
||||
# `<a data-l10n-name="android-link">` - Link to Android Download
|
||||
# `<img data-l10n-name="ios-icon">` - iOS logo icon
|
||||
# `<a data-l10n-name="ios-link">` - Link to iOS Download
|
||||
#
|
||||
# They can be moved within the sentence as needed to adapt
|
||||
# to your language, but should not be changed or translated.
|
||||
sync-mobile-promo = Download Firefox for <img data-l10n-name="android-icon"/> <a data-l10n-name="android-link">Android</a> or <img data-l10n-name="ios-icon"/> <a data-l10n-name="ios-link">iOS</a> to sync with your mobile device.
|
||||
|
||||
## Sync Section - Signed in
|
||||
|
||||
sync-profile-picture =
|
||||
|
@ -619,6 +633,25 @@ forms-master-pw-change =
|
|||
|
||||
history-header = History
|
||||
|
||||
# This label is followed, on the same line, by a dropdown list of options
|
||||
# (Remember history, etc.).
|
||||
# In English it visually creates a full sentence, e.g.
|
||||
# "Firefox will" + "Remember history".
|
||||
#
|
||||
# If this doesn't work for your language, you can translate this message:
|
||||
# - Simply as "Firefox", moving the verb into each option.
|
||||
# This will result in "Firefox" + "Will remember history", etc.
|
||||
# - As a stand-alone message, for example "Firefox history settings:".
|
||||
history-remember-label = { -brand-short-name } will
|
||||
.accesskey = w
|
||||
|
||||
history-remember-option-all =
|
||||
.label = Remember history
|
||||
history-remember-option-never =
|
||||
.label = Never remember history
|
||||
history-remember-option-custom =
|
||||
.label = Use custom settings for history
|
||||
|
||||
history-remember-description = { -brand-short-name } will remember your browsing, download, form and search history.
|
||||
history-dontremember-description = { -brand-short-name } will use the same settings as private browsing, and will not remember any history as you browse the Web.
|
||||
|
||||
|
|
|
@ -1,13 +0,0 @@
|
|||
<!-- This Source Code Form is subject to the terms of the Mozilla Public
|
||||
- License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
- file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
|
||||
|
||||
<!-- LOCALIZATION NOTE (translation.options.attribution.beforeLogo,
|
||||
- translation.options.attribution.afterLogo):
|
||||
- These 2 strings are displayed before and after a 'Microsoft Translator'
|
||||
- logo.
|
||||
- The translations for these strings should match the translations in
|
||||
- browser/translation.dtd
|
||||
-->
|
||||
<!ENTITY translation.options.attribution.beforeLogo "Translations by">
|
||||
<!ENTITY translation.options.attribution.afterLogo "">
|
|
@ -1,10 +0,0 @@
|
|||
<!-- This Source Code Form is subject to the terms of the Mozilla Public
|
||||
- License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
- file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
|
||||
|
||||
<!ENTITY historyHeader2.pre.label "&brandShortName; will">
|
||||
<!ENTITY historyHeader2.pre.accesskey "w">
|
||||
<!ENTITY historyHeader.remember.label "Remember history">
|
||||
<!ENTITY historyHeader.dontremember.label "Never remember history">
|
||||
<!ENTITY historyHeader.custom.label "Use custom settings for history">
|
||||
<!ENTITY historyHeader.post.label "">
|
|
@ -1,19 +0,0 @@
|
|||
<!-- This Source Code Form is subject to the terms of the Mozilla Public
|
||||
- License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
- file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
|
||||
|
||||
<!-- LOCALIZATION NOTE (mobilePromo3.*): the following strings will be used to
|
||||
create a single sentence with active links.
|
||||
The resulting sentence in English is: "Download Firefox for
|
||||
Android or iOS to sync with your mobile device." -->
|
||||
|
||||
<!ENTITY mobilePromo3.start "Download Firefox for ">
|
||||
<!-- LOCALIZATION NOTE (mobilePromo3.androidLink): This is a link title that links to https://www.mozilla.org/firefox/android/ -->
|
||||
<!ENTITY mobilePromo3.androidLink "Android">
|
||||
|
||||
<!-- LOCALIZATION NOTE (mobilePromo3.iOSBefore): This is text displayed between mobilePromo3.androidLink and mobilePromo3.iosLink -->
|
||||
<!ENTITY mobilePromo3.iOSBefore " or ">
|
||||
<!-- LOCALIZATION NOTE (mobilePromo3.iOSLink): This is a link title that links to https://www.mozilla.org/firefox/ios/ -->
|
||||
<!ENTITY mobilePromo3.iOSLink "iOS">
|
||||
|
||||
<!ENTITY mobilePromo3.end " to sync with your mobile device.">
|
|
@ -56,11 +56,8 @@
|
|||
locale/browser/migration/migration.dtd (%chrome/browser/migration/migration.dtd)
|
||||
locale/browser/migration/migration.properties (%chrome/browser/migration/migration.properties)
|
||||
locale/browser/preferences/clearSiteData.properties (%chrome/browser/preferences/clearSiteData.properties)
|
||||
locale/browser/preferences/content.dtd (%chrome/browser/preferences/content.dtd)
|
||||
locale/browser/preferences/preferences.properties (%chrome/browser/preferences/preferences.properties)
|
||||
locale/browser/preferences/privacy.dtd (%chrome/browser/preferences/privacy.dtd)
|
||||
locale/browser/preferences/security.dtd (%chrome/browser/preferences/security.dtd)
|
||||
locale/browser/preferences/sync.dtd (%chrome/browser/preferences/sync.dtd)
|
||||
locale/browser/syncBrand.dtd (%chrome/browser/syncBrand.dtd)
|
||||
locale/browser/syncSetup.properties (%chrome/browser/syncSetup.properties)
|
||||
#if BUILD_FASTER
|
||||
|
|
|
@ -22,16 +22,21 @@ var ReaderParent = {
|
|||
switch (message.name) {
|
||||
case "Reader:FaviconRequest": {
|
||||
if (message.target.messageManager) {
|
||||
let faviconUrl = PlacesUtils.promiseFaviconLinkUrl(message.data.url);
|
||||
faviconUrl.then(function onResolution(favicon) {
|
||||
message.target.messageManager.sendAsyncMessage("Reader:FaviconReturn", {
|
||||
url: message.data.url,
|
||||
faviconUrl: favicon.pathQueryRef.replace(/^favicon:/, "")
|
||||
});
|
||||
},
|
||||
function onRejection(reason) {
|
||||
Cu.reportError("Error requesting favicon URL for about:reader content: " + reason);
|
||||
}).catch(Cu.reportError);
|
||||
try {
|
||||
let preferredWidth = message.data.preferredWidth || 0;
|
||||
let uri = Services.io.newURI(message.data.url);
|
||||
PlacesUtils.favicons.getFaviconURLForPage(uri, iconUri => {
|
||||
if (iconUri) {
|
||||
iconUri = PlacesUtils.favicons.getFaviconLinkForIcon(iconUri);
|
||||
message.target.messageManager.sendAsyncMessage("Reader:FaviconReturn", {
|
||||
url: message.data.url,
|
||||
faviconUrl: iconUri.pathQueryRef.replace(/^favicon:/, "")
|
||||
});
|
||||
}
|
||||
}, preferredWidth);
|
||||
} catch (ex) {
|
||||
Cu.reportError("Error requesting favicon URL for about:reader content: " + ex);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -627,16 +627,8 @@ button > hbox > label {
|
|||
margin-top: 2px !important;
|
||||
}
|
||||
|
||||
.androidLink {
|
||||
list-style-image: url("chrome://browser/skin/preferences/in-content/logo-android.svg");
|
||||
}
|
||||
|
||||
.iOSLink {
|
||||
list-style-image: url("chrome://browser/skin/preferences/in-content/logo-ios.svg");
|
||||
}
|
||||
|
||||
.androidLink,
|
||||
.iOSLink {
|
||||
.androidIcon,
|
||||
.iOSIcon {
|
||||
margin-inline-start: 2px;
|
||||
margin-inline-end: 4px;
|
||||
width: 20px;
|
||||
|
|
|
@ -76,7 +76,7 @@ AUTOMATION_EXTRA_CMDLINE-l10n-check = -j1
|
|||
# However, the target automation/buildsymbols will still be executed in this
|
||||
# case because it is a prerequisite of automation/upload.
|
||||
define automation_commands
|
||||
@+$(MAKE) $1 $(AUTOMATION_EXTRA_CMDLINE-$1)
|
||||
@+$(PYTHON) $(topsrcdir)/config/run-and-prefix.py $1 $(MAKE) $1 $(AUTOMATION_EXTRA_CMDLINE-$1)
|
||||
$(call BUILDSTATUS,TIER_FINISH $1)
|
||||
endef
|
||||
|
||||
|
|
|
@ -0,0 +1,35 @@
|
|||
#!/usr/bin/env python
|
||||
# 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/.
|
||||
|
||||
# This script runs a process and prefixes its output with.
|
||||
# Usage: run-and-prefix.py prefix command arg0 argv1...
|
||||
|
||||
from __future__ import absolute_import, print_function
|
||||
|
||||
import os
|
||||
import subprocess
|
||||
import sys
|
||||
|
||||
sys.stdout = os.fdopen(sys.stdout.fileno(), 'w', 0)
|
||||
sys.stderr = os.fdopen(sys.stderr.fileno(), 'w', 0)
|
||||
|
||||
prefix = sys.argv[1]
|
||||
args = sys.argv[2:]
|
||||
|
||||
p = subprocess.Popen(args, bufsize=0,
|
||||
stdout=subprocess.PIPE,
|
||||
stderr=subprocess.STDOUT,
|
||||
stdin=sys.stdin.fileno(),
|
||||
universal_newlines=True)
|
||||
|
||||
while True:
|
||||
data = p.stdout.readline()
|
||||
|
||||
if data == b'':
|
||||
break
|
||||
|
||||
print('%s> %s' % (prefix, data), end=b'')
|
||||
|
||||
sys.exit(p.wait())
|
|
@ -48,13 +48,13 @@ const testCases = [
|
|||
]
|
||||
],
|
||||
[["localStorage", "http://test1.example.org"],
|
||||
["ls1", "ls2"]],
|
||||
["key", "ls1", "ls2"]],
|
||||
[["localStorage", "http://sectest1.example.org"],
|
||||
["iframe-u-ls1"]],
|
||||
[["localStorage", "https://sectest1.example.org"],
|
||||
["iframe-s-ls1"]],
|
||||
[["sessionStorage", "http://test1.example.org"],
|
||||
["ss1"]],
|
||||
["key", "ss1"]],
|
||||
[["sessionStorage", "http://sectest1.example.org"],
|
||||
["iframe-u-ss1", "iframe-u-ss2"]],
|
||||
[["sessionStorage", "https://sectest1.example.org"],
|
||||
|
|
|
@ -33,13 +33,13 @@ const testCases = [
|
|||
]
|
||||
],
|
||||
[["localStorage", "http://test1.example.org"],
|
||||
["ls1", "ls2"]],
|
||||
["key", "ls1", "ls2"]],
|
||||
[["localStorage", "http://sectest1.example.org"],
|
||||
["iframe-u-ls1"]],
|
||||
[["localStorage", "https://sectest1.example.org"],
|
||||
["iframe-s-ls1"]],
|
||||
[["sessionStorage", "http://test1.example.org"],
|
||||
["ss1"]],
|
||||
["key", "ss1"]],
|
||||
[["sessionStorage", "http://sectest1.example.org"],
|
||||
["iframe-u-ss1", "iframe-u-ss2"]],
|
||||
[["sessionStorage", "https://sectest1.example.org"],
|
||||
|
|
|
@ -18,13 +18,13 @@ add_task(async function() {
|
|||
info("test state before delete");
|
||||
const beforeState = [
|
||||
[["localStorage", "http://test1.example.org"],
|
||||
["ls1", "ls2"]],
|
||||
["key", "ls1", "ls2"]],
|
||||
[["localStorage", "http://sectest1.example.org"],
|
||||
["iframe-u-ls1"]],
|
||||
[["localStorage", "https://sectest1.example.org"],
|
||||
["iframe-s-ls1"]],
|
||||
[["sessionStorage", "http://test1.example.org"],
|
||||
["ss1"]],
|
||||
["key", "ss1"]],
|
||||
[["sessionStorage", "http://sectest1.example.org"],
|
||||
["iframe-u-ss1", "iframe-u-ss2"]],
|
||||
[["sessionStorage", "https://sectest1.example.org"],
|
||||
|
@ -67,13 +67,13 @@ add_task(async function() {
|
|||
// iframes from the same host, one secure, one unsecure, are independent
|
||||
// from each other. Delete all in one doesn't touch the other one.
|
||||
[["localStorage", "http://test1.example.org"],
|
||||
["ls1", "ls2"]],
|
||||
["key", "ls1", "ls2"]],
|
||||
[["localStorage", "http://sectest1.example.org"],
|
||||
["iframe-u-ls1"]],
|
||||
[["localStorage", "https://sectest1.example.org"],
|
||||
[]],
|
||||
[["sessionStorage", "http://test1.example.org"],
|
||||
["ss1"]],
|
||||
["key", "ss1"]],
|
||||
[["sessionStorage", "http://sectest1.example.org"],
|
||||
["iframe-u-ss1", "iframe-u-ss2"]],
|
||||
[["sessionStorage", "https://sectest1.example.org"],
|
||||
|
|
|
@ -28,8 +28,8 @@ add_task(async function() {
|
|||
getCookieId("uc2", ".example.org", "/")
|
||||
]
|
||||
],
|
||||
[["localStorage", "http://test1.example.org"], ["ls1", "ls2"]],
|
||||
[["sessionStorage", "http://test1.example.org"], ["ss1"]],
|
||||
[["localStorage", "http://test1.example.org"], ["key", "ls1", "ls2"]],
|
||||
[["sessionStorage", "http://test1.example.org"], ["key", "ss1"]],
|
||||
[["indexedDB", "http://test1.example.org", "idb1 (default)", "obj1"], [1, 2, 3]],
|
||||
[["Cache", "http://test1.example.org", "plop"],
|
||||
[MAIN_DOMAIN + "404_cached_file.js", MAIN_DOMAIN + "browser_storage_basic.js"]],
|
||||
|
|
|
@ -51,13 +51,13 @@ const storageItemsForDefault = [
|
|||
]
|
||||
],
|
||||
[["localStorage", "http://test1.example.org"],
|
||||
["ls1", "ls2"]],
|
||||
["key", "ls1", "ls2"]],
|
||||
[["localStorage", "http://sectest1.example.org"],
|
||||
["iframe-u-ls1"]],
|
||||
[["localStorage", "https://sectest1.example.org"],
|
||||
["iframe-s-ls1"]],
|
||||
[["sessionStorage", "http://test1.example.org"],
|
||||
["ss1"]],
|
||||
["key", "ss1"]],
|
||||
[["sessionStorage", "http://sectest1.example.org"],
|
||||
["iframe-u-ss1", "iframe-u-ss2"]],
|
||||
[["sessionStorage", "https://sectest1.example.org"],
|
||||
|
|
|
@ -16,13 +16,13 @@ add_task(async function() {
|
|||
|
||||
const state = [
|
||||
[["localStorage", "http://test1.example.org"],
|
||||
["ls1", "ls2"]],
|
||||
["key", "ls1", "ls2"]],
|
||||
[["localStorage", "http://sectest1.example.org"],
|
||||
["iframe-u-ls1"]],
|
||||
[["localStorage", "https://sectest1.example.org"],
|
||||
["iframe-s-ls1"]],
|
||||
[["sessionStorage", "http://test1.example.org"],
|
||||
["ss1"]],
|
||||
["key", "ss1"]],
|
||||
[["sessionStorage", "http://sectest1.example.org"],
|
||||
["iframe-u-ss1", "iframe-u-ss2"]],
|
||||
[["sessionStorage", "https://sectest1.example.org"],
|
||||
|
|
|
@ -27,8 +27,20 @@ document.cookie = "c4=foobar-3; expires=" +
|
|||
// ... and some local storage items ..
|
||||
localStorage.setItem("ls1", "foobar");
|
||||
localStorage.setItem("ls2", "foobar-2");
|
||||
|
||||
// Because localStorage contains key() on the prototype and it can't be iterated
|
||||
// using object.keys() we check the the value "key" exists.
|
||||
// See bug 1451991 for details.
|
||||
localStorage.setItem("key", "value1");
|
||||
|
||||
// ... and finally some session storage items too
|
||||
sessionStorage.setItem("ss1", "foobar-3");
|
||||
|
||||
// Because sessionStorage contains key() on the prototype and it can't be
|
||||
// iterated using object.keys() we check the the value "key" exists.
|
||||
// See bug 1451991 for details.
|
||||
sessionStorage.setItem("key", "value2");
|
||||
|
||||
dump("added cookies and storage from main page\n");
|
||||
|
||||
let idbGenerator = async function () {
|
||||
|
|
|
@ -258,6 +258,15 @@ checkbox:-moz-focusring {
|
|||
outline: none;
|
||||
}
|
||||
|
||||
/* Tab and button of toolbox does not need to display outline */
|
||||
|
||||
.devtools-button:-moz-focusring,
|
||||
.devtools-tab:-moz-focusring {
|
||||
outline:none;
|
||||
padding-inline-end: 0;
|
||||
padding-inline-start: 0;
|
||||
}
|
||||
|
||||
/* Toolbar buttons */
|
||||
.devtools-menulist,
|
||||
.devtools-toolbarbutton,
|
||||
|
@ -277,6 +286,11 @@ checkbox:-moz-focusring {
|
|||
white-space: nowrap;
|
||||
}
|
||||
|
||||
/* Remove system form border from devtools-button. */
|
||||
.devtools-button::-moz-focus-inner {
|
||||
border: 0;
|
||||
}
|
||||
|
||||
.devtools-toolbarbutton:not([label]) > .toolbarbutton-icon,
|
||||
.devtools-button:empty::before {
|
||||
width: 16px;
|
||||
|
@ -352,6 +366,10 @@ checkbox:-moz-focusring {
|
|||
background: var(--toolbarbutton-background);
|
||||
}
|
||||
|
||||
.devtools-button:focus {
|
||||
background-color: var(--theme-toolbar-hover);
|
||||
}
|
||||
|
||||
.devtools-button:not(:empty):not(:disabled):not(.checked):hover,
|
||||
.devtools-toolbarbutton[label]:not(:-moz-any([checked=true],[disabled])):hover,
|
||||
.devtools-button:empty:not(:disabled):-moz-any(:hover:active,.checked),
|
||||
|
@ -743,6 +761,12 @@ checkbox:-moz-focusring {
|
|||
transform: scaleX(1);
|
||||
}
|
||||
|
||||
.devtools-tab:not(.selected):focus .devtools-tab-line {
|
||||
background: var(--tab-line-hover-color);
|
||||
opacity: 1;
|
||||
transform: scaleX(1);
|
||||
}
|
||||
|
||||
/* No result message styles */
|
||||
|
||||
.devtools-sidepanel-no-result {
|
||||
|
|
|
@ -99,10 +99,16 @@
|
|||
color: var(--theme-toolbar-color);
|
||||
}
|
||||
|
||||
.devtools-tab:hover {
|
||||
.devtools-tab:hover,
|
||||
.devtools-tab:focus {
|
||||
background-color: var(--theme-toolbar-hover);
|
||||
}
|
||||
|
||||
/* Remove system control border from devtools-tab. */
|
||||
.devtools-tab::-moz-focus-inner {
|
||||
border: 0;
|
||||
}
|
||||
|
||||
.devtools-tab:hover:active {
|
||||
background-color: var(--theme-toolbar-hover-active);
|
||||
}
|
||||
|
|
|
@ -1168,10 +1168,20 @@ function getObjectForLocalOrSessionStorage(type) {
|
|||
if (!storage) {
|
||||
return [];
|
||||
}
|
||||
return Object.keys(storage).map(key => ({
|
||||
name: key,
|
||||
value: storage.getItem(key)
|
||||
}));
|
||||
|
||||
// local and session storage cannot be iterated over using Object.keys()
|
||||
// because it skips keys that are duplicated on the prototype
|
||||
// e.g. "key", "getKeys" so we need to gather the real keys using the
|
||||
// storage.key() function.
|
||||
const storageArray = [];
|
||||
for (let i = 0; i < storage.length; i++) {
|
||||
const key = storage.key(i);
|
||||
storageArray.push({
|
||||
name: key,
|
||||
value: storage.getItem(key)
|
||||
});
|
||||
}
|
||||
return storageArray;
|
||||
},
|
||||
|
||||
populateStoresForHost(host, window) {
|
||||
|
|
|
@ -117,6 +117,13 @@ types.getType = function(type) {
|
|||
throw Error("Unknown type: " + type);
|
||||
};
|
||||
|
||||
/**
|
||||
* Helper function to identify iterators. This will return false for Arrays.
|
||||
*/
|
||||
function isIterator(v) {
|
||||
return v && typeof v === "object" && Symbol.iterator in v && !Array.isArray(v);
|
||||
}
|
||||
|
||||
/**
|
||||
* Don't allow undefined when writing primitive types to packets. If
|
||||
* you want to allow undefined, use a nullable type.
|
||||
|
@ -127,7 +134,7 @@ function identityWrite(v) {
|
|||
}
|
||||
// This has to handle iterator->array conversion because arrays of
|
||||
// primitive types pass through here.
|
||||
if (v && typeof (v) === "object" && Symbol.iterator in v) {
|
||||
if (isIterator(v)) {
|
||||
return [...v];
|
||||
}
|
||||
return v;
|
||||
|
@ -215,8 +222,18 @@ types.addArrayType = function(subtype) {
|
|||
}
|
||||
return types.addType(name, {
|
||||
category: "array",
|
||||
read: (v, ctx) => [...v].map(i => subtype.read(i, ctx)),
|
||||
write: (v, ctx) => [...v].map(i => subtype.write(i, ctx))
|
||||
read: (v, ctx) => {
|
||||
if (isIterator(v)) {
|
||||
v = [...v];
|
||||
}
|
||||
return v.map(i => subtype.read(i, ctx));
|
||||
},
|
||||
write: (v, ctx) => {
|
||||
if (isIterator(v)) {
|
||||
v = [...v];
|
||||
}
|
||||
return v.map(i => subtype.write(i, ctx));
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
|
@ -932,9 +949,8 @@ var Actor = function(conn) {
|
|||
if (this._actorSpec && this._actorSpec.events) {
|
||||
for (let key of this._actorSpec.events.keys()) {
|
||||
let name = key;
|
||||
let sendEvent = this._sendEvent.bind(this, name);
|
||||
this.on(name, (...args) => {
|
||||
sendEvent.apply(null, args);
|
||||
this._sendEvent(name, ...args);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -1159,7 +1175,7 @@ var generateRequestHandlers = function(actorSpec, actorProto) {
|
|||
return p
|
||||
.then(() => ret)
|
||||
.then(sendReturn)
|
||||
.catch(this.writeError.bind(this));
|
||||
.catch(e => this.writeError(e));
|
||||
});
|
||||
} catch (e) {
|
||||
this._queueResponse(p => {
|
||||
|
|
|
@ -284,11 +284,7 @@ TimeStamp EventStateManager::sHandlingInputStart;
|
|||
EventStateManager::WheelPrefs*
|
||||
EventStateManager::WheelPrefs::sInstance = nullptr;
|
||||
bool EventStateManager::WheelPrefs::sWheelEventsEnabledOnPlugins = true;
|
||||
#ifdef EARLY_BETA_OR_EARLIER
|
||||
bool EventStateManager::WheelPrefs::sIsAutoDirEnabled = true;
|
||||
#else
|
||||
bool EventStateManager::WheelPrefs::sIsAutoDirEnabled = false;
|
||||
#endif
|
||||
bool EventStateManager::WheelPrefs::sHonoursRootForAutoDir = false;
|
||||
EventStateManager::DeltaAccumulator*
|
||||
EventStateManager::DeltaAccumulator::sInstance = nullptr;
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
#include "mozilla/dom/Nullable.h" // for dom::Nullable
|
||||
#include "mozilla/layers/CompositorThread.h" // for CompositorThreadHolder
|
||||
#include "mozilla/layers/LayerAnimationUtils.h" // for TimingFunctionToComputedTimingFunction
|
||||
#include "mozilla/ServoBindings.h" // for Servo_ComposeAnimationSegment, etc
|
||||
#include "mozilla/StyleAnimationValue.h" // for StyleAnimationValue, etc
|
||||
#include "nsDeviceContext.h" // for AppUnitsPerCSSPixel
|
||||
#include "nsDisplayList.h" // for nsDisplayTransform, etc
|
||||
|
@ -139,7 +140,7 @@ AnimationHelper::SampleAnimationForEachNode(
|
|||
TimeStamp aTime,
|
||||
AnimationArray& aAnimations,
|
||||
InfallibleTArray<AnimData>& aAnimationData,
|
||||
AnimationValue& aAnimationValue,
|
||||
RefPtr<RawServoAnimationValue>& aAnimationValue,
|
||||
bool& aHasInEffectAnimations)
|
||||
{
|
||||
MOZ_ASSERT(!aAnimations.IsEmpty(), "Should be called with animations");
|
||||
|
@ -206,8 +207,10 @@ AnimationHelper::SampleAnimationForEachNode(
|
|||
AnimationPropertySegment animSegment;
|
||||
animSegment.mFromKey = 0.0;
|
||||
animSegment.mToKey = 1.0;
|
||||
animSegment.mFromValue = animData.mStartValues[segmentIndex];
|
||||
animSegment.mToValue = animData.mEndValues[segmentIndex];
|
||||
animSegment.mFromValue =
|
||||
AnimationValue(animData.mStartValues[segmentIndex]);
|
||||
animSegment.mToValue =
|
||||
AnimationValue(animData.mEndValues[segmentIndex]);
|
||||
animSegment.mFromComposite =
|
||||
static_cast<dom::CompositeOperation>(segment->startComposite());
|
||||
animSegment.mToComposite =
|
||||
|
@ -218,11 +221,11 @@ AnimationHelper::SampleAnimationForEachNode(
|
|||
static_cast<dom::IterationCompositeOperation>(
|
||||
animation.iterationComposite());
|
||||
|
||||
aAnimationValue.mServo =
|
||||
aAnimationValue =
|
||||
Servo_ComposeAnimationSegment(
|
||||
&animSegment,
|
||||
aAnimationValue.mServo,
|
||||
animData.mEndValues.LastElement().mServo,
|
||||
aAnimationValue,
|
||||
animData.mEndValues.LastElement(),
|
||||
iterCompositeOperation,
|
||||
portion,
|
||||
computedTiming.mCurrentIteration).Consume();
|
||||
|
@ -407,10 +410,10 @@ CreateCSSValueList(const InfallibleTArray<TransformFunction>& aFunctions)
|
|||
return new nsCSSValueSharedList(result.forget());
|
||||
}
|
||||
|
||||
static AnimationValue
|
||||
static already_AddRefed<RawServoAnimationValue>
|
||||
ToAnimationValue(const Animatable& aAnimatable)
|
||||
{
|
||||
AnimationValue result;
|
||||
RefPtr<RawServoAnimationValue> result;
|
||||
|
||||
switch (aAnimatable.type()) {
|
||||
case Animatable::Tnull_t:
|
||||
|
@ -422,23 +425,24 @@ ToAnimationValue(const Animatable& aAnimatable)
|
|||
if (listOrError.isOk()) {
|
||||
RefPtr<nsCSSValueSharedList> list = listOrError.unwrap();
|
||||
MOZ_ASSERT(list, "Transform list should be non null");
|
||||
result = AnimationValue::Transform(*list);
|
||||
result = Servo_AnimationValue_Transform(*list).Consume();
|
||||
}
|
||||
break;
|
||||
}
|
||||
case Animatable::Tfloat:
|
||||
result = AnimationValue::Opacity(aAnimatable.get_float());
|
||||
result = Servo_AnimationValue_Opacity(aAnimatable.get_float()).Consume();
|
||||
break;
|
||||
default:
|
||||
MOZ_ASSERT_UNREACHABLE("Unsupported type");
|
||||
}
|
||||
return result;
|
||||
return result.forget();
|
||||
}
|
||||
|
||||
void
|
||||
AnimationHelper::SetAnimations(AnimationArray& aAnimations,
|
||||
InfallibleTArray<AnimData>& aAnimData,
|
||||
AnimationValue& aBaseAnimationStyle)
|
||||
AnimationHelper::SetAnimations(
|
||||
AnimationArray& aAnimations,
|
||||
InfallibleTArray<AnimData>& aAnimData,
|
||||
RefPtr<RawServoAnimationValue>& aBaseAnimationStyle)
|
||||
{
|
||||
for (uint32_t i = 0; i < aAnimations.Length(); i++) {
|
||||
Animation& animation = aAnimations[i];
|
||||
|
@ -463,8 +467,10 @@ AnimationHelper::SetAnimations(AnimationArray& aAnimations,
|
|||
AnimData* data = aAnimData.AppendElement();
|
||||
InfallibleTArray<Maybe<ComputedTimingFunction>>& functions =
|
||||
data->mFunctions;
|
||||
InfallibleTArray<AnimationValue>& startValues = data->mStartValues;
|
||||
InfallibleTArray<AnimationValue>& endValues = data->mEndValues;
|
||||
InfallibleTArray<RefPtr<RawServoAnimationValue>>& startValues =
|
||||
data->mStartValues;
|
||||
InfallibleTArray<RefPtr<RawServoAnimationValue>>& endValues =
|
||||
data->mEndValues;
|
||||
|
||||
const InfallibleTArray<AnimationSegment>& segments = animation.segments();
|
||||
for (const AnimationSegment& segment : segments) {
|
||||
|
@ -511,7 +517,7 @@ AnimationHelper::SampleAnimations(CompositorAnimationStorage* aStorage,
|
|||
continue;
|
||||
}
|
||||
|
||||
AnimationValue animationValue;
|
||||
RefPtr<RawServoAnimationValue> animationValue;
|
||||
InfallibleTArray<AnimData> animationData;
|
||||
AnimationHelper::SetAnimations(*animations,
|
||||
animationData,
|
||||
|
@ -530,12 +536,14 @@ AnimationHelper::SampleAnimations(CompositorAnimationStorage* aStorage,
|
|||
Animation& animation = animations->LastElement();
|
||||
switch (animation.property()) {
|
||||
case eCSSProperty_opacity: {
|
||||
aStorage->SetAnimatedValue(iter.Key(), animationValue.GetOpacity());
|
||||
aStorage->SetAnimatedValue(
|
||||
iter.Key(),
|
||||
Servo_AnimationValue_GetOpacity(animationValue));
|
||||
break;
|
||||
}
|
||||
case eCSSProperty_transform: {
|
||||
RefPtr<const nsCSSValueSharedList> list =
|
||||
animationValue.GetTransformList();
|
||||
RefPtr<nsCSSValueSharedList> list;
|
||||
Servo_AnimationValue_GetTransform(animationValue, &list);
|
||||
const TransformData& transformData = animation.data().get_TransformData();
|
||||
nsPoint origin = transformData.origin();
|
||||
// we expect all our transform data to arrive in device pixels
|
||||
|
|
|
@ -20,8 +20,8 @@ class Animation;
|
|||
typedef InfallibleTArray<layers::Animation> AnimationArray;
|
||||
|
||||
struct AnimData {
|
||||
InfallibleTArray<mozilla::AnimationValue> mStartValues;
|
||||
InfallibleTArray<mozilla::AnimationValue> mEndValues;
|
||||
InfallibleTArray<RefPtr<RawServoAnimationValue>> mStartValues;
|
||||
InfallibleTArray<RefPtr<RawServoAnimationValue>> mEndValues;
|
||||
InfallibleTArray<Maybe<mozilla::ComputedTimingFunction>> mFunctions;
|
||||
};
|
||||
|
||||
|
@ -201,7 +201,7 @@ public:
|
|||
SampleAnimationForEachNode(TimeStamp aTime,
|
||||
AnimationArray& aAnimations,
|
||||
InfallibleTArray<AnimData>& aAnimationData,
|
||||
AnimationValue& aAnimationValue,
|
||||
RefPtr<RawServoAnimationValue>& aAnimationValue,
|
||||
bool& aHasInEffectAnimations);
|
||||
/**
|
||||
* Populates AnimData stuctures into |aAnimData| and |aBaseAnimationStyle|
|
||||
|
@ -210,7 +210,7 @@ public:
|
|||
static void
|
||||
SetAnimations(AnimationArray& aAnimations,
|
||||
InfallibleTArray<AnimData>& aAnimData,
|
||||
AnimationValue& aBaseAnimationStyle);
|
||||
RefPtr<RawServoAnimationValue>& aBaseAnimationStyle);
|
||||
|
||||
/**
|
||||
* Get a unique id to represent the compositor animation between child
|
||||
|
|
|
@ -7,9 +7,12 @@
|
|||
#ifndef GFX_ANIMATIONINFO_H
|
||||
#define GFX_ANIMATIONINFO_H
|
||||
|
||||
#include "mozilla/StyleAnimationValue.h"
|
||||
#include "nsAutoPtr.h"
|
||||
#include "nsDisplayItemTypes.h"
|
||||
|
||||
struct RawServoAnimationValue;
|
||||
class nsIFrame;
|
||||
|
||||
namespace mozilla {
|
||||
namespace layers {
|
||||
|
||||
|
@ -52,7 +55,10 @@ public:
|
|||
void TransferMutatedFlagToLayer(Layer* aLayer);
|
||||
|
||||
uint64_t GetCompositorAnimationsId() { return mCompositorAnimationsId; }
|
||||
AnimationValue GetBaseAnimationStyle() const { return mBaseAnimationStyle; }
|
||||
RawServoAnimationValue* GetBaseAnimationStyle() const
|
||||
{
|
||||
return mBaseAnimationStyle;
|
||||
}
|
||||
InfallibleTArray<AnimData>& GetAnimationData() { return mAnimationData; }
|
||||
AnimationArray& GetAnimations() { return mAnimations; }
|
||||
bool ApplyPendingUpdatesForThisTransaction();
|
||||
|
@ -71,7 +77,7 @@ protected:
|
|||
// If this layer is used for OMTA, then this counter is used to ensure we
|
||||
// stay in sync with the animation manager
|
||||
uint64_t mAnimationGeneration;
|
||||
AnimationValue mBaseAnimationStyle;
|
||||
RefPtr<RawServoAnimationValue> mBaseAnimationStyle;
|
||||
bool mMutated;
|
||||
};
|
||||
|
||||
|
|
|
@ -25,7 +25,6 @@
|
|||
#include "mozilla/Maybe.h" // for Maybe
|
||||
#include "mozilla/Poison.h"
|
||||
#include "mozilla/RefPtr.h" // for already_AddRefed
|
||||
#include "mozilla/StyleAnimationValue.h" // for StyleAnimationValue, etc
|
||||
#include "mozilla/TimeStamp.h" // for TimeStamp, TimeDuration
|
||||
#include "mozilla/UniquePtr.h" // for UniquePtr
|
||||
#include "mozilla/gfx/BaseMargin.h" // for BaseMargin
|
||||
|
@ -65,7 +64,6 @@ namespace mozilla {
|
|||
|
||||
class ComputedTimingFunction;
|
||||
class FrameLayerBuilder;
|
||||
class StyleAnimationValue;
|
||||
|
||||
namespace gl {
|
||||
class GLContext;
|
||||
|
@ -1387,7 +1385,7 @@ public:
|
|||
bool HasTransformAnimation() const;
|
||||
bool HasOpacityAnimation() const;
|
||||
|
||||
AnimationValue GetBaseAnimationStyle() const
|
||||
RawServoAnimationValue* GetBaseAnimationStyle() const
|
||||
{
|
||||
return mAnimationInfo.GetBaseAnimationStyle();
|
||||
}
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
#include "Layers.h" // for Layer, ContainerLayer, etc
|
||||
#include "gfxPoint.h" // for gfxPoint, gfxSize
|
||||
#include "gfxPrefs.h" // for gfxPrefs
|
||||
#include "mozilla/StyleAnimationValue.h" // for StyleAnimationValue, etc
|
||||
#include "mozilla/ServoBindings.h" // for Servo_AnimationValue_GetOpacity, etc
|
||||
#include "mozilla/WidgetUtils.h" // for ComputeTransformForRotation
|
||||
#include "mozilla/gfx/BaseRect.h" // for BaseRect
|
||||
#include "mozilla/gfx/Point.h" // for RoundedToInt, PointTyped
|
||||
|
@ -580,9 +580,9 @@ ApplyAnimatedValue(Layer* aLayer,
|
|||
CompositorAnimationStorage* aStorage,
|
||||
nsCSSPropertyID aProperty,
|
||||
const AnimationData& aAnimationData,
|
||||
const AnimationValue& aValue)
|
||||
const RefPtr<RawServoAnimationValue>& aValue)
|
||||
{
|
||||
if (aValue.IsNull()) {
|
||||
if (!aValue) {
|
||||
// Return gracefully if we have no valid AnimationValue.
|
||||
return;
|
||||
}
|
||||
|
@ -590,15 +590,16 @@ ApplyAnimatedValue(Layer* aLayer,
|
|||
HostLayer* layerCompositor = aLayer->AsHostLayer();
|
||||
switch (aProperty) {
|
||||
case eCSSProperty_opacity: {
|
||||
layerCompositor->SetShadowOpacity(aValue.GetOpacity());
|
||||
float opacity = Servo_AnimationValue_GetOpacity(aValue);
|
||||
layerCompositor->SetShadowOpacity(opacity);
|
||||
layerCompositor->SetShadowOpacitySetByAnimation(true);
|
||||
aStorage->SetAnimatedValue(aLayer->GetCompositorAnimationsId(),
|
||||
aValue.GetOpacity());
|
||||
aStorage->SetAnimatedValue(aLayer->GetCompositorAnimationsId(), opacity);
|
||||
|
||||
break;
|
||||
}
|
||||
case eCSSProperty_transform: {
|
||||
RefPtr<const nsCSSValueSharedList> list = aValue.GetTransformList();
|
||||
RefPtr<nsCSSValueSharedList> list;
|
||||
Servo_AnimationValue_GetTransform(aValue, &list);
|
||||
const TransformData& transformData = aAnimationData.get_TransformData();
|
||||
nsPoint origin = transformData.origin();
|
||||
// we expect all our transform data to arrive in device pixels
|
||||
|
@ -655,7 +656,8 @@ SampleAnimations(Layer* aLayer,
|
|||
}
|
||||
isAnimating = true;
|
||||
bool hasInEffectAnimations = false;
|
||||
AnimationValue animationValue = layer->GetBaseAnimationStyle();
|
||||
RefPtr<RawServoAnimationValue> animationValue =
|
||||
layer->GetBaseAnimationStyle();
|
||||
AnimationHelper::SampleAnimationForEachNode(aTime,
|
||||
animations,
|
||||
layer->GetAnimationData(),
|
||||
|
|
|
@ -796,6 +796,13 @@ WebRenderBridgeParent::RecvGetSnapshot(PTextureParent* aTexture)
|
|||
}
|
||||
MOZ_ASSERT(!mPaused);
|
||||
|
||||
// This function should only get called in the root WRBP. If this function
|
||||
// gets called in a non-root WRBP, we will set mForceRendering in this WRBP
|
||||
// but it will have no effect because CompositeToTarget (which reads the
|
||||
// flag) only gets invoked in the root WRBP. So we assert that this is the
|
||||
// root WRBP (i.e. has a non-null mWidget) to catch violations of this rule.
|
||||
MOZ_ASSERT(mWidget);
|
||||
|
||||
RefPtr<TextureHost> texture = TextureHost::AsTextureHost(aTexture);
|
||||
if (!texture) {
|
||||
// We kill the content process rather than have it continue with an invalid
|
||||
|
@ -1199,6 +1206,9 @@ WebRenderBridgeParent::SampleAnimations(nsTArray<wr::WrOpacityProperty>& aOpacit
|
|||
void
|
||||
WebRenderBridgeParent::CompositeToTarget(gfx::DrawTarget* aTarget, const gfx::IntRect* aRect)
|
||||
{
|
||||
// This function should only get called in the root WRBP
|
||||
MOZ_ASSERT(mWidget);
|
||||
|
||||
// The two arguments are part of the CompositorVsyncSchedulerOwner API but in
|
||||
// this implementation they should never be non-null.
|
||||
MOZ_ASSERT(aTarget == nullptr);
|
||||
|
|
|
@ -509,7 +509,7 @@ private:
|
|||
DECL_GFX_PREF(Once, "gfx.webrender.all", WebRenderAll, bool, false);
|
||||
DECL_GFX_PREF(Once, "gfx.webrender.async-scene-build", WebRenderAsyncSceneBuild, bool, false);
|
||||
DECL_GFX_PREF(Once, "gfx.webrender.enabled", WebRenderEnabledDoNotUseDirectly, bool, false);
|
||||
DECL_OVERRIDE_PREF(Live, "gfx.webrender.blob-images", WebRenderBlobImages, gfxPrefs::WebRenderAll());
|
||||
DECL_GFX_PREF(Live, "gfx.webrender.blob-images", WebRenderBlobImages, bool, true);
|
||||
DECL_GFX_PREF(Live, "gfx.webrender.blob.invalidation", WebRenderBlobInvalidation, bool, false);
|
||||
DECL_GFX_PREF(Live, "gfx.webrender.highlight-painted-layers",WebRenderHighlightPaintedLayers, bool, false);
|
||||
DECL_GFX_PREF(Live, "gfx.webrender.hit-test", WebRenderHitTest, bool, true);
|
||||
|
@ -538,7 +538,7 @@ private:
|
|||
DECL_GFX_PREF(Live, "image.mem.discardable", ImageMemDiscardable, bool, false);
|
||||
DECL_GFX_PREF(Once, "image.mem.animated.discardable", ImageMemAnimatedDiscardable, bool, false);
|
||||
DECL_GFX_PREF(Live, "image.mem.animated.use_heap", ImageMemAnimatedUseHeap, bool, false);
|
||||
DECL_OVERRIDE_PREF(Live, "image.mem.shared", ImageMemShared, gfxPrefs::WebRenderAll());
|
||||
DECL_GFX_PREF(Live, "image.mem.shared", ImageMemShared, bool, true);
|
||||
DECL_GFX_PREF(Once, "image.mem.surfacecache.discard_factor", ImageMemSurfaceCacheDiscardFactor, uint32_t, 1);
|
||||
DECL_GFX_PREF(Once, "image.mem.surfacecache.max_size_kb", ImageMemSurfaceCacheMaxSizeKB, uint32_t, 100 * 1024);
|
||||
DECL_GFX_PREF(Once, "image.mem.surfacecache.min_expiration_ms", ImageMemSurfaceCacheMinExpirationMS, uint32_t, 60*1000);
|
||||
|
|
|
@ -62,6 +62,14 @@ SERVO_BINDING_FUNC(Servo_StyleSheet_FromUTF8Bytes,
|
|||
uint32_t line_number_offset,
|
||||
nsCompatibility quirks_mode,
|
||||
mozilla::css::LoaderReusableStyleSheets* reusable_sheets)
|
||||
SERVO_BINDING_FUNC(Servo_StyleSheet_FromUTF8BytesAsync,
|
||||
void,
|
||||
mozilla::css::SheetLoadDataHolder* load_data,
|
||||
RawGeckoURLExtraData* extra_data,
|
||||
const nsACString* bytes,
|
||||
mozilla::css::SheetParsingMode parsing_mode,
|
||||
uint32_t line_number_offset,
|
||||
nsCompatibility quirks_mode)
|
||||
SERVO_BINDING_FUNC(Servo_StyleSheet_Empty, RawServoStyleSheetContentsStrong,
|
||||
mozilla::css::SheetParsingMode parsing_mode)
|
||||
SERVO_BINDING_FUNC(Servo_StyleSheet_HasRules, bool,
|
||||
|
@ -296,6 +304,10 @@ SERVO_BINDING_FUNC(Servo_ImportRule_GetHref, void,
|
|||
SERVO_BINDING_FUNC(Servo_ImportRule_GetSheet,
|
||||
const mozilla::ServoStyleSheet*,
|
||||
RawServoImportRuleBorrowed rule)
|
||||
SERVO_BINDING_FUNC(Servo_ImportRule_SetSheet,
|
||||
void,
|
||||
RawServoImportRuleBorrowed rule,
|
||||
mozilla::ServoStyleSheet* sheet);
|
||||
SERVO_BINDING_FUNC(Servo_Keyframe_GetKeyText, void,
|
||||
RawServoKeyframeBorrowed keyframe, nsAString* result)
|
||||
// Returns whether it successfully changes the key text.
|
||||
|
|
|
@ -39,6 +39,7 @@
|
|||
#include "nsMediaFeatures.h"
|
||||
#include "nsNameSpaceManager.h"
|
||||
#include "nsNetUtil.h"
|
||||
#include "nsProxyRelease.h"
|
||||
#include "nsString.h"
|
||||
#include "nsStyleStruct.h"
|
||||
#include "nsStyleUtil.h"
|
||||
|
@ -2513,28 +2514,38 @@ Gecko_GetAppUnitsPerPhysicalInch(RawGeckoPresContextBorrowed aPresContext)
|
|||
return presContext->DeviceContext()->AppUnitsPerPhysicalInch();
|
||||
}
|
||||
|
||||
ServoStyleSheet*
|
||||
Gecko_LoadStyleSheet(css::Loader* aLoader,
|
||||
ServoStyleSheet* aParent,
|
||||
SheetLoadData* aParentLoadData,
|
||||
css::LoaderReusableStyleSheets* aReusableSheets,
|
||||
RawGeckoURLExtraData* aURLExtraData,
|
||||
const uint8_t* aURLString,
|
||||
uint32_t aURLStringLength,
|
||||
RawServoMediaListStrong aMediaList)
|
||||
NS_IMPL_THREADSAFE_FFI_REFCOUNTING(SheetLoadDataHolder, SheetLoadDataHolder);
|
||||
|
||||
void
|
||||
Gecko_StyleSheet_FinishAsyncParse(SheetLoadDataHolder* aData,
|
||||
RawServoStyleSheetContentsStrong aSheetContents)
|
||||
{
|
||||
RefPtr<SheetLoadDataHolder> loadData = aData;
|
||||
RefPtr<RawServoStyleSheetContents> sheetContents = aSheetContents.Consume();
|
||||
NS_DispatchToMainThread(NS_NewRunnableFunction(__func__,
|
||||
[d = Move(loadData),
|
||||
s = Move(sheetContents)]() mutable {
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
d->get()->mSheet->AsServo()->FinishAsyncParse(s.forget());
|
||||
}));
|
||||
}
|
||||
|
||||
static already_AddRefed<ServoStyleSheet>
|
||||
LoadImportSheet(css::Loader* aLoader,
|
||||
ServoStyleSheet* aParent,
|
||||
SheetLoadData* aParentLoadData,
|
||||
css::LoaderReusableStyleSheets* aReusableSheets,
|
||||
css::URLValue* aURL,
|
||||
already_AddRefed<RawServoMediaList> aMediaList)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
MOZ_ASSERT(aLoader, "Should've catched this before");
|
||||
MOZ_ASSERT(aParent, "Only used for @import, so parent should exist!");
|
||||
MOZ_ASSERT(aURLString, "Invalid URLs shouldn't be loaded!");
|
||||
MOZ_ASSERT(aURLExtraData, "Need URL extra data");
|
||||
MOZ_ASSERT(aURL, "Invalid URLs shouldn't be loaded!");
|
||||
|
||||
RefPtr<dom::MediaList> media = new ServoMediaList(aMediaList.Consume());
|
||||
nsDependentCSubstring urlSpec(reinterpret_cast<const char*>(aURLString),
|
||||
aURLStringLength);
|
||||
nsCOMPtr<nsIURI> uri;
|
||||
nsresult rv = NS_NewURI(getter_AddRefs(uri), urlSpec, nullptr,
|
||||
aURLExtraData->BaseURI());
|
||||
RefPtr<dom::MediaList> media = new ServoMediaList(Move(aMediaList));
|
||||
nsCOMPtr<nsIURI> uri = aURL->GetURI();
|
||||
nsresult rv = uri ? NS_OK : NS_ERROR_FAILURE;
|
||||
|
||||
StyleSheet* previousFirstChild = aParent->GetFirstChild();
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
|
@ -2558,15 +2569,52 @@ Gecko_LoadStyleSheet(css::Loader* aLoader,
|
|||
NS_NewURI(getter_AddRefs(uri), NS_LITERAL_CSTRING("about:invalid"));
|
||||
}
|
||||
emptySheet->SetURIs(uri, uri, uri);
|
||||
emptySheet->SetPrincipal(aURLExtraData->GetPrincipal());
|
||||
emptySheet->SetPrincipal(aURL->mExtraData->GetPrincipal());
|
||||
emptySheet->SetComplete();
|
||||
aParent->PrependStyleSheet(emptySheet);
|
||||
return emptySheet.forget().take();
|
||||
return emptySheet.forget();
|
||||
}
|
||||
|
||||
RefPtr<ServoStyleSheet> sheet =
|
||||
static_cast<ServoStyleSheet*>(aParent->GetFirstChild());
|
||||
return sheet.forget().take();
|
||||
return sheet.forget();
|
||||
}
|
||||
|
||||
ServoStyleSheet*
|
||||
Gecko_LoadStyleSheet(css::Loader* aLoader,
|
||||
ServoStyleSheet* aParent,
|
||||
SheetLoadData* aParentLoadData,
|
||||
css::LoaderReusableStyleSheets* aReusableSheets,
|
||||
ServoBundledURI aServoURL,
|
||||
RawServoMediaListStrong aMediaList)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
RefPtr<css::URLValue> url = aServoURL.IntoCssUrl();
|
||||
return LoadImportSheet(aLoader, aParent, aParentLoadData, aReusableSheets,
|
||||
url, aMediaList.Consume()).take();
|
||||
}
|
||||
|
||||
void
|
||||
Gecko_LoadStyleSheetAsync(css::SheetLoadDataHolder* aParentData,
|
||||
ServoBundledURI aServoURL,
|
||||
RawServoMediaListStrong aMediaList,
|
||||
RawServoImportRuleStrong aImportRule)
|
||||
{
|
||||
RefPtr<SheetLoadDataHolder> loadData = aParentData;
|
||||
RefPtr<css::URLValue> urlVal = aServoURL.IntoCssUrl();
|
||||
RefPtr<RawServoMediaList> mediaList = aMediaList.Consume();
|
||||
RefPtr<RawServoImportRule> importRule = aImportRule.Consume();
|
||||
NS_DispatchToMainThread(NS_NewRunnableFunction(__func__,
|
||||
[data = Move(loadData),
|
||||
url = Move(urlVal),
|
||||
media = Move(mediaList),
|
||||
import = Move(importRule)]() mutable {
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
SheetLoadData* d = data->get();
|
||||
RefPtr<ServoStyleSheet> sheet =
|
||||
LoadImportSheet(d->mLoader, d->mSheet->AsServo(), d, nullptr, url, media.forget());
|
||||
Servo_ImportRule_SetSheet(import, sheet);
|
||||
}));
|
||||
}
|
||||
|
||||
nsCSSKeyword
|
||||
|
|
|
@ -172,16 +172,25 @@ void Gecko_ConstructStyleChildrenIterator(RawGeckoElementBorrowed aElement,
|
|||
void Gecko_DestroyStyleChildrenIterator(RawGeckoStyleChildrenIteratorBorrowedMut aIterator);
|
||||
RawGeckoNodeBorrowedOrNull Gecko_GetNextStyleChild(RawGeckoStyleChildrenIteratorBorrowedMut it);
|
||||
|
||||
NS_DECL_THREADSAFE_FFI_REFCOUNTING(mozilla::css::SheetLoadDataHolder, SheetLoadDataHolder);
|
||||
|
||||
void Gecko_StyleSheet_FinishAsyncParse(mozilla::css::SheetLoadDataHolder* data,
|
||||
RawServoStyleSheetContentsStrong sheet_contents);
|
||||
|
||||
mozilla::ServoStyleSheet*
|
||||
Gecko_LoadStyleSheet(mozilla::css::Loader* loader,
|
||||
mozilla::ServoStyleSheet* parent,
|
||||
mozilla::css::SheetLoadData* parent_load_data,
|
||||
mozilla::css::LoaderReusableStyleSheets* reusable_sheets,
|
||||
RawGeckoURLExtraData* base_url_data,
|
||||
const uint8_t* url_bytes,
|
||||
uint32_t url_length,
|
||||
ServoBundledURI url,
|
||||
RawServoMediaListStrong media_list);
|
||||
|
||||
void
|
||||
Gecko_LoadStyleSheetAsync(mozilla::css::SheetLoadDataHolder* parent_data,
|
||||
ServoBundledURI url,
|
||||
RawServoMediaListStrong media_list,
|
||||
RawServoImportRuleStrong import_rule);
|
||||
|
||||
// Selector Matching.
|
||||
uint64_t Gecko_ElementState(RawGeckoElementBorrowed element);
|
||||
bool Gecko_IsRootElement(RawGeckoElementBorrowed element);
|
||||
|
|
|
@ -230,6 +230,7 @@ whitelist-types = [
|
|||
"mozilla::css::ErrorReporter",
|
||||
"mozilla::css::LoaderReusableStyleSheets",
|
||||
"mozilla::css::SheetLoadData",
|
||||
"mozilla::css::SheetLoadDataHolder",
|
||||
"mozilla::css::SheetParsingMode",
|
||||
"mozilla::css::URLMatchingFunction",
|
||||
"mozilla::dom::IterationCompositeOperation",
|
||||
|
@ -588,6 +589,7 @@ structs-types = [
|
|||
"Loader",
|
||||
"LoaderReusableStyleSheets",
|
||||
"SheetLoadData",
|
||||
"SheetLoadDataHolder",
|
||||
"ServoStyleSheet",
|
||||
"ServoComputedData",
|
||||
"ComputedStyleStrong",
|
||||
|
|
|
@ -11,10 +11,12 @@
|
|||
#include "mozilla/ServoCSSRuleList.h"
|
||||
#include "mozilla/ServoImportRule.h"
|
||||
#include "mozilla/ServoMediaList.h"
|
||||
#include "mozilla/StaticPrefs.h"
|
||||
#include "mozilla/css/GroupRule.h"
|
||||
#include "mozilla/dom/CSSRuleList.h"
|
||||
#include "mozilla/dom/MediaList.h"
|
||||
#include "nsIStyleSheetLinkingElement.h"
|
||||
#include "ErrorReporter.h"
|
||||
#include "Loader.h"
|
||||
|
||||
|
||||
|
@ -193,6 +195,42 @@ ServoStyleSheet::HasRules() const
|
|||
return Servo_StyleSheet_HasRules(Inner()->mContents);
|
||||
}
|
||||
|
||||
// We disable parallel stylesheet parsing if any of the following three
|
||||
// conditions hold:
|
||||
//
|
||||
// (1) The pref is off.
|
||||
// (2) The browser is recording CSS errors (which parallel parsing can't handle).
|
||||
// (3) The stylesheet is a chrome stylesheet, since those can use -moz-bool-pref,
|
||||
// which needs to access the pref service, which is not threadsafe.
|
||||
static bool
|
||||
AllowParallelParse(css::Loader* aLoader, nsIURI* aSheetURI)
|
||||
{
|
||||
// Check the pref.
|
||||
if (!StaticPrefs::layout_css_parsing_parallel()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// If the browser is recording CSS errors, we need to use the sequential path
|
||||
// because the parallel path doesn't support that.
|
||||
nsIDocument* doc = aLoader->GetDocument();
|
||||
if (doc && css::ErrorReporter::ShouldReportErrors(*doc)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// If this is a chrome stylesheet, it might use -moz-bool-pref, which needs to
|
||||
// access the pref service, which is not thread-safe. We could probably expose
|
||||
// the relevant booleans as thread-safe var caches if we needed to, but
|
||||
// parsing chrome stylesheets in parallel is unlikely to be a win anyway.
|
||||
//
|
||||
// Note that UA stylesheets can also use -moz-bool-pref, but those are always
|
||||
// parsed sync.
|
||||
if (dom::IsChromeURI(aSheetURI)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
RefPtr<StyleSheetParsePromise>
|
||||
ServoStyleSheet::ParseSheet(css::Loader* aLoader,
|
||||
const nsACString& aBytes,
|
||||
|
@ -201,27 +239,50 @@ ServoStyleSheet::ParseSheet(css::Loader* aLoader,
|
|||
nsIPrincipal* aSheetPrincipal,
|
||||
css::SheetLoadData* aLoadData,
|
||||
uint32_t aLineNumber,
|
||||
nsCompatibility aCompatMode,
|
||||
css::LoaderReusableStyleSheets* aReusableSheets)
|
||||
nsCompatibility aCompatMode)
|
||||
{
|
||||
MOZ_ASSERT(mParsePromise.IsEmpty());
|
||||
RefPtr<StyleSheetParsePromise> p = mParsePromise.Ensure(__func__);
|
||||
Inner()->mURLData = new URLExtraData(aBaseURI, aSheetURI, aSheetPrincipal); // RefPtr
|
||||
Inner()->mContents = Servo_StyleSheet_FromUTF8Bytes(aLoader,
|
||||
this,
|
||||
aLoadData,
|
||||
&aBytes,
|
||||
mParsingMode,
|
||||
Inner()->mURLData,
|
||||
aLineNumber,
|
||||
aCompatMode,
|
||||
aReusableSheets)
|
||||
.Consume();
|
||||
FinishParse();
|
||||
mParsePromise.Resolve(true, __func__);
|
||||
|
||||
if (!AllowParallelParse(aLoader, aSheetURI)) {
|
||||
RefPtr<RawServoStyleSheetContents> contents =
|
||||
Servo_StyleSheet_FromUTF8Bytes(aLoader,
|
||||
this,
|
||||
aLoadData,
|
||||
&aBytes,
|
||||
mParsingMode,
|
||||
Inner()->mURLData,
|
||||
aLineNumber,
|
||||
aCompatMode,
|
||||
/* reusable_sheets = */ nullptr)
|
||||
.Consume();
|
||||
FinishAsyncParse(contents.forget());
|
||||
} else {
|
||||
RefPtr<css::SheetLoadDataHolder> loadDataHolder =
|
||||
new css::SheetLoadDataHolder(__func__, aLoadData);
|
||||
Servo_StyleSheet_FromUTF8BytesAsync(loadDataHolder,
|
||||
Inner()->mURLData,
|
||||
&aBytes,
|
||||
mParsingMode,
|
||||
aLineNumber,
|
||||
aCompatMode);
|
||||
}
|
||||
|
||||
return Move(p);
|
||||
}
|
||||
|
||||
void
|
||||
ServoStyleSheet::FinishAsyncParse(already_AddRefed<RawServoStyleSheetContents> aSheetContents)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
MOZ_ASSERT(!mParsePromise.IsEmpty());
|
||||
Inner()->mContents = aSheetContents;
|
||||
FinishParse();
|
||||
mParsePromise.Resolve(true, __func__);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ServoStyleSheet::ParseSheetSync(css::Loader* aLoader,
|
||||
const nsACString& aBytes,
|
||||
|
|
|
@ -99,8 +99,11 @@ public:
|
|||
nsIPrincipal* aSheetPrincipal,
|
||||
css::SheetLoadData* aLoadData,
|
||||
uint32_t aLineNumber,
|
||||
nsCompatibility aCompatMode,
|
||||
css::LoaderReusableStyleSheets* aReusableSheets = nullptr);
|
||||
nsCompatibility aCompatMode);
|
||||
|
||||
// Common code that needs to be called after servo finishes parsing. This is
|
||||
// shared between the parallel and sequential paths.
|
||||
void FinishAsyncParse(already_AddRefed<RawServoStyleSheetContents> aSheetContents);
|
||||
|
||||
// Similar to the above, but guarantees that parsing will be performed
|
||||
// synchronously.
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
#include "mozilla/Encoding.h"
|
||||
#include "mozilla/NotNull.h"
|
||||
#include "nsIThreadInternal.h"
|
||||
#include "nsProxyRelease.h"
|
||||
|
||||
namespace mozilla {
|
||||
class StyleSheet;
|
||||
|
@ -202,7 +203,19 @@ private:
|
|||
void FireLoadEvent(nsIThreadInternal* aThread);
|
||||
};
|
||||
|
||||
typedef nsMainThreadPtrHolder<SheetLoadData> SheetLoadDataHolder;
|
||||
|
||||
} // namespace css
|
||||
} // namespace mozilla
|
||||
|
||||
/**
|
||||
* Casting SheetLoadData to nsISupports is ambiguous.
|
||||
* This method handles that.
|
||||
*/
|
||||
inline nsISupports*
|
||||
ToSupports(mozilla::css::SheetLoadData* p)
|
||||
{
|
||||
return NS_ISUPPORTS_CAST(nsIRunnable*, p);
|
||||
}
|
||||
|
||||
#endif // mozilla_css_SheetLoadData_h
|
||||
|
|
|
@ -765,6 +765,11 @@ nsLayoutStylesheetCache::LoadSheet(nsIURI* aURI,
|
|||
|
||||
nsZipArchive::sFileCorruptedReason = nullptr;
|
||||
|
||||
// Note: The parallel parsing code assume that UA sheets are always loaded
|
||||
// synchrously like they are here, and thus that we'll never attempt parallel
|
||||
// parsing on them. If that ever changes, we'll either need to find a
|
||||
// different way to prohibit parallel parsing for UA sheets, or handle
|
||||
// -moz-bool-pref and various other things in the parallel parsing code.
|
||||
nsresult rv = gCSSLoader->LoadSheetSync(aURI, aParsingMode, true, aSheet);
|
||||
if (NS_FAILED(rv)) {
|
||||
ErrorLoadingSheet(aURI,
|
||||
|
|
|
@ -5,4 +5,4 @@ Makefile.in build files for the Mozilla build system.
|
|||
|
||||
The audioipc-2 git repository is: https://github.com/djg/audioipc-2.git
|
||||
|
||||
The git commit ID used was b93386611d7d9689c4f0177a4704f0adc16bc2d1 (2018-03-09 14:45:24 +1000)
|
||||
The git commit ID used was 219a811b62b83bd6e4cb54ae6aebc56bbb43203c (2018-04-18 13:57:59 +1200)
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
[package]
|
||||
name = "audioipc"
|
||||
version = "0.2.3"
|
||||
version = "0.2.4"
|
||||
authors = [
|
||||
"Matthew Gregan <kinetik@flim.org>",
|
||||
"Dan Glastonbury <dan.glastonbury@gmail.com>"
|
||||
|
|
|
@ -47,7 +47,7 @@ impl CoreThread {
|
|||
|
||||
impl Drop for CoreThread {
|
||||
fn drop(&mut self) {
|
||||
trace!("Shutting down {:?}", self);
|
||||
debug!("Shutting down {:?}", self);
|
||||
if let Some(inner) = self.inner.take() {
|
||||
let _ = inner.shutdown.send(());
|
||||
drop(inner.join.join());
|
||||
|
|
|
@ -85,7 +85,7 @@ where
|
|||
{
|
||||
// If there is a buffered frame, try to write it to `A`
|
||||
fn do_write(&mut self) -> Poll<(), io::Error> {
|
||||
debug!("do_write...");
|
||||
trace!("do_write...");
|
||||
// Create a frame from any pending message in `write_buf`.
|
||||
if !self.write_buf.is_empty() {
|
||||
self.set_frame(None);
|
||||
|
@ -141,8 +141,7 @@ where
|
|||
_ => panic!(),
|
||||
}
|
||||
}
|
||||
debug!("process {} frames", processed);
|
||||
|
||||
trace!("process {} frames", processed);
|
||||
trace!("pending frames: {:?}", self.frames);
|
||||
|
||||
Ok(().into())
|
||||
|
|
|
@ -118,6 +118,7 @@ impl From<DeviceInfo> for ffi::cubeb_device_info {
|
|||
}
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
#[derive(Clone, Copy, Debug, Deserialize, Serialize)]
|
||||
pub struct StreamParams {
|
||||
pub format: ffi::cubeb_sample_format,
|
||||
|
|
|
@ -90,6 +90,7 @@ where
|
|||
Async::Ready(None) => {
|
||||
trace!(" --> got None");
|
||||
// The service is done with the connection.
|
||||
self.run = false;
|
||||
break;
|
||||
}
|
||||
// Nothing to dispatch
|
||||
|
@ -139,6 +140,7 @@ where
|
|||
try!(self.flush());
|
||||
|
||||
if self.is_done() {
|
||||
trace!(" --> is done.");
|
||||
return Ok(().into());
|
||||
}
|
||||
|
||||
|
|
|
@ -42,6 +42,9 @@ macro_rules! t(
|
|||
|
||||
pub const CLIENT_OPS: Ops = capi_new!(ClientContext, ClientStream);
|
||||
|
||||
// ClientContext's layout *must* match cubeb.c's `struct cubeb` for the
|
||||
// common fields.
|
||||
#[repr(C)]
|
||||
pub struct ClientContext {
|
||||
_ops: *const Ops,
|
||||
rpc: rpc::ClientProxy<ServerMessage, ClientMessage>,
|
||||
|
@ -227,7 +230,7 @@ impl ContextOps for ClientContext {
|
|||
}
|
||||
|
||||
let stream_name = match stream_name {
|
||||
Some(s) => Some(s.to_bytes().to_vec()),
|
||||
Some(s) => Some(s.to_bytes_with_nul().to_vec()),
|
||||
None => None,
|
||||
};
|
||||
|
||||
|
@ -258,7 +261,7 @@ impl ContextOps for ClientContext {
|
|||
|
||||
impl Drop for ClientContext {
|
||||
fn drop(&mut self) {
|
||||
debug!("ClientContext drop...");
|
||||
debug!("ClientContext dropped...");
|
||||
let _ = send_recv!(self.rpc(), ClientDisconnect => ClientDisconnected);
|
||||
unsafe {
|
||||
if G_SERVER_FD.is_some() {
|
||||
|
|
|
@ -40,11 +40,15 @@ impl Drop for Device {
|
|||
}
|
||||
}
|
||||
|
||||
// ClientStream's layout *must* match cubeb.c's `struct cubeb_stream` for the
|
||||
// common fields.
|
||||
#[repr(C)]
|
||||
#[derive(Debug)]
|
||||
pub struct ClientStream<'ctx> {
|
||||
// This must be a reference to Context for cubeb, cubeb accesses
|
||||
// stream methods via stream->context->ops
|
||||
context: &'ctx ClientContext,
|
||||
user_ptr: *mut c_void,
|
||||
token: usize,
|
||||
}
|
||||
|
||||
|
@ -66,9 +70,10 @@ impl rpc::Server for CallbackServer {
|
|||
fn process(&mut self, req: Self::Request) -> Self::Future {
|
||||
match req {
|
||||
CallbackReq::Data(nframes, frame_size) => {
|
||||
debug!(
|
||||
trace!(
|
||||
"stream_thread: Data Callback: nframes={} frame_size={}",
|
||||
nframes, frame_size
|
||||
nframes,
|
||||
frame_size
|
||||
);
|
||||
|
||||
// Clone values that need to be moved into the cpu pool thread.
|
||||
|
@ -104,7 +109,7 @@ impl rpc::Server for CallbackServer {
|
|||
})
|
||||
}
|
||||
CallbackReq::State(state) => {
|
||||
debug!("stream_thread: State Callback: {:?}", state);
|
||||
trace!("stream_thread: State Callback: {:?}", state);
|
||||
let user_ptr = self.user_ptr;
|
||||
let cb = self.state_cb.unwrap();
|
||||
self.cpu_pool.spawn_fn(move || {
|
||||
|
@ -134,7 +139,7 @@ impl<'ctx> ClientStream<'ctx> {
|
|||
let rpc = ctx.rpc();
|
||||
let data = try!(send_recv!(rpc, StreamInit(init_params) => StreamCreated()));
|
||||
|
||||
trace!("token = {}, fds = {:?}", data.token, data.fds);
|
||||
debug!("token = {}, fds = {:?}", data.token, data.fds);
|
||||
|
||||
let stm = data.fds[0];
|
||||
let stream = unsafe { net::UnixStream::from_raw_fd(stm) };
|
||||
|
@ -172,6 +177,7 @@ impl<'ctx> ClientStream<'ctx> {
|
|||
|
||||
let stream = Box::into_raw(Box::new(ClientStream {
|
||||
context: ctx,
|
||||
user_ptr: user_ptr,
|
||||
token: data.token,
|
||||
}));
|
||||
Ok(unsafe { Stream::from_ptr(stream as *mut _) })
|
||||
|
@ -180,7 +186,7 @@ impl<'ctx> ClientStream<'ctx> {
|
|||
|
||||
impl<'ctx> Drop for ClientStream<'ctx> {
|
||||
fn drop(&mut self) {
|
||||
trace!("ClientStream drop...");
|
||||
debug!("ClientStream dropped...");
|
||||
let rpc = self.context.rpc();
|
||||
let _ = send_recv!(rpc, StreamDestroy(self.token) => StreamDestroyed);
|
||||
}
|
||||
|
@ -268,5 +274,13 @@ pub fn init(
|
|||
state_callback: ffi::cubeb_state_callback,
|
||||
user_ptr: *mut c_void,
|
||||
) -> Result<Stream> {
|
||||
ClientStream::init(ctx, init_params, data_callback, state_callback, user_ptr)
|
||||
let stm = try!(ClientStream::init(
|
||||
ctx,
|
||||
init_params,
|
||||
data_callback,
|
||||
state_callback,
|
||||
user_ptr
|
||||
));
|
||||
debug_assert_eq!(stm.user_ptr(), user_ptr);
|
||||
Ok(stm)
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
[package]
|
||||
name = "audioipc-server"
|
||||
version = "0.2.2"
|
||||
version = "0.2.3"
|
||||
authors = [
|
||||
"Matthew Gregan <kinetik@flim.org>",
|
||||
"Dan Glastonbury <dan.glastonbury@gmail.com>"
|
||||
|
@ -9,7 +9,7 @@ description = "Remote cubeb server"
|
|||
|
||||
[dependencies]
|
||||
audioipc = { path = "../audioipc" }
|
||||
cubeb = "0.5.2"
|
||||
cubeb-core = "0.5.1"
|
||||
bytes = "0.4"
|
||||
lazycell = "^0.4"
|
||||
libc = "0.2"
|
||||
|
|
|
@ -6,7 +6,7 @@ extern crate log;
|
|||
|
||||
extern crate audioipc;
|
||||
extern crate bytes;
|
||||
extern crate cubeb;
|
||||
extern crate cubeb_core as cubeb;
|
||||
extern crate futures;
|
||||
extern crate lazycell;
|
||||
extern crate libc;
|
||||
|
@ -22,16 +22,19 @@ use audioipc::messages::{CallbackReq, CallbackResp, ClientMessage, Device, Devic
|
|||
ServerMessage, StreamCreate, StreamInitParams, StreamParams};
|
||||
use audioipc::rpc;
|
||||
use audioipc::shm::{SharedMemReader, SharedMemWriter};
|
||||
use futures::Future;
|
||||
use cubeb::ffi;
|
||||
use futures::future::{self, FutureResult};
|
||||
use futures::sync::oneshot;
|
||||
use std::{ptr, slice};
|
||||
use futures::Future;
|
||||
use std::cell::RefCell;
|
||||
use std::convert::From;
|
||||
use std::error::Error;
|
||||
use std::os::raw::c_void;
|
||||
use std::ffi::{CStr, CString};
|
||||
use std::mem::{size_of, ManuallyDrop};
|
||||
use std::os::raw::{c_long, c_void};
|
||||
use std::os::unix::net;
|
||||
use std::os::unix::prelude::*;
|
||||
use std::{panic, ptr, slice};
|
||||
use tokio_core::reactor::Remote;
|
||||
use tokio_uds::UnixStream;
|
||||
|
||||
|
@ -60,7 +63,8 @@ where
|
|||
CONTEXT_KEY.with(|k| {
|
||||
let mut context = k.borrow_mut();
|
||||
if context.is_none() {
|
||||
*context = Some(cubeb::init("AudioIPC Server"));
|
||||
let name = CString::new("AudioIPC Server").unwrap();
|
||||
*context = Some(cubeb::Context::init(Some(name.as_c_str()), None));
|
||||
}
|
||||
f(context.as_ref().unwrap())
|
||||
})
|
||||
|
@ -80,7 +84,84 @@ impl rpc::Client for CallbackClient {
|
|||
type Transport = Framed<UnixStream, LengthDelimitedCodec<Self::Request, Self::Response>>;
|
||||
}
|
||||
|
||||
type StreamSlab = slab::Slab<cubeb::Stream<u8>, usize>;
|
||||
struct ServerStreamCallbacks {
|
||||
/// Size of input frame in bytes
|
||||
input_frame_size: u16,
|
||||
/// Size of output frame in bytes
|
||||
output_frame_size: u16,
|
||||
/// Shared memory buffer for sending input data to client
|
||||
input_shm: SharedMemWriter,
|
||||
/// Shared memory buffer for receiving output data from client
|
||||
output_shm: SharedMemReader,
|
||||
/// RPC interface to callback server running in client
|
||||
rpc: rpc::ClientProxy<CallbackReq, CallbackResp>,
|
||||
}
|
||||
|
||||
impl ServerStreamCallbacks {
|
||||
fn data_callback(&mut self, input: &[u8], output: &mut [u8]) -> isize {
|
||||
trace!("Stream data callback: {} {}", input.len(), output.len());
|
||||
|
||||
// len is of input and output is frame len. Turn these into the real lengths.
|
||||
let real_input = unsafe {
|
||||
let nbytes = input.len() * self.input_frame_size as usize;
|
||||
slice::from_raw_parts(input.as_ptr(), nbytes)
|
||||
};
|
||||
|
||||
self.input_shm.write(real_input).unwrap();
|
||||
|
||||
let r = self.rpc
|
||||
.call(CallbackReq::Data(
|
||||
output.len() as isize,
|
||||
self.output_frame_size as usize,
|
||||
))
|
||||
.wait();
|
||||
|
||||
match r {
|
||||
Ok(CallbackResp::Data(frames)) => {
|
||||
if frames >= 0 {
|
||||
let nbytes = frames as usize * self.output_frame_size as usize;
|
||||
let real_output = unsafe {
|
||||
trace!("Resize output to {}", nbytes);
|
||||
slice::from_raw_parts_mut(output.as_mut_ptr(), nbytes)
|
||||
};
|
||||
self.output_shm.read(&mut real_output[..nbytes]).unwrap();
|
||||
}
|
||||
frames
|
||||
}
|
||||
_ => {
|
||||
debug!("Unexpected message {:?} during data_callback", r);
|
||||
-1
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn state_callback(&mut self, state: cubeb::State) {
|
||||
trace!("Stream state callback: {:?}", state);
|
||||
let r = self.rpc.call(CallbackReq::State(state.into())).wait();
|
||||
match r {
|
||||
Ok(CallbackResp::State) => {}
|
||||
_ => {
|
||||
debug!("Unexpected message {:?} during callback", r);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct ServerStream {
|
||||
stream: ManuallyDrop<cubeb::Stream>,
|
||||
cbs: ManuallyDrop<Box<ServerStreamCallbacks>>,
|
||||
}
|
||||
|
||||
impl Drop for ServerStream {
|
||||
fn drop(&mut self) {
|
||||
unsafe {
|
||||
ManuallyDrop::drop(&mut self.stream);
|
||||
ManuallyDrop::drop(&mut self.cbs);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
type StreamSlab = slab::Slab<ServerStream, usize>;
|
||||
|
||||
pub struct CubebServer {
|
||||
cb_remote: Remote,
|
||||
|
@ -167,47 +248,55 @@ impl CubebServer {
|
|||
}
|
||||
|
||||
ServerMessage::StreamStart(stm_tok) => self.streams[stm_tok]
|
||||
.stream
|
||||
.start()
|
||||
.map(|_| ClientMessage::StreamStarted)
|
||||
.unwrap_or_else(error),
|
||||
|
||||
ServerMessage::StreamStop(stm_tok) => self.streams[stm_tok]
|
||||
.stream
|
||||
.stop()
|
||||
.map(|_| ClientMessage::StreamStopped)
|
||||
.unwrap_or_else(error),
|
||||
|
||||
ServerMessage::StreamResetDefaultDevice(stm_tok) => self.streams[stm_tok]
|
||||
.stream
|
||||
.reset_default_device()
|
||||
.map(|_| ClientMessage::StreamDefaultDeviceReset)
|
||||
.unwrap_or_else(error),
|
||||
|
||||
ServerMessage::StreamGetPosition(stm_tok) => self.streams[stm_tok]
|
||||
.stream
|
||||
.position()
|
||||
.map(ClientMessage::StreamPosition)
|
||||
.unwrap_or_else(error),
|
||||
|
||||
ServerMessage::StreamGetLatency(stm_tok) => self.streams[stm_tok]
|
||||
.stream
|
||||
.latency()
|
||||
.map(ClientMessage::StreamLatency)
|
||||
.unwrap_or_else(error),
|
||||
|
||||
ServerMessage::StreamSetVolume(stm_tok, volume) => self.streams[stm_tok]
|
||||
.stream
|
||||
.set_volume(volume)
|
||||
.map(|_| ClientMessage::StreamVolumeSet)
|
||||
.unwrap_or_else(error),
|
||||
|
||||
ServerMessage::StreamSetPanning(stm_tok, panning) => self.streams[stm_tok]
|
||||
.stream
|
||||
.set_panning(panning)
|
||||
.map(|_| ClientMessage::StreamPanningSet)
|
||||
.unwrap_or_else(error),
|
||||
|
||||
ServerMessage::StreamGetCurrentDevice(stm_tok) => self.streams[stm_tok]
|
||||
.stream
|
||||
.current_device()
|
||||
.map(|device| ClientMessage::StreamCurrentDevice(Device::from(device)))
|
||||
.unwrap_or_else(error),
|
||||
};
|
||||
|
||||
debug!("process_msg: req={:?}, resp={:?}", msg, resp);
|
||||
trace!("process_msg: req={:?}, resp={:?}", msg, resp);
|
||||
|
||||
resp
|
||||
}
|
||||
|
@ -236,17 +325,13 @@ impl CubebServer {
|
|||
.unwrap_or(0u16)
|
||||
}
|
||||
|
||||
// TODO: Yuck!
|
||||
let input_device = params.input_device as *const _;
|
||||
let output_device = params.output_device as *const _;
|
||||
let latency = params.latency_frames;
|
||||
|
||||
// Create the callback handling struct which is attached the cubeb stream.
|
||||
let input_frame_size = frame_size_in_bytes(params.input_stream_params.as_ref());
|
||||
let output_frame_size = frame_size_in_bytes(params.output_stream_params.as_ref());
|
||||
|
||||
let (stm1, stm2) = net::UnixStream::pair()?;
|
||||
debug!("Created callback pair: {:?}-{:?}", stm1, stm2);
|
||||
let (mut input_shm, input_file) =
|
||||
let (input_shm, input_file) =
|
||||
SharedMemWriter::new(&audioipc::get_shm_path("input"), SHM_AREA_SIZE)?;
|
||||
let (output_shm, output_file) =
|
||||
SharedMemReader::new(&audioipc::get_shm_path("output"), SHM_AREA_SIZE)?;
|
||||
|
@ -270,112 +355,89 @@ impl CubebServer {
|
|||
Ok(())
|
||||
});
|
||||
|
||||
let rpc_data: rpc::ClientProxy<CallbackReq, CallbackResp> = match rx.wait() {
|
||||
let rpc: rpc::ClientProxy<CallbackReq, CallbackResp> = match rx.wait() {
|
||||
Ok(rpc) => rpc,
|
||||
Err(_) => bail!("Failed to create callback rpc."),
|
||||
};
|
||||
let rpc_state = rpc_data.clone();
|
||||
|
||||
let mut builder = cubeb::StreamBuilder::new();
|
||||
let cbs = Box::new(ServerStreamCallbacks {
|
||||
input_frame_size,
|
||||
output_frame_size,
|
||||
input_shm,
|
||||
output_shm,
|
||||
rpc,
|
||||
});
|
||||
|
||||
if let Some(ref stream_name) = params.stream_name {
|
||||
builder.name(stream_name.clone());
|
||||
}
|
||||
// Create cubeb stream from params
|
||||
let stream_name = params
|
||||
.stream_name
|
||||
.as_ref()
|
||||
.and_then(|name| CStr::from_bytes_with_nul(name).ok());
|
||||
|
||||
if let Some(ref isp) = params.input_stream_params {
|
||||
let input_stream_params =
|
||||
unsafe { cubeb::StreamParamsRef::from_ptr(isp as *const StreamParams as *mut _) };
|
||||
builder.input(input_device, input_stream_params);
|
||||
}
|
||||
let input_device = params.input_device as *const _;
|
||||
let input_stream_params = params.input_stream_params.as_ref().map(|isp| unsafe {
|
||||
cubeb::StreamParamsRef::from_ptr(isp as *const StreamParams as *mut _)
|
||||
});
|
||||
|
||||
if let Some(ref osp) = params.output_stream_params {
|
||||
let output_stream_params =
|
||||
unsafe { cubeb::StreamParamsRef::from_ptr(osp as *const StreamParams as *mut _) };
|
||||
builder.output(output_device, output_stream_params);
|
||||
}
|
||||
let output_device = params.output_device as *const _;
|
||||
let output_stream_params = params.output_stream_params.as_ref().map(|osp| unsafe {
|
||||
cubeb::StreamParamsRef::from_ptr(osp as *const StreamParams as *mut _)
|
||||
});
|
||||
|
||||
builder
|
||||
.latency(latency)
|
||||
.data_callback(move |input, output| {
|
||||
trace!("Stream data callback: {} {}", input.len(), output.len());
|
||||
let latency = params.latency_frames;
|
||||
assert!(size_of::<Box<ServerStreamCallbacks>>() == size_of::<usize>());
|
||||
let user_ptr = cbs.as_ref() as *const ServerStreamCallbacks as *mut c_void;
|
||||
|
||||
// len is of input and output is frame len. Turn these into the real lengths.
|
||||
let real_input = unsafe {
|
||||
let nbytes = input.len() * input_frame_size as usize;
|
||||
slice::from_raw_parts(input.as_ptr(), nbytes)
|
||||
};
|
||||
unsafe {
|
||||
context
|
||||
.stream_init(
|
||||
stream_name,
|
||||
input_device,
|
||||
input_stream_params,
|
||||
output_device,
|
||||
output_stream_params,
|
||||
latency,
|
||||
Some(data_cb_c),
|
||||
Some(state_cb_c),
|
||||
user_ptr,
|
||||
)
|
||||
.and_then(|stream| {
|
||||
if !self.streams.has_available() {
|
||||
trace!(
|
||||
"server connection ran out of stream slots. reserving {} more.",
|
||||
STREAM_CONN_CHUNK_SIZE
|
||||
);
|
||||
self.streams.reserve_exact(STREAM_CONN_CHUNK_SIZE);
|
||||
}
|
||||
|
||||
input_shm.write(real_input).unwrap();
|
||||
let stm_tok = match self.streams.vacant_entry() {
|
||||
Some(entry) => {
|
||||
debug!("Registering stream {:?}", entry.index(),);
|
||||
|
||||
let r = rpc_data
|
||||
.call(CallbackReq::Data(
|
||||
output.len() as isize,
|
||||
output_frame_size as usize,
|
||||
))
|
||||
.wait();
|
||||
|
||||
match r {
|
||||
Ok(CallbackResp::Data(frames)) => {
|
||||
if frames >= 0 {
|
||||
let nbytes = frames as usize * output_frame_size as usize;
|
||||
let real_output = unsafe {
|
||||
trace!("Resize output to {}", nbytes);
|
||||
slice::from_raw_parts_mut(output.as_mut_ptr(), nbytes)
|
||||
};
|
||||
output_shm.read(&mut real_output[..nbytes]).unwrap();
|
||||
entry
|
||||
.insert(ServerStream {
|
||||
stream: ManuallyDrop::new(stream),
|
||||
cbs: ManuallyDrop::new(cbs),
|
||||
})
|
||||
.index()
|
||||
}
|
||||
frames
|
||||
}
|
||||
_ => {
|
||||
debug!("Unexpected message {:?} during data_callback", r);
|
||||
-1
|
||||
}
|
||||
}
|
||||
})
|
||||
.state_callback(move |state| {
|
||||
trace!("Stream state callback: {:?}", state);
|
||||
let r = rpc_state.call(CallbackReq::State(state.into())).wait();
|
||||
match r {
|
||||
Ok(CallbackResp::State) => {}
|
||||
_ => {
|
||||
debug!("Unexpected message {:?} during callback", r);
|
||||
}
|
||||
}
|
||||
});
|
||||
None => {
|
||||
// TODO: Turn into error
|
||||
panic!("Failed to insert stream into slab. No entries")
|
||||
}
|
||||
};
|
||||
|
||||
builder
|
||||
.init(context)
|
||||
.and_then(|stream| {
|
||||
if !self.streams.has_available() {
|
||||
trace!(
|
||||
"server connection ran out of stream slots. reserving {} more.",
|
||||
STREAM_CONN_CHUNK_SIZE
|
||||
);
|
||||
self.streams.reserve_exact(STREAM_CONN_CHUNK_SIZE);
|
||||
}
|
||||
|
||||
let stm_tok = match self.streams.vacant_entry() {
|
||||
Some(entry) => {
|
||||
debug!("Registering stream {:?}", entry.index(),);
|
||||
|
||||
entry.insert(stream).index()
|
||||
}
|
||||
None => {
|
||||
// TODO: Turn into error
|
||||
panic!("Failed to insert stream into slab. No entries")
|
||||
}
|
||||
};
|
||||
|
||||
Ok(ClientMessage::StreamCreated(StreamCreate {
|
||||
token: stm_tok,
|
||||
fds: [
|
||||
stm1.into_raw_fd(),
|
||||
input_file.into_raw_fd(),
|
||||
output_file.into_raw_fd(),
|
||||
],
|
||||
}))
|
||||
})
|
||||
.map_err(|e| e.into())
|
||||
Ok(ClientMessage::StreamCreated(StreamCreate {
|
||||
token: stm_tok,
|
||||
fds: [
|
||||
stm1.into_raw_fd(),
|
||||
input_file.into_raw_fd(),
|
||||
output_file.into_raw_fd(),
|
||||
],
|
||||
}))
|
||||
})
|
||||
.map_err(|e| e.into())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -467,3 +529,41 @@ pub extern "C" fn audioipc_server_stop(p: *mut c_void) {
|
|||
fn error(error: cubeb::Error) -> ClientMessage {
|
||||
ClientMessage::Error(error.raw_code())
|
||||
}
|
||||
|
||||
// C callable callbacks
|
||||
unsafe extern "C" fn data_cb_c(
|
||||
_: *mut ffi::cubeb_stream,
|
||||
user_ptr: *mut c_void,
|
||||
input_buffer: *const c_void,
|
||||
output_buffer: *mut c_void,
|
||||
nframes: c_long,
|
||||
) -> c_long {
|
||||
let ok = panic::catch_unwind(|| {
|
||||
let cbs = &mut *(user_ptr as *mut ServerStreamCallbacks);
|
||||
let input = if input_buffer.is_null() {
|
||||
&[]
|
||||
} else {
|
||||
slice::from_raw_parts(input_buffer as *const u8, nframes as usize)
|
||||
};
|
||||
let output: &mut [u8] = if output_buffer.is_null() {
|
||||
&mut []
|
||||
} else {
|
||||
slice::from_raw_parts_mut(output_buffer as *mut u8, nframes as usize)
|
||||
};
|
||||
cbs.data_callback(input, output) as c_long
|
||||
});
|
||||
ok.unwrap_or(0)
|
||||
}
|
||||
|
||||
unsafe extern "C" fn state_cb_c(
|
||||
_: *mut ffi::cubeb_stream,
|
||||
user_ptr: *mut c_void,
|
||||
state: ffi::cubeb_state,
|
||||
) {
|
||||
let ok = panic::catch_unwind(|| {
|
||||
let state = cubeb::State::from(state);
|
||||
let cbs = &mut *(user_ptr as *mut ServerStreamCallbacks);
|
||||
cbs.state_callback(state);
|
||||
});
|
||||
ok.expect("State callback panicked");
|
||||
}
|
||||
|
|
|
@ -5,4 +5,4 @@ Makefile.in build files for the Mozilla build system.
|
|||
|
||||
The cubeb-pulse-rs git repository is: https://github.com/djg/cubeb-pulse-rs.git
|
||||
|
||||
The git commit ID used was 55ce985ad6c53049355907e3df09f172827aecfd (2018-03-29 13:31:04 +1000)
|
||||
The git commit ID used was f90aecf00ed6e5c67f593b3ecf412a8f3ffc0b1f (2018-04-18 08:06:35 +1000)
|
||||
|
|
|
@ -25,6 +25,7 @@ pub struct DefaultInfo {
|
|||
|
||||
pub const PULSE_OPS: Ops = capi_new!(PulseContext, PulseStream);
|
||||
|
||||
#[repr(C)]
|
||||
#[derive(Debug)]
|
||||
pub struct PulseContext {
|
||||
_ops: *const Ops,
|
||||
|
|
|
@ -96,6 +96,7 @@ impl Drop for Device {
|
|||
}
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
#[derive(Debug)]
|
||||
pub struct PulseStream<'ctx> {
|
||||
context: &'ctx PulseContext,
|
||||
|
|
|
@ -1374,6 +1374,7 @@ public class BrowserApp extends GeckoApp
|
|||
}
|
||||
|
||||
MmaDelegate.track(MmaDelegate.RESUMED_FROM_BACKGROUND);
|
||||
MmaDelegate.notifyDefaultBrowserStatus(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -16,6 +16,8 @@ import android.util.Log;
|
|||
|
||||
import java.lang.ref.WeakReference;
|
||||
|
||||
import static org.mozilla.gecko.AppConstants.Versions;
|
||||
|
||||
public class AudioFocusAgent implements Tabs.OnTabsChangedListener {
|
||||
private static final String LOGTAG = "AudioFocusAgent";
|
||||
|
||||
|
@ -201,6 +203,12 @@ public class AudioFocusAgent implements Tabs.OnTabsChangedListener {
|
|||
}
|
||||
|
||||
private void notifyMediaControlService(String action) {
|
||||
if (Versions.preLollipop) {
|
||||
// The notification only works from Lollipop onwards (at least until we try using
|
||||
// the support library version), so there's no point in starting the service.
|
||||
return;
|
||||
}
|
||||
|
||||
Intent intent = new Intent(mContext, MediaControlService.class);
|
||||
intent.setAction(action);
|
||||
mContext.startService(intent);
|
||||
|
|
|
@ -81,7 +81,6 @@ public class MediaControlService extends Service {
|
|||
@Override
|
||||
public void onCreate() {
|
||||
initialize();
|
||||
mHeadSetStateReceiver = new HeadSetStateReceiver().registerReceiver(getApplicationContext());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -110,8 +109,12 @@ public class MediaControlService extends Service {
|
|||
}
|
||||
|
||||
private void initialize() {
|
||||
if (mInitialize ||
|
||||
!isAndroidVersionLollipopOrHigher()) {
|
||||
if (mInitialize) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!isAndroidVersionLollipopOrHigher()) {
|
||||
stopSelf();
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -126,6 +129,8 @@ public class MediaControlService extends Service {
|
|||
coverSize = (int) getResources().getDimension(R.dimen.notification_media_cover);
|
||||
minCoverSize = getResources().getDimensionPixelSize(R.dimen.favicon_bg);
|
||||
|
||||
mHeadSetStateReceiver = new HeadSetStateReceiver().registerReceiver(getApplicationContext());
|
||||
|
||||
mInitialize = true;
|
||||
}
|
||||
|
||||
|
|
|
@ -29,7 +29,6 @@ import org.mozilla.gecko.preferences.GeckoPreferences;
|
|||
import org.mozilla.gecko.switchboard.SwitchBoard;
|
||||
import org.mozilla.gecko.util.ContextUtils;
|
||||
|
||||
import java.lang.ref.WeakReference;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
|
@ -50,7 +49,7 @@ public class MmaDelegate {
|
|||
public static final String RESUMED_FROM_BACKGROUND = "E_Resumed_From_Background";
|
||||
public static final String NEW_TAB = "E_Opened_New_Tab";
|
||||
public static final String DISMISS_ONBOARDING = "E_Dismiss_Onboarding";
|
||||
|
||||
public static final String CHANGED_DEFAULT_TO_FENNEC = "E_Changed_Default_To_Fennec";
|
||||
|
||||
public static final String USER_ATT_FOCUS_INSTALLED = "Focus Installed";
|
||||
public static final String USER_ATT_KLAR_INSTALLED = "Klar Installed";
|
||||
|
@ -66,13 +65,15 @@ public class MmaDelegate {
|
|||
private static final String TAG = "MmaDelegate";
|
||||
|
||||
public static final String KEY_ANDROID_PREF_STRING_LEANPLUM_DEVICE_ID = "android.not_a_preference.leanplum.device_id";
|
||||
private static final String KEY_ANDROID_PREF_BOOLEAN_FENNEC_IS_DEFAULT = "android.not_a_preference.fennec.default.browser.status";
|
||||
|
||||
private static final String DEBUG_LEANPLUM_DEVICE_ID = "8effda84-99df-11e7-abc4-cec278b6b50a";
|
||||
|
||||
private static final MmaInterface mmaHelper = MmaConstants.getMma();
|
||||
private static WeakReference<Context> applicationContext;
|
||||
private static Context applicationContext;
|
||||
|
||||
public static void init(Activity activity) {
|
||||
applicationContext = new WeakReference<>(activity.getApplicationContext());
|
||||
applicationContext = activity.getApplicationContext();
|
||||
// Since user attributes are gathered in Fennec, not in MMA implementation,
|
||||
// we gather the information here then pass to mmaHelper.init()
|
||||
// Note that generateUserAttribute always return a non null HashMap.
|
||||
|
@ -110,15 +111,35 @@ public class MmaDelegate {
|
|||
return attributes;
|
||||
}
|
||||
|
||||
public static void notifyDefaultBrowserStatus(Activity activity) {
|
||||
if (!isMmaEnabled(activity)) {
|
||||
return;
|
||||
}
|
||||
|
||||
final SharedPreferences sharedPreferences = activity.getPreferences(Context.MODE_PRIVATE);
|
||||
final boolean isFennecDefaultBrowser = isDefaultBrowser(activity);
|
||||
|
||||
// Only if this is not the first run of LeanPlum and we previously tracked default browser status
|
||||
// we can check for changes
|
||||
if (sharedPreferences.contains(KEY_ANDROID_PREF_BOOLEAN_FENNEC_IS_DEFAULT)) {
|
||||
// Will only inform LeanPlum of the event if Fennec was not previously the default browser
|
||||
if (!sharedPreferences.getBoolean(KEY_ANDROID_PREF_BOOLEAN_FENNEC_IS_DEFAULT, true) && isFennecDefaultBrowser) {
|
||||
track(CHANGED_DEFAULT_TO_FENNEC);
|
||||
}
|
||||
}
|
||||
|
||||
sharedPreferences.edit().putBoolean(KEY_ANDROID_PREF_BOOLEAN_FENNEC_IS_DEFAULT, isFennecDefaultBrowser).apply();
|
||||
}
|
||||
|
||||
public static void track(String event) {
|
||||
if (applicationContext != null && isMmaEnabled(applicationContext.get())) {
|
||||
if (applicationContext != null && isMmaEnabled(applicationContext)) {
|
||||
mmaHelper.event(event);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static void track(String event, long value) {
|
||||
if (applicationContext != null && isMmaEnabled(applicationContext.get())) {
|
||||
if (applicationContext != null && isMmaEnabled(applicationContext)) {
|
||||
mmaHelper.event(event, value);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -282,6 +282,13 @@
|
|||
<!ENTITY pref_whats_new_notification "What\'s new in &brandShortName;">
|
||||
<!ENTITY pref_whats_new_notification_summary "Learn about new features after an update">
|
||||
|
||||
<!-- Localization note (pref_feature_tips_notification): Title of a new toggleable setting in Settings-Notifications screen.
|
||||
Similar to the already existing "pref_whats_new_notification"-->
|
||||
<!ENTITY pref_feature_tips_notification "Product and feature tips">
|
||||
<!-- Localization note (pref_feature_tips_notification_summary): Description of a new toggleable setting in Settings-Notifications screen.
|
||||
Similar to the already existing "pref_whats_new_notification_summary"-->
|
||||
<!ENTITY pref_feature_tips_notification_summary "Learn more about using &brandShortName; and other &vendorShortName; products">
|
||||
|
||||
<!-- Localization note (pref_category_experimental): Title of a sub category in the 'advanced' category
|
||||
for experimental features. -->
|
||||
<!ENTITY pref_category_experimental "Experimental features">
|
||||
|
|
|
@ -225,6 +225,10 @@
|
|||
<string name="pref_whats_new_notification">&pref_whats_new_notification;</string>
|
||||
<string name="pref_whats_new_notification_summary">&pref_whats_new_notification_summary;</string>
|
||||
|
||||
|
||||
<string name="pref_feature_tips_notification">&pref_feature_tips_notification;</string>
|
||||
<string name="pref_feature_tips_notification_summary">&pref_feature_tips_notification_summary;</string>
|
||||
|
||||
<string name="pref_category_experimental">&pref_category_experimental;</string>
|
||||
|
||||
<string name="pref_custom_tabs">&pref_custom_tabs2;</string>
|
||||
|
|
|
@ -160,6 +160,10 @@ List of current Events related data that is sent:
|
|||
{
|
||||
"event" : "E_Resumed_From_Background"
|
||||
}
|
||||
* User set Fennec as default browser and resumed the app
|
||||
{
|
||||
"event" : "E_Changed_Default_To_Fennec"
|
||||
}
|
||||
|
||||
Deep Links:
|
||||
Deep links are actions that can point Fennec to open certain pages or load features such as `show bookmark list` or
|
||||
|
|
|
@ -145,6 +145,13 @@ VARCACHE_PREF(
|
|||
// Layout prefs
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
// Is parallel CSS parsing enabled?
|
||||
VARCACHE_PREF(
|
||||
"layout.css.parsing.parallel",
|
||||
layout_css_parsing_parallel,
|
||||
bool, false
|
||||
)
|
||||
|
||||
// Is support for the font-display @font-face descriptor enabled?
|
||||
VARCACHE_PREF(
|
||||
"layout.css.font-display.enabled",
|
||||
|
|
|
@ -855,7 +855,7 @@ pref("gfx.compositor.glcontext.opaque", false);
|
|||
|
||||
pref("gfx.webrender.highlight-painted-layers", false);
|
||||
pref("gfx.webrender.async-scene-build", false);
|
||||
pref("gfx.webrender.blob-images", 1);
|
||||
pref("gfx.webrender.blob-images", true);
|
||||
pref("gfx.webrender.blob.invalidation", true);
|
||||
pref("gfx.webrender.hit-test", true);
|
||||
|
||||
|
@ -2675,11 +2675,7 @@ pref("mousewheel.min_line_scroll_amount", 5);
|
|||
// scroll is converted to a horizontal scroll for that target.
|
||||
// Note that auto-dir only takes effect for |mousewheel.*.action|s and
|
||||
// |mousewheel.*.action.override_x|s whose values are 1.
|
||||
#ifdef EARLY_BETA_OR_EARLIER
|
||||
pref("mousewheel.autodir.enabled", true);
|
||||
#else
|
||||
pref("mousewheel.autodir.enabled", false);
|
||||
#endif
|
||||
// When a wheel scroll is converted due to auto-dir, which side the converted
|
||||
// scroll goes towards is decided by one thing called "honoured target". If the
|
||||
// content of the honoured target horizontally starts from right to left, then
|
||||
|
@ -4561,7 +4557,7 @@ pref("image.mem.animated.use_heap", false);
|
|||
|
||||
// Decodes images into shared memory to allow direct use in separate
|
||||
// rendering processes. Only applicable with WebRender.
|
||||
pref("image.mem.shared", 1);
|
||||
pref("image.mem.shared", true);
|
||||
|
||||
// Allows image locking of decoded image data in content processes.
|
||||
pref("image.mem.allow_locking_in_content_processes", true);
|
||||
|
|
|
@ -0,0 +1,140 @@
|
|||
# coding=utf8
|
||||
|
||||
# Any copyright is dedicated to the Public Domain.
|
||||
# http://creativecommons.org/publicdomain/zero/1.0/
|
||||
|
||||
from __future__ import absolute_import
|
||||
import fluent.syntax.ast as FTL
|
||||
from fluent.migrate.transforms import REPLACE
|
||||
from fluent.migrate.helpers import MESSAGE_REFERENCE
|
||||
from fluent.migrate import COPY, CONCAT
|
||||
|
||||
|
||||
# Custom extension of the CONCAT migration tailored to concat
|
||||
# two strings separated by a placeable.
|
||||
class CONCAT_BEFORE_AFTER(CONCAT):
|
||||
def __call__(self, ctx):
|
||||
assert len(self.elements) == 3
|
||||
pattern_before, middle, pattern_after = self.elements
|
||||
elem_before = pattern_before.elements[0]
|
||||
elem_after = pattern_after.elements[0]
|
||||
|
||||
if isinstance(elem_before, FTL.TextElement) and \
|
||||
len(elem_before.value) > 0 and \
|
||||
elem_before.value[-1] != " ":
|
||||
elem_before.value += " "
|
||||
if isinstance(elem_after, FTL.TextElement) and \
|
||||
len(elem_after.value) > 0 and \
|
||||
elem_after.value[0] != " ":
|
||||
elem_after.value = " " + elem_after.value
|
||||
return super(CONCAT_BEFORE_AFTER, self).__call__(ctx)
|
||||
|
||||
def migrate(ctx):
|
||||
"""Bug 1453540 - Migrate remaining DTDs in Preferences to Fluent, part {index}."""
|
||||
|
||||
ctx.add_transforms(
|
||||
'browser/browser/preferences/preferences.ftl',
|
||||
'browser/browser/preferences/preferences.ftl',
|
||||
[
|
||||
FTL.Message(
|
||||
id=FTL.Identifier('translate-attribution'),
|
||||
value=CONCAT_BEFORE_AFTER(
|
||||
COPY(
|
||||
'browser/chrome/browser/preferences/content.dtd',
|
||||
'translation.options.attribution.beforeLogo',
|
||||
),
|
||||
FTL.TextElement('<img data-l10n-name="logo"/>'),
|
||||
COPY(
|
||||
'browser/chrome/browser/preferences/content.dtd',
|
||||
'translation.options.attribution.afterLogo',
|
||||
),
|
||||
)
|
||||
),
|
||||
FTL.Message(
|
||||
id=FTL.Identifier('sync-mobile-promo'),
|
||||
value=CONCAT(
|
||||
COPY(
|
||||
'browser/chrome/browser/preferences/sync.dtd',
|
||||
'mobilePromo3.start',
|
||||
),
|
||||
FTL.TextElement('<img data-l10n-name="android-icon"/> <a data-l10n-name="android-link">'),
|
||||
COPY(
|
||||
'browser/chrome/browser/preferences/sync.dtd',
|
||||
'mobilePromo3.androidLink',
|
||||
),
|
||||
FTL.TextElement('</a>'),
|
||||
COPY(
|
||||
'browser/chrome/browser/preferences/sync.dtd',
|
||||
'mobilePromo3.iOSBefore',
|
||||
),
|
||||
FTL.TextElement('<img data-l10n-name="ios-icon"/> <a data-l10n-name="ios-link">'),
|
||||
COPY(
|
||||
'browser/chrome/browser/preferences/sync.dtd',
|
||||
'mobilePromo3.iOSLink',
|
||||
),
|
||||
FTL.TextElement('</a>'),
|
||||
COPY(
|
||||
'browser/chrome/browser/preferences/sync.dtd',
|
||||
'mobilePromo3.end',
|
||||
),
|
||||
)
|
||||
),
|
||||
FTL.Message(
|
||||
id=FTL.Identifier('history-remember-label'),
|
||||
value=REPLACE(
|
||||
'browser/chrome/browser/preferences/privacy.dtd',
|
||||
'historyHeader2.pre.label',
|
||||
{
|
||||
'&brandShortName;': MESSAGE_REFERENCE(
|
||||
'-brand-short-name'
|
||||
)
|
||||
}
|
||||
),
|
||||
attributes=[
|
||||
FTL.Attribute(
|
||||
FTL.Identifier('accesskey'),
|
||||
COPY(
|
||||
'browser/chrome/browser/preferences/privacy.dtd',
|
||||
'historyHeader2.pre.accesskey',
|
||||
)
|
||||
)
|
||||
]
|
||||
),
|
||||
FTL.Message(
|
||||
id=FTL.Identifier('history-remember-option-all'),
|
||||
attributes=[
|
||||
FTL.Attribute(
|
||||
FTL.Identifier('label'),
|
||||
COPY(
|
||||
'browser/chrome/browser/preferences/privacy.dtd',
|
||||
'historyHeader.remember.label',
|
||||
)
|
||||
)
|
||||
]
|
||||
),
|
||||
FTL.Message(
|
||||
id=FTL.Identifier('history-remember-option-never'),
|
||||
attributes=[
|
||||
FTL.Attribute(
|
||||
FTL.Identifier('label'),
|
||||
COPY(
|
||||
'browser/chrome/browser/preferences/privacy.dtd',
|
||||
'historyHeader.dontremember.label',
|
||||
)
|
||||
)
|
||||
]
|
||||
),
|
||||
FTL.Message(
|
||||
id=FTL.Identifier('history-remember-option-custom'),
|
||||
attributes=[
|
||||
FTL.Attribute(
|
||||
FTL.Identifier('label'),
|
||||
COPY(
|
||||
'browser/chrome/browser/preferences/privacy.dtd',
|
||||
'historyHeader.custom.label',
|
||||
)
|
||||
)
|
||||
]
|
||||
),
|
||||
]
|
||||
)
|
|
@ -136,7 +136,12 @@ class ProcessExecutionMixin(LoggingMixin):
|
|||
ignore_children=ignore_children)
|
||||
p.run()
|
||||
p.processOutput()
|
||||
status = p.wait()
|
||||
status = None
|
||||
while status is None:
|
||||
try:
|
||||
status = p.wait()
|
||||
except KeyboardInterrupt:
|
||||
status = p.kill()
|
||||
|
||||
if ensure_exit_code is False:
|
||||
return status
|
||||
|
|
|
@ -65,6 +65,7 @@ class BackendTupfile(object):
|
|||
self.rules_included = False
|
||||
self.defines = []
|
||||
self.host_defines = []
|
||||
self.outputs = set()
|
||||
self.delayed_generated_files = []
|
||||
self.delayed_installed_files = []
|
||||
self.per_source_flags = defaultdict(list)
|
||||
|
@ -116,6 +117,8 @@ class BackendTupfile(object):
|
|||
'extra_outputs': ' | ' + ' '.join(extra_outputs) if extra_outputs else '',
|
||||
})
|
||||
|
||||
self.outputs.update(outputs)
|
||||
|
||||
def symlink_rule(self, source, output=None, output_group=None):
|
||||
outputs = [output] if output else [mozpath.basename(source)]
|
||||
if output_group:
|
||||
|
@ -172,6 +175,18 @@ class BackendTupfile(object):
|
|||
def close(self):
|
||||
return self.fh.close()
|
||||
|
||||
def requires_delay(self, inputs):
|
||||
# We need to delay the generated file rule in the Tupfile until the
|
||||
# generated inputs in the current directory are processed. We do this by
|
||||
# checking all ObjDirPaths to make sure they are in
|
||||
# self.outputs, or are in other directories.
|
||||
for f in inputs:
|
||||
if (isinstance(f, ObjDirPath) and
|
||||
f.target_basename not in self.outputs and
|
||||
mozpath.dirname(f.full_path) == self.objdir):
|
||||
return True
|
||||
return False
|
||||
|
||||
@property
|
||||
def diff(self):
|
||||
return self.fh.diff
|
||||
|
@ -208,18 +223,6 @@ class TupOnly(CommonBackend, PartialBackend):
|
|||
self._built_in_addons = set()
|
||||
self._built_in_addons_file = 'dist/bin/browser/chrome/browser/content/browser/built_in_addons.json'
|
||||
|
||||
# application.ini.h is a special case since we need to process
|
||||
# the FINAL_TARGET_PP_FILES for application.ini before running
|
||||
# the GENERATED_FILES script, and tup doesn't handle the rules
|
||||
# out of order. Similarly, dependentlibs.list uses libxul as
|
||||
# an input, so must be written after the rule for libxul.
|
||||
self._delayed_files = (
|
||||
'application.ini.h',
|
||||
'dependentlibs.list',
|
||||
'dependentlibs.list.gtest'
|
||||
)
|
||||
|
||||
|
||||
def _get_backend_file(self, relobjdir):
|
||||
objdir = mozpath.normpath(mozpath.join(self.environment.topobjdir, relobjdir))
|
||||
if objdir not in self._backend_files:
|
||||
|
@ -390,7 +393,7 @@ class TupOnly(CommonBackend, PartialBackend):
|
|||
if any(mozpath.match(f, p) for p in skip_files):
|
||||
return False
|
||||
|
||||
if any([f in obj.outputs for f in self._delayed_files]):
|
||||
if backend_file.requires_delay(obj.inputs):
|
||||
backend_file.delayed_generated_files.append(obj)
|
||||
else:
|
||||
self._process_generated_file(backend_file, obj)
|
||||
|
@ -465,8 +468,8 @@ class TupOnly(CommonBackend, PartialBackend):
|
|||
gen_method(backend_file)
|
||||
for obj in backend_file.delayed_generated_files:
|
||||
self._process_generated_file(backend_file, obj)
|
||||
for path, output in backend_file.delayed_installed_files:
|
||||
backend_file.symlink_rule(path, output=output)
|
||||
for path, output, output_group in backend_file.delayed_installed_files:
|
||||
backend_file.symlink_rule(path, output=output, output_group=output_group)
|
||||
with self._write_file(fh=backend_file):
|
||||
pass
|
||||
|
||||
|
@ -490,7 +493,7 @@ class TupOnly(CommonBackend, PartialBackend):
|
|||
fh.write('topsrcdir = $(MOZ_OBJ_ROOT)/%s\n' % (
|
||||
os.path.relpath(self.environment.topsrcdir, self.environment.topobjdir)
|
||||
))
|
||||
fh.write('PYTHON = $(MOZ_OBJ_ROOT)/_virtualenv/bin/python -B\n')
|
||||
fh.write('PYTHON = PYTHONDONTWRITEBYTECODE=1 $(MOZ_OBJ_ROOT)/_virtualenv/bin/python\n')
|
||||
fh.write('PYTHON_PATH = $(PYTHON) $(topsrcdir)/config/pythonpath.py\n')
|
||||
fh.write('PLY_INCLUDE = -I$(topsrcdir)/other-licenses/ply\n')
|
||||
fh.write('IDL_PARSER_DIR = $(topsrcdir)/xpcom/idl-parser\n')
|
||||
|
@ -625,8 +628,9 @@ class TupOnly(CommonBackend, PartialBackend):
|
|||
output = mozpath.join('$(MOZ_OBJ_ROOT)', target, path,
|
||||
f.target_basename)
|
||||
gen_backend_file = self._get_backend_file(f.context.relobjdir)
|
||||
if f.target_basename in self._delayed_files:
|
||||
gen_backend_file.delayed_installed_files.append((f.full_path, output))
|
||||
if gen_backend_file.requires_delay([f]):
|
||||
output_group = self._installed_files if f.target_basename.endswith('.h') else None
|
||||
gen_backend_file.delayed_installed_files.append((f.full_path, output, output_group))
|
||||
else:
|
||||
gen_backend_file.symlink_rule(f.full_path, output=output,
|
||||
output_group=self._installed_files)
|
||||
|
@ -670,6 +674,7 @@ class TupOnly(CommonBackend, PartialBackend):
|
|||
'-I$(IDL_PARSER_CACHE_DIR)',
|
||||
'$(topsrcdir)/python/mozbuild/mozbuild/action/xpidl-process.py',
|
||||
'--cache-dir', '$(IDL_PARSER_CACHE_DIR)',
|
||||
'--bindings-conf', '$(topsrcdir)/dom/bindings/Bindings.conf',
|
||||
'$(DIST)/idl',
|
||||
'$(DIST)/include',
|
||||
'$(DIST)/xpcrs',
|
||||
|
@ -695,20 +700,19 @@ class TupOnly(CommonBackend, PartialBackend):
|
|||
extra_outputs=[self._installed_files],
|
||||
)
|
||||
|
||||
cpp_backend_file = self._get_backend_file('xpcom/typelib/xpt')
|
||||
cpp_backend_file = self._get_backend_file('xpcom/reflect/xptinfo')
|
||||
cpp_backend_file.export_shell()
|
||||
cpp_backend_file.rule(
|
||||
inputs=all_xpts,
|
||||
display='XPIDL linkgen %o',
|
||||
display='XPIDL xptcodegen.py %o',
|
||||
cmd=[
|
||||
'$(PYTHON_PATH)',
|
||||
'$(PLY_INCLUDE)',
|
||||
'$(topsrcdir)/xpcom/typelib/xpt/tools/xpt.py',
|
||||
'linkgen',
|
||||
'XPTInfo.cpp',
|
||||
'$(topsrcdir)/xpcom/reflect/xptinfo/xptcodegen.py',
|
||||
'%o',
|
||||
'%f',
|
||||
],
|
||||
outputs=['XPTInfo.cpp'],
|
||||
outputs=['xptdata.cpp'],
|
||||
)
|
||||
|
||||
def _preprocess(self, backend_file, input_file, destdir=None, target=None):
|
||||
|
|
|
@ -53,12 +53,10 @@ let SyncedTabsInternal = {
|
|||
icon = tab.icon;
|
||||
}
|
||||
if (!icon) {
|
||||
try {
|
||||
icon = (await PlacesUtils.promiseFaviconLinkUrl(url)).spec;
|
||||
} catch (ex) { /* no favicon avaiable */ }
|
||||
}
|
||||
if (!icon) {
|
||||
icon = "";
|
||||
// By not specifying a size the favicon service will pick the default,
|
||||
// that is usually set through setDefaultIconURIPreferredSize by the
|
||||
// first browser window. Commonly it's 16px at current dpi.
|
||||
icon = "page-icon:" + url;
|
||||
}
|
||||
return {
|
||||
type: "tab",
|
||||
|
|
|
@ -2,20 +2,20 @@
|
|||
"next": null,
|
||||
"results": [
|
||||
{
|
||||
"name": "Unsigned Test XPI",
|
||||
"name": "Tet Webext XPI",
|
||||
"type": "extension",
|
||||
"guid": "unsigned-xpi@tests.mozilla.org",
|
||||
"guid": "test-webext@quality.mozilla.org",
|
||||
"current_version": {
|
||||
"version": "1.0",
|
||||
"files": [
|
||||
{
|
||||
"platform": "all",
|
||||
"size": 452,
|
||||
"url": "http://127.0.0.1:4567/addons/unsigned.xpi"
|
||||
"size": 3412,
|
||||
"url": "http://127.0.0.1:4567/addons/webextension.xpi"
|
||||
}
|
||||
]
|
||||
},
|
||||
"last_updated": "2011-09-05T20:42:09Z"
|
||||
"last_updated": "2018-04-17T18:24:42Z"
|
||||
}
|
||||
]
|
||||
}
|
Двоичные данные
services/sync/tests/tps/addons/unsigned.xpi
Двоичные данные
services/sync/tests/tps/addons/unsigned.xpi
Двоичный файл не отображается.
Двоичный файл не отображается.
|
@ -22,7 +22,7 @@
|
|||
"test_client_wipe.js",
|
||||
"test_special_tabs.js",
|
||||
"test_addon_restartless_xpi.js",
|
||||
"test_addon_nonrestartless_xpi.js",
|
||||
"test_addon_webext_xpi.js",
|
||||
"test_addon_reconciling.js",
|
||||
"test_addon_wipe.js",
|
||||
"test_existing_bookmarks.js",
|
||||
|
|
|
@ -1,121 +0,0 @@
|
|||
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
// This test verifies that install of extensions that require restart
|
||||
// syncs between profiles.
|
||||
EnableEngines(["addons"]);
|
||||
|
||||
var phases = {
|
||||
"phase01": "profile1",
|
||||
"phase02": "profile1",
|
||||
"phase03": "profile2",
|
||||
"phase04": "profile2",
|
||||
"phase05": "profile1",
|
||||
"phase06": "profile1",
|
||||
"phase07": "profile2",
|
||||
"phase08": "profile2",
|
||||
"phase09": "profile1",
|
||||
"phase10": "profile1",
|
||||
"phase11": "profile2",
|
||||
"phase12": "profile2",
|
||||
"phase13": "profile1",
|
||||
"phase14": "profile1",
|
||||
"phase15": "profile2",
|
||||
"phase16": "profile2"
|
||||
};
|
||||
|
||||
const id = "unsigned-xpi@tests.mozilla.org";
|
||||
|
||||
Phase("phase01", [
|
||||
[Addons.verifyNot, [id]],
|
||||
[Addons.install, [id]],
|
||||
[Sync],
|
||||
[Addons.skipValidation] // Validation disabled due to bug 1427835
|
||||
]);
|
||||
Phase("phase02", [
|
||||
[Addons.verify, [id], STATE_ENABLED],
|
||||
[Sync],
|
||||
[Addons.skipValidation] // Validation disabled due to bug 1427835
|
||||
]);
|
||||
Phase("phase03", [
|
||||
[Addons.verifyNot, [id]],
|
||||
[Sync],
|
||||
[Addons.skipValidation] // Validation disabled due to bug 1427835
|
||||
]);
|
||||
Phase("phase04", [
|
||||
[Addons.verify, [id], STATE_ENABLED],
|
||||
[Sync],
|
||||
[Addons.skipValidation] // Validation disabled due to bug 1427835
|
||||
]);
|
||||
|
||||
// Now we disable the add-on
|
||||
Phase("phase05", [
|
||||
[EnsureTracking],
|
||||
[Addons.setEnabled, [id], STATE_DISABLED],
|
||||
[Sync],
|
||||
[Addons.skipValidation] // Validation disabled due to bug 1380472
|
||||
]);
|
||||
Phase("phase06", [
|
||||
[Addons.verify, [id], STATE_DISABLED],
|
||||
[Sync],
|
||||
[Addons.skipValidation] // Validation disabled due to bug 1380472
|
||||
]);
|
||||
Phase("phase07", [
|
||||
[Addons.verify, [id], STATE_ENABLED],
|
||||
[Sync],
|
||||
[Addons.skipValidation] // Validation disabled due to bug 1380472
|
||||
]);
|
||||
Phase("phase08", [
|
||||
[Addons.verify, [id], STATE_DISABLED],
|
||||
[Sync],
|
||||
[Addons.skipValidation] // Validation disabled due to bug 1380472
|
||||
]);
|
||||
|
||||
// Now we re-enable it again.
|
||||
Phase("phase09", [
|
||||
[EnsureTracking],
|
||||
[Addons.setEnabled, [id], STATE_ENABLED],
|
||||
[Sync],
|
||||
[Addons.skipValidation] // Validation disabled due to bug 1427835
|
||||
]);
|
||||
Phase("phase10", [
|
||||
[Addons.verify, [id], STATE_ENABLED],
|
||||
[Sync],
|
||||
[Addons.skipValidation] // Validation disabled due to bug 1427835
|
||||
]);
|
||||
Phase("phase11", [
|
||||
[Addons.verify, [id], STATE_DISABLED],
|
||||
[Sync],
|
||||
[Addons.skipValidation] // Validation disabled due to bug 1427835
|
||||
]);
|
||||
Phase("phase12", [
|
||||
[Addons.verify, [id], STATE_ENABLED],
|
||||
[Sync],
|
||||
[Addons.skipValidation] // Validation disabled due to bug 1427835
|
||||
]);
|
||||
|
||||
// And we uninstall it
|
||||
|
||||
Phase("phase13", [
|
||||
[EnsureTracking],
|
||||
[Addons.verify, [id], STATE_ENABLED],
|
||||
[Addons.uninstall, [id]],
|
||||
[Sync],
|
||||
[Addons.skipValidation] // Validation disabled due to bug 1427835
|
||||
]);
|
||||
Phase("phase14", [
|
||||
[Addons.verifyNot, [id]],
|
||||
[Sync],
|
||||
[Addons.skipValidation] // Validation disabled due to bug 1427835
|
||||
]);
|
||||
Phase("phase15", [
|
||||
[Addons.verify, [id], STATE_ENABLED],
|
||||
[Sync],
|
||||
[Addons.skipValidation] // Validation disabled due to bug 1427835
|
||||
]);
|
||||
Phase("phase16", [
|
||||
[Addons.verifyNot, [id]],
|
||||
[Sync],
|
||||
[Addons.skipValidation] // Validation disabled due to bug 1427835
|
||||
]);
|
|
@ -0,0 +1,71 @@
|
|||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
// This test verifies that install of web extensions sync to other profiles.
|
||||
// It's more or less copied from test_addon_restartless_xpi with a different id.
|
||||
|
||||
EnableEngines(["addons"]);
|
||||
|
||||
var phases = {
|
||||
"phase01": "profile1",
|
||||
"phase02": "profile2",
|
||||
"phase03": "profile1",
|
||||
"phase04": "profile2",
|
||||
"phase05": "profile1",
|
||||
"phase06": "profile2",
|
||||
"phase07": "profile1",
|
||||
"phase08": "profile2"
|
||||
};
|
||||
|
||||
const id = "test-webext@quality.mozilla.org";
|
||||
|
||||
// Verify install is synced
|
||||
Phase("phase01", [
|
||||
[Addons.verifyNot, [id]],
|
||||
[Addons.install, [id]],
|
||||
[Addons.verify, [id], STATE_ENABLED],
|
||||
[Sync]
|
||||
]);
|
||||
Phase("phase02", [
|
||||
[Addons.verifyNot, [id]],
|
||||
[Sync],
|
||||
[Addons.verify, [id], STATE_ENABLED]
|
||||
]);
|
||||
|
||||
// Now disable and see that is is synced.
|
||||
Phase("phase03", [
|
||||
[EnsureTracking],
|
||||
[Addons.setEnabled, [id], STATE_DISABLED],
|
||||
[Addons.verify, [id], STATE_DISABLED],
|
||||
[Sync]
|
||||
]);
|
||||
Phase("phase04", [
|
||||
[Sync],
|
||||
[Addons.verify, [id], STATE_DISABLED]
|
||||
]);
|
||||
|
||||
// Enable and see it is synced.
|
||||
Phase("phase05", [
|
||||
[EnsureTracking],
|
||||
[Addons.setEnabled, [id], STATE_ENABLED],
|
||||
[Addons.verify, [id], STATE_ENABLED],
|
||||
[Sync]
|
||||
]);
|
||||
Phase("phase06", [
|
||||
[Sync],
|
||||
[Addons.verify, [id], STATE_ENABLED]
|
||||
]);
|
||||
|
||||
// Uninstall and see it is synced.
|
||||
Phase("phase07", [
|
||||
[EnsureTracking],
|
||||
[Addons.verify, [id], STATE_ENABLED],
|
||||
[Addons.uninstall, [id]],
|
||||
[Addons.verifyNot, [id]],
|
||||
[Sync]
|
||||
]);
|
||||
Phase("phase08", [
|
||||
[Addons.verify, [id], STATE_ENABLED],
|
||||
[Sync],
|
||||
[Addons.verifyNot, [id]]
|
||||
]);
|
|
@ -15,7 +15,7 @@ var phases = {
|
|||
};
|
||||
|
||||
const id1 = "restartless-xpi@tests.mozilla.org";
|
||||
const id2 = "unsigned-xpi@tests.mozilla.org";
|
||||
const id2 = "test-webext@quality.mozilla.org";
|
||||
|
||||
Phase("phase01", [
|
||||
[Addons.install, [id1]],
|
||||
|
|
|
@ -192,8 +192,8 @@ add_task(async function test_clientWithTabsIconsDisabled() {
|
|||
clients.sort((a, b) => { return a.name.localeCompare(b.name); });
|
||||
equal(clients[0].tabs.length, 1);
|
||||
equal(clients[0].tabs[0].url, "http://foo.com/");
|
||||
// expect the default favicon (empty string) due to the pref being false.
|
||||
equal(clients[0].tabs[0].icon, "");
|
||||
// Expect the default favicon due to the pref being false.
|
||||
equal(clients[0].tabs[0].icon, "page-icon:http://foo.com/");
|
||||
Services.prefs.clearUserPref("services.sync.syncedTabs.showRemoteIcons");
|
||||
});
|
||||
|
||||
|
|
|
@ -17,7 +17,7 @@ XPCOMUtils.defineLazyServiceGetter(this, "resProto",
|
|||
|
||||
const Cm = Components.manager.QueryInterface(Ci.nsIComponentRegistrar);
|
||||
|
||||
const CATMAN_CONTRACTID = "@mozilla.org/categorymanager;1";
|
||||
const CATMAN_CONTRACTID = "@mozilla.org/categorymanager;1";
|
||||
|
||||
const CATEGORY_NAME = "command-line-handler";
|
||||
const CATEGORY_ENTRY = "m-tps";
|
||||
|
@ -93,7 +93,7 @@ TPSCmdLine.prototype = {
|
|||
|
||||
function startup(data, reason) {
|
||||
TPSCmdLine.prototype.register();
|
||||
resProto.setSubstitution("tps", Services.io.newURI("resource", null, data.resourceURI));
|
||||
resProto.setSubstitution("tps", Services.io.newURI("resource/", null, data.resourceURI));
|
||||
}
|
||||
|
||||
function shutdown(data, reason) {
|
||||
|
|
|
@ -312,3 +312,9 @@ impl_threadsafe_refcount!(
|
|||
Gecko_AddRefSharedFontListArbitraryThread,
|
||||
Gecko_ReleaseSharedFontListArbitraryThread
|
||||
);
|
||||
|
||||
impl_threadsafe_refcount!(
|
||||
::gecko_bindings::structs::SheetLoadDataHolder,
|
||||
Gecko_AddRefSheetLoadDataHolderArbitraryThread,
|
||||
Gecko_ReleaseSheetLoadDataHolderArbitraryThread
|
||||
);
|
||||
|
|
|
@ -171,10 +171,9 @@ pub struct ImportRule {
|
|||
/// The `<url>` this `@import` rule is loading.
|
||||
pub url: CssUrl,
|
||||
|
||||
/// The stylesheet is always present.
|
||||
///
|
||||
/// It contains an empty list of rules and namespace set that is updated
|
||||
/// when it loads.
|
||||
/// The stylesheet is always present. However, in the case of gecko async
|
||||
/// parsing, we don't actually have a Gecko sheet at first, and so the
|
||||
/// ImportSheet just has stub behavior until it appears.
|
||||
pub stylesheet: ImportSheet,
|
||||
|
||||
/// The line and column of the rule's source code.
|
||||
|
|
|
@ -6,6 +6,7 @@ use cssparser::{ParseErrorKind, Parser, ParserInput, SourceLocation};
|
|||
use cssparser::ToCss as ParserToCss;
|
||||
use env_logger::Builder;
|
||||
use malloc_size_of::MallocSizeOfOps;
|
||||
use nsstring::nsCString;
|
||||
use selectors::{NthIndexCache, SelectorList};
|
||||
use selectors::matching::{MatchingContext, MatchingMode, matches_selector};
|
||||
use servo_arc::{Arc, ArcBorrow, RawOffsetArc};
|
||||
|
@ -92,7 +93,8 @@ use style::gecko_bindings::structs;
|
|||
use style::gecko_bindings::structs::{CallerType, CSSPseudoElementType, CompositeOperation};
|
||||
use style::gecko_bindings::structs::{Loader, LoaderReusableStyleSheets};
|
||||
use style::gecko_bindings::structs::{RawServoStyleRule, ComputedStyleStrong, RustString};
|
||||
use style::gecko_bindings::structs::{ServoStyleSheet, SheetLoadData, SheetParsingMode, nsAtom, nsCSSPropertyID};
|
||||
use style::gecko_bindings::structs::{ServoStyleSheet, SheetLoadData, SheetLoadDataHolder};
|
||||
use style::gecko_bindings::structs::{SheetParsingMode, nsAtom, nsCSSPropertyID};
|
||||
use style::gecko_bindings::structs::{nsCSSFontDesc, nsCSSCounterDesc};
|
||||
use style::gecko_bindings::structs::{nsRestyleHint, nsChangeHint, PropertyValuePair};
|
||||
use style::gecko_bindings::structs::AtomArray;
|
||||
|
@ -145,6 +147,7 @@ use style::stylesheets::{DocumentRule, FontFaceRule, FontFeatureValuesRule, Impo
|
|||
use style::stylesheets::{KeyframesRule, MediaRule, NamespaceRule, Origin, OriginSet, PageRule};
|
||||
use style::stylesheets::{StyleRule, StylesheetContents, SupportsRule};
|
||||
use style::stylesheets::StylesheetLoader as StyleStylesheetLoader;
|
||||
use style::stylesheets::import_rule::ImportSheet;
|
||||
use style::stylesheets::keyframes_rule::{Keyframe, KeyframeSelector, KeyframesStepValue};
|
||||
use style::stylesheets::supports_rule::parse_condition_or_declaration;
|
||||
use style::stylist::{add_size_of_ua_cache, AuthorStylesEnabled, RuleInclusion, Stylist};
|
||||
|
@ -163,7 +166,7 @@ use style::values::specified::gecko::{IntersectionObserverRootMargin, PixelOrPer
|
|||
use style::values::specified::source_size_list::SourceSizeList;
|
||||
use style_traits::{CssWriter, ParsingMode, StyleParseErrorKind, ToCss};
|
||||
use super::error_reporter::ErrorReporter;
|
||||
use super::stylesheet_loader::StylesheetLoader;
|
||||
use super::stylesheet_loader::{AsyncStylesheetParser, StylesheetLoader};
|
||||
|
||||
/*
|
||||
* For Gecko->Servo function calls, we need to redeclare the same signature that was declared in
|
||||
|
@ -1122,6 +1125,15 @@ pub extern "C" fn Servo_StyleSheet_Empty(mode: SheetParsingMode) -> RawServoStyl
|
|||
).into_strong()
|
||||
}
|
||||
|
||||
fn mode_to_origin(mode: SheetParsingMode) -> Origin {
|
||||
match mode {
|
||||
SheetParsingMode::eAuthorSheetFeatures => Origin::Author,
|
||||
SheetParsingMode::eUserSheetFeatures => Origin::User,
|
||||
SheetParsingMode::eAgentSheetFeatures => Origin::UserAgent,
|
||||
SheetParsingMode::eSafeAgentSheetFeatures => Origin::UserAgent,
|
||||
}
|
||||
}
|
||||
|
||||
/// Note: The load_data corresponds to this sheet, and is passed as the parent
|
||||
/// load data for child sheet loads. It may be null for certain cases where we
|
||||
/// know we won't have child loads.
|
||||
|
@ -1140,13 +1152,6 @@ pub extern "C" fn Servo_StyleSheet_FromUTF8Bytes(
|
|||
let global_style_data = &*GLOBAL_STYLE_DATA;
|
||||
let input: &str = unsafe { (*bytes).as_str_unchecked() };
|
||||
|
||||
let origin = match mode {
|
||||
SheetParsingMode::eAuthorSheetFeatures => Origin::Author,
|
||||
SheetParsingMode::eUserSheetFeatures => Origin::User,
|
||||
SheetParsingMode::eAgentSheetFeatures => Origin::UserAgent,
|
||||
SheetParsingMode::eSafeAgentSheetFeatures => Origin::UserAgent,
|
||||
};
|
||||
|
||||
let reporter = ErrorReporter::new(stylesheet, loader, extra_data);
|
||||
let url_data = unsafe { RefPtr::from_ptr_ref(&extra_data) };
|
||||
let loader = if loader.is_null() {
|
||||
|
@ -1163,12 +1168,44 @@ pub extern "C" fn Servo_StyleSheet_FromUTF8Bytes(
|
|||
|
||||
|
||||
Arc::new(StylesheetContents::from_str(
|
||||
input, url_data.clone(), origin,
|
||||
input, url_data.clone(), mode_to_origin(mode),
|
||||
&global_style_data.shared_lock, loader, &reporter,
|
||||
quirks_mode.into(), line_number_offset)
|
||||
).into_strong()
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "C" fn Servo_StyleSheet_FromUTF8BytesAsync(
|
||||
load_data: *mut SheetLoadDataHolder,
|
||||
extra_data: *mut URLExtraData,
|
||||
bytes: *const nsACString,
|
||||
mode: SheetParsingMode,
|
||||
line_number_offset: u32,
|
||||
quirks_mode: nsCompatibility,
|
||||
) {
|
||||
let (load_data, extra_data, bytes) = unsafe {
|
||||
let mut b = nsCString::new();
|
||||
b.assign(&*bytes);
|
||||
(RefPtr::new(load_data), RefPtr::new(extra_data), b)
|
||||
};
|
||||
let async_parser = AsyncStylesheetParser::new(
|
||||
load_data,
|
||||
extra_data,
|
||||
bytes,
|
||||
mode_to_origin(mode),
|
||||
quirks_mode.into(),
|
||||
line_number_offset
|
||||
);
|
||||
|
||||
if let Some(thread_pool) = STYLE_THREAD_POOL.style_thread_pool.as_ref() {
|
||||
thread_pool.spawn(|| {
|
||||
async_parser.parse();
|
||||
});
|
||||
} else {
|
||||
async_parser.parse();
|
||||
}
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "C" fn Servo_StyleSet_AppendStyleSheet(
|
||||
raw_data: RawServoStyleSetBorrowed,
|
||||
|
@ -2051,6 +2088,17 @@ pub extern "C" fn Servo_ImportRule_GetSheet(
|
|||
})
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "C" fn Servo_ImportRule_SetSheet(
|
||||
rule: RawServoImportRuleBorrowed,
|
||||
sheet: *mut ServoStyleSheet,
|
||||
) {
|
||||
write_locked_arc(rule, |rule: &mut ImportRule| {
|
||||
let sheet = unsafe { GeckoStyleSheet::new(sheet) };
|
||||
rule.stylesheet = ImportSheet::new(sheet);
|
||||
})
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "C" fn Servo_Keyframe_GetKeyText(
|
||||
keyframe: RawServoKeyframeBorrowed,
|
||||
|
|
|
@ -9,6 +9,7 @@ extern crate env_logger;
|
|||
extern crate libc;
|
||||
#[macro_use] extern crate log;
|
||||
extern crate malloc_size_of;
|
||||
extern crate nsstring;
|
||||
extern crate selectors;
|
||||
extern crate servo_arc;
|
||||
extern crate smallvec;
|
||||
|
|
|
@ -3,15 +3,24 @@
|
|||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
use cssparser::SourceLocation;
|
||||
use nsstring::nsCString;
|
||||
use servo_arc::Arc;
|
||||
use style::context::QuirksMode;
|
||||
use style::error_reporting::NullReporter;
|
||||
use style::gecko::data::GeckoStyleSheet;
|
||||
use style::gecko::global_style_data::GLOBAL_STYLE_DATA;
|
||||
use style::gecko_bindings::bindings;
|
||||
use style::gecko_bindings::bindings::Gecko_LoadStyleSheet;
|
||||
use style::gecko_bindings::structs::{Loader, ServoStyleSheet, SheetLoadData, LoaderReusableStyleSheets};
|
||||
use style::gecko_bindings::structs::{Loader, LoaderReusableStyleSheets};
|
||||
use style::gecko_bindings::structs::{ServoStyleSheet, SheetLoadData, SheetLoadDataHolder};
|
||||
use style::gecko_bindings::structs::URLExtraData;
|
||||
use style::gecko_bindings::sugar::ownership::FFIArcHelpers;
|
||||
use style::gecko_bindings::sugar::refptr::RefPtr;
|
||||
use style::media_queries::MediaList;
|
||||
use style::parser::ParserContext;
|
||||
use style::shared_lock::{Locked, SharedRwLock};
|
||||
use style::stylesheets::{ImportRule, StylesheetLoader as StyleStylesheetLoader};
|
||||
use style::stylesheets::{ImportRule, Origin, StylesheetLoader as StyleStylesheetLoader};
|
||||
use style::stylesheets::StylesheetContents;
|
||||
use style::stylesheets::import_rule::ImportSheet;
|
||||
use style::values::CssUrl;
|
||||
|
||||
|
@ -41,15 +50,11 @@ impl StyleStylesheetLoader for StylesheetLoader {
|
|||
// so this raw pointer will still be valid.
|
||||
|
||||
let child_sheet = unsafe {
|
||||
let (spec_bytes, spec_len) = url.as_slice_components();
|
||||
let base_url_data = url.extra_data.get();
|
||||
Gecko_LoadStyleSheet(self.0,
|
||||
self.1,
|
||||
self.2,
|
||||
self.3,
|
||||
base_url_data,
|
||||
spec_bytes,
|
||||
spec_len as u32,
|
||||
url.for_ffi(),
|
||||
media.into_strong())
|
||||
};
|
||||
|
||||
|
@ -60,3 +65,75 @@ impl StyleStylesheetLoader for StylesheetLoader {
|
|||
Arc::new(lock.wrap(ImportRule { url, source_location, stylesheet }))
|
||||
}
|
||||
}
|
||||
|
||||
pub struct AsyncStylesheetParser {
|
||||
load_data: RefPtr<SheetLoadDataHolder>,
|
||||
extra_data: RefPtr<URLExtraData>,
|
||||
bytes: nsCString,
|
||||
origin: Origin,
|
||||
quirks_mode: QuirksMode,
|
||||
line_number_offset: u32,
|
||||
}
|
||||
|
||||
impl AsyncStylesheetParser {
|
||||
pub fn new(
|
||||
load_data: RefPtr<SheetLoadDataHolder>,
|
||||
extra_data: RefPtr<URLExtraData>,
|
||||
bytes: nsCString,
|
||||
origin: Origin,
|
||||
quirks_mode: QuirksMode,
|
||||
line_number_offset: u32,
|
||||
) -> Self {
|
||||
AsyncStylesheetParser {
|
||||
load_data,
|
||||
extra_data,
|
||||
bytes,
|
||||
origin,
|
||||
quirks_mode,
|
||||
line_number_offset,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn parse(self) {
|
||||
let global_style_data = &*GLOBAL_STYLE_DATA;
|
||||
let input: &str = unsafe { (*self.bytes).as_str_unchecked() };
|
||||
|
||||
// Note: Parallel CSS parsing doesn't report CSS errors. When errors
|
||||
// are being logged, Gecko prevents the parallel parsing path from
|
||||
// running.
|
||||
let sheet = Arc::new(StylesheetContents::from_str(
|
||||
input, self.extra_data.clone(), self.origin,
|
||||
&global_style_data.shared_lock, Some(&self), &NullReporter,
|
||||
self.quirks_mode.into(), self.line_number_offset)
|
||||
);
|
||||
|
||||
unsafe {
|
||||
bindings::Gecko_StyleSheet_FinishAsyncParse(self.load_data.get(), sheet.into_strong());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl StyleStylesheetLoader for AsyncStylesheetParser {
|
||||
fn request_stylesheet(
|
||||
&self,
|
||||
url: CssUrl,
|
||||
source_location: SourceLocation,
|
||||
_context: &ParserContext,
|
||||
lock: &SharedRwLock,
|
||||
media: Arc<Locked<MediaList>>,
|
||||
) -> Arc<Locked<ImportRule>> {
|
||||
let stylesheet = ImportSheet::new_pending(self.origin, self.quirks_mode);
|
||||
let rule = Arc::new(lock.wrap(ImportRule { url: url.clone(), source_location, stylesheet }));
|
||||
|
||||
unsafe {
|
||||
bindings::Gecko_LoadStyleSheetAsync(
|
||||
self.load_data.get(),
|
||||
url.for_ffi(),
|
||||
media.into_strong(),
|
||||
rule.clone().into_strong()
|
||||
);
|
||||
}
|
||||
|
||||
rule
|
||||
}
|
||||
}
|
||||
|
|
|
@ -33,11 +33,16 @@ job-defaults:
|
|||
- "browser/config/version.txt"
|
||||
- "browser/config/version_display.txt"
|
||||
- "config/milestone.txt"
|
||||
mozilla-esr60:
|
||||
- "browser/config/version.txt"
|
||||
- "browser/config/version_display.txt"
|
||||
- "config/milestone.txt"
|
||||
push:
|
||||
by-project:
|
||||
mozilla-beta: true
|
||||
mozilla-release: true
|
||||
mozilla-esr52: true
|
||||
mozilla-esr60: true
|
||||
maple: true
|
||||
birch: true
|
||||
default: false
|
||||
|
|
|
@ -53,10 +53,8 @@ config = {
|
|||
'MOZ_CRASHREPORTER_NO_REPORT': '1',
|
||||
'LC_ALL': 'C',
|
||||
# 32 bit specific
|
||||
'PATH': '/usr/local/bin:/usr/lib/ccache:\
|
||||
/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/sbin:/tools/git/bin:\
|
||||
/tools/python27/bin:/tools/python27-mercurial/bin:/home/cltbld/bin',
|
||||
'LD_LIBRARY_PATH': "/tools/gcc-4.3.3/installed/lib",
|
||||
'PATH': '/usr/local/bin:\
|
||||
/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/sbin',
|
||||
},
|
||||
"check_test_env": {
|
||||
'MINIDUMP_STACKWALK': '%(abs_tools_dir)s/breakpad/linux/minidump_stackwalk',
|
||||
|
|
|
@ -52,10 +52,9 @@ config = {
|
|||
'MOZ_CRASHREPORTER_NO_REPORT': '1',
|
||||
'LC_ALL': 'C',
|
||||
## 64 bit specific
|
||||
'PATH': '/usr/local/bin:/usr/lib64/ccache:/bin:\
|
||||
/usr/bin:/usr/local/sbin:/usr/sbin:/sbin:/tools/git/bin:/tools/python27/bin:\
|
||||
/tools/python27-mercurial/bin:/home/cltbld/bin',
|
||||
'LD_LIBRARY_PATH': "/tools/gcc-4.3.3/installed/lib64",
|
||||
'PATH': '/usr/local/bin:/bin:'
|
||||
'/usr/bin:/usr/local/sbin:/usr/sbin:'
|
||||
'/sbin'
|
||||
##
|
||||
},
|
||||
"check_test_env": {
|
||||
|
|
|
@ -42,9 +42,8 @@ config = {
|
|||
'MOZ_CRASHREPORTER_NO_REPORT': '1',
|
||||
'LC_ALL': 'C',
|
||||
## 64 bit specific
|
||||
'PATH': '/usr/local/bin:/usr/lib64/ccache:/bin:\
|
||||
/usr/bin:/usr/local/sbin:/usr/sbin:/sbin:/tools/git/bin:/tools/python27/bin:\
|
||||
/tools/python27-mercurial/bin:/home/cltbld/bin',
|
||||
'PATH': '/usr/local/bin:/bin:'
|
||||
'/usr/bin:/usr/local/sbin:/usr/sbin:/sbin'
|
||||
##
|
||||
},
|
||||
"check_test_env": {
|
||||
|
|
|
@ -39,10 +39,8 @@ config = {
|
|||
'MOZ_CRASHREPORTER_NO_REPORT': '1',
|
||||
'LC_ALL': 'C',
|
||||
# 32 bit specific
|
||||
'PATH': '/usr/local/bin:/usr/lib/ccache:\
|
||||
/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/sbin:/tools/git/bin:\
|
||||
/tools/python27/bin:/tools/python27-mercurial/bin:/home/cltbld/bin',
|
||||
'LD_LIBRARY_PATH': "/tools/gcc-4.3.3/installed/lib",
|
||||
'PATH': '/usr/local/bin:\
|
||||
/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/sbin:',
|
||||
},
|
||||
'mozconfig_variant': 'artifact',
|
||||
#########################################################################
|
||||
|
|
|
@ -19,10 +19,9 @@ config = {
|
|||
'MOZ_CRASHREPORTER_NO_REPORT': '1',
|
||||
'LC_ALL': 'C',
|
||||
# 32 bit specific
|
||||
'PATH': '/usr/local/bin:/usr/lib/ccache:/bin:\
|
||||
/usr/bin:/usr/local/sbin:/usr/sbin:/sbin:/tools/git/bin:/tools/python27/bin:\
|
||||
/tools/python27-mercurial/bin:/home/cltbld/bin',
|
||||
'LD_LIBRARY_PATH': '/tools/gcc-4.3.3/installed/lib64:%(abs_obj_dir)s/dist/bin',
|
||||
'PATH': '/usr/local/bin:/bin:\
|
||||
/usr/bin:/usr/local/sbin:/usr/sbin:/sbin:',
|
||||
'LD_LIBRARY_PATH': '%(abs_obj_dir)s/dist/bin',
|
||||
'XPCOM_DEBUG_BREAK': 'stack-and-abort',
|
||||
'TINDERBOX_OUTPUT': '1',
|
||||
},
|
||||
|
|
|
@ -43,10 +43,8 @@ config = {
|
|||
# debug-specific
|
||||
'XPCOM_DEBUG_BREAK': 'stack-and-abort',
|
||||
# 32 bit specific
|
||||
'PATH': '/usr/local/bin:/usr/lib/ccache:\
|
||||
/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/sbin:/tools/git/bin:\
|
||||
/tools/python27/bin:/tools/python27-mercurial/bin:/home/cltbld/bin',
|
||||
'LD_LIBRARY_PATH': "/tools/gcc-4.3.3/installed/lib",
|
||||
'PATH': '/usr/local/bin:\
|
||||
/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/sbin',
|
||||
},
|
||||
'mozconfig_variant': 'debug-artifact',
|
||||
#########################################################################
|
||||
|
|
|
@ -17,10 +17,9 @@ config = {
|
|||
'MOZ_CRASHREPORTER_NO_REPORT': '1',
|
||||
'LC_ALL': 'C',
|
||||
# 32 bit specific
|
||||
'PATH': '/usr/local/bin:/usr/lib/ccache:/bin:\
|
||||
/usr/bin:/usr/local/sbin:/usr/sbin:/sbin:/tools/git/bin:/tools/python27/bin:\
|
||||
/tools/python27-mercurial/bin:/home/cltbld/bin',
|
||||
'LD_LIBRARY_PATH': '/tools/gcc-4.3.3/installed/lib64:%(abs_obj_dir)s/dist/bin',
|
||||
'PATH': '/usr/local/bin:/bin:\
|
||||
/usr/bin:/usr/local/sbin:/usr/sbin:/sbin',
|
||||
'LD_LIBRARY_PATH': '%(abs_obj_dir)s/dist/bin',
|
||||
'XPCOM_DEBUG_BREAK': 'stack-and-abort',
|
||||
'TINDERBOX_OUTPUT': '1',
|
||||
},
|
||||
|
|
|
@ -18,10 +18,9 @@ config = {
|
|||
'MOZ_CRASHREPORTER_NO_REPORT': '1',
|
||||
'LC_ALL': 'C',
|
||||
# 32 bit specific
|
||||
'PATH': '/usr/local/bin:/usr/lib/ccache:/bin:\
|
||||
/usr/bin:/usr/local/sbin:/usr/sbin:/sbin:/tools/git/bin:/tools/python27/bin:\
|
||||
/tools/python27-mercurial/bin:/home/cltbld/bin',
|
||||
'LD_LIBRARY_PATH': '/tools/gcc-4.3.3/installed/lib64:%(abs_obj_dir)s/dist/bin',
|
||||
'PATH': '/usr/local/bin:/bin:\
|
||||
/usr/bin:/usr/local/sbin:/usr/sbin:/sbin',
|
||||
'LD_LIBRARY_PATH': '%(abs_obj_dir)s/dist/bin',
|
||||
'XPCOM_DEBUG_BREAK': 'stack-and-abort',
|
||||
'TINDERBOX_OUTPUT': '1',
|
||||
},
|
||||
|
|
|
@ -20,9 +20,8 @@ config = {
|
|||
'MOZ_CRASHREPORTER_NO_REPORT': '1',
|
||||
'LC_ALL': 'C',
|
||||
## 64 bit specific
|
||||
'PATH': '/builds/worker/workspace/build/src/gcc/bin:/usr/local/bin:/usr/lib64/ccache:/bin:\
|
||||
/usr/bin:/usr/local/sbin:/usr/sbin:/sbin:/tools/git/bin:/tools/python27/bin:\
|
||||
/tools/python27-mercurial/bin:/home/cltbld/bin',
|
||||
'PATH': '/builds/worker/workspace/build/src/gcc/bin:/usr/local/bin:/bin:\
|
||||
/usr/bin:/usr/local/sbin:/usr/sbin:/sbin',
|
||||
},
|
||||
'mozconfig_variant': 'add-on-devel',
|
||||
#######################
|
||||
|
|
|
@ -40,10 +40,8 @@ config = {
|
|||
'MOZ_CRASHREPORTER_NO_REPORT': '1',
|
||||
'LC_ALL': 'C',
|
||||
## 64 bit specific
|
||||
'PATH': '/usr/local/bin:/usr/lib64/ccache:/bin:\
|
||||
/usr/bin:/usr/local/sbin:/usr/sbin:/sbin:/tools/git/bin:/tools/python27/bin:\
|
||||
/tools/python27-mercurial/bin:/home/cltbld/bin',
|
||||
'LD_LIBRARY_PATH': "/tools/gcc-4.3.3/installed/lib64",
|
||||
'PATH': '/usr/local/bin:/bin:\
|
||||
/usr/bin:/usr/local/sbin:/usr/sbin:/sbin',
|
||||
##
|
||||
},
|
||||
# This doesn't actually inherit from anything.
|
||||
|
|
Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше
Загрузка…
Ссылка в новой задаче