Merge inbound to mozilla-central. a=merge

This commit is contained in:
Bogdan Tara 2018-09-05 02:24:27 +03:00
commit f302cbb0b3
127 changed files with 1659 additions and 1262 deletions

View File

@ -15,6 +15,10 @@ var FastBlock = {
XPCOMUtils.defineLazyPreferenceGetter(this, "enabled", this.PREF_ENABLED, false);
XPCOMUtils.defineLazyPreferenceGetter(this, "visible", this.PREF_UI_ENABLED, false);
},
isBlockerActivated(state) {
return state & Ci.nsIWebProgressListener.STATE_BLOCKED_SLOW_TRACKING_CONTENT;
},
};
var TrackingProtection = {
@ -128,6 +132,10 @@ var TrackingProtection = {
}
}
},
isBlockerActivated(state) {
return state & Ci.nsIWebProgressListener.STATE_BLOCKED_TRACKING_CONTENT;
},
};
var ThirdPartyCookies = {
@ -154,6 +162,11 @@ var ThirdPartyCookies = {
get enabled() {
return this.PREF_ENABLED_VALUES.includes(this.behaviorPref);
},
isBlockerActivated(state) {
return (state & Ci.nsIWebProgressListener.STATE_COOKIES_BLOCKED_TRACKER) != 0 ||
(state & Ci.nsIWebProgressListener.STATE_COOKIES_BLOCKED_FOREIGN) != 0;
},
};
@ -434,23 +447,21 @@ var ContentBlocking = {
this.iconBox.removeAttribute("animate");
}
let isBlocking = state & Ci.nsIWebProgressListener.STATE_BLOCKED_TRACKING_CONTENT;
let isAllowing = state & Ci.nsIWebProgressListener.STATE_LOADED_TRACKING_CONTENT;
let detected = isBlocking || isAllowing;
let anyBlockerEnabled = false;
let anyBlockerActivated = false;
for (let blocker of this.blockers) {
blocker.categoryItem.classList.toggle("blocked", this.enabled && blocker.enabled);
blocker.categoryItem.hidden = !blocker.visible;
anyBlockerEnabled = anyBlockerEnabled || blocker.enabled;
anyBlockerActivated = anyBlockerActivated || blocker.isBlockerActivated(state);
}
// We consider the shield state "active" when any kind of blocking-related
// activity occurs on the page (blocking or allowing) and at least one blocker
// is enabled.
// We consider the shield state "active" when some kind of blocking activity
// occurs on the page. Note that merely allowing the loading of content that
// we could have blocked does not trigger the appearance of the shield.
// This state will be overriden later if there's an exception set for this site.
let active = this.enabled && detected && anyBlockerEnabled;
let active = this.enabled && anyBlockerActivated;
let isAllowing = state & Ci.nsIWebProgressListener.STATE_LOADED_TRACKING_CONTENT;
let detected = anyBlockerActivated || isAllowing;
let isBrowserPrivate = PrivateBrowsingUtils.isBrowserPrivate(gBrowser.selectedBrowser);

View File

@ -3,6 +3,8 @@ tags = trackingprotection
support-files =
head.js
benignPage.html
cookiePage.html
cookieServer.sjs
trackingPage.html
[browser_trackingUI_3.js]

View File

@ -75,7 +75,7 @@ function testTrackingPageUnblocked() {
ok(ContentBlocking.content.hasAttribute("detected"), "trackers are detected");
ok(ContentBlocking.content.hasAttribute("hasException"), "content shows exception");
ok(ContentBlocking.iconBox.hasAttribute("active"), "shield is active");
ok(!ContentBlocking.iconBox.hasAttribute("active"), "shield is active");
ok(ContentBlocking.iconBox.hasAttribute("hasException"), "shield shows exception");
is(ContentBlocking.iconBox.getAttribute("tooltiptext"),
gNavigatorBundle.getString("trackingProtection.icon.disabledTooltip"), "correct tooltip");

View File

@ -18,18 +18,29 @@ const CB_PREF = "browser.contentblocking.enabled";
const CB_UI_PREF = "browser.contentblocking.ui.enabled";
const TP_PREF = "privacy.trackingprotection.enabled";
const TP_PB_PREF = "privacy.trackingprotection.pbmode.enabled";
const FB_PREF = "browser.fastblock.enabled";
const FB_TIMEOUT_PREF = "browser.fastblock.timeout";
const TPC_PREF = "network.cookie.cookieBehavior";
const BENIGN_PAGE = "http://tracking.example.org/browser/browser/base/content/test/trackingUI/benignPage.html";
const TRACKING_PAGE = "http://tracking.example.org/browser/browser/base/content/test/trackingUI/trackingPage.html";
const COOKIE_PAGE = "http://not-tracking.example.com/browser/browser/base/content/test/trackingUI/cookiePage.html";
var ContentBlocking = null;
var FastBlock = null;
var TrackingProtection = null;
var ThirdPartyCookies = null;
var tabbrowser = null;
var gTrackingPageURL = TRACKING_PAGE;
registerCleanupFunction(function() {
TrackingProtection = ContentBlocking = tabbrowser = null;
TrackingProtection = ContentBlocking = FastBlock =
ThirdPartyCookies = tabbrowser = null;
UrlClassifierTestUtils.cleanupTestTrackers();
Services.prefs.clearUserPref(TP_PREF);
Services.prefs.clearUserPref(TP_PB_PREF);
Services.prefs.clearUserPref(CB_PREF);
Services.prefs.clearUserPref(FB_PREF);
Services.prefs.clearUserPref(FB_TIMEOUT_PREF);
Services.prefs.clearUserPref(TPC_PREF);
});
// This is a special version of "hidden" that doesn't check for item
@ -98,25 +109,47 @@ function testBenignPageWithException() {
}
}
function areTrackersBlocked(isPrivateBrowsing) {
let cbEnabled = Services.prefs.getBoolPref(CB_PREF);
let blockedByTP = cbEnabled &&
Services.prefs.getBoolPref(isPrivateBrowsing ? TP_PB_PREF : TP_PREF);
let blockedByFB = cbEnabled &&
Services.prefs.getBoolPref(FB_PREF) &&
// The timeout pref is only checked for completeness,
// checking it is technically unneeded for this test.
Services.prefs.getIntPref(FB_TIMEOUT_PREF) == 0;
let blockedByTPC = cbEnabled &&
Services.prefs.getIntPref(TPC_PREF) == Ci.nsICookieService.BEHAVIOR_REJECT_TRACKER;
return blockedByTP || blockedByFB || blockedByTPC;
}
function testTrackingPage(window) {
info("Tracking content must be blocked");
ok(ContentBlocking.content.hasAttribute("detected"), "trackers are detected");
ok(!ContentBlocking.content.hasAttribute("hasException"), "content shows no exception");
ok(BrowserTestUtils.is_visible(ContentBlocking.iconBox), "icon box is visible");
ok(ContentBlocking.iconBox.hasAttribute("active"), "shield is active");
let isPrivateBrowsing = PrivateBrowsingUtils.isWindowPrivate(window);
let blockedByTP = areTrackersBlocked(isPrivateBrowsing);
is(BrowserTestUtils.is_visible(ContentBlocking.iconBox), blockedByTP,
"icon box is" + (blockedByTP ? "" : " not") + " visible");
is(ContentBlocking.iconBox.hasAttribute("active"), blockedByTP,
"shield is" + (blockedByTP ? "" : " not") + " active");
ok(!ContentBlocking.iconBox.hasAttribute("hasException"), "icon box shows no exception");
is(ContentBlocking.iconBox.getAttribute("tooltiptext"),
gNavigatorBundle.getString("trackingProtection.icon.activeTooltip"), "correct tooltip");
blockedByTP ? gNavigatorBundle.getString("trackingProtection.icon.activeTooltip") : "",
"correct tooltip");
ok(hidden("#tracking-action-block"), "blockButton is hidden");
let cbEnabled = Services.prefs.getBoolPref(CB_PREF);
if (PrivateBrowsingUtils.isWindowPrivate(window)) {
ok(hidden("#tracking-action-unblock"), "unblockButton is hidden");
ok(!hidden("#tracking-action-unblock-private"), "unblockButtonPrivate is visible");
is(hidden("#tracking-action-unblock-private"), !cbEnabled,
"unblockButtonPrivate is" + (cbEnabled ? "" : " not") + " visible");
} else {
ok(!hidden("#tracking-action-unblock"), "unblockButton is visible");
ok(hidden("#tracking-action-unblock-private"), "unblockButtonPrivate is hidden");
is(hidden("#tracking-action-unblock-private"), cbEnabled,
"unblockButtonPrivate is" + (cbEnabled ? "" : " not") + " hidden");
}
ok(hidden("#identity-popup-content-blocking-not-detected"), "blocking not detected label is hidden");
@ -124,25 +157,37 @@ function testTrackingPage(window) {
if (Services.prefs.getBoolPref(CB_UI_PREF)) {
ok(!hidden("#identity-popup-content-blocking-category-list"), "category list is visible");
ok(hidden("#identity-popup-content-blocking-category-tracking-protection > .identity-popup-content-blocking-category-add-blocking"),
"TP category item is not showing add blocking");
ok(!hidden("#identity-popup-content-blocking-category-tracking-protection > .identity-popup-content-blocking-category-state-label"),
"TP category item is set to blocked");
let category;
if (Services.prefs.getBoolPref(FB_PREF)) {
category = "#identity-popup-content-blocking-category-fastblock";
} else {
category = Services.prefs.getIntPref(TPC_PREF) == Ci.nsICookieService.BEHAVIOR_REJECT_TRACKER ?
"#identity-popup-content-blocking-category-3rdpartycookies" :
"#identity-popup-content-blocking-category-tracking-protection";
}
is(hidden(category + " > .identity-popup-content-blocking-category-add-blocking"), blockedByTP,
"Category item is" + (blockedByTP ? " not" : "") + " showing add blocking");
is(hidden(category + " > .identity-popup-content-blocking-category-state-label"), !blockedByTP,
"Category item is" + (blockedByTP ? "" : " not") + " set to blocked");
}
}
function testTrackingPageUnblocked() {
function testTrackingPageUnblocked(blockedByTP) {
info("Tracking content must be white-listed and not blocked");
ok(ContentBlocking.content.hasAttribute("detected"), "trackers are detected");
ok(ContentBlocking.content.hasAttribute("hasException"), "content shows exception");
ok(ContentBlocking.iconBox.hasAttribute("active"), "shield is active");
ok(ContentBlocking.iconBox.hasAttribute("hasException"), "shield shows exception");
let cbEnabled = Services.prefs.getBoolPref(CB_PREF);
ok(!ContentBlocking.iconBox.hasAttribute("active"), "shield is active");
is(ContentBlocking.iconBox.hasAttribute("hasException"), cbEnabled,
"shield" + (cbEnabled ? " shows" : " doesn't show") + " exception");
is(ContentBlocking.iconBox.getAttribute("tooltiptext"),
gNavigatorBundle.getString("trackingProtection.icon.disabledTooltip"), "correct tooltip");
ok(BrowserTestUtils.is_visible(ContentBlocking.iconBox), "icon box is visible");
ok(!hidden("#tracking-action-block"), "blockButton is visible");
is(BrowserTestUtils.is_visible(ContentBlocking.iconBox), cbEnabled,
"icon box is" + (cbEnabled ? "" : " not") + " visible");
is(hidden("#tracking-action-block"), !cbEnabled,
"blockButton is" + (cbEnabled ? " not" : "") + " visible");
ok(hidden("#tracking-action-unblock"), "unblockButton is hidden");
ok(!hidden("#identity-popup-content-blocking-disabled-label"), "disabled label is visible");
@ -151,8 +196,17 @@ function testTrackingPageUnblocked() {
if (Services.prefs.getBoolPref(CB_UI_PREF)) {
ok(!hidden("#identity-popup-content-blocking-category-list"), "category list is visible");
ok(hidden("#identity-popup-content-blocking-category-tracking-protection > .identity-popup-content-blocking-category-add-blocking"),
"TP category item is not showing add blocking");
let category;
if (Services.prefs.getBoolPref(FB_PREF)) {
category = "#identity-popup-content-blocking-category-fastblock";
} else {
category = Services.prefs.getIntPref(TPC_PREF) == Ci.nsICookieService.BEHAVIOR_REJECT_TRACKER ?
"#identity-popup-content-blocking-category-3rdpartycookies" :
"#identity-popup-content-blocking-category-tracking-protection";
}
is(hidden(category + " > .identity-popup-content-blocking-category-add-blocking"), blockedByTP,
"Category item is" + (blockedByTP ? " not" : "") + " showing add blocking");
// Always hidden no matter if blockedByTP or not, since we have an exception.
ok(hidden("#identity-popup-content-blocking-category-tracking-protection > .identity-popup-content-blocking-category-state-label"),
"TP category item is not set to blocked");
}
@ -210,14 +264,15 @@ async function testContentBlockingEnabled(tab) {
}
info("Load a test page containing tracking elements");
await promiseTabLoadEvent(tab, TRACKING_PAGE);
await promiseTabLoadEvent(tab, gTrackingPageURL);
testTrackingPage(tab.ownerGlobal);
info("Disable CB for the page (which reloads the page)");
let tabReloadPromise = promiseTabLoadEvent(tab);
clickButton("#tracking-action-unblock");
await tabReloadPromise;
testTrackingPageUnblocked();
let blockedByTP = areTrackersBlocked(isPrivateBrowsing);
testTrackingPageUnblocked(blockedByTP);
info("Re-enable TP for the page (which reloads the page)");
tabReloadPromise = promiseTabLoadEvent(tab);
@ -252,7 +307,7 @@ async function testContentBlockingDisabled(tab) {
}
info("Load a test page containing tracking elements");
await promiseTabLoadEvent(tab, TRACKING_PAGE);
await promiseTabLoadEvent(tab, gTrackingPageURL);
testTrackingPageWithCBDisabled();
}
@ -269,6 +324,20 @@ add_task(async function testNormalBrowsing() {
is(TrackingProtection.enabled, Services.prefs.getBoolPref(TP_PREF),
"TP.enabled is based on the original pref value");
Services.prefs.setBoolPref(FB_PREF, false);
await testContentBlockingEnabled(tab);
if (Services.prefs.getBoolPref(CB_UI_PREF)) {
Services.prefs.setBoolPref(CB_PREF, false);
ok(!ContentBlocking.enabled, "CB is disabled after setting the pref");
} else {
Services.prefs.setBoolPref(TP_PREF, false);
ok(!TrackingProtection.enabled, "TP is disabled after setting the pref");
}
await testContentBlockingDisabled(tab);
Services.prefs.setBoolPref(TP_PREF, true);
ok(TrackingProtection.enabled, "TP is enabled after setting the pref");
Services.prefs.setBoolPref(CB_PREF, true);
@ -287,6 +356,8 @@ add_task(async function testNormalBrowsing() {
await testContentBlockingDisabled(tab);
gBrowser.removeCurrentTab();
Services.prefs.clearUserPref(FB_PREF);
});
add_task(async function testPrivateBrowsing() {
@ -297,6 +368,8 @@ add_task(async function testPrivateBrowsing() {
// Set the normal mode pref to false to check the pbmode pref.
Services.prefs.setBoolPref(TP_PREF, false);
Services.prefs.setBoolPref(FB_PREF, false);
ContentBlocking = tabbrowser.ownerGlobal.ContentBlocking;
ok(ContentBlocking, "CB is attached to the private window");
TrackingProtection = tabbrowser.ownerGlobal.TrackingProtection;
@ -304,6 +377,18 @@ add_task(async function testPrivateBrowsing() {
is(TrackingProtection.enabled, Services.prefs.getBoolPref(TP_PB_PREF),
"TP.enabled is based on the pb pref value");
await testContentBlockingEnabled(tab);
if (Services.prefs.getBoolPref(CB_UI_PREF)) {
Services.prefs.setBoolPref(CB_PREF, false);
ok(!ContentBlocking.enabled, "CB is disabled after setting the pref");
} else {
Services.prefs.setBoolPref(TP_PREF, false);
ok(!TrackingProtection.enabled, "TP is disabled after setting the pref");
}
await testContentBlockingDisabled(tab);
Services.prefs.setBoolPref(TP_PB_PREF, true);
ok(TrackingProtection.enabled, "TP is enabled after setting the pref");
Services.prefs.setBoolPref(CB_PREF, true);
@ -322,4 +407,105 @@ add_task(async function testPrivateBrowsing() {
await testContentBlockingDisabled(tab);
privateWin.close();
Services.prefs.clearUserPref(FB_PREF);
});
add_task(async function testFastBlock() {
if (!SpecialPowers.getBoolPref(CB_UI_PREF)) {
info("The FastBlock test is disabled when the Content Blocking UI is disabled");
return;
}
await UrlClassifierTestUtils.addTestTrackers();
tabbrowser = gBrowser;
let tab = tabbrowser.selectedTab = BrowserTestUtils.addTab(tabbrowser);
Services.prefs.setBoolPref(FB_PREF, false);
ContentBlocking = gBrowser.ownerGlobal.ContentBlocking;
ok(ContentBlocking, "CB is attached to the browser window");
FastBlock = gBrowser.ownerGlobal.FastBlock;
ok(FastBlock, "TP is attached to the browser window");
is(FastBlock.enabled, Services.prefs.getBoolPref(FB_PREF),
"FB.enabled is based on the original pref value");
Services.prefs.setBoolPref(CB_PREF, true);
ok(ContentBlocking.enabled, "CB is enabled after setting the pref");
await testContentBlockingEnabled(tab);
ok(Services.prefs.getBoolPref(CB_UI_PREF), "CB UI must be enabled here");
Services.prefs.setBoolPref(CB_PREF, false);
ok(!ContentBlocking.enabled, "CB is disabled after setting the pref");
await testContentBlockingDisabled(tab);
Services.prefs.setBoolPref(FB_PREF, true);
Services.prefs.setIntPref(FB_TIMEOUT_PREF, 0);
ok(FastBlock.enabled, "FB is enabled after setting the pref");
Services.prefs.setBoolPref(CB_PREF, true);
ok(ContentBlocking.enabled, "CB is enabled after setting the pref");
await testContentBlockingEnabled(tab);
ok(Services.prefs.getBoolPref(CB_UI_PREF), "CB UI must be enabled here");
Services.prefs.setBoolPref(CB_PREF, false);
ok(!ContentBlocking.enabled, "CB is disabled after setting the pref");
await testContentBlockingDisabled(tab);
Services.prefs.clearUserPref(FB_PREF);
Services.prefs.clearUserPref(FB_TIMEOUT_PREF);
gBrowser.removeCurrentTab();
});
add_task(async function testThirdPartyCookies() {
if (!SpecialPowers.getBoolPref(CB_UI_PREF)) {
info("The ThirdPartyCookies test is disabled when the Content Blocking UI is disabled");
return;
}
await UrlClassifierTestUtils.addTestTrackers();
gTrackingPageURL = COOKIE_PAGE;
Services.prefs.setBoolPref(FB_PREF, false);
tabbrowser = gBrowser;
let tab = tabbrowser.selectedTab = BrowserTestUtils.addTab(tabbrowser);
ContentBlocking = gBrowser.ownerGlobal.ContentBlocking;
ok(ContentBlocking, "CB is attached to the browser window");
ThirdPartyCookies = gBrowser.ownerGlobal.ThirdPartyCookies;
ok(ThirdPartyCookies, "TP is attached to the browser window");
is(ThirdPartyCookies.enabled,
Services.prefs.getIntPref(TPC_PREF) == Ci.nsICookieService.BEHAVIOR_REJECT_TRACKER,
"TPC.enabled is based on the original pref value");
Services.prefs.setBoolPref(CB_PREF, true);
ok(ContentBlocking.enabled, "CB is enabled after setting the pref");
await testContentBlockingEnabled(tab);
ok(Services.prefs.getBoolPref(CB_UI_PREF), "CB UI must be enabled here");
Services.prefs.setBoolPref(CB_PREF, false);
ok(!ContentBlocking.enabled, "CB is disabled after setting the pref");
await testContentBlockingDisabled(tab);
Services.prefs.setIntPref(TPC_PREF, Ci.nsICookieService.BEHAVIOR_REJECT_TRACKER);
ok(ThirdPartyCookies.enabled, "TPC is enabled after setting the pref");
Services.prefs.setBoolPref(CB_PREF, true);
ok(ContentBlocking.enabled, "CB is enabled after setting the pref");
await testContentBlockingEnabled(tab);
ok(Services.prefs.getBoolPref(CB_UI_PREF), "CB UI must be enabled here");
Services.prefs.setBoolPref(CB_PREF, false);
ok(!ContentBlocking.enabled, "CB is disabled after setting the pref");
await testContentBlockingDisabled(tab);
Services.prefs.clearUserPref(FB_PREF);
Services.prefs.clearUserPref(TPC_PREF);
gBrowser.removeCurrentTab();
});

View File

@ -0,0 +1,12 @@
<!DOCTYPE HTML>
<!-- 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/. -->
<html dir="ltr" xml:lang="en-US" lang="en-US">
<head>
<meta charset="utf8">
</head>
<body>
<iframe src="http://trackertest.org/browser/browser/base/content/test/trackingUI/cookieServer.sjs"></iframe>
</body>
</html>

View File

@ -0,0 +1,9 @@
/* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/
*/
function handleRequest(request, response) {
response.setStatusLine(request.httpVersion, 200);
response.setHeader("Set-Cookie", "foopy=1");
response.write("cookie served");
}

View File

@ -370,7 +370,6 @@
data-l10n-id="content-blocking-tracking-protection-option-always"
flex="1" />
</radiogroup>
<label id="changeBlockListLink" data-l10n-id="content-blocking-tracking-protection-change-block-list" class="text-link"/>
<label id="changeBlockListLink"
data-l10n-id="content-blocking-tracking-protection-change-block-list"
class="text-link"

View File

@ -10,6 +10,9 @@ if [ "x$IS_NIGHTLY" = "xyes" ]; then
fi
. "$topsrcdir/build/mozconfig.common"
# Rust requires dsymutil into PATH
mk_add_options "export PATH=$topsrcdir/llvm-dsymutil/bin:$PATH"
# ld needs libLTO.so from llvm
mk_add_options "export LD_LIBRARY_PATH=$topsrcdir/clang/lib"

View File

@ -6,10 +6,3 @@ CFLAGS="$CFLAGS -march=pentium-m -msse -msse2 -mfpmath=sse"
CXXFLAGS="$CXXFLAGS -march=pentium-m -msse -msse2 -mfpmath=sse"
ac_add_options --target=i686-pc-linux
# The linux32 builds are effectively cross-compilations, and geckodriver
# is not enabled by default on cross-compilations, because in most cases,
# the target is not something we can run binaries of, and geckodriver
# is a target binary instead of a host binary. But for linux32, we actually
# can run the target binaries, so we can manually enable geckodriver.
ac_add_options --enable-geckodriver

View File

@ -6,9 +6,9 @@
def main(output, data_file, data_symbol):
output.write(''' AREA .rdata,ALIGN=4,DATA,READONLY
EXPORT _{data_symbol}[DATA]
_{data_symbol}
output.write(''' AREA |.rdata|,ALIGN=4,DATA,READONLY
EXPORT |{data_symbol}|[DATA]
|{data_symbol}|
INCBIN {data_file}
END
'''.format(data_file=data_file, data_symbol=data_symbol))

View File

@ -0,0 +1,58 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
"use strict";
// Tests that the flex display badge toggles on the flexbox highlighter.
const TEST_URI = `
<style type="text/css">
#flex {
display: flex;
}
</style>
<div id="flex"></div>
`;
const HIGHLIGHTER_TYPE = "FlexboxHighlighter";
add_task(async function() {
await pushPref("devtools.inspector.flexboxHighlighter.enabled", true);
await pushPref("devtools.flexboxinspector.enabled", true);
await addTab("data:text/html;charset=utf-8," + encodeURIComponent(TEST_URI));
const { inspector } = await openLayoutView();
const { highlighters, store } = inspector;
info("Check the flex display badge is shown and not active.");
await selectNode("#flex", inspector);
const flexContainer = await getContainerForSelector("#flex", inspector);
const flexDisplayBadge = flexContainer.elt.querySelector(".markup-badge[data-display]");
ok(!flexDisplayBadge.classList.contains("active"), "flex display badge is not active.");
info("Check the initial state of the flex highlighter.");
ok(!highlighters.highlighters[HIGHLIGHTER_TYPE],
"No flexbox highlighter exists in the highlighters overlay.");
ok(!highlighters.flexboxHighlighterShown, "No flexbox highlighter is shown.");
info("Toggling ON the flexbox highlighter from the flex display badge.");
const onHighlighterShown = highlighters.once("flexbox-highlighter-shown");
let onCheckboxChange = waitUntilState(store, state => state.flexbox.highlighted);
flexDisplayBadge.click();
await onHighlighterShown;
await onCheckboxChange;
info("Check the flexbox highlighter is created and flex display badge state.");
ok(highlighters.highlighters[HIGHLIGHTER_TYPE],
"Flexbox highlighter is created in the highlighters overlay.");
ok(highlighters.flexboxHighlighterShown, "Flexbox highlighter is shown.");
ok(flexDisplayBadge.classList.contains("active"), "flex display badge is active.");
info("Toggling OFF the flexbox highlighter from the flex display badge.");
const onHighlighterHidden = highlighters.once("flexbox-highlighter-hidden");
onCheckboxChange = waitUntilState(store, state => !state.flexbox.highlighted);
flexDisplayBadge.click();
await onHighlighterHidden;
await onCheckboxChange;
ok(!flexDisplayBadge.classList.contains("active"), "flex display badge is not active.");
});

View File

@ -124,10 +124,9 @@ responsive.reloadConditions.touchSimulation=Reload when touch simulation is togg
# to select whether to reload when user agent is changed.
responsive.reloadConditions.userAgent=Reload when user agent is changed
# LOCALIZATION NOTE (responsive.reloadNotification.description): Text in notification bar
# shown on first open to clarify that some features need a reload to apply. %1$S is the
# label on the reload conditions menu (responsive.reloadConditions.label).
responsive.reloadNotification.description=Device simulation changes require a reload to fully apply. Automatic reloads are disabled by default to avoid losing any changes in DevTools. You can enable reloading via the “%1$S” menu.
# LOCALIZATION NOTE (responsive.reloadNotification.description2): Text in notification bar
# shown on first open to clarify that some features need a reload to apply.
responsive.reloadNotification.description2=Device simulation changes require a reload to fully apply. Automatic reloads are disabled by default to avoid losing any changes in DevTools. You can enable reloading via the Settings menu.
# LOCALIZATION NOTE (responsive.leftAlignViewport): Label on checkbox used in the settings
# menu.

View File

@ -4,6 +4,8 @@
"use strict";
const Services = require("Services");
const {
ADD_DEVICE,
ADD_DEVICE_TYPE,
@ -18,7 +20,6 @@ const { removeDeviceAssociation } = require("./viewports");
const { addDevice, getDevices, removeDevice } = require("devtools/client/shared/devices");
const Services = require("Services");
const DISPLAYED_DEVICES_PREF = "devtools.responsive.html.displayedDeviceList";
/**

View File

@ -1,23 +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/. */
"use strict";
const { CHANGE_DISPLAY_PIXEL_RATIO } = require("./index");
module.exports = {
/**
* The pixel ratio of the display has changed. This may be triggered by the user
* when changing the monitor resolution, or when the window is dragged to a different
* display with a different pixel ratio.
*/
changeDisplayPixelRatio(displayPixelRatio) {
return {
type: CHANGE_DISPLAY_PIXEL_RATIO,
displayPixelRatio,
};
},
};

View File

@ -48,9 +48,6 @@ createEnum([
// Change one of the reload conditions.
"CHANGE_RELOAD_CONDITION",
// Change the touch simulation state.
"CHANGE_TOUCH_SIMULATION",
// Indicates that the device list is being loaded.
"LOAD_DEVICE_LIST_START",
@ -84,6 +81,9 @@ createEnum([
// Toggles the left alignment of the viewports.
"TOGGLE_LEFT_ALIGNMENT",
// Toggles the touch simulation state of the viewports.
"TOGGLE_TOUCH_SIMULATION",
// Update the device display state in the device selector.
"UPDATE_DEVICE_DISPLAYED",

View File

@ -1,22 +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/. */
"use strict";
const { CHANGE_LOCATION } = require("./index");
module.exports = {
/**
* The location of the page has changed. This may be triggered by the user
* directly entering a new URL, navigating with links, etc.
*/
changeLocation(location) {
return {
type: CHANGE_LOCATION,
location,
};
},
};

View File

@ -6,12 +6,9 @@
DevToolsModules(
'devices.js',
'display-pixel-ratio.js',
'index.js',
'location.js',
'reload-conditions.js',
'screenshot.js',
'touch-simulation.js',
'ui.js',
'viewports.js',
)

View File

@ -4,13 +4,14 @@
"use strict";
const Services = require("Services");
const {
CHANGE_RELOAD_CONDITION,
LOAD_RELOAD_CONDITIONS_END,
} = require("./index");
const Types = require("../types");
const Services = require("Services");
const PREF_PREFIX = "devtools.responsive.reloadConditions.";

View File

@ -6,6 +6,8 @@
"use strict";
const Services = require("Services");
const {
TAKE_SCREENSHOT_START,
TAKE_SCREENSHOT_END,
@ -14,7 +16,6 @@ const {
const { getFormatStr } = require("../utils/l10n");
const { getTopLevelWindow } = require("../utils/window");
const e10s = require("../utils/e10s");
const Services = require("Services");
const CAMERA_AUDIO_URL = "resource://devtools/client/themes/audio/shutter.wav";

View File

@ -1,22 +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/. */
/* eslint-env browser */
"use strict";
const {
CHANGE_TOUCH_SIMULATION
} = require("./index");
module.exports = {
changeTouchSimulation(enabled) {
return {
type: CHANGE_TOUCH_SIMULATION,
enabled,
};
},
};

View File

@ -5,11 +5,25 @@
"use strict";
const {
CHANGE_DISPLAY_PIXEL_RATIO,
TOGGLE_LEFT_ALIGNMENT,
TOGGLE_TOUCH_SIMULATION,
} = require("./index");
module.exports = {
/**
* The pixel ratio of the display has changed. This may be triggered by the user
* when changing the monitor resolution, or when the window is dragged to a different
* display with a different pixel ratio.
*/
changeDisplayPixelRatio(displayPixelRatio) {
return {
type: CHANGE_DISPLAY_PIXEL_RATIO,
displayPixelRatio,
};
},
toggleLeftAlignment(enabled) {
return {
type: TOGGLE_LEFT_ALIGNMENT,
@ -17,4 +31,11 @@ module.exports = {
};
},
toggleTouchSimulation(enabled) {
return {
type: TOGGLE_TOUCH_SIMULATION,
enabled,
};
},
};

View File

@ -5,9 +5,9 @@
"use strict";
const { Ci } = require("chrome");
const Services = require("Services");
const { E10SUtils } = require("resource://gre/modules/E10SUtils.jsm");
const { tunnelToInnerBrowser } = require("./tunnel");
const Services = require("Services");
function debug(msg) {
// console.log(`RDM swap: ${msg}`);

View File

@ -10,6 +10,7 @@ const Services = require("Services");
const { NetUtil } = require("resource://gre/modules/NetUtil.jsm");
const { Utils } = require("resource://gre/modules/sessionstore/Utils.jsm");
const Telemetry = require("devtools/client/shared/telemetry");
const telemetry = new Telemetry();
function readInputStreamToString(stream) {

View File

@ -6,7 +6,7 @@
"use strict";
const { Component, createFactory } = require("devtools/client/shared/vendor/react");
const { createFactory, PureComponent } = require("devtools/client/shared/vendor/react");
const dom = require("devtools/client/shared/vendor/react-dom-factories");
const PropTypes = require("devtools/client/shared/vendor/react-prop-types");
const { connect } = require("devtools/client/shared/vendor/react-redux");
@ -27,8 +27,10 @@ const {
} = require("../actions/devices");
const { changeReloadCondition } = require("../actions/reload-conditions");
const { takeScreenshot } = require("../actions/screenshot");
const { changeTouchSimulation } = require("../actions/touch-simulation");
const { toggleLeftAlignment } = require("../actions/ui");
const {
toggleTouchSimulation,
toggleLeftAlignment,
} = require("../actions/ui");
const {
changeDevice,
changePixelRatio,
@ -39,16 +41,14 @@ const {
const Types = require("../types");
class App extends Component {
class App extends PureComponent {
static get propTypes() {
return {
devices: PropTypes.shape(Types.devices).isRequired,
dispatch: PropTypes.func.isRequired,
displayPixelRatio: Types.pixelRatio.value.isRequired,
networkThrottling: PropTypes.shape(Types.networkThrottling).isRequired,
reloadConditions: PropTypes.shape(Types.reloadConditions).isRequired,
screenshot: PropTypes.shape(Types.screenshot).isRequired,
touchSimulation: PropTypes.shape(Types.touchSimulation).isRequired,
viewports: PropTypes.arrayOf(PropTypes.shape(Types.viewport)).isRequired,
};
}
@ -93,7 +93,7 @@ class App extends Component {
device,
}, "*");
this.props.dispatch(changeDevice(id, device.name, deviceType));
this.props.dispatch(changeTouchSimulation(device.touch));
this.props.dispatch(toggleTouchSimulation(device.touch));
this.props.dispatch(changePixelRatio(id, device.pixelRatio));
}
@ -123,7 +123,7 @@ class App extends Component {
type: "change-touch-simulation",
enabled,
}, "*");
this.props.dispatch(changeTouchSimulation(enabled));
this.props.dispatch(toggleTouchSimulation(enabled));
}
onContentResize({ width, height }) {
@ -150,7 +150,7 @@ class App extends Component {
// TODO: Bug 1332754: Move messaging and logic into the action creator so that device
// property changes are sent from there instead of this function.
this.props.dispatch(removeDeviceAssociation(id));
this.props.dispatch(changeTouchSimulation(false));
this.props.dispatch(toggleTouchSimulation(false));
this.props.dispatch(changePixelRatio(id, 0));
}
@ -181,11 +181,9 @@ class App extends Component {
render() {
const {
devices,
displayPixelRatio,
networkThrottling,
reloadConditions,
screenshot,
touchSimulation,
viewports,
} = this.props;
@ -226,13 +224,11 @@ class App extends Component {
dom.div({ id: "app" },
Toolbar({
devices,
displayPixelRatio,
networkThrottling,
reloadConditions,
screenshot,
selectedDevice,
selectedPixelRatio,
touchSimulation,
viewport: viewports[0],
onChangeDevice,
onChangeNetworkThrottling,

View File

@ -21,10 +21,10 @@ class DevicePixelRatioMenu extends PureComponent {
static get propTypes() {
return {
devices: PropTypes.shape(Types.devices).isRequired,
displayPixelRatio: Types.pixelRatio.value.isRequired,
displayPixelRatio: PropTypes.number.isRequired,
onChangePixelRatio: PropTypes.func.isRequired,
selectedDevice: PropTypes.string.isRequired,
selectedPixelRatio: PropTypes.shape(Types.pixelRatio).isRequired,
selectedPixelRatio: PropTypes.number.isRequired,
};
}
@ -44,8 +44,8 @@ class DevicePixelRatioMenu extends PureComponent {
return {
label: getFormatStr("responsive.devicePixelRatioOption", value),
type: "checkbox",
checked: selectedPixelRatio.value > 0 ?
selectedPixelRatio.value === value :
checked: selectedPixelRatio > 0 ?
selectedPixelRatio === value :
displayPixelRatio === value,
click: () => onChangePixelRatio(+value),
};
@ -86,7 +86,7 @@ class DevicePixelRatioMenu extends PureComponent {
},
dom.span({ className: "title" },
getFormatStr("responsive.devicePixelRatioOption",
selectedPixelRatio.value || displayPixelRatio)
selectedPixelRatio || displayPixelRatio)
)
)
);

View File

@ -6,7 +6,7 @@
"use strict";
const { Component, createFactory } = require("devtools/client/shared/vendor/react");
const { createFactory, PureComponent } = require("devtools/client/shared/vendor/react");
const dom = require("devtools/client/shared/vendor/react-dom-factories");
const PropTypes = require("devtools/client/shared/vendor/react-prop-types");
@ -18,7 +18,7 @@ const Types = require("../types");
const VIEWPORT_MIN_WIDTH = Constants.MIN_VIEWPORT_DIMENSION;
const VIEWPORT_MIN_HEIGHT = Constants.MIN_VIEWPORT_DIMENSION;
class ResizableViewport extends Component {
class ResizableViewport extends PureComponent {
static get propTypes() {
return {
leftAlignmentEnabled: PropTypes.bool.isRequired,

View File

@ -22,7 +22,7 @@ class Toolbar extends PureComponent {
static get propTypes() {
return {
devices: PropTypes.shape(Types.devices).isRequired,
displayPixelRatio: Types.pixelRatio.value.isRequired,
displayPixelRatio: PropTypes.number.isRequired,
leftAlignmentEnabled: PropTypes.bool.isRequired,
networkThrottling: PropTypes.shape(Types.networkThrottling).isRequired,
onChangeDevice: PropTypes.func.isRequired,
@ -40,8 +40,8 @@ class Toolbar extends PureComponent {
reloadConditions: PropTypes.shape(Types.reloadConditions).isRequired,
screenshot: PropTypes.shape(Types.screenshot).isRequired,
selectedDevice: PropTypes.string.isRequired,
selectedPixelRatio: PropTypes.shape(Types.pixelRatio).isRequired,
touchSimulation: PropTypes.shape(Types.touchSimulation).isRequired,
selectedPixelRatio: PropTypes.number.isRequired,
touchSimulationEnabled: PropTypes.bool.isRequired,
viewport: PropTypes.shape(Types.viewport).isRequired,
};
}
@ -68,7 +68,7 @@ class Toolbar extends PureComponent {
screenshot,
selectedDevice,
selectedPixelRatio,
touchSimulation,
touchSimulationEnabled,
viewport,
} = this.props;
@ -121,10 +121,10 @@ class Toolbar extends PureComponent {
dom.button({
id: "touch-simulation-button",
className: "devtools-button" +
(touchSimulation.enabled ? " checked" : ""),
title: (touchSimulation.enabled ?
(touchSimulationEnabled ? " checked" : ""),
title: (touchSimulationEnabled ?
getStr("responsive.disableTouch") : getStr("responsive.enableTouch")),
onClick: () => onChangeTouchSimulation(!touchSimulation.enabled),
onClick: () => onChangeTouchSimulation(!touchSimulationEnabled),
})
),
dom.div(
@ -156,7 +156,9 @@ class Toolbar extends PureComponent {
const mapStateToProps = state => {
return {
displayPixelRatio: state.ui.displayPixelRatio,
leftAlignmentEnabled: state.ui.leftAlignmentEnabled,
touchSimulationEnabled: state.ui.touchSimulationEnabled,
};
};

View File

@ -4,7 +4,7 @@
"use strict";
const { Component } = require("devtools/client/shared/vendor/react");
const { PureComponent } = require("devtools/client/shared/vendor/react");
const dom = require("devtools/client/shared/vendor/react-dom-factories");
const PropTypes = require("devtools/client/shared/vendor/react-prop-types");
@ -12,7 +12,7 @@ const { isKeyIn } = require("../utils/key");
const { MIN_VIEWPORT_DIMENSION } = require("../constants");
const Types = require("../types");
class ViewportDimension extends Component {
class ViewportDimension extends PureComponent {
static get propTypes() {
return {
onResizeViewport: PropTypes.func.isRequired,

View File

@ -4,16 +4,16 @@
"use strict";
const { connect } = require("devtools/client/shared/vendor/react-redux");
const { Component, createFactory } = require("devtools/client/shared/vendor/react");
const { createFactory, PureComponent } = require("devtools/client/shared/vendor/react");
const dom = require("devtools/client/shared/vendor/react-dom-factories");
const PropTypes = require("devtools/client/shared/vendor/react-prop-types");
const { connect } = require("devtools/client/shared/vendor/react-redux");
const ResizableViewport = createFactory(require("./ResizableViewport"));
const Types = require("../types");
class Viewports extends Component {
class Viewports extends PureComponent {
static get propTypes() {
return {
leftAlignmentEnabled: PropTypes.bool.isRequired,

View File

@ -23,10 +23,9 @@ const message = require("./utils/message");
const App = createFactory(require("./components/App"));
const Store = require("./store");
const { loadDevices } = require("./actions/devices");
const { changeDisplayPixelRatio } = require("./actions/display-pixel-ratio");
const { changeLocation } = require("./actions/location");
const { loadReloadConditions } = require("./actions/reload-conditions");
const { addViewport, resizeViewport } = require("./actions/viewports");
const { changeDisplayPixelRatio } = require("./actions/ui");
// Exposed for use by tests
window.require = require;
@ -117,7 +116,6 @@ function onDevicePixelRatioChange() {
window.addInitialViewport = ({ uri, userContextId }) => {
try {
onDevicePixelRatioChange();
bootstrap.dispatch(changeLocation(uri));
bootstrap.dispatch(changeDisplayPixelRatio(window.devicePixelRatio));
bootstrap.dispatch(addViewport(userContextId));
} catch (e) {

View File

@ -491,8 +491,7 @@ ResponsiveUI.prototype = {
showReloadNotification() {
if (Services.prefs.getBoolPref(RELOAD_NOTIFICATION_PREF, false)) {
showNotification(this.browserWindow, this.tab, {
msg: l10n.getFormatStr("responsive.reloadNotification.description",
l10n.getStr("responsive.reloadConditions.label")),
msg: l10n.getFormatStr("responsive.reloadNotification.description2"),
});
Services.prefs.setBoolPref(RELOAD_NOTIFICATION_PREF, false);
}

View File

@ -5,11 +5,8 @@
"use strict";
exports.devices = require("./reducers/devices");
exports.displayPixelRatio = require("./reducers/display-pixel-ratio");
exports.location = require("./reducers/location");
exports.networkThrottling = require("devtools/client/shared/components/throttling/reducer");
exports.reloadConditions = require("./reducers/reload-conditions");
exports.screenshot = require("./reducers/screenshot");
exports.touchSimulation = require("./reducers/touch-simulation");
exports.ui = require("./reducers/ui");
exports.viewports = require("./reducers/viewports");

View File

@ -18,10 +18,10 @@ const {
const Types = require("../types");
const INITIAL_DEVICES = {
types: [],
isModalOpen: false,
modalOpenedFromViewport: null,
listState: Types.loadableState.INITIALIZED,
modalOpenedFromViewport: null,
types: [],
};
const reducers = {

View File

@ -1,26 +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/. */
/* eslint-env browser */
"use strict";
const { CHANGE_DISPLAY_PIXEL_RATIO } = require("../actions/index");
const INITIAL_DISPLAY_PIXEL_RATIO = 0;
const reducers = {
[CHANGE_DISPLAY_PIXEL_RATIO](_, action) {
return action.displayPixelRatio;
},
};
module.exports = function(displayPixelRatio = INITIAL_DISPLAY_PIXEL_RATIO, action) {
const reducer = reducers[action.type];
if (!reducer) {
return displayPixelRatio;
}
return reducer(displayPixelRatio, action);
};

View File

@ -1,25 +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/. */
"use strict";
const { CHANGE_LOCATION } = require("../actions/index");
const INITIAL_LOCATION = "about:blank";
const reducers = {
[CHANGE_LOCATION](_, action) {
return action.location;
},
};
module.exports = function(location = INITIAL_LOCATION, action) {
const reducer = reducers[action.type];
if (!reducer) {
return location;
}
return reducer(location, action);
};

View File

@ -6,11 +6,8 @@
DevToolsModules(
'devices.js',
'display-pixel-ratio.js',
'location.js',
'reload-conditions.js',
'screenshot.js',
'touch-simulation.js',
'ui.js',
'viewports.js',
)

View File

@ -9,7 +9,9 @@ const {
TAKE_SCREENSHOT_START,
} = require("../actions/index");
const INITIAL_SCREENSHOT = { isCapturing: false };
const INITIAL_SCREENSHOT = {
isCapturing: false,
};
const reducers = {

View File

@ -1,31 +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/. */
"use strict";
const {
CHANGE_TOUCH_SIMULATION,
} = require("../actions/index");
const INITIAL_TOUCH_SIMULATION = {
enabled: false,
};
const reducers = {
[CHANGE_TOUCH_SIMULATION](touchSimulation, { enabled }) {
return Object.assign({}, touchSimulation, {
enabled,
});
},
};
module.exports = function(touchSimulation = INITIAL_TOUCH_SIMULATION, action) {
const reducer = reducers[action.type];
if (!reducer) {
return touchSimulation;
}
return reducer(touchSimulation, action);
};

View File

@ -7,18 +7,30 @@
const Services = require("Services");
const {
CHANGE_DISPLAY_PIXEL_RATIO,
TOGGLE_LEFT_ALIGNMENT,
TOGGLE_TOUCH_SIMULATION,
} = require("../actions/index");
const LEFT_ALIGNMENT_ENABLED = "devtools.responsive.leftAlignViewport.enabled";
const INITIAL_UI = {
// The pixel ratio of the display.
displayPixelRatio: 0,
// Whether or not the viewports are left aligned.
leftAlignmentEnabled: Services.prefs.getBoolPref(LEFT_ALIGNMENT_ENABLED),
// Whether or not touch simulation is enabled.
touchSimulationEnabled: false,
};
const reducers = {
[CHANGE_DISPLAY_PIXEL_RATIO](ui, { displayPixelRatio }) {
return Object.assign({}, ui, {
displayPixelRatio,
});
},
[TOGGLE_LEFT_ALIGNMENT](ui, { enabled }) {
const leftAlignmentEnabled = enabled !== undefined ?
enabled : !ui.leftAlignmentEnabled;
@ -30,6 +42,12 @@ const reducers = {
});
},
[TOGGLE_TOUCH_SIMULATION](ui, { enabled }) {
return Object.assign({}, ui, {
touchSimulationEnabled: enabled,
});
},
};
module.exports = function(ui = INITIAL_UI, action) {

View File

@ -22,9 +22,7 @@ const INITIAL_VIEWPORT = {
deviceType: "",
width: 320,
height: 480,
pixelRatio: {
value: 0,
},
pixelRatio: 0,
userContextId: 0,
};
@ -60,9 +58,7 @@ const reducers = {
}
return Object.assign({}, viewport, {
pixelRatio: {
value: pixelRatio
},
pixelRatio,
});
});
},

View File

@ -5,18 +5,18 @@
// Test changing the display pixel ratio.
const { changeDisplayPixelRatio } =
require("devtools/client/responsive.html/actions/display-pixel-ratio");
const { changeDisplayPixelRatio } = require("devtools/client/responsive.html/actions/ui");
const NEW_PIXEL_RATIO = 5.5;
add_task(async function() {
const store = Store();
const { getState, dispatch } = store;
equal(getState().displayPixelRatio, 0,
equal(getState().ui.displayPixelRatio, 0,
"Defaults to 0 at startup");
dispatch(changeDisplayPixelRatio(NEW_PIXEL_RATIO));
equal(getState().displayPixelRatio, NEW_PIXEL_RATIO,
equal(getState().ui.displayPixelRatio, NEW_PIXEL_RATIO,
`Display Pixel Ratio changed to ${NEW_PIXEL_RATIO}`);
});

View File

@ -1,22 +0,0 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
"use strict";
// Test changing the location of the displayed page.
const { changeLocation } =
require("devtools/client/responsive.html/actions/location");
const TEST_URL = "http://example.com";
add_task(async function() {
const store = Store();
const { getState, dispatch } = store;
equal(getState().location, "about:blank",
"Defaults to about:blank at startup");
dispatch(changeLocation(TEST_URL));
equal(getState().location, TEST_URL, "Location changed to TEST_URL");
});

View File

@ -17,6 +17,6 @@ add_task(async function() {
dispatch(changePixelRatio(0, NEW_PIXEL_RATIO));
const viewport = getState().viewports[0];
equal(viewport.pixelRatio.value, NEW_PIXEL_RATIO,
equal(viewport.pixelRatio, NEW_PIXEL_RATIO,
`Viewport's pixel ratio changed to ${NEW_PIXEL_RATIO}`);
});

View File

@ -5,19 +5,17 @@
// Test updating the touch simulation `enabled` property
const {
changeTouchSimulation,
} = require("devtools/client/responsive.html/actions/touch-simulation");
const { toggleTouchSimulation } = require("devtools/client/responsive.html/actions/ui");
add_task(async function() {
const store = Store();
const { getState, dispatch } = store;
ok(!getState().touchSimulation.enabled,
ok(!getState().ui.touchSimulationEnabled,
"Touch simulation is disabled by default.");
dispatch(changeTouchSimulation(true));
dispatch(toggleTouchSimulation(true));
ok(getState().touchSimulation.enabled,
ok(getState().ui.touchSimulationEnabled,
"Touch simulation is enabled.");
});

View File

@ -8,7 +8,6 @@ firefox-appdir = browser
[test_add_viewport.js]
[test_change_device.js]
[test_change_display_pixel_ratio.js]
[test_change_location.js]
[test_change_network_throttling.js]
[test_change_pixel_ratio.js]
[test_resize_viewport.js]

View File

@ -24,11 +24,6 @@ exports.loadableState = createEnum([
/* GLOBAL */
/**
* The location of the document displayed in the viewport(s).
*/
exports.location = PropTypes.string;
/**
* Whether to reload the page automatically when certain actions occur.
*/
@ -130,16 +125,6 @@ exports.networkThrottling = {
};
/**
* Device pixel ratio for a given viewport.
*/
const pixelRatio = exports.pixelRatio = {
// The device pixel ratio value
value: PropTypes.number,
};
/**
* Touch simulation state for a given viewport.
*/
@ -171,7 +156,7 @@ exports.viewport = {
height: PropTypes.number,
// The device pixel ratio of the viewport
pixelRatio: PropTypes.shape(pixelRatio),
pixelRatio: PropTypes.number,
// The user context (container) ID for the viewport
// Defaults to 0 meaning the default context

View File

@ -14,11 +14,11 @@
"use strict";
const ctx = new AudioContext();
const osc = ctx.createStereoPanner();
const panner = ctx.createStereoPanner();
function throwError() {
try {
osc.connect({});
panner.connect({});
} catch (e) {
return {
lineNumber: e.lineNumber,
@ -34,7 +34,7 @@
function throwDOMException() {
try {
osc.channelCount = 3;
panner.channelCount = 3;
} catch (e) {
return {
lineNumber: e.lineNumber,

View File

@ -178,8 +178,8 @@ const nullPrincipalTests = [{
property: descriptor({value: "Error"}),
afterTest: `trapDidRun === false`,
}, {
// Like the previous test, but now the object has a Function class.
string: "[object Function]",
// Like the previous test, but now the object is a callable Proxy.
string: "function () {\n [native code]\n}",
isFunction: true,
hasPreview: false,
code: `

View File

@ -145,7 +145,7 @@
#include "nsIWritablePropertyBag2.h"
#include "nsIWyciwygChannel.h"
#include "nsPICommandUpdater.h"
#include "nsCommandManager.h"
#include "nsPIDOMWindow.h"
#include "nsPILoadGroupInternal.h"
#include "nsPIWindowRoot.h"
@ -1550,6 +1550,14 @@ nsDocShell::GetHasTrackingContentBlocked(bool* aHasTrackingContentBlocked)
return NS_OK;
}
NS_IMETHODIMP
nsDocShell::GetHasSlowTrackingContentBlocked(bool* aHasSlowTrackingContentBlocked)
{
nsCOMPtr<nsIDocument> doc(GetDocument());
*aHasSlowTrackingContentBlocked = doc && doc->GetHasSlowTrackingContentBlocked();
return NS_OK;
}
NS_IMETHODIMP
nsDocShell::GetHasTrackingContentLoaded(bool* aHasTrackingContentLoaded)
{
@ -1558,6 +1566,38 @@ nsDocShell::GetHasTrackingContentLoaded(bool* aHasTrackingContentLoaded)
return NS_OK;
}
NS_IMETHODIMP
nsDocShell::GetHasCookiesBlockedByPermission(bool* aHasCookiesBlockedByPermission)
{
nsCOMPtr<nsIDocument> doc(GetDocument());
*aHasCookiesBlockedByPermission = doc && doc->GetHasCookiesBlockedByPermission();
return NS_OK;
}
NS_IMETHODIMP
nsDocShell::GetHasCookiesBlockedDueToTrackers(bool* aHasCookiesBlockedDueToTrackers)
{
nsCOMPtr<nsIDocument> doc(GetDocument());
*aHasCookiesBlockedDueToTrackers = doc && doc->GetHasTrackingCookiesBlocked();
return NS_OK;
}
NS_IMETHODIMP
nsDocShell::GetHasAllCookiesBeenBlocked(bool* aHasAllCookiesBeenBlocked)
{
nsCOMPtr<nsIDocument> doc(GetDocument());
*aHasAllCookiesBeenBlocked = doc && doc->GetHasAllCookiesBlocked();
return NS_OK;
}
NS_IMETHODIMP
nsDocShell::GetHasForeignCookiesBeenBlocked(bool* aHasForeignCookiesBeenBlocked)
{
nsCOMPtr<nsIDocument> doc(GetDocument());
*aHasForeignCookiesBeenBlocked = doc && doc->GetHasForeignCookiesBlocked();
return NS_OK;
}
NS_IMETHODIMP
nsDocShell::GetAllowPlugins(bool* aAllowPlugins)
{
@ -13245,11 +13285,7 @@ nsresult
nsDocShell::EnsureCommandHandler()
{
if (!mCommandManager) {
nsCOMPtr<nsPICommandUpdater> commandUpdater =
do_CreateInstance("@mozilla.org/embedcomp/command-manager;1");
if (!commandUpdater) {
return NS_ERROR_OUT_OF_MEMORY;
}
nsCOMPtr<nsPICommandUpdater> commandUpdater = new nsCommandManager();
nsCOMPtr<nsPIDOMWindowOuter> domWindow = GetWindow();
nsresult rv = commandUpdater->Init(domWindow);

View File

@ -625,6 +625,36 @@ interface nsIDocShell : nsIDocShellTreeItem
*/
[infallible] readonly attribute boolean hasTrackingContentLoaded;
/**
* This attribute determines whether a document has Slow Tracking Content
* that has been blocked from loading.
*/
[infallible] readonly attribute boolean hasSlowTrackingContentBlocked;
/**
* This attribute determines whether a document seen cookies or storage
* blocked due to a site permission being denied.
*/
[infallible] readonly attribute boolean hasCookiesBlockedByPermission;
/**
* This attribute determines whether a document seen cookies or storage
* blocked due to a the request being made by a tracker.
*/
[infallible] readonly attribute boolean hasCookiesBlockedDueToTrackers;
/**
* This attribute determines whether a document seen cookies or storage
* blocked due to cookie behavior settings blocking all cookies.
*/
[infallible] readonly attribute boolean hasAllCookiesBeenBlocked;
/**
* This attribute determines whether a document seen cookies or storage
* blocked due to cookie behavior settings blocking all third-party cookies.
*/
[infallible] readonly attribute boolean hasForeignCookiesBeenBlocked;
/**
* Disconnects this docshell's editor from its window, and stores the
* editor data in the open document's session history entry. This

View File

@ -2044,23 +2044,54 @@ Element::AttrValueIs(int32_t aNameSpaceID,
} // namespace dom
} // namespace mozilla
inline mozilla::dom::Element* nsINode::AsElement()
inline mozilla::dom::Element*
nsINode::AsElement()
{
MOZ_ASSERT(IsElement());
return static_cast<mozilla::dom::Element*>(this);
}
inline const mozilla::dom::Element* nsINode::AsElement() const
inline const mozilla::dom::Element*
nsINode::AsElement() const
{
MOZ_ASSERT(IsElement());
return static_cast<const mozilla::dom::Element*>(this);
}
inline mozilla::dom::Element* nsINode::GetParentElement() const
inline mozilla::dom::Element*
nsINode::GetParentElement() const
{
return mozilla::dom::Element::FromNodeOrNull(mParent);
}
inline mozilla::dom::Element*
nsINode::GetPreviousElementSibling() const
{
nsIContent* previousSibling = GetPreviousSibling();
while (previousSibling) {
if (previousSibling->IsElement()) {
return previousSibling->AsElement();
}
previousSibling = previousSibling->GetPreviousSibling();
}
return nullptr;
}
inline mozilla::dom::Element*
nsINode::GetNextElementSibling() const
{
nsIContent* nextSibling = GetNextSibling();
while (nextSibling) {
if (nextSibling->IsElement()) {
return nextSibling->AsElement();
}
nextSibling = nextSibling->GetNextSibling();
}
return nullptr;
}
/**
* Macros to implement Clone(). _elementName is the class for which to implement
* Clone.

View File

@ -9,10 +9,10 @@
#include "mozilla/EventStates.h"
#include "mozilla/MemoryReporting.h"
#include "mozilla/dom/Element.h"
#ifdef ANDROID
#include "mozilla/IHistory.h"
#else
#if defined(MOZ_PLACES)
#include "mozilla/places/History.h"
#else
#include "mozilla/IHistory.h"
#endif
#include "nsIURL.h"
#include "nsIURIMutator.h"
@ -35,7 +35,7 @@
namespace mozilla {
namespace dom {
#ifndef ANDROID
#if defined(MOZ_PLACES)
using places::History;
#endif
@ -381,8 +381,10 @@ Link::LinkState() const
if (mHistory && hrefURI) {
#ifdef ANDROID
nsCOMPtr<IHistory> history = services::GetHistoryService();
#else
#elif defined(MOZ_PLACES)
History* history = History::GetService();
#else
nsCOMPtr<IHistory> history;
#endif
if (history) {
nsresult rv = history->RegisterVisitedCallback(hrefURI, self);
@ -846,8 +848,10 @@ Link::UnregisterFromHistory()
if (mHistory && mCachedURI) {
#ifdef ANDROID
nsCOMPtr<IHistory> history = services::GetHistoryService();
#else
#elif defined(MOZ_PLACES)
History* history = History::GetService();
#else
nsCOMPtr<IHistory> history;
#endif
if (history) {
nsresult rv = history->UnregisterVisitedCallback(mCachedURI, this);

View File

@ -1415,6 +1415,11 @@ nsIDocument::nsIDocument()
mHasUnsafeEvalCSP(false),
mHasUnsafeInlineCSP(false),
mHasTrackingContentBlocked(false),
mHasSlowTrackingContentBlocked(false),
mHasAllCookiesBlocked(false),
mHasTrackingCookiesBlocked(false),
mHasForeignCookiesBlocked(false),
mHasCookiesBlockedByPermission(false),
mHasTrackingContentLoaded(false),
mBFCacheDisallowed(false),
mHasHadDefaultView(false),

View File

@ -5291,8 +5291,16 @@ nsGlobalWindowOuter::NotifyContentBlockingState(unsigned aState,
securityUI->GetState(&state);
if (aState == nsIWebProgressListener::STATE_BLOCKED_TRACKING_CONTENT) {
doc->SetHasTrackingContentBlocked(true);
} else if (aState == nsIWebProgressListener::STATE_BLOCKED_SLOW_TRACKING_CONTENT) {
doc->SetHasSlowTrackingContentBlocked(true);
} else if (aState == nsIWebProgressListener::STATE_COOKIES_BLOCKED_BY_PERMISSION) {
doc->SetHasCookiesBlockedByPermission(true);
} else if (aState == nsIWebProgressListener::STATE_COOKIES_BLOCKED_TRACKER) {
doc->SetHasTrackingCookiesBlocked(true);
} else if (aState == nsIWebProgressListener::STATE_COOKIES_BLOCKED_ALL) {
doc->SetHasAllCookiesBlocked(true);
} else if (aState == nsIWebProgressListener::STATE_COOKIES_BLOCKED_FOREIGN) {
doc->SetHasForeignCookiesBlocked(true);
} else {
// Ignore nsIWebProgressListener::STATE_BLOCKED_UNSAFE_CONTENT;
}

View File

@ -977,6 +977,22 @@ public:
return mHasTrackingContentBlocked;
}
/**
* Get slow tracking content blocked flag for this document.
*/
bool GetHasSlowTrackingContentBlocked()
{
return mHasSlowTrackingContentBlocked;
}
/**
* Get all cookies blocked flag for this document.
*/
bool GetHasAllCookiesBlocked()
{
return mHasAllCookiesBlocked;
}
/**
* Get tracking cookies blocked flag for this document.
*/
@ -985,6 +1001,22 @@ public:
return mHasTrackingCookiesBlocked;
}
/**
* Get third-party cookies blocked flag for this document.
*/
bool GetHasForeignCookiesBlocked()
{
return mHasForeignCookiesBlocked;
}
/**
* Get cookies blocked by site permission flag for this document.
*/
bool GetHasCookiesBlockedByPermission()
{
return mHasCookiesBlockedByPermission;
}
/**
* Set the tracking content blocked flag for this document.
*/
@ -993,6 +1025,22 @@ public:
mHasTrackingContentBlocked = aHasTrackingContentBlocked;
}
/**
* Set the slow tracking content blocked flag for this document.
*/
void SetHasSlowTrackingContentBlocked(bool aHasSlowTrackingContentBlocked)
{
mHasSlowTrackingContentBlocked = aHasSlowTrackingContentBlocked;
}
/**
* Set the all cookies blocked flag for this document.
*/
void SetHasAllCookiesBlocked(bool aHasAllCookiesBlocked)
{
mHasAllCookiesBlocked = aHasAllCookiesBlocked;
}
/**
* Set the tracking cookies blocked flag for this document.
*/
@ -1001,6 +1049,22 @@ public:
mHasTrackingCookiesBlocked = aHasTrackingCookiesBlocked;
}
/**
* Set the third-party cookies blocked flag for this document.
*/
void SetHasForeignCookiesBlocked(bool aHasForeignCookiesBlocked)
{
mHasForeignCookiesBlocked = aHasForeignCookiesBlocked;
}
/**
* Set the cookies blocked by site permission flag for this document.
*/
void SetHasCookiesBlockedByPermission(bool aHasCookiesBlockedByPermission)
{
mHasCookiesBlockedByPermission = aHasCookiesBlockedByPermission;
}
/**
* Get tracking content loaded flag for this document.
*/
@ -4003,9 +4067,21 @@ protected:
// True if a document has blocked Tracking Content
bool mHasTrackingContentBlocked : 1;
// True if a document has blocked Slow Tracking Content
bool mHasSlowTrackingContentBlocked : 1;
// True if a document has blocked All Cookies
bool mHasAllCookiesBlocked : 1;
// True if a document has blocked Tracking Cookies
bool mHasTrackingCookiesBlocked : 1;
// True if a document has blocked Foreign Cookies
bool mHasForeignCookiesBlocked : 1;
// True if a document has blocked Cookies By Site Permission
bool mHasCookiesBlockedByPermission : 1;
// True if a document has loaded Tracking Content
bool mHasTrackingContentLoaded : 1;

View File

@ -1571,34 +1571,6 @@ nsINode::ComputeIndexOf(const nsINode* aChild) const
return -1;
}
Element*
nsINode::GetPreviousElementSibling() const
{
nsIContent* previousSibling = GetPreviousSibling();
while (previousSibling) {
if (previousSibling->IsElement()) {
return previousSibling->AsElement();
}
previousSibling = previousSibling->GetPreviousSibling();
}
return nullptr;
}
Element*
nsINode::GetNextElementSibling() const
{
nsIContent* nextSibling = GetNextSibling();
while (nextSibling) {
if (nextSibling->IsElement()) {
return nextSibling->AsElement();
}
nextSibling = nextSibling->GetNextSibling();
}
return nullptr;
}
static already_AddRefed<nsINode>
GetNodeFromNodeOrString(const OwningNodeOrString& aNode,
nsIDocument* aDocument)

View File

@ -1836,8 +1836,8 @@ public:
}
// ChildNode methods
mozilla::dom::Element* GetPreviousElementSibling() const;
mozilla::dom::Element* GetNextElementSibling() const;
inline mozilla::dom::Element* GetPreviousElementSibling() const;
inline mozilla::dom::Element* GetNextElementSibling() const;
MOZ_CAN_RUN_SCRIPT void Before(const Sequence<OwningNodeOrString>& aNodes,
ErrorResult& aRv);

View File

@ -120,6 +120,11 @@ const size_t gStackSize = 8192;
#define NS_CC_SKIPPABLE_DELAY 250 // ms
// In case the cycle collector isn't run at all, we don't want
// forget skippables to run too often. So limit the forget skippable cycle to
// start at earliest 2000 ms after the end of the previous cycle.
#define NS_TIME_BETWEEN_FORGET_SKIPPABLE_CYCLES 2000 // ms
// ForgetSkippable is usually fast, so we can use small budgets.
// This isn't a real budget but a hint to IdleTaskRunner whether there
// is enough time to call ForgetSkippable.
@ -161,6 +166,8 @@ static StaticRefPtr<IdleTaskRunner> sInterSliceGCRunner;
static TimeStamp sLastCCEndTime;
static TimeStamp sLastForgetSkippableCycleEndTime;
static bool sCCLockedOut;
static PRTime sCCLockedOutTime;
@ -2014,6 +2021,10 @@ CCRunnerFired(TimeStamp aDeadline)
// next time, so kill the timer.
sPreviousSuspectedCount = 0;
nsJSContext::KillCCRunner();
if (!didDoWork) {
sLastForgetSkippableCycleEndTime = TimeStamp::Now();
}
}
return didDoWork;
@ -2228,6 +2239,17 @@ nsJSContext::MaybePokeCC()
return;
}
// If GC hasn't run recently and forget skippable only cycle was run,
// don't start a new cycle too soon.
if (sCleanupsSinceLastGC > NS_MAJOR_FORGET_SKIPPABLE_CALLS) {
uint32_t sinceLastForgetSkippableCycle =
TimeUntilNow(sLastForgetSkippableCycleEndTime);
if (sinceLastForgetSkippableCycle &&
sinceLastForgetSkippableCycle < NS_TIME_BETWEEN_FORGET_SKIPPABLE_CYCLES) {
return;
}
}
if (ShouldTriggerCC(nsCycleCollector_suspectedCount())) {
sCCRunnerFireCount = 0;
@ -2490,6 +2512,7 @@ mozilla::dom::StartupJSEnvironment()
sCCLockedOut = false;
sCCLockedOutTime = 0;
sLastCCEndTime = TimeStamp();
sLastForgetSkippableCycleEndTime = TimeStamp();
sHasRunGC = false;
sPendingLoadCount = 0;
sLoadingInProgress = false;

View File

@ -106,9 +106,9 @@ MSG_DEF(MSG_CACHE_OPEN_FAILED, 0, JSEXN_TYPEERR, "CacheStorage.open() failed to
MSG_DEF(MSG_MATRIX_INIT_LENGTH_WRONG, 1, JSEXN_TYPEERR, "Matrix init sequence must have a length of 6 or 16 (actual value: {0})")
MSG_DEF(MSG_INVALID_MEDIA_VIDEO_CONFIGURATION, 0, JSEXN_TYPEERR, "Invalid VideoConfiguration.")
MSG_DEF(MSG_INVALID_MEDIA_AUDIO_CONFIGURATION, 0, JSEXN_TYPEERR, "Invalid AudioConfiguration.")
MSG_DEF(MSG_INVALID_CURVE_DURATION_ERROR, 0, JSEXN_RANGEERR, "The curve duration for SetValueCurve must be strictly positive.")
MSG_DEF(MSG_INVALID_AUDIOPARAM_METHOD_START_TIME_ERROR, 0, JSEXN_RANGEERR, "The start time for an AudioParam method must be positive.")
MSG_DEF(MSG_INVALID_AUDIOPARAM_METHOD_END_TIME_ERROR, 0, JSEXN_RANGEERR, "The end time for an AudioParam method must be positive.")
MSG_DEF(MSG_INVALID_AUDIOPARAM_EXPONENTIAL_VALUE_ERROR, 0, JSEXN_RANGEERR, "The value passed to exponentialCurveToValueAtTime must be positive.")
MSG_DEF(MSG_INVALID_AUDIOPARAM_EXPONENTIAL_CONSTANT_ERROR, 0, JSEXN_RANGEERR, "The exponential constant passed to setTargetAtTime must be positive.")
MSG_DEF(MSG_INVALID_CURVE_DURATION_ERROR, 0, JSEXN_RANGEERR, "The curve duration for setValueCurveAtTime must be strictly positive.")
MSG_DEF(MSG_INVALID_AUDIOPARAM_METHOD_START_TIME_ERROR, 0, JSEXN_RANGEERR, "The start time for an AudioParam method must be non-negative.")
MSG_DEF(MSG_INVALID_AUDIOPARAM_METHOD_END_TIME_ERROR, 0, JSEXN_RANGEERR, "The end time for an AudioParam method must be non-negative.")
MSG_DEF(MSG_INVALID_AUDIOPARAM_EXPONENTIAL_VALUE_ERROR, 0, JSEXN_RANGEERR, "The value passed to exponentialRampToValueAtTime must be positive.")
MSG_DEF(MSG_INVALID_AUDIOPARAM_EXPONENTIAL_CONSTANT_ERROR, 0, JSEXN_RANGEERR, "The exponential constant passed to setTargetAtTime must be non-negative.")
MSG_DEF(MSG_VALUE_OUT_OF_RANGE, 1, JSEXN_RANGEERR, "The value for the {0} is outside the valid range.")

View File

@ -8,6 +8,8 @@ with Files("**"):
BUG_COMPONENT = ("Core", "Embedding: APIs")
EXPORTS += [
'nsBaseCommandController.h',
'nsCommandManager.h',
'nsCommandParams.h',
]

View File

@ -7,11 +7,6 @@
#ifndef nsBaseCommandController_h__
#define nsBaseCommandController_h__
#define NS_BASECOMMANDCONTROLLER_CID \
{ 0xbf88b48c, 0xfd8e, 0x40b4, { 0xba, 0x36, 0xc7, 0xc3, 0xad, 0x6d, 0x8a, 0xc9 } }
#define NS_BASECOMMANDCONTROLLER_CONTRACTID \
"@mozilla.org/embedcomp/base-command-controller;1"
#include "nsIController.h"
#include "nsIControllerContext.h"
#include "nsIControllerCommandTable.h"

View File

@ -105,14 +105,3 @@ Arguments to observers "Observe" method are as follows:
*/
// {64edb481-0c04-11d5-a73c-e964b968b0bc}
%{C++
#define NS_COMMAND_MANAGER_CID \
{ 0x64edb481, 0x0c04, 0x11d5, { 0xa7, 0x3c, 0xe9, 0x64, 0xb9, 0x68, 0xb0, 0xbc } }
#define NS_COMMAND_MANAGER_CONTRACTID \
"@mozilla.org/embedcomp/command-manager;1"
%}

View File

@ -116,7 +116,7 @@ AudioEventTimeline::GetValuesAtTimeHelper(TimeType aTime, float* aBuffer,
MOZ_ASSERT(aSize);
auto TimeOf = [](const AudioTimelineEvent& aEvent) -> TimeType {
return aEvent.template Time<TimeType>();
return aEvent.Time<TimeType>();
};
size_t eventIndex = 0;
@ -186,7 +186,7 @@ AudioEventTimeline::GetValuesAtTimeHelper(int64_t aTime, float* aBuffer,
template<class TimeType> float
AudioEventTimeline::GetValueAtTimeOfEvent(const AudioTimelineEvent* aNext)
{
TimeType time = aNext->template Time<TimeType>();
TimeType time = aNext->Time<TimeType>();
switch (aNext->mType) {
case AudioTimelineEvent::SetTarget:
// SetTarget nodes can be handled no matter what their next node is
@ -225,9 +225,9 @@ AudioEventTimeline::GetValuesAtTimeHelperInternal(TimeType aTime,
// Otherwise, this returns the time of the event.
auto TimeOf = [](const AudioTimelineEvent* aEvent) -> TimeType {
if (aEvent->mType == AudioTimelineEvent::SetValueCurve) {
return aEvent->template Time<TimeType>() + aEvent->mDuration;
return aEvent->Time<TimeType>() + aEvent->mDuration;
}
return aEvent->template Time<TimeType>();
return aEvent->Time<TimeType>();
};
// Value for an event. For a ValueCurve event, this is the value of the last
@ -243,17 +243,21 @@ AudioEventTimeline::GetValuesAtTimeHelperInternal(TimeType aTime,
// they have one)
if (aPrevious->mType == AudioTimelineEvent::SetTarget) {
return ExponentialApproach(TimeOf(aPrevious),
mLastComputedValue, ValueOf(aPrevious),
aPrevious->mTimeConstant, aTime);
mLastComputedValue,
ValueOf(aPrevious),
aPrevious->mTimeConstant,
aTime);
}
// SetValueCurve events can be handled no matter what their next node is
// (if they have one), when aTime is in the curve region.
if (aPrevious->mType == AudioTimelineEvent::SetValueCurve &&
aTime <= aPrevious->template Time<TimeType>() + aPrevious->mDuration) {
return ExtractValueFromCurve(aPrevious->template Time<TimeType>(),
aPrevious->mCurve, aPrevious->mCurveLength,
aPrevious->mDuration, aTime);
aTime <= aPrevious->Time<TimeType>() + aPrevious->mDuration) {
return ExtractValueFromCurve(aPrevious->Time<TimeType>(),
aPrevious->mCurve,
aPrevious->mCurveLength,
aPrevious->mDuration,
aTime);
}
// If the requested time is after all of the existing events
@ -265,9 +269,11 @@ AudioEventTimeline::GetValuesAtTimeHelperInternal(TimeType aTime,
// The value will be constant after the last event
return aPrevious->mValue;
case AudioTimelineEvent::SetValueCurve:
return ExtractValueFromCurve(aPrevious->template Time<TimeType>(),
aPrevious->mCurve, aPrevious->mCurveLength,
aPrevious->mDuration, aTime);
return ExtractValueFromCurve(aPrevious->Time<TimeType>(),
aPrevious->mCurve,
aPrevious->mCurveLength,
aPrevious->mDuration,
aTime);
case AudioTimelineEvent::SetTarget:
MOZ_FALLTHROUGH_ASSERT("AudioTimelineEvent::SetTarget");
case AudioTimelineEvent::SetValue:
@ -286,13 +292,15 @@ AudioEventTimeline::GetValuesAtTimeHelperInternal(TimeType aTime,
return LinearInterpolate(TimeOf(aPrevious),
ValueOf(aPrevious),
TimeOf(aNext),
ValueOf(aNext), aTime);
ValueOf(aNext),
aTime);
case AudioTimelineEvent::ExponentialRamp:
return ExponentialInterpolate(TimeOf(aPrevious),
ValueOf(aPrevious),
TimeOf(aNext),
ValueOf(aNext), aTime);
ValueOf(aNext),
aTime);
case AudioTimelineEvent::SetValueAtTime:
case AudioTimelineEvent::SetTarget:
@ -313,9 +321,11 @@ AudioEventTimeline::GetValuesAtTimeHelperInternal(TimeType aTime,
// value is constant.
return aPrevious->mValue;
case AudioTimelineEvent::SetValueCurve:
return ExtractValueFromCurve(aPrevious->template Time<TimeType>(),
aPrevious->mCurve, aPrevious->mCurveLength,
aPrevious->mDuration, aTime);
return ExtractValueFromCurve(aPrevious->Time<TimeType>(),
aPrevious->mCurve,
aPrevious->mCurveLength,
aPrevious->mDuration,
aTime);
case AudioTimelineEvent::SetTarget:
MOZ_FALLTHROUGH_ASSERT("AudioTimelineEvent::SetTarget");
case AudioTimelineEvent::SetValue:
@ -343,7 +353,7 @@ AudioEventTimeline::GetPreviousEvent(double aTime) const
const AudioTimelineEvent* next = nullptr;
auto TimeOf = [](const AudioTimelineEvent& aEvent) -> double {
return aEvent.template Time<double>();
return aEvent.Time<double>();
};
bool bailOut = false;

View File

@ -131,32 +131,28 @@ public:
MOZ_ASSERT(NS_IsMainThread());
auto TimeOf = [](const AudioTimelineEvent& aEvent) -> double {
return aEvent.template Time<double>();
return aEvent.Time<double>();
};
// Validate the event itself
if (!WebAudioUtils::IsTimeValid(TimeOf(aEvent))) {
aRv.template ThrowRangeError<
aRv.ThrowRangeError<
MSG_INVALID_AUDIOPARAM_METHOD_START_TIME_ERROR>();
return false;
}
if (!WebAudioUtils::IsTimeValid(aEvent.mTimeConstant)) {
aRv.template ThrowRangeError<
aRv.ThrowRangeError<
MSG_INVALID_AUDIOPARAM_EXPONENTIAL_CONSTANT_ERROR>();
return false;
}
if (aEvent.mType == AudioTimelineEvent::SetValueCurve) {
if (!aEvent.mCurve || !aEvent.mCurveLength) {
aRv.Throw(NS_ERROR_DOM_INVALID_STATE_ERR);
return false;
}
if (aEvent.mCurveLength < 2) {
if (!aEvent.mCurve || aEvent.mCurveLength < 2) {
aRv.Throw(NS_ERROR_DOM_INVALID_STATE_ERR);
return false;
}
if (aEvent.mDuration <= 0) {
aRv.template ThrowRangeError<MSG_INVALID_CURVE_DURATION_ERROR>();
aRv.ThrowRangeError<MSG_INVALID_CURVE_DURATION_ERROR>();
return false;
}
}
@ -174,12 +170,12 @@ public:
}
}
// Make sure that new curve events don't fall in a range which includes other
// events.
// Make sure that new curve events don't fall in a range which includes
// other events.
if (aEvent.mType == AudioTimelineEvent::SetValueCurve) {
for (unsigned i = 0; i < mEvents.Length(); ++i) {
if (TimeOf(aEvent) < TimeOf(mEvents[i]) &&
TimeOf(aEvent) + aEvent.mDuration >= TimeOf(mEvents[i])) {
TimeOf(aEvent) + aEvent.mDuration > TimeOf(mEvents[i])) {
aRv.Throw(NS_ERROR_DOM_NOT_SUPPORTED_ERR);
return false;
}
@ -189,7 +185,7 @@ public:
// Make sure that invalid values are not used for exponential curves
if (aEvent.mType == AudioTimelineEvent::ExponentialRamp) {
if (aEvent.mValue <= 0.f) {
aRv.template ThrowRangeError<
aRv.ThrowRangeError<
MSG_INVALID_AUDIOPARAM_EXPONENTIAL_VALUE_ERROR>();
return false;
}
@ -213,18 +209,18 @@ public:
void InsertEvent(const AudioTimelineEvent& aEvent)
{
for (unsigned i = 0; i < mEvents.Length(); ++i) {
if (aEvent.template Time<TimeType>() == mEvents[i].template Time<TimeType>()) {
if (aEvent.Time<TimeType>() == mEvents[i].Time<TimeType>()) {
// If two events happen at the same time, have them in chronological
// order of insertion.
do {
++i;
} while (i < mEvents.Length() &&
aEvent.mType != mEvents[i].mType &&
aEvent.template Time<TimeType>() == mEvents[i].template Time<TimeType>());
} while (i < mEvents.Length() && aEvent.mType != mEvents[i].mType &&
aEvent.Time<TimeType>() == mEvents[i].Time<TimeType>());
mEvents.InsertElementAt(i, aEvent);
return;
}
// Otherwise, place the event right after the latest existing event
if (aEvent.template Time<TimeType>() < mEvents[i].template Time<TimeType>()) {
if (aEvent.Time<TimeType>() < mEvents[i].Time<TimeType>()) {
mEvents.InsertElementAt(i, aEvent);
return;
}
@ -308,12 +304,12 @@ public:
void CancelScheduledValues(TimeType aStartTime)
{
for (unsigned i = 0; i < mEvents.Length(); ++i) {
if (mEvents[i].template Time<TimeType>() >= aStartTime) {
if (mEvents[i].Time<TimeType>() >= aStartTime) {
#ifdef DEBUG
// Sanity check: the array should be sorted, so all of the following
// events should have a time greater than aStartTime too.
for (unsigned j = i + 1; j < mEvents.Length(); ++j) {
MOZ_ASSERT(mEvents[j].template Time<TimeType>() >= aStartTime);
MOZ_ASSERT(mEvents[j].Time<TimeType>() >= aStartTime);
}
#endif
mEvents.TruncateLength(i);
@ -364,13 +360,11 @@ public:
template<class TimeType>
void CleanupEventsOlderThan(TimeType aTime)
{
while (mEvents.Length() > 1 &&
aTime > mEvents[1].template Time<TimeType>()) {
while (mEvents.Length() > 1 && aTime > mEvents[1].Time<TimeType>()) {
if (mEvents[1].mType == AudioTimelineEvent::SetTarget) {
mLastComputedValue = GetValuesAtTimeHelperInternal(
mEvents[1].template Time<TimeType>(),
&mEvents[0], nullptr);
mEvents[1].Time<TimeType>(), &mEvents[0], nullptr);
}
mEvents.RemoveElementAt(0);

View File

@ -51,14 +51,13 @@ public:
ErrorResult& aRv)
{
if (!WebAudioUtils::IsTimeValid(aStartTime)) {
aRv.template ThrowRangeError<
aRv.ThrowRangeError<
MSG_INVALID_AUDIOPARAM_METHOD_START_TIME_ERROR>();
return this;
}
aStartTime = std::max(aStartTime, GetParentObject()->CurrentTime());
EventInsertionHelper(aRv, AudioTimelineEvent::SetValueCurve,
aStartTime, 0.0f,
0.0f, aDuration, aValues.Elements(),
aStartTime, 0.0f, 0.0f, aDuration, aValues.Elements(),
aValues.Length());
return this;
@ -83,7 +82,7 @@ public:
AudioParam* SetValueAtTime(float aValue, double aStartTime, ErrorResult& aRv)
{
if (!WebAudioUtils::IsTimeValid(aStartTime)) {
aRv.template ThrowRangeError<
aRv.ThrowRangeError<
MSG_INVALID_AUDIOPARAM_METHOD_START_TIME_ERROR>();
return this;
}
@ -98,7 +97,7 @@ public:
ErrorResult& aRv)
{
if (!WebAudioUtils::IsTimeValid(aEndTime)) {
aRv.template ThrowRangeError<
aRv.ThrowRangeError<
MSG_INVALID_AUDIOPARAM_METHOD_END_TIME_ERROR>();
return this;
}
@ -111,7 +110,7 @@ public:
ErrorResult& aRv)
{
if (!WebAudioUtils::IsTimeValid(aEndTime)) {
aRv.template ThrowRangeError<
aRv.ThrowRangeError<
MSG_INVALID_AUDIOPARAM_METHOD_END_TIME_ERROR>();
return this;
}
@ -126,7 +125,7 @@ public:
{
if (!WebAudioUtils::IsTimeValid(aStartTime) ||
!WebAudioUtils::IsTimeValid(aTimeConstant)) {
aRv.template ThrowRangeError<
aRv.ThrowRangeError<
MSG_INVALID_AUDIOPARAM_METHOD_START_TIME_ERROR>();
return this;
}
@ -141,7 +140,7 @@ public:
AudioParam* CancelScheduledValues(double aStartTime, ErrorResult& aRv)
{
if (!WebAudioUtils::IsTimeValid(aStartTime)) {
aRv.template ThrowRangeError<
aRv.ThrowRangeError<
MSG_INVALID_AUDIOPARAM_METHOD_START_TIME_ERROR>();
return this;
}

View File

@ -53,7 +53,7 @@ public:
void InsertEvent(const AudioTimelineEvent& aEvent)
{
if (aEvent.mType == AudioTimelineEvent::Cancel) {
CancelScheduledValues(aEvent.template Time<TimeType>());
CancelScheduledValues(aEvent.Time<TimeType>());
return;
}
if (aEvent.mType == AudioTimelineEvent::Stream) {

View File

@ -9,6 +9,7 @@
#include "mozilla/ModuleUtils.h"
#include "mozilla/mozalloc.h" // for operator new
#include "nsCOMPtr.h" // for nsCOMPtr, getter_AddRefs, etc
#include "nsBaseCommandController.h" // for nsBaseCommandController
#include "nsComponentManagerUtils.h" // for do_CreateInstance
#include "nsComposeTxtSrvFilter.h" // for nsComposeTxtSrvFilter, etc
#include "nsDebug.h" // for NS_ENSURE_SUCCESS
@ -99,10 +100,9 @@ nsComposeTxtSrvFilterConstructorForMail(nsISupports *aOuter,
static nsresult
CreateControllerWithSingletonCommandTable(const nsCID& inCommandTableCID, nsIController **aResult)
{
nsresult rv;
nsCOMPtr<nsIController> controller = do_CreateInstance("@mozilla.org/embedcomp/base-command-controller;1", &rv);
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsIController> controller = new nsBaseCommandController();
nsresult rv;
nsCOMPtr<nsIControllerCommandTable> composerCommandTable = do_GetService(inCommandTableCID, &rv);
NS_ENSURE_SUCCESS(rv, rv);

View File

@ -291,7 +291,6 @@ GCRuntime::checkAllocatorState(JSContext* cx, AllocKind kind)
kind != AllocKind::ATOM &&
kind != AllocKind::FAT_INLINE_ATOM);
MOZ_ASSERT(!JS::RuntimeHeapIsBusy());
MOZ_ASSERT(cx->isAllocAllowed());
#endif
// Crash if we perform a GC action when it is not safe.

View File

@ -7689,8 +7689,6 @@ GCRuntime::checkCanCallAPI()
/* If we attempt to invoke the GC while we are running in the GC, assert. */
MOZ_RELEASE_ASSERT(!JS::RuntimeHeapIsBusy());
MOZ_ASSERT(rt->mainContextFromOwnThread()->isAllocAllowed());
}
bool

View File

@ -3,12 +3,7 @@ var functionProxy = new Proxy(function() {}, {});
assertEq(Object.prototype.toString.call(objectProxy), '[object Object]');
assertEq(Object.prototype.toString.call(functionProxy), '[object Function]');
try {
Function.prototype.toString.call(functionProxy);
assertEq(true, false);
} catch (e) {
assertEq(!!/incompatible/.exec(e), true);
}
try {
Function.prototype.toString.call(objectProxy);
assertEq(true, false);

View File

@ -1,7 +1,5 @@
// |jit-test| error: out of memory
if (!('oomTest' in this))
throw new Error("out of memory");
quit()
var dbg = new Debugger;
dbg.onNewGlobalObject = function(global) {

View File

@ -1,7 +1,5 @@
// |jit-test| error: out of memory
if (!('oomTest' in this))
throw new Error("out of memory");
quit();
// jsfunfuzz-generated
fullcompartmentchecks(true);

View File

@ -1,7 +1,5 @@
// |jit-test| error: boom
if (!('oomTest' in this))
throw new Error("boom");
quit();
evaluate(`
function ERROR(msg) {

View File

@ -1,7 +1,7 @@
// |jit-test| error: out of memory; slow;
// |jit-test| slow
if (!('oomTest' in this))
throw new Error("out of memory");
quit();
var g = newGlobal();
var dbg = new Debugger(g);

View File

@ -1,7 +1,7 @@
// |jit-test| error:ReferenceError; slow
// |jit-test| slow
if (!('oomTest' in this))
throw (new ReferenceError);
quit();
var g = newGlobal();
g.debuggeeGlobal = this;

View File

@ -20,9 +20,7 @@ function loadFile(lfVarx) {
var k = 0;
oomTest(function() {
// In practice a crash occurs before iteration 4000.
if (k++ > 4000)
quit();
if (k++ <= 4000)
eval(lfVarx);
})
}

View File

@ -1,12 +1,15 @@
// |jit-test| error: out of memory; slow;
// |jit-test| slow
if (!('oomTest' in this))
quit();
// Adapted from randomly chosen test: js/src/jit-test/tests/modules/bug-1233915.js
g = newGlobal();
g.parent = this;
g.eval("(" + function() {
Debugger(parent).onExceptionUnwind = function(frame)
Debugger(parent).onExceptionUnwind = function(frame) {
frame.eval("")
} + ")()");
} } + ")()");
// Adapted from randomly chosen test: js/src/jit-test/tests/debug/bug1254123.js
function ERROR(msg) {
throw new Error("boom");

View File

@ -1,6 +1,5 @@
// |jit-test| error:InternalError
if (!('stackTest' in this))
throw InternalError();
quit();
stackTest(new Function(`
var g = newGlobal();
var dbg = new Debugger(g);

View File

@ -0,0 +1,4 @@
// |jit-test| --ion-limit-script-size=off; --ion-gvn=off
for (var i = 0; i < 1; ++i) {
"".replace(/x/, "").replace(/y/, "12");
}

View File

@ -1,10 +1,10 @@
load(libdir + 'asserts.js');
// Function.prototype.toString doesn't accept ES6 proxies.
var nativeCode = "function () {\n [native code]\n}";
var proxy = new Proxy(function() {}, {});
assertThrowsInstanceOf(() => Function.prototype.toString.call(proxy), TypeError);
assertEq(Function.prototype.toString.call(proxy), nativeCode);
var o = Proxy.revocable(function() {}, {});
assertThrowsInstanceOf(() => Function.prototype.toString.call(o.proxy), TypeError);
assertEq(Function.prototype.toString.call(o.proxy), nativeCode);
o.revoke();
assertThrowsInstanceOf(() => Function.prototype.toString.call(o.proxy), TypeError);
assertEq(Function.prototype.toString.call(o.proxy), nativeCode);

View File

@ -7589,7 +7589,10 @@ class MGetFirstDollarIndex
: MUnaryInstruction(classOpcode, str)
{
setResultType(MIRType::Int32);
setMovable();
// Codegen assumes string length > 0. Don't allow LICM to move this
// before the .length > 1 check in RegExpReplace in RegExp.js.
MOZ_ASSERT(!isMovable());
}
public:

View File

@ -310,8 +310,9 @@ BaseProxyHandler::fun_toString(JSContext* cx, HandleObject proxy, bool isToSourc
{
if (proxy->isCallable())
return JS_NewStringCopyZ(cx, "function () {\n [native code]\n}");
RootedValue v(cx, ObjectValue(*proxy));
ReportIsNotFunction(cx, v);
JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, JSMSG_INCOMPATIBLE_PROTO,
js_Function_str, js_toString_str, "object");
return nullptr;
}

View File

@ -1264,9 +1264,9 @@ ScriptedProxyHandler::className(JSContext* cx, HandleObject proxy) const
JSString*
ScriptedProxyHandler::fun_toString(JSContext* cx, HandleObject proxy, bool isToSource) const
{
JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, JSMSG_INCOMPATIBLE_PROTO,
js_Function_str, js_toString_str, "object");
return nullptr;
// The BaseProxyHandler has the desired behavior: Throw for non-callable,
// otherwise return [native code].
return BaseProxyHandler::fun_toString(cx, proxy, isToSource);
}
RegExpShared*

View File

@ -8243,12 +8243,19 @@ js::shell::AutoReportException::~AutoReportException()
savedExc.restore();
}
JS_ClearPendingException(cx);
#if defined(DEBUG) || defined(JS_OOM_BREAKPOINT)
// Don't quit the shell if an unhandled exception is reported during OOM
// testing.
if (cx->runningOOMTest)
return;
#endif
if (report.report()->errorNumber == JSMSG_OUT_OF_MEMORY)
sc->exitCode = EXITCODE_OUT_OF_MEMORY;
else
sc->exitCode = EXITCODE_RUNTIME_ERROR;
JS_ClearPendingException(cx);
}
void

View File

@ -414,19 +414,6 @@ skip script test262/annexB/built-ins/Function/createdynfn-html-close-comment-par
# https://bugzilla.mozilla.org/show_bug.cgi?id=1334813
skip script test262/built-ins/DataView/length.js
# https://bugzilla.mozilla.org/show_bug.cgi?id=1440468
skip script test262/built-ins/Function/prototype/toString/proxy.js
skip script test262/built-ins/Function/prototype/toString/proxy-async-generator-function.js
skip script test262/built-ins/Function/prototype/toString/proxy-class.js
skip script test262/built-ins/Function/prototype/toString/proxy-async-method-definition.js
skip script test262/built-ins/Function/prototype/toString/proxy-arrow-function.js
skip script test262/built-ins/Function/prototype/toString/proxy-async-generator-method-definition.js
skip script test262/built-ins/Function/prototype/toString/proxy-async-function.js
skip script test262/built-ins/Function/prototype/toString/proxy-bound-function.js
skip script test262/built-ins/Function/prototype/toString/proxy-method-definition.js
skip script test262/built-ins/Function/prototype/toString/proxy-function-expression.js
skip script test262/built-ins/Function/prototype/toString/proxy-generator-function.js
# https://bugzilla.mozilla.org/show_bug.cgi?id=1462741
skip script test262/built-ins/Function/prototype/toString/well-known-intrinsic-object-functions.js

View File

@ -1150,11 +1150,7 @@ ToDisassemblySource(JSContext* cx, HandleValue v, JSAutoByteString* bytes)
return true;
}
if (JS::RuntimeHeapIsBusy()
#ifdef DEBUG
|| !cx->isAllocAllowed()
#endif
) {
if (JS::RuntimeHeapIsBusy()) {
UniqueChars source = JS_smprintf("<value>");
if (!source) {
ReportOutOfMemory(cx);

View File

@ -1293,7 +1293,6 @@ JSContext::JSContext(JSRuntime* runtime, const JS::ContextOptions& options)
gcSweeping(false),
gcHelperStateThread(false),
isTouchingGrayThings(false),
noGCOrAllocationCheck(0),
noNurseryAllocationCheck(0),
disableStrictProxyCheckingCount(0),
#endif

View File

@ -544,7 +544,6 @@ struct JSContext : public JS::RootingContext,
// Whether this thread is currently manipulating possibly-gray GC things.
js::ThreadData<size_t> isTouchingGrayThings;
js::ThreadData<size_t> noGCOrAllocationCheck;
js::ThreadData<size_t> noNurseryAllocationCheck;
/*
@ -555,13 +554,6 @@ struct JSContext : public JS::RootingContext,
*/
js::ThreadData<uintptr_t> disableStrictProxyCheckingCount;
bool isAllocAllowed() { return noGCOrAllocationCheck == 0; }
void disallowAlloc() { ++noGCOrAllocationCheck; }
void allowAlloc() {
MOZ_ASSERT(!isAllocAllowed());
--noGCOrAllocationCheck;
}
bool isNurseryAllocAllowed() { return noNurseryAllocationCheck == 0; }
void disallowNurseryAlloc() { ++noNurseryAllocationCheck; }
void allowNurseryAlloc() {

View File

@ -1831,15 +1831,6 @@ JSObject::swap(JSContext* cx, HandleObject a, HandleObject b)
return true;
}
static bool
DefineStandardSlot(JSContext* cx, HandleObject obj, JSAtom* atom,
HandleValue v, uint32_t attrs, bool& named)
{
RootedId id(cx, AtomToId(atom));
named = DefineDataProperty(cx, obj, id, v, attrs);
return named;
}
static void
SetClassObject(JSObject* obj, JSProtoKey key, JSObject* cobj, JSObject* proto)
{
@ -1898,9 +1889,15 @@ DefineConstructorAndPrototype(JSContext* cx, HandleObject obj, JSProtoKey key, H
if (!proto)
return nullptr;
/*
* Whether we need to define a constructor property on |obj| and which
* attributes to use.
*/
bool defineConstructorProperty = false;
uint32_t propertyAttrs = 0;
/* After this point, control must exit via label bad or out. */
RootedNativeObject ctor(cx);
bool named = false;
bool cached = false;
if (!constructor) {
/*
@ -1912,12 +1909,10 @@ DefineConstructorAndPrototype(JSContext* cx, HandleObject obj, JSProtoKey key, H
if (!(clasp->flags & JSCLASS_IS_ANONYMOUS) || !obj->is<GlobalObject>() ||
key == JSProto_Null)
{
uint32_t attrs = (clasp->flags & JSCLASS_IS_ANONYMOUS)
defineConstructorProperty = true;
propertyAttrs = (clasp->flags & JSCLASS_IS_ANONYMOUS)
? JSPROP_READONLY | JSPROP_PERMANENT
: 0;
RootedValue value(cx, ObjectValue(*proto));
if (!DefineStandardSlot(cx, obj, atom, value, attrs, named))
goto bad;
}
ctor = proto;
@ -1936,9 +1931,8 @@ DefineConstructorAndPrototype(JSContext* cx, HandleObject obj, JSProtoKey key, H
cached = true;
}
RootedValue value(cx, ObjectValue(*fun));
if (!DefineStandardSlot(cx, obj, atom, value, 0, named))
goto bad;
defineConstructorProperty = true;
propertyAttrs = 0;
/*
* Optionally construct the prototype object, before the class has
@ -1961,6 +1955,13 @@ DefineConstructorAndPrototype(JSContext* cx, HandleObject obj, JSProtoKey key, H
goto bad;
}
if (defineConstructorProperty) {
RootedId id(cx, AtomToId(atom));
RootedValue value(cx, ObjectValue(*ctor));
if (!DefineDataProperty(cx, obj, id, value, propertyAttrs))
goto bad;
}
/* If this is a standard class, cache its prototype. */
if (!cached && key != JSProto_Null)
SetClassObject(obj, key, ctor, proto);
@ -1970,13 +1971,6 @@ DefineConstructorAndPrototype(JSContext* cx, HandleObject obj, JSProtoKey key, H
return proto;
bad:
if (named) {
ObjectOpResult ignored;
RootedId id(cx, AtomToId(atom));
// XXX FIXME - absurd to call this here; instead define the property last.
DeleteProperty(cx, obj, id, ignored);
}
if (cached)
ClearClassObject(obj, key);
return nullptr;

View File

@ -155,6 +155,7 @@ static void Shutdown();
#include "mozilla/dom/PresentationTCPSessionTransport.h"
#include "nsScriptError.h"
#include "nsBaseCommandController.h"
#include "mozilla/TextInputProcessor.h"
@ -606,12 +607,9 @@ static nsresult
CreateWindowControllerWithSingletonCommandTable(nsISupports *aOuter,
REFNSIID aIID, void **aResult)
{
nsCOMPtr<nsIController> controller = new nsBaseCommandController();
nsresult rv;
nsCOMPtr<nsIController> controller =
do_CreateInstance("@mozilla.org/embedcomp/base-command-controller;1", &rv);
if (NS_FAILED(rv)) return rv;
nsCOMPtr<nsIControllerCommandTable> windowCommandTable = do_GetService(kNS_WINDOWCOMMANDTABLE_CID, &rv);
if (NS_FAILED(rv)) return rv;
@ -632,10 +630,9 @@ CreateWindowControllerWithSingletonCommandTable(nsISupports *aOuter,
static nsresult
EditorControllerConstructor(nsISupports* aOuter, REFNSIID aIID, void** aResult)
{
nsresult rv;
nsCOMPtr<nsIController> controller = do_CreateInstance("@mozilla.org/embedcomp/base-command-controller;1", &rv);
if (NS_FAILED(rv)) return rv;
nsCOMPtr<nsIController> controller = new nsBaseCommandController();
nsresult rv;
nsCOMPtr<nsIControllerCommandTable> editorCommandTable = do_GetService(kNS_EDITORCOMMANDTABLE_CID, &rv);
if (NS_FAILED(rv)) return rv;
@ -657,10 +654,9 @@ static nsresult
nsEditingControllerConstructor(nsISupports *aOuter, REFNSIID aIID,
void **aResult)
{
nsresult rv;
nsCOMPtr<nsIController> controller = do_CreateInstance("@mozilla.org/embedcomp/base-command-controller;1", &rv);
if (NS_FAILED(rv)) return rv;
nsCOMPtr<nsIController> controller = new nsBaseCommandController();
nsresult rv;
nsCOMPtr<nsIControllerCommandTable> editingCommandTable = do_GetService(kNS_EDITINGCOMMANDTABLE_CID, &rv);
if (NS_FAILED(rv)) return rv;

View File

@ -190,6 +190,26 @@ tasks.withType(org.jetbrains.kotlin.gradle.tasks.KotlinCompile) {
}
}
tasks.withType(Javadoc) {
// Implement warning-as-error for javadoc.
def warnings = 0
def listener = {
if (it.contains(': warning')) {
warnings++
}
} as StandardOutputListener
doFirst {
logging.addStandardErrorListener(listener)
}
doLast {
logging.removeStandardErrorListener(listener)
if (warnings > 0) {
throw new GradleException("Treating $warnings javadoc warning(s) as error(s)")
}
}
}
dependencies {
implementation "com.android.support:support-v4:$support_library_version"
implementation "com.android.support:palette-v7:$support_library_version"

View File

@ -251,8 +251,8 @@ public final class GeckoRuntimeSettings implements Parcelable {
/** Set whether or not known malware sites should be blocked.
*
* Note: For each blocked site, {@link NavigationDelegate#onLoadError}
* with error category {@link NavigationDelegate#ERROR_CATEGORY_SAFEBROWSING}
* Note: For each blocked site, {@link GeckoSession.NavigationDelegate#onLoadError}
* with error category {@link GeckoSession.NavigationDelegate#ERROR_CATEGORY_SAFEBROWSING}
* is called.
*
* @param enabled A flag determining whether or not to block malware
@ -267,8 +267,8 @@ public final class GeckoRuntimeSettings implements Parcelable {
/**
* Set whether or not known phishing sites should be blocked.
*
* Note: For each blocked site, {@link NavigationDelegate#onLoadError}
* with error category {@link NavigationDelegate#ERROR_CATEGORY_SAFEBROWSING}
* Note: For each blocked site, {@link GeckoSession.NavigationDelegate#onLoadError}
* with error category {@link GeckoSession.NavigationDelegate#ERROR_CATEGORY_SAFEBROWSING}
* is called.
*
* @param enabled A flag determining whether or not to block phishing
@ -532,7 +532,9 @@ public final class GeckoRuntimeSettings implements Parcelable {
}
/**
* Get the Job Id used on Oreo and later devices to manage crash reporting in background.
* Get the Job ID used on Oreo and later devices to manage crash reporting in background.
*
* @return Crash reporting service Job ID
*/
public int getCrashReportingServiceJobId() {
return mCrashReportingJobId;
@ -724,8 +726,8 @@ public final class GeckoRuntimeSettings implements Parcelable {
/**
* Set whether or not known malware sites should be blocked.
*
* Note: For each blocked site, {@link NavigationDelegate#onLoadError}
* with error category {@link NavigationDelegate#ERROR_CATEGORY_SAFEBROWSING}
* Note: For each blocked site, {@link GeckoSession.NavigationDelegate#onLoadError}
* with error category {@link GeckoSession.NavigationDelegate#ERROR_CATEGORY_SAFEBROWSING}
* is called.
*
* @param enabled A flag determining whether or not to block malware sites.
@ -748,8 +750,8 @@ public final class GeckoRuntimeSettings implements Parcelable {
/**
* Set whether or not known phishing sites should be blocked.
*
* Note: For each blocked site, {@link NavigationDelegate#onLoadError}
* with error category {@link NavigationDelegate#ERROR_CATEGORY_SAFEBROWSING}
* Note: For each blocked site, {@link GeckoSession.NavigationDelegate#onLoadError}
* with error category {@link GeckoSession.NavigationDelegate#ERROR_CATEGORY_SAFEBROWSING}
* is called.
*
* @param enabled A flag determining whether or not to block phishing sites.

View File

@ -9,7 +9,7 @@
#include "nsURLHelper.h"
#include "nsNetCID.h"
#include "nsMimeTypes.h"
#include "nsIContentSniffer.h"
#include "nsUnknownDecoder.h"
#include "nsIScriptSecurityManager.h"
#include "nsMimeTypes.h"
#include "nsIHttpChannel.h"
@ -824,10 +824,7 @@ CallUnknownTypeSniffer(void *aClosure, const uint8_t *aData, uint32_t aCount)
{
nsIChannel *chan = static_cast<nsIChannel*>(aClosure);
nsCOMPtr<nsIContentSniffer> sniffer =
do_CreateInstance(NS_GENERIC_CONTENT_SNIFFER);
if (!sniffer)
return;
RefPtr<nsUnknownDecoder> sniffer = new nsUnknownDecoder();
nsAutoCString detected;
nsresult rv = sniffer->GetMIMETypeFromContent(chan, aData, aCount, detected);

View File

@ -952,14 +952,6 @@
{0xa1, 0x6c, 0x00, 0x50, 0x04, 0x1c, 0xaf, 0x44} \
}
/**
* General-purpose content sniffer component. Use with CreateInstance.
*
* Implements nsIContentSniffer
*/
#define NS_GENERIC_CONTENT_SNIFFER \
"@mozilla.org/network/content-sniffer;1"
/**
* Detector that can act as either an nsIStreamConverter or an
* nsIContentSniffer to decide whether text/plain data is "really" text/plain

View File

@ -948,7 +948,6 @@ static const mozilla::Module::ContractIDEntry kNeckoContracts[] = {
{ NS_ISTREAMCONVERTER_KEY MULTI_BYTERANGES, &kNS_MULTIMIXEDCONVERTER_CID },
{ NS_ISTREAMCONVERTER_KEY MULTI_MIXED, &kNS_MULTIMIXEDCONVERTER_CID },
{ NS_ISTREAMCONVERTER_KEY UNKNOWN_CONTENT, &kNS_UNKNOWNDECODER_CID },
{ NS_GENERIC_CONTENT_SNIFFER, &kNS_UNKNOWNDECODER_CID },
{ NS_BINARYDETECTOR_CONTRACTID, &kNS_BINARYDETECTOR_CID },
{ NS_ISTREAMCONVERTER_KEY GZIP_TO_UNCOMPRESSED, &kNS_HTTPCOMPRESSCONVERTER_CID },
{ NS_ISTREAMCONVERTER_KEY XGZIP_TO_UNCOMPRESSED, &kNS_HTTPCOMPRESSCONVERTER_CID },

View File

@ -26,22 +26,22 @@ using mozilla::Encoding;
static char *DecodeQ(const char *, uint32_t);
static bool Is7bitNonAsciiString(const char *, uint32_t);
static void CopyRawHeader(const char *, uint32_t, const char *, nsACString &);
static nsresult DecodeRFC2047Str(const char *, const char *, bool, nsACString&);
static nsresult internalDecodeParameter(const nsACString&, const char*,
const char*, bool, bool, nsACString&);
static void CopyRawHeader(const char *, uint32_t, const nsACString&, nsACString &);
static nsresult DecodeRFC2047Str(const char *, const nsACString&, bool, nsACString&);
static nsresult internalDecodeParameter(const nsACString&, const nsACString&,
const nsACString&, bool, bool, nsACString&);
static nsresult
ToUTF8(const nsACString& aString,
const char* aCharset,
const nsACString& aCharset,
bool aAllowSubstitution,
nsACString& aResult)
{
if (!aCharset || !*aCharset)
if (aCharset.IsEmpty()) {
return NS_ERROR_INVALID_ARG;
}
auto encoding = Encoding::ForLabelNoReplacement(
mozilla::MakeStringSpan(aCharset));
auto encoding = Encoding::ForLabelNoReplacement(aCharset);
if (!encoding) {
return NS_ERROR_UCONV_NOCONV;
}
@ -58,7 +58,7 @@ ToUTF8(const nsACString& aString,
static nsresult
ConvertStringToUTF8(const nsACString& aString,
const char* aCharset,
const nsACString& aCharset,
bool aSkipCheck,
bool aAllowSubstitution,
nsACString& aUTF8String)
@ -161,7 +161,7 @@ nsMIMEHeaderParamImpl::DoGetParameter(const nsACString& aHeaderVal,
// if necessary.
nsAutoCString str1;
rv = internalDecodeParameter(med, charset.get(), nullptr, false,
rv = internalDecodeParameter(med, charset, EmptyCString(), false,
// was aDecoding == MIME_FIELD_ENCODING
// see bug 875615
true,
@ -172,8 +172,7 @@ nsMIMEHeaderParamImpl::DoGetParameter(const nsACString& aHeaderVal,
{
const Encoding* encoding = Encoding::ForLabel(aFallbackCharset);
nsAutoCString str2;
if (NS_SUCCEEDED(ConvertStringToUTF8(str1,
PromiseFlatCString(aFallbackCharset).get(), false,
if (NS_SUCCEEDED(ConvertStringToUTF8(str1, aFallbackCharset, false,
encoding != UTF_8_ENCODING,
str2))) {
CopyUTF8toUTF16(str2, aResult);
@ -372,14 +371,13 @@ int32_t parseSegmentNumber(const char *aValue, int32_t aLen)
// validate a given octet sequence for compliance with the specified
// encoding
bool IsValidOctetSequenceForCharset(nsACString& aCharset, const char *aOctets)
bool IsValidOctetSequenceForCharset(const nsACString& aCharset, const char *aOctets)
{
nsAutoCString tmpRaw;
tmpRaw.Assign(aOctets);
nsAutoCString tmpDecoded;
nsresult rv = ConvertStringToUTF8(tmpRaw,
PromiseFlatCString(aCharset).get(),
nsresult rv = ConvertStringToUTF8(tmpRaw, aCharset,
false, false, tmpDecoded);
if (rv != NS_OK) {
@ -780,7 +778,7 @@ increment_str:
}
nsresult
internalDecodeRFC2047Header(const char* aHeaderVal, const char* aDefaultCharset,
internalDecodeRFC2047Header(const char* aHeaderVal, const nsACString& aDefaultCharset,
bool aOverrideCharset, bool aEatContinuations,
nsACString& aResult)
{
@ -795,7 +793,7 @@ internalDecodeRFC2047Header(const char* aHeaderVal, const char* aDefaultCharset,
// aDefaultCharset is specified, decodes RFC 2047 encoding and converts
// to UTF-8. Otherwise, just strips away CRLF.
if (PL_strstr(aHeaderVal, "=?") ||
(aDefaultCharset && (!IsUTF8(nsDependentCString(aHeaderVal)) ||
(!aDefaultCharset.IsEmpty() && (!IsUTF8(nsDependentCString(aHeaderVal)) ||
Is7bitNonAsciiString(aHeaderVal, strlen(aHeaderVal))))) {
DecodeRFC2047Str(aHeaderVal, aDefaultCharset, aOverrideCharset, aResult);
} else if (aEatContinuations &&
@ -824,7 +822,8 @@ nsMIMEHeaderParamImpl::DecodeRFC2047Header(const char* aHeaderVal,
bool aEatContinuations,
nsACString& aResult)
{
return internalDecodeRFC2047Header(aHeaderVal, aDefaultCharset,
return internalDecodeRFC2047Header(aHeaderVal,
nsCString(aDefaultCharset),
aOverrideCharset, aEatContinuations,
aResult);
}
@ -933,7 +932,7 @@ nsMIMEHeaderParamImpl::DecodeRFC5987Param(const nsACString& aParamVal,
// finally convert octet sequence to UTF-8 and be done
nsAutoCString utf8;
nsresult rv = ConvertStringToUTF8(value, charset.get(), true, false, utf8);
nsresult rv = ConvertStringToUTF8(value, charset, true, false, utf8);
NS_ENSURE_SUCCESS(rv, rv);
CopyUTF8toUTF16(utf8, aResult);
@ -941,14 +940,14 @@ nsMIMEHeaderParamImpl::DecodeRFC5987Param(const nsACString& aParamVal,
}
nsresult
internalDecodeParameter(const nsACString& aParamValue, const char* aCharset,
const char* aDefaultCharset, bool aOverrideCharset,
internalDecodeParameter(const nsACString& aParamValue, const nsACString& aCharset,
const nsACString& aDefaultCharset, bool aOverrideCharset,
bool aDecode2047, nsACString& aResult)
{
aResult.Truncate();
// If aCharset is given, aParamValue was obtained from RFC2231/5987
// encoding and we're pretty sure that it's in aCharset.
if (aCharset && *aCharset)
if (!aCharset.IsEmpty())
{
return ConvertStringToUTF8(aParamValue, aCharset, true, true, aResult);
}
@ -997,7 +996,8 @@ nsMIMEHeaderParamImpl::DecodeParameter(const nsACString& aParamValue,
bool aOverrideCharset,
nsACString& aResult)
{
return internalDecodeParameter(aParamValue, aCharset, aDefaultCharset,
return internalDecodeParameter(aParamValue, nsCString(aCharset),
nsCString(aDefaultCharset),
aOverrideCharset, true, aResult);
}
@ -1111,12 +1111,12 @@ bool Is7bitNonAsciiString(const char *input, uint32_t len)
// chars. *aOutput is advanced by the number of output octets.
// static
void CopyRawHeader(const char *aInput, uint32_t aLen,
const char *aDefaultCharset, nsACString &aOutput)
const nsACString& aDefaultCharset, nsACString &aOutput)
{
int32_t c;
// If aDefaultCharset is not specified, make a blind copy.
if (!aDefaultCharset || !*aDefaultCharset) {
if (aDefaultCharset.IsEmpty()) {
aOutput.Append(aInput, aLen);
return;
}
@ -1135,14 +1135,14 @@ void CopyRawHeader(const char *aInput, uint32_t aLen,
// skip ASCIIness/UTF8ness test if aInput is supected to be a 7bit non-ascii
// string and aDefaultCharset is a 7bit non-ascii charset.
bool skipCheck = (c == 0x1B || c == '~') &&
IS_7BIT_NON_ASCII_CHARSET(aDefaultCharset);
IS_7BIT_NON_ASCII_CHARSET(PromiseFlatCString(aDefaultCharset).get());
// If not UTF-8, treat as default charset
nsAutoCString utf8Text;
if (NS_SUCCEEDED(
ConvertStringToUTF8(Substring(aInput, aInput + aLen),
aDefaultCharset, skipCheck, true,
utf8Text))) {
PromiseFlatCString(aDefaultCharset),
skipCheck, true, utf8Text))) {
aOutput.Append(utf8Text);
} else { // replace each octet with Unicode replacement char in UTF-8.
for (uint32_t i = 0; i < aLen; i++) {
@ -1156,7 +1156,7 @@ void CopyRawHeader(const char *aInput, uint32_t aLen,
}
nsresult DecodeQOrBase64Str(const char *aEncoded, size_t aLen, char aQOrBase64,
const char *aCharset, nsACString &aResult)
const nsACString& aCharset, nsACString &aResult)
{
char *decodedText;
NS_ASSERTION(aQOrBase64 == 'Q' || aQOrBase64 == 'B', "Should be 'Q' or 'B'");
@ -1176,7 +1176,7 @@ nsresult DecodeQOrBase64Str(const char *aEncoded, size_t aLen, char aQOrBase64,
// skip ASCIIness/UTF8ness test if aCharset is 7bit non-ascii charset.
nsresult rv = ConvertStringToUTF8(nsDependentCString(decodedText),
aCharset,
IS_7BIT_NON_ASCII_CHARSET(aCharset),
IS_7BIT_NON_ASCII_CHARSET(PromiseFlatCString(aCharset).get()),
true, utf8Text);
free(decodedText);
if (NS_FAILED(rv)) {
@ -1195,7 +1195,7 @@ static const char especials[] = R"(()<>@,;:\"/[]?.=)";
// ignored and aDefaultCharset is assumed, instead. aDefaultCharset
// is also used to convert raw octets (without RFC 2047 encoding) to UTF-8.
//static
nsresult DecodeRFC2047Str(const char *aHeader, const char *aDefaultCharset,
nsresult DecodeRFC2047Str(const char *aHeader, const nsACString& aDefaultCharset,
bool aOverrideCharset, nsACString &aResult)
{
const char *p, *q = nullptr, *r;
@ -1228,7 +1228,7 @@ nsresult DecodeRFC2047Str(const char *aHeader, const char *aDefaultCharset,
if (!isLastEncodedWord || q < p) {
if (!encodedText.IsEmpty()) {
rv = DecodeQOrBase64Str(encodedText.get(), encodedText.Length(),
prevEncoding, prevCharset.get(), aResult);
prevEncoding, prevCharset, aResult);
if (NS_FAILED(rv)) {
aResult.Append(encodedText);
}
@ -1286,7 +1286,7 @@ nsresult DecodeRFC2047Str(const char *aHeader, const char *aDefaultCharset,
// Override charset if requested. Never override labeled UTF-8.
// Use default charset instead of UNKNOWN-8BIT
if ((aOverrideCharset && 0 != nsCRT::strcasecmp(curCharset.get(), "UTF-8"))
|| (aDefaultCharset && 0 == nsCRT::strcasecmp(curCharset.get(), "UNKNOWN-8BIT"))
|| (!aDefaultCharset.IsEmpty() && 0 == nsCRT::strcasecmp(curCharset.get(), "UNKNOWN-8BIT"))
) {
curCharset = aDefaultCharset;
}
@ -1321,7 +1321,7 @@ nsresult DecodeRFC2047Str(const char *aHeader, const char *aDefaultCharset,
bDecoded = true;
}
rv = DecodeQOrBase64Str(encodedText.get(), encodedText.Length(),
prevEncoding, prevCharset.get(), aResult);
prevEncoding, prevCharset, aResult);
if (NS_FAILED(rv)) {
aResult.Append(encodedText);
}
@ -1331,7 +1331,7 @@ nsresult DecodeRFC2047Str(const char *aHeader, const char *aDefaultCharset,
}
if (!bDecoded) {
rv = DecodeQOrBase64Str(q + 2, R - (q + 2), curEncoding,
curCharset.get(), aResult);
curCharset, aResult);
if (NS_FAILED(rv)) {
aResult.Append(encodedText);
}
@ -1344,7 +1344,7 @@ nsresult DecodeRFC2047Str(const char *aHeader, const char *aDefaultCharset,
badsyntax:
if (!encodedText.IsEmpty()) {
rv = DecodeQOrBase64Str(encodedText.get(), encodedText.Length(),
prevEncoding, prevCharset.get(), aResult);
prevEncoding, prevCharset, aResult);
if (NS_FAILED(rv)) {
aResult.Append(encodedText);
}
@ -1359,7 +1359,7 @@ nsresult DecodeRFC2047Str(const char *aHeader, const char *aDefaultCharset,
if (!encodedText.IsEmpty()) {
rv = DecodeQOrBase64Str(encodedText.get(), encodedText.Length(),
prevEncoding, prevCharset.get(), aResult);
prevEncoding, prevCharset, aResult);
if (NS_FAILED(rv)) {
aResult.Append(encodedText);
}

View File

@ -8,6 +8,10 @@ XPIDL_SOURCES += [
'nsICompressConvStats.idl'
]
EXPORTS += [
'nsUnknownDecoder.h',
]
XPIDL_MODULE = 'necko_http'
UNIFIED_SOURCES += [

View File

@ -2617,6 +2617,9 @@ i*86)
x86_64)
MOZ_D3D_CPU_SUFFIX=x64
;;
aarch64)
MOZ_D3D_CPU_SUFFIX=arm
;;
esac
dnl ========================================================
@ -2648,6 +2651,9 @@ if test -n "$MOZ_ANGLE_RENDERER"; then
if test -f "$MOZ_D3DCOMPILER_VISTA_DLL_PATH"; then
AC_MSG_RESULT([Found MOZ_D3DCOMPILER_VISTA_DLL_PATH: $MOZ_D3DCOMPILER_VISTA_DLL_PATH])
MOZ_HAS_WINSDK_WITH_D3D=1
elif test "$target_cpu" = "aarch64" -a "$MOZ_D3DCOMPILER_VISTA_DLL" = "d3dcompiler_47.dll"; then
AC_MSG_RESULT([AArch64 Windows includes d3dcompiler DLLs])
MOZ_D3DCOMPILER_VISTA_DLL_PATH=
else
AC_MSG_RESULT([MOZ_D3DCOMPILER_VISTA_DLL_PATH doesn't exist: $MOZ_D3DCOMPILER_VISTA_DLL_PATH])
AC_MSG_ERROR([Windows SDK at "$WINDOWSSDKDIR" appears broken. Try updating to MozillaBuild 1.9 final or higher.])

View File

@ -265,9 +265,24 @@ nsSecureBrowserUIImpl::MapInternalToExternalState(uint32_t* aState, lockIconStat
if (docShell->GetHasTrackingContentBlocked())
*aState |= nsIWebProgressListener::STATE_BLOCKED_TRACKING_CONTENT;
if (docShell->GetHasSlowTrackingContentBlocked())
*aState |= nsIWebProgressListener::STATE_BLOCKED_SLOW_TRACKING_CONTENT;
if (docShell->GetHasTrackingContentLoaded())
*aState |= nsIWebProgressListener::STATE_LOADED_TRACKING_CONTENT;
if (docShell->GetHasCookiesBlockedByPermission())
*aState |= nsIWebProgressListener::STATE_COOKIES_BLOCKED_BY_PERMISSION;
if (docShell->GetHasCookiesBlockedDueToTrackers())
*aState |= nsIWebProgressListener::STATE_COOKIES_BLOCKED_TRACKER;
if (docShell->GetHasForeignCookiesBeenBlocked())
*aState |= nsIWebProgressListener::STATE_COOKIES_BLOCKED_FOREIGN;
if (docShell->GetHasAllCookiesBeenBlocked())
*aState |= nsIWebProgressListener::STATE_COOKIES_BLOCKED_ALL;
// Copy forward any diagnostic flags for downstream use (e.g., warnings)
if (mNewToplevelSecurityStateKnown &&
mNewToplevelSecurityState & STATE_CERT_DISTRUST_IMMINENT) {

View File

@ -1,17 +1,16 @@
extern crate tempdir;
pub mod profile;
pub mod preferences;
pub mod prefreader;
pub mod profile;
#[cfg(test)]
mod test {
// use std::fs::File;
// use profile::Profile;
use prefreader::{parse, tokenize, serialize};
use prefreader::{PrefToken, Position};
use preferences::Pref;
use prefreader::{parse, serialize, tokenize};
use prefreader::{Position, PrefToken};
use std::collections::BTreeMap;
use std::error::Error;
use std::io::Cursor;
@ -19,11 +18,13 @@ mod test {
#[test]
fn tokenize_simple() {
let prefs = " user_pref ( 'example.pref.string', 'value' ) ;\n pref(\"example.pref.int\", -123); sticky_pref('example.pref.bool',false);";
let prefs = " user_pref ( 'example.pref.string', 'value' ) ;\n \
pref(\"example.pref.int\", -123); sticky_pref('example.pref.bool',false);";
let p = Position::new();
let expected = vec![PrefToken::UserPrefFunction(p),
let expected = vec![
PrefToken::UserPrefFunction(p),
PrefToken::Paren('(', p),
PrefToken::String("example.pref.string".into(), p),
PrefToken::Comma(p),
@ -43,18 +44,22 @@ mod test {
PrefToken::Comma(p),
PrefToken::Bool(false, p),
PrefToken::Paren(')', p),
PrefToken::Semicolon(p)];
PrefToken::Semicolon(p),
];
tokenize_test(prefs, &expected);
}
#[test]
fn tokenize_comments() {
let prefs = "# bash style comment\n /*block comment*/ user_pref/*block comment*/(/*block comment*/ 'example.pref.string' /*block comment*/,/*block comment*/ 'value'/*block comment*/ )// line comment";
let prefs = "# bash style comment\n /*block comment*/ user_pref/*block comment*/(/*block \
comment*/ 'example.pref.string' /*block comment*/,/*block comment*/ \
'value'/*block comment*/ )// line comment";
let p = Position::new();
let expected = vec![PrefToken::CommentBashLine(" bash style comment".into(), p),
let expected = vec![
PrefToken::CommentBashLine(" bash style comment".into(), p),
PrefToken::CommentBlock("block comment".into(), p),
PrefToken::UserPrefFunction(p),
PrefToken::CommentBlock("block comment".into(), p),
@ -67,7 +72,8 @@ mod test {
PrefToken::String("value".into(), p),
PrefToken::CommentBlock("block comment".into(), p),
PrefToken::Paren(')', p),
PrefToken::CommentLine(" line comment".into(), p)];
PrefToken::CommentLine(" line comment".into(), p),
];
tokenize_test(prefs, &expected);
}
@ -78,12 +84,14 @@ mod test {
let p = Position::new();
let expected = vec![PrefToken::UserPrefFunction(p),
let expected = vec![
PrefToken::UserPrefFunction(p),
PrefToken::Paren('(', p),
PrefToken::String("example pref".into(), p),
PrefToken::Comma(p),
PrefToken::String(" ☃𐂖\"'\n\r\\\\w".into(), p),
PrefToken::Paren(')', p)];
PrefToken::Paren(')', p),
];
tokenize_test(prefs, &expected);
}
@ -93,49 +101,31 @@ mod test {
for (e, a) in expected.iter().zip(tokenize(prefs.as_bytes())) {
let success = match (e, &a) {
(&PrefToken::PrefFunction(_),
&PrefToken::PrefFunction(_)) => true,
(&PrefToken::UserPrefFunction(_),
&PrefToken::UserPrefFunction(_)) => true,
(&PrefToken::StickyPrefFunction(_),
&PrefToken::StickyPrefFunction(_)) => true,
(&PrefToken::CommentBlock(ref data_e, _),
&PrefToken::CommentBlock(ref data_a, _)) => {
(&PrefToken::PrefFunction(_), &PrefToken::PrefFunction(_)) => true,
(&PrefToken::UserPrefFunction(_), &PrefToken::UserPrefFunction(_)) => true,
(&PrefToken::StickyPrefFunction(_), &PrefToken::StickyPrefFunction(_)) => true,
(
&PrefToken::CommentBlock(ref data_e, _),
&PrefToken::CommentBlock(ref data_a, _),
) => data_e == data_a,
(
&PrefToken::CommentLine(ref data_e, _),
&PrefToken::CommentLine(ref data_a, _),
) => data_e == data_a,
(
&PrefToken::CommentBashLine(ref data_e, _),
&PrefToken::CommentBashLine(ref data_a, _),
) => data_e == data_a,
(&PrefToken::Paren(data_e, _), &PrefToken::Paren(data_a, _)) => data_e == data_a,
(&PrefToken::Semicolon(_), &PrefToken::Semicolon(_)) => true,
(&PrefToken::Comma(_), &PrefToken::Comma(_)) => true,
(&PrefToken::String(ref data_e, _), &PrefToken::String(ref data_a, _)) => {
data_e == data_a
},
(&PrefToken::CommentLine(ref data_e, _),
&PrefToken::CommentLine(ref data_a, _)) => {
data_e == data_a
},
(&PrefToken::CommentBashLine(ref data_e, _),
&PrefToken::CommentBashLine(ref data_a, _)) => {
data_e == data_a
},
(&PrefToken::Paren(data_e, _),
&PrefToken::Paren(data_a, _)) => {
data_e == data_a
},
(&PrefToken::Semicolon(_),
&PrefToken::Semicolon(_)) => true,
(&PrefToken::Comma(_),
&PrefToken::Comma(_)) => true,
(&PrefToken::String(ref data_e, _),
&PrefToken::String(ref data_a, _)) => {
data_e == data_a
},
(&PrefToken::Int(data_e, _),
&PrefToken::Int(data_a, _)) => {
data_e == data_a
},
(&PrefToken::Bool(data_e, _),
&PrefToken::Bool(data_a, _)) => {
data_e == data_a
},
(&PrefToken::Error(data_e, _),
&PrefToken::Error(data_a, _)) => {
data_e == data_a
},
(_, _) => false
}
(&PrefToken::Int(data_e, _), &PrefToken::Int(data_a, _)) => data_e == data_a,
(&PrefToken::Bool(data_e, _), &PrefToken::Bool(data_a, _)) => data_e == data_a,
(&PrefToken::Error(data_e, _), &PrefToken::Error(data_a, _)) => data_e == data_a,
(_, _) => false,
};
if !success {
println!("Expected {:?}, got {:?}", e, a);
@ -146,7 +136,8 @@ mod test {
#[test]
fn parse_simple() {
let input = " user_pref /* block comment */ ( 'example.pref.string', 'value' ) ;\n pref(\"example.pref.int\", -123); sticky_pref('example.pref.bool',false)";
let input = " user_pref /* block comment */ ( 'example.pref.string', 'value' ) ;\n \
pref(\"example.pref.int\", -123); sticky_pref('example.pref.bool',false)";
let mut expected: BTreeMap<String, Pref> = BTreeMap::new();
expected.insert("example.pref.string".into(), Pref::new("value"));
@ -181,7 +172,8 @@ mod test {
#[test]
fn serialize_simple() {
let input = " user_pref /* block comment */ ( 'example.pref.string', 'value' ) ;\n pref(\"example.pref.int\", -123); sticky_pref('example.pref.bool',false)";
let input = " user_pref /* block comment */ ( 'example.pref.string', 'value' ) ;\n \
pref(\"example.pref.int\", -123); sticky_pref('example.pref.bool',false)";
let expected = "sticky_pref(\"example.pref.bool\", false);
user_pref(\"example.pref.int\", -123);
user_pref(\"example.pref.string\", \"value\");\n";

Some files were not shown because too many files have changed in this diff Show More