зеркало из https://github.com/mozilla/gecko-dev.git
Merge mozilla-central to mozilla-inbound. CLOSED TREE
This commit is contained in:
Коммит
c317b7ed38
|
@ -117,8 +117,8 @@ devtools/startup/preferences/devtools-startup.js
|
|||
|
||||
# Ignore devtools generated code
|
||||
devtools/shared/css/generated/properties-db.js
|
||||
devtools/client/webconsole/test/fixtures/stubs/*.js
|
||||
!devtools/client/webconsole/test/fixtures/stubs/index.js
|
||||
devtools/client/webconsole/test/node/fixtures/stubs/*.js
|
||||
!devtools/client/webconsole/test/node/fixtures/stubs/index.js
|
||||
|
||||
# Ignore devtools third-party libs
|
||||
devtools/shared/jsbeautify/*
|
||||
|
@ -146,8 +146,8 @@ devtools/client/debugger/test/mochitest/code_*.js
|
|||
devtools/client/framework/test/code_*
|
||||
devtools/client/inspector/markup/test/events_bundle.js
|
||||
devtools/client/netmonitor/test/xhr_bundle.js
|
||||
devtools/client/webconsole/test/mochitest/code_bundle_nosource.js
|
||||
devtools/client/webconsole/test/mochitest/code_bundle_invalidmap.js
|
||||
devtools/client/webconsole/test/browser/code_bundle_nosource.js
|
||||
devtools/client/webconsole/test/browser/code_bundle_invalidmap.js
|
||||
devtools/server/tests/unit/babel_and_browserify_script_with_source_map.js
|
||||
devtools/server/tests/unit/setBreakpoint*
|
||||
devtools/server/tests/unit/sourcemapped.js
|
||||
|
@ -275,7 +275,6 @@ services/fxaccounts/FxAccountsPairingChannel.js
|
|||
|
||||
# Uses `#filter substitution`
|
||||
services/sync/modules/constants.js
|
||||
services/sync/services-sync.js
|
||||
|
||||
# Servo is imported.
|
||||
servo/**
|
||||
|
|
|
@ -29,8 +29,6 @@ modules/libpref/test/unit/data/testPrefLocked.js
|
|||
modules/libpref/test/unit/data/testPrefSticky.js
|
||||
modules/libpref/test/unit/extdata/testExt.js
|
||||
remote/pref/remote.js
|
||||
services/common/services-common.js
|
||||
services/sync/services-sync.js
|
||||
services/sync/tests/unit/prefs_test_prefs_store.js
|
||||
testing/marionette/prefs/marionette.js
|
||||
toolkit/components/telemetry/datareporting-prefs.js
|
||||
|
|
|
@ -40,7 +40,6 @@
|
|||
# push: {owner, pushlog_id, revision},
|
||||
# repository: {url, project, level},
|
||||
# input,
|
||||
# parameters,
|
||||
# taskId, // targetted taskId
|
||||
# taskGroupId, // targetted taskGroupId
|
||||
# action: {name, title, description, taskGroupId, symbol, repo_scope, cb_name}
|
||||
|
@ -208,7 +207,6 @@ tasks:
|
|||
ACTION_TASK_ID: {$json: {$eval: 'taskId'}} # taskId of the target task (JSON-encoded)
|
||||
ACTION_INPUT: {$json: {$eval: 'input'}}
|
||||
ACTION_CALLBACK: '${action.cb_name}'
|
||||
ACTION_PARAMETERS: {$json: {$eval: 'parameters'}}
|
||||
|
||||
cache:
|
||||
level-${repository.level}-checkouts-sparse-v2: /builds/worker/checkouts
|
||||
|
@ -287,7 +285,6 @@ tasks:
|
|||
taskGroupId: '${action.taskGroupId}'
|
||||
taskId: {$eval: 'taskId'}
|
||||
input: {$eval: 'input'}
|
||||
parameters: {$eval: 'parameters'}
|
||||
clientId: {$eval: 'clientId'}
|
||||
- $if: 'tasks_for == "cron"'
|
||||
then:
|
||||
|
|
|
@ -2257,7 +2257,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
|
||||
[[package]]
|
||||
name = "plane-split"
|
||||
version = "0.14.0"
|
||||
version = "0.14.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"binary-space-partition 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
|
@ -3648,7 +3648,7 @@ dependencies = [
|
|||
"log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"malloc_size_of_derive 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"num-traits 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"plane-split 0.14.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"plane-split 0.14.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rayon 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"ron 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde 1.0.88 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
|
@ -4092,7 +4092,7 @@ dependencies = [
|
|||
"checksum phf_shared 0.7.21 (registry+https://github.com/rust-lang/crates.io-index)" = "07e24b0ca9643bdecd0632f2b3da6b1b89bbb0030e0b992afc1113b23a7bc2f2"
|
||||
"checksum pkg-config 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)" = "3a8b4c6b8165cd1a1cd4b9b120978131389f64bdaf456435caa41e630edba903"
|
||||
"checksum plain 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "b4596b6d070b27117e987119b4dac604f3c58cfb0b191112e24771b2faeac1a6"
|
||||
"checksum plane-split 0.14.0 (registry+https://github.com/rust-lang/crates.io-index)" = "91821c7436aefc1b912552d494232efcaf9810c0189918749532be1e9dbace59"
|
||||
"checksum plane-split 0.14.1 (registry+https://github.com/rust-lang/crates.io-index)" = "68a117c887fbcd9af8dfc1b8b12ee19ba9dec0b2a91d0a9d2bd9114e459f9c78"
|
||||
"checksum plist 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "95bef0807b4fe77618f8d24f0c4ec37a4ad1dad9348c3b27d8b624c824d8cf48"
|
||||
"checksum png 0.14.0 (registry+https://github.com/rust-lang/crates.io-index)" = "9adebf7fb91ccf5eac9da1a8e00e83cb8ae882c3e8d8e4ad59da73cb8c82a2c9"
|
||||
"checksum podio 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "e5422a1ee1bc57cc47ae717b0137314258138f38fd5f3cea083f43a9725383a0"
|
||||
|
|
|
@ -1613,6 +1613,15 @@ pref("browser.contentblocking.report.monitor.enabled", true);
|
|||
pref("browser.contentblocking.report.monitor.url", "https://monitor.firefox.com");
|
||||
pref("browser.contentblocking.report.lockwise.url", "https://lockwise.firefox.com/");
|
||||
|
||||
// Protection Report's SUMO urls
|
||||
pref("browser.contentblocking.report.monitor.how_it_works.url", "https://support.mozilla.org/1/firefox/%VERSION%/%OS%/%LOCALE%/monitor-faq");
|
||||
pref("browser.contentblocking.report.lockwise.how_it_works.url", "https://support.mozilla.org/1/firefox/%VERSION%/%OS%/%LOCALE%/password-manager-report");
|
||||
pref("browser.contentblocking.report.social.url", "https://support.mozilla.org/1/firefox/%VERSION%/%OS%/%LOCALE%/social-media-tracking-report");
|
||||
pref("browser.contentblocking.report.cookie.url", "https://support.mozilla.org/1/firefox/%VERSION%/%OS%/%LOCALE%/cross-site-tracking-report");
|
||||
pref("browser.contentblocking.report.tracker.url", "https://support.mozilla.org/1/firefox/%VERSION%/%OS%/%LOCALE%/tracking-content-report");
|
||||
pref("browser.contentblocking.report.fingerprinter.url", "https://support.mozilla.org/1/firefox/%VERSION%/%OS%/%LOCALE%/fingerprinters-report");
|
||||
pref("browser.contentblocking.report.cryptominer.url", "https://support.mozilla.org/1/firefox/%VERSION%/%OS%/%LOCALE%/cryptominers-report");
|
||||
|
||||
// Enables the new Protections Panel.
|
||||
#ifdef NIGHTLY_BUILD
|
||||
pref("browser.protections_panel.enabled", true);
|
||||
|
|
|
@ -1399,7 +1399,10 @@ var gIdentityHandler = {
|
|||
"identity-popup-permission-icon",
|
||||
aPermission.id + "-icon"
|
||||
);
|
||||
if (aPermission.state == SitePermissions.BLOCK) {
|
||||
if (
|
||||
aPermission.state == SitePermissions.BLOCK ||
|
||||
aPermission.state == SitePermissions.AUTOPLAY_BLOCKED_ALL
|
||||
) {
|
||||
img.classList.add("blocked-permission-icon");
|
||||
}
|
||||
|
||||
|
|
|
@ -48,6 +48,12 @@ function autoplayBlockedIcon() {
|
|||
);
|
||||
}
|
||||
|
||||
function permissionListBlockedIcons() {
|
||||
return document.querySelectorAll(
|
||||
"image.identity-popup-permission-icon.blocked-permission-icon"
|
||||
);
|
||||
}
|
||||
|
||||
function sleep(ms) {
|
||||
/* eslint-disable mozilla/no-arbitrary-setTimeout */
|
||||
return new Promise(resolve => setTimeout(resolve, ms));
|
||||
|
@ -251,6 +257,12 @@ add_task(async function testBlockedAll() {
|
|||
|
||||
await openIdentityPopup();
|
||||
|
||||
Assert.equal(
|
||||
permissionListBlockedIcons().length,
|
||||
1,
|
||||
"Blocked icon is shown"
|
||||
);
|
||||
|
||||
let menulist = document.getElementById("identity-popup-popup-menulist");
|
||||
await EventUtils.synthesizeMouseAtCenter(menulist, { type: "mousedown" });
|
||||
await TestUtils.waitForCondition(() => {
|
||||
|
|
|
@ -2689,7 +2689,7 @@ BrowserGlue.prototype = {
|
|||
_migrateUI: function BG__migrateUI() {
|
||||
// Use an increasing number to keep track of the current migration state.
|
||||
// Completely unrelated to the current Firefox release number.
|
||||
const UI_VERSION = 85;
|
||||
const UI_VERSION = 86;
|
||||
const BROWSER_DOCURL = AppConstants.BROWSER_CHROME_URL;
|
||||
|
||||
let currentUIVersion;
|
||||
|
@ -3080,6 +3080,25 @@ BrowserGlue.prototype = {
|
|||
Services.prefs.setBoolPref(CUSTOM_BLOCKING_PREF, true);
|
||||
}
|
||||
}
|
||||
|
||||
if (currentUIVersion < 86) {
|
||||
// If the user has set "media.autoplay.allow-muted" to false
|
||||
// migrate that to media.autoplay.default=BLOCKED_ALL.
|
||||
if (
|
||||
Services.prefs.prefHasUserValue("media.autoplay.allow-muted") &&
|
||||
!Services.prefs.getBoolPref("media.autoplay.allow-muted") &&
|
||||
!Services.prefs.prefHasUserValue("media.autoplay.default") &&
|
||||
Services.prefs.getIntPref("media.autoplay.default") ==
|
||||
Ci.nsIAutoplay.BLOCKED
|
||||
) {
|
||||
Services.prefs.setIntPref(
|
||||
"media.autoplay.default",
|
||||
Ci.nsIAutoplay.BLOCKED_ALL
|
||||
);
|
||||
}
|
||||
Services.prefs.clearUserPref("media.autoplay.allow-muted");
|
||||
}
|
||||
|
||||
// Update the migration version.
|
||||
Services.prefs.setIntPref("browser.migration.version", UI_VERSION);
|
||||
},
|
||||
|
|
|
@ -15,14 +15,17 @@
|
|||
<panelmultiview id="protections-popup-multiView"
|
||||
mainViewId="protections-popup-mainView">
|
||||
<panelview id="protections-popup-mainView"
|
||||
role="document"
|
||||
descriptionheightworkaround="true">
|
||||
<hbox id="protections-popup-mainView-panel-header"
|
||||
flex="1"
|
||||
onclick="gProtectionsHandler.onHeaderClicked(event);">
|
||||
<label id="protections-popup-main-header-label" flex="1">
|
||||
<label id="protections-popup-main-header-label" flex="1"
|
||||
role="heading" aria-level="1">
|
||||
<html:span id="protections-popup-mainView-panel-header-span"/>
|
||||
</label>
|
||||
<toolbarbutton id="protections-popup-info-button" class="panel-info-button">
|
||||
<toolbarbutton id="protections-popup-info-button" class="panel-info-button"
|
||||
aria-label="&protections.etpMoreInfo.label;">
|
||||
<image/>
|
||||
</toolbarbutton>
|
||||
<description id="protections-popup-toast-panel-tp-on-desc">&protections.etpON.header;</description>
|
||||
|
@ -35,8 +38,12 @@
|
|||
|
||||
<hbox id="protections-popup-tp-switch-section" class="protections-popup-section">
|
||||
<vbox class="protections-popup-tp-switch-label-box" flex="1">
|
||||
<label class="protections-popup-tp-switch-on-header">&protections.etpON.header;</label>
|
||||
<label class="protections-popup-tp-switch-off-header">&protections.etpOFF.header;</label>
|
||||
<label class="protections-popup-tp-switch-on-header"
|
||||
role="heading"
|
||||
aria-level="2">&protections.etpON.header;</label>
|
||||
<label class="protections-popup-tp-switch-off-header"
|
||||
role="heading"
|
||||
aria-level="2">&protections.etpOFF.header;</label>
|
||||
<label id="protections-popup-tp-switch-breakage-link"
|
||||
class="text-link"
|
||||
onclick="gProtectionsHandler.showSiteNotWorkingView();">&protections.siteNotWorking.label;</label>
|
||||
|
@ -56,7 +63,10 @@
|
|||
<tooltip id="protections-popup-not-blocking-why-etp-off-tooltip">&protections.notBlocking.why.etpOff.tooltip;</tooltip>
|
||||
<vbox id="protections-popup-content" flex="1">
|
||||
<vbox id="protections-popup-category-list">
|
||||
<description id="protections-popup-blocking-section-header" hidden="true">&protections.blocking.label;</description>
|
||||
<description id="protections-popup-blocking-section-header"
|
||||
hidden="true"
|
||||
role="heading"
|
||||
aria-level="2">&protections.blocking.label;</description>
|
||||
<hbox id="protections-popup-not-blocking-section-header" hidden="true">
|
||||
<description id="protections-popup-not-blocking-section-description">&protections.notBlocking.label;</description>
|
||||
<label id="protections-popup-not-blocking-section-why"
|
||||
|
@ -133,13 +143,18 @@
|
|||
|
||||
<!-- Site Not Working? SubView -->
|
||||
<panelview id="protections-popup-siteNotWorkingView"
|
||||
role="document"
|
||||
title="&protections.siteNotWorkingView.title;"
|
||||
descriptionheightworkaround="true"
|
||||
flex="1">
|
||||
<hbox id="protections-popup-siteNotWorkingView-header">
|
||||
<vbox class="protections-popup-tp-switch-label-box" flex="1">
|
||||
<label class="protections-popup-tp-switch-on-header">&protections.etpON.header;</label>
|
||||
<label class="protections-popup-tp-switch-off-header">&protections.etpOFF.header;</label>
|
||||
<label class="protections-popup-tp-switch-on-header"
|
||||
role="heading"
|
||||
aria-level="1">&protections.etpON.header;</label>
|
||||
<label class="protections-popup-tp-switch-off-header"
|
||||
role="heading"
|
||||
aria-level="1">&protections.etpOFF.header;</label>
|
||||
</vbox>
|
||||
<vbox class="protections-popup-tp-switch-box">
|
||||
<toolbarbutton id="protections-popup-siteNotWorking-tp-switch"
|
||||
|
@ -149,7 +164,7 @@
|
|||
</vbox>
|
||||
</hbox>
|
||||
<vbox id="protections-popup-siteNotWorkingView-body">
|
||||
<label>&protections.siteNotWorkingView.header;</label>
|
||||
<label role="heading" aria-level="2">&protections.siteNotWorkingView.header;</label>
|
||||
<label>
|
||||
<html:ul id="protections-popup-siteNotWorkingView-body-issue-list">
|
||||
<html:li>&protections.siteNotWorkingView.issueList.logInFields;</html:li>
|
||||
|
@ -261,12 +276,12 @@
|
|||
</vbox>
|
||||
<vbox id="protections-popup-sendReportView-body" class="panel-view-body-unscrollable">
|
||||
<vbox class="protections-popup-sendReportView-collection-section">
|
||||
<label>&contentBlocking.breakageReportView.collection.url.label;</label>
|
||||
<html:input readonly="readonly" id="protections-popup-sendReportView-collection-url"/>
|
||||
<label control="protections-popup-sendReportView-collection-url">&contentBlocking.breakageReportView.collection.url.label;</label>
|
||||
<html:input readonly="readonly" id="protections-popup-sendReportView-collection-url" aria-label="&contentBlocking.breakageReportView.collection.url.label;"/>
|
||||
</vbox>
|
||||
<vbox class="protections-popup-sendReportView-collection-section">
|
||||
<label>&contentBlocking.breakageReportView2.collection.comments.label;</label>
|
||||
<html:textarea id="protections-popup-sendReportView-collection-comments"/>
|
||||
<label control="protections-popup-sendReportView-collection-comments">&contentBlocking.breakageReportView2.collection.comments.label;</label>
|
||||
<html:textarea id="protections-popup-sendReportView-collection-comments" aria-label="&contentBlocking.breakageReportView2.collection.comments.label;"/>
|
||||
</vbox>
|
||||
</vbox>
|
||||
<vbox id="protections-popup-sendReportView-footer"
|
||||
|
|
|
@ -539,6 +539,10 @@ var PanelMultiView = class extends AssociatedToNode {
|
|||
try {
|
||||
canCancel = false;
|
||||
this._panel.openPopup(anchor, options, ...args);
|
||||
// Set an attribute on the popup to let consumers style popup elements -
|
||||
// for example, the anchor arrow is styled to match the color of the header
|
||||
// in the Protections Panel main view.
|
||||
this._panel.setAttribute("mainviewshowing", true);
|
||||
|
||||
// On Windows, if another popup is hiding while we call openPopup, the
|
||||
// call won't fail but the popup won't open. In this case, we have to
|
||||
|
@ -1019,6 +1023,17 @@ var PanelMultiView = class extends AssociatedToNode {
|
|||
|
||||
// Kick off the transition!
|
||||
details.phase = TRANSITION_PHASES.TRANSITION;
|
||||
|
||||
// If we're going to show the main view, we can remove the
|
||||
// min-height property on the view container. It's also time
|
||||
// to set the mainviewshowing attribute on the popup.
|
||||
if (viewNode.getAttribute("mainview")) {
|
||||
this._viewContainer.style.removeProperty("min-height");
|
||||
this._panel.setAttribute("mainviewshowing", true);
|
||||
} else {
|
||||
this._panel.removeAttribute("mainviewshowing");
|
||||
}
|
||||
|
||||
this._viewStack.style.transform =
|
||||
"translateX(" + (moveToLeft ? "" : "-") + deltaX + "px)";
|
||||
|
||||
|
|
|
@ -377,7 +377,7 @@ export class ASRouterUISurface extends React.PureComponent {
|
|||
sendUserActionTelemetry={this.sendUserActionTelemetry}
|
||||
executeAction={ASRouterUtils.executeAction}
|
||||
dispatch={this.props.dispatch}
|
||||
onBlock={this.onBlockById(this.state.message.id)}
|
||||
onBlockById={ASRouterUtils.blockById}
|
||||
onDismiss={this.onDismissById(this.state.message.id)}
|
||||
fxaEndpoint={this.props.fxaEndpoint}
|
||||
fetchFlowParams={this.fetchFlowParams}
|
||||
|
|
|
@ -7,6 +7,9 @@ import { Interrupt } from "./Interrupt";
|
|||
import { Triplets } from "./Triplets";
|
||||
import { BASE_PARAMS } from "./addUtmParams";
|
||||
|
||||
// Note: should match the transition time on .trailheadCards in _Trailhead.scss
|
||||
const TRANSITION_LENGTH = 500;
|
||||
|
||||
export const FLUENT_FILES = [
|
||||
"branding/brand.ftl",
|
||||
"browser/branding/brandings.ftl",
|
||||
|
@ -140,10 +143,11 @@ export class FirstRun extends React.PureComponent {
|
|||
|
||||
closeTriplets() {
|
||||
this.setState({ isTripletsContainerVisible: false });
|
||||
// TODO: Needs to block ALL extended triplets as well
|
||||
if (this.props.message.template === "extended_triplets") {
|
||||
this.props.onBlock();
|
||||
}
|
||||
|
||||
// Closing triplets should prevent any future extended triplets from showing up
|
||||
setTimeout(() => {
|
||||
this.props.onBlockById("EXTENDED_TRIPLETS_1");
|
||||
}, TRANSITION_LENGTH);
|
||||
}
|
||||
|
||||
render() {
|
||||
|
@ -175,6 +179,7 @@ export class FirstRun extends React.PureComponent {
|
|||
onNextScene={this.closeInterrupt}
|
||||
UTMTerm={UTMTerm}
|
||||
sendUserActionTelemetry={sendUserActionTelemetry}
|
||||
executeAction={executeAction}
|
||||
dispatch={dispatch}
|
||||
flowParams={flowParams}
|
||||
onDismiss={this.closeInterrupt}
|
||||
|
|
|
@ -265,8 +265,13 @@
|
|||
background: var(--trailhead-cards-background-color);
|
||||
overflow: hidden;
|
||||
text-align: center;
|
||||
// Note: should match TRANSITION_LENGTH in FirstRun.jsx
|
||||
transition: max-height 0.5s $photon-easing;
|
||||
|
||||
// This is needed for the transition to work, but will cut off content at the smallest breakpoint
|
||||
@media (min-width: $break-point-medium) {
|
||||
max-height: 1000px;
|
||||
}
|
||||
|
||||
&.collapsed {
|
||||
max-height: 0;
|
||||
|
|
|
@ -4123,6 +4123,9 @@ a.firstrun-link {
|
|||
overflow: hidden;
|
||||
text-align: center;
|
||||
transition: max-height 0.5s cubic-bezier(0.07, 0.95, 0, 1); }
|
||||
@media (min-width: 610px) {
|
||||
.trailheadCards {
|
||||
max-height: 1000px; } }
|
||||
.trailheadCards.collapsed {
|
||||
max-height: 0; }
|
||||
.trailheadCards h1 {
|
||||
|
|
|
@ -4126,6 +4126,9 @@ a.firstrun-link {
|
|||
overflow: hidden;
|
||||
text-align: center;
|
||||
transition: max-height 0.5s cubic-bezier(0.07, 0.95, 0, 1); }
|
||||
@media (min-width: 610px) {
|
||||
.trailheadCards {
|
||||
max-height: 1000px; } }
|
||||
.trailheadCards.collapsed {
|
||||
max-height: 0; }
|
||||
.trailheadCards h1 {
|
||||
|
|
|
@ -4123,6 +4123,9 @@ a.firstrun-link {
|
|||
overflow: hidden;
|
||||
text-align: center;
|
||||
transition: max-height 0.5s cubic-bezier(0.07, 0.95, 0, 1); }
|
||||
@media (min-width: 610px) {
|
||||
.trailheadCards {
|
||||
max-height: 1000px; } }
|
||||
.trailheadCards.collapsed {
|
||||
max-height: 0; }
|
||||
.trailheadCards h1 {
|
||||
|
|
|
@ -2220,7 +2220,7 @@ class ASRouterUISurface extends react__WEBPACK_IMPORTED_MODULE_6___default.a.Pur
|
|||
sendUserActionTelemetry: this.sendUserActionTelemetry,
|
||||
executeAction: ASRouterUtils.executeAction,
|
||||
dispatch: this.props.dispatch,
|
||||
onBlock: this.onBlockById(this.state.message.id),
|
||||
onBlockById: ASRouterUtils.blockById,
|
||||
onDismiss: this.onDismissById(this.state.message.id),
|
||||
fxaEndpoint: this.props.fxaEndpoint,
|
||||
fetchFlowParams: this.fetchFlowParams
|
||||
|
@ -13264,7 +13264,7 @@ function DiscoveryStream(prevState = INITIAL_STATE.DiscoveryStream, action) {
|
|||
});
|
||||
|
||||
switch (action.type) {
|
||||
case Actions["actionTypes"].DISCOVERY_STREAM_CONFIG_CHANGE: // The reason this is a separate action is so it doesn't trigger a listener update on init
|
||||
case Actions["actionTypes"].DISCOVERY_STREAM_CONFIG_CHANGE: // Fall through to a separate action is so it doesn't trigger a listener update on init
|
||||
|
||||
case Actions["actionTypes"].DISCOVERY_STREAM_CONFIG_SETUP:
|
||||
return { ...prevState,
|
||||
|
@ -13545,7 +13545,9 @@ var addUtmParams = __webpack_require__(22);
|
|||
|
||||
|
||||
|
||||
// Note: should match the transition time on .trailheadCards in _Trailhead.scss
|
||||
|
||||
const TRANSITION_LENGTH = 500;
|
||||
const FLUENT_FILES = ["branding/brand.ftl", "browser/branding/brandings.ftl", "browser/branding/sync-brand.ftl", "browser/newtab/onboarding.ftl"];
|
||||
const helpers = {
|
||||
selectInterruptAndTriplets(message = {}) {
|
||||
|
@ -13671,11 +13673,11 @@ class FirstRun_FirstRun extends external_React_default.a.PureComponent {
|
|||
closeTriplets() {
|
||||
this.setState({
|
||||
isTripletsContainerVisible: false
|
||||
}); // TODO: Needs to block ALL extended triplets as well
|
||||
}); // Closing triplets should prevent any future extended triplets from showing up
|
||||
|
||||
if (this.props.message.template === "extended_triplets") {
|
||||
this.props.onBlock();
|
||||
}
|
||||
setTimeout(() => {
|
||||
this.props.onBlockById("EXTENDED_TRIPLETS_1");
|
||||
}, TRANSITION_LENGTH);
|
||||
}
|
||||
|
||||
render() {
|
||||
|
@ -13704,6 +13706,7 @@ class FirstRun_FirstRun extends external_React_default.a.PureComponent {
|
|||
onNextScene: this.closeInterrupt,
|
||||
UTMTerm: UTMTerm,
|
||||
sendUserActionTelemetry: sendUserActionTelemetry,
|
||||
executeAction: executeAction,
|
||||
dispatch: dispatch,
|
||||
flowParams: flowParams,
|
||||
onDismiss: this.closeInterrupt,
|
||||
|
|
|
@ -94,6 +94,11 @@ const TRAILHEAD_CONFIG = {
|
|||
},
|
||||
LOCALES: ["en-US", "en-GB", "en-CA", "de", "de-DE", "fr", "fr-FR"],
|
||||
EXPERIMENT_RATIOS: [["", 0], ["interrupts", 1], ["triplets", 3]],
|
||||
// Per bug 1571817, for those who meet the targeting criteria of extended
|
||||
// triplets, 99% users (control group) will see the extended triplets, and
|
||||
// the rest 1% (holdback group) won't.
|
||||
EXPERIMENT_RATIOS_FOR_EXTENDED_TRIPLETS: [["control", 99], ["holdback", 1]],
|
||||
EXTENDED_TRIPLETS_EXPERIMENT_PREF: "trailhead.extendedTriplets.experiment",
|
||||
};
|
||||
|
||||
const INCOMING_MESSAGE_NAME = "ASRouter:child-to-parent";
|
||||
|
@ -490,6 +495,8 @@ class _ASRouter {
|
|||
trailheadTriplet: "",
|
||||
messages: [],
|
||||
errors: [],
|
||||
extendedTripletsInitialized: false,
|
||||
showExtendedTriplets: true,
|
||||
};
|
||||
this._triggerHandler = this._triggerHandler.bind(this);
|
||||
this._localProviders = localProviders;
|
||||
|
@ -988,6 +995,40 @@ class _ASRouter {
|
|||
});
|
||||
}
|
||||
|
||||
async setupExtendedTriplets() {
|
||||
// Don't re-initialize
|
||||
if (this.state.extendedTripletsInitialized) {
|
||||
return;
|
||||
}
|
||||
|
||||
let branch = Services.prefs.getStringPref(
|
||||
TRAILHEAD_CONFIG.EXTENDED_TRIPLETS_EXPERIMENT_PREF,
|
||||
""
|
||||
);
|
||||
if (!branch) {
|
||||
const { userId } = ClientEnvironment;
|
||||
branch = await chooseBranch(
|
||||
`${userId}-extended-triplets-experiment`,
|
||||
TRAILHEAD_CONFIG.EXPERIMENT_RATIOS_FOR_EXTENDED_TRIPLETS
|
||||
);
|
||||
Services.prefs.setStringPref(
|
||||
TRAILHEAD_CONFIG.EXTENDED_TRIPLETS_EXPERIMENT_PREF,
|
||||
branch
|
||||
);
|
||||
}
|
||||
|
||||
// In order for ping centre to pick this up, it MUST contain a substring activity-stream
|
||||
const experimentName = `activity-stream-extended-triplets`;
|
||||
TelemetryEnvironment.setExperimentActive(experimentName, branch);
|
||||
|
||||
const state = { extendedTripletsInitialized: true };
|
||||
// Disable the extended triplets for the "holdback" group.
|
||||
if (branch === "holdback") {
|
||||
state.showExtendedTriplets = false;
|
||||
}
|
||||
await this.setState(state);
|
||||
}
|
||||
|
||||
async setupTrailhead() {
|
||||
// Don't initialize
|
||||
if (
|
||||
|
@ -1823,11 +1864,24 @@ class _ASRouter {
|
|||
}));
|
||||
} else {
|
||||
// On new tab, send cards if they match; othwerise send a snippet
|
||||
message =
|
||||
(await this.handleMessageRequest({
|
||||
provider: "onboarding",
|
||||
template: "extended_triplets",
|
||||
})) || (await this.handleMessageRequest({ provider: "snippets" }));
|
||||
message = await this.handleMessageRequest({
|
||||
provider: "onboarding",
|
||||
template: "extended_triplets",
|
||||
});
|
||||
|
||||
// Set up the experiment for extended triplets. It's done here because we
|
||||
// only want to enroll users (for both control and holdback) if they meet
|
||||
// the targeting criteria.
|
||||
if (message) {
|
||||
await this.setupExtendedTriplets();
|
||||
}
|
||||
|
||||
// If no extended triplets message was returned, or the holdback experiment
|
||||
// is active, show snippets instead
|
||||
if (!message || !this.state.showExtendedTriplets) {
|
||||
message = await this.handleMessageRequest({ provider: "snippets" });
|
||||
}
|
||||
|
||||
await this.setState({ lastMessageId: message ? message.id : null });
|
||||
}
|
||||
|
||||
|
|
|
@ -68,7 +68,12 @@ class PageAction {
|
|||
this._showPopupOnClick = this._showPopupOnClick.bind(this);
|
||||
this.dispatchUserAction = this.dispatchUserAction.bind(this);
|
||||
|
||||
this._l10n = new DOMLocalization(["browser/newtab/asrouter.ftl"]);
|
||||
this._l10n = new DOMLocalization([
|
||||
"browser/newtab/asrouter.ftl",
|
||||
"browser/branding/brandings.ftl",
|
||||
"browser/branding/sync-brand.ftl",
|
||||
"branding/brand.ftl",
|
||||
]);
|
||||
|
||||
// Saved timeout IDs for scheduled state changes, so they can be cancelled
|
||||
this.stateTransitionTimeoutIDs = [];
|
||||
|
|
|
@ -101,6 +101,7 @@ const ONBOARDING_MESSAGES = () => [
|
|||
{
|
||||
id: "EXTENDED_TRIPLETS_1",
|
||||
template: "extended_triplets",
|
||||
campaign: "firstrun_triplets",
|
||||
targeting:
|
||||
"trailheadTriplet && ((currentDate|date - profileAgeCreated) / 86400000) < 7",
|
||||
includeBundle: {
|
||||
|
|
|
@ -2,8 +2,12 @@
|
|||
# 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/.
|
||||
|
||||
## These messages are used as headings in the recommendation doorhanger
|
||||
|
||||
cfr-doorhanger-extension-heading = Recommended Extension
|
||||
cfr-doorhanger-feature-heading = Recommended Feature
|
||||
cfr-doorhanger-pintab-heading = Try This: Pin Tab
|
||||
##
|
||||
|
||||
cfr-doorhanger-extension-sumo-link =
|
||||
.tooltiptext = Why am I seeing this
|
||||
|
@ -81,3 +85,25 @@ cfr-whatsnew-button =
|
|||
.tooltiptext = What’s New
|
||||
|
||||
cfr-whatsnew-panel-header = What’s New
|
||||
|
||||
## Bookmark Sync
|
||||
|
||||
cfr-doorhanger-sync-bookmarks-header = Get this bookmark on your phone
|
||||
cfr-doorhanger-sync-bookmarks-body = Take your bookmarks, passwords, history and more everywhere you’re signed into { -brand-product-name }.
|
||||
cfr-doorhanger-sync-bookmarks-ok-button = Turn on { -sync-brand-short-name }
|
||||
.accesskey = T
|
||||
|
||||
## Send Tab
|
||||
|
||||
cfr-doorhanger-send-tab-header = Read this on the go
|
||||
cfr-doorhanger-send-tab-recipe-header = Take this recipe to the kitchen
|
||||
cfr-doorhanger-send-tab-body = Send Tab lets you easily share this link to your phone or anywhere you’re signed in to { -brand-product-name }.
|
||||
cfr-doorhanger-send-tab-ok-button = Try Send Tab
|
||||
.accesskey = T
|
||||
|
||||
## Firefox Send
|
||||
|
||||
cfr-doorhanger-firefox-send-header = Share this PDF securely
|
||||
cfr-doorhanger-firefox-send-body = Keep your sensitive documents safe from prying eyes with end-to-end encryption and a link that disappears when you’re done.
|
||||
cfr-doorhanger-firefox-send-ok-button = Try { -send-brand-name }
|
||||
.accesskey = T
|
||||
|
|
|
@ -23,6 +23,7 @@ cd /mozilla-central && ./mach build \
|
|||
browser/base/content/test/static/browser_parsable_css.js \
|
||||
browser/base/content/test/tabs/browser_new_tab_in_privileged_process_pref.js \
|
||||
browser/components/enterprisepolicies/tests/browser/browser_policy_set_homepage.js \
|
||||
browser/components/extensions/test/browser/browser_ext_topSites.js \
|
||||
browser/components/preferences/in-content/tests/browser_hometab_restore_defaults.js \
|
||||
browser/components/preferences/in-content/tests/browser_newtab_menu.js \
|
||||
browser/components/preferences/in-content/tests/browser_search_subdialogs_within_preferences_1.js \
|
||||
|
|
|
@ -1222,6 +1222,81 @@ describe("ASRouter", () => {
|
|||
|
||||
assert.lengthOf(Router.state.providers.filter(p => p.url === url), 0);
|
||||
});
|
||||
it("should handle onboarding message provider", async () => {
|
||||
const handleMessageRequestStub = sandbox.stub(
|
||||
Router,
|
||||
"handleMessageRequest"
|
||||
);
|
||||
handleMessageRequestStub
|
||||
.withArgs({
|
||||
provider: "onboarding",
|
||||
template: "extended_triplets",
|
||||
})
|
||||
.resolves({ id: "foo" });
|
||||
const spy = sandbox.spy(Router, "setupExtendedTriplets");
|
||||
const msg = fakeAsyncMessage({
|
||||
type: "NEWTAB_MESSAGE_REQUEST",
|
||||
data: {},
|
||||
});
|
||||
await Router.onMessage(msg);
|
||||
|
||||
assert.calledOnce(spy);
|
||||
});
|
||||
it("should fallback to snippets if one was assigned to the holdback experiment", async () => {
|
||||
sandbox.stub(global.Sampling, "ratioSample").resolves(1); // 1 = holdback branch
|
||||
const handleMessageRequestStub = sandbox.stub(
|
||||
Router,
|
||||
"handleMessageRequest"
|
||||
);
|
||||
handleMessageRequestStub
|
||||
.withArgs({
|
||||
provider: "onboarding",
|
||||
template: "extended_triplets",
|
||||
})
|
||||
.resolves({ id: "foo" });
|
||||
const msg = fakeAsyncMessage({
|
||||
type: "NEWTAB_MESSAGE_REQUEST",
|
||||
data: {},
|
||||
});
|
||||
await Router.onMessage(msg);
|
||||
|
||||
assert.calledTwice(handleMessageRequestStub);
|
||||
assert.calledWithExactly(handleMessageRequestStub, {
|
||||
provider: "onboarding",
|
||||
template: "extended_triplets",
|
||||
});
|
||||
assert.calledWithExactly(handleMessageRequestStub, {
|
||||
provider: "snippets",
|
||||
});
|
||||
});
|
||||
it("should fallback to snippets if onboarding message provider returned none", async () => {
|
||||
const handleMessageRequestStub = sandbox.stub(
|
||||
Router,
|
||||
"handleMessageRequest"
|
||||
);
|
||||
handleMessageRequestStub
|
||||
.withArgs({
|
||||
provider: "onboarding",
|
||||
template: "extended_triplets",
|
||||
})
|
||||
.resolves(null);
|
||||
const spy = sandbox.spy(Router, "setupExtendedTriplets");
|
||||
const msg = fakeAsyncMessage({
|
||||
type: "NEWTAB_MESSAGE_REQUEST",
|
||||
data: {},
|
||||
});
|
||||
await Router.onMessage(msg);
|
||||
|
||||
assert.notCalled(spy);
|
||||
assert.calledTwice(handleMessageRequestStub);
|
||||
assert.calledWithExactly(handleMessageRequestStub, {
|
||||
provider: "onboarding",
|
||||
template: "extended_triplets",
|
||||
});
|
||||
assert.calledWithExactly(handleMessageRequestStub, {
|
||||
provider: "snippets",
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe("#onMessage: BLOCK_MESSAGE_BY_ID", () => {
|
||||
|
@ -2882,6 +2957,75 @@ describe("ASRouter", () => {
|
|||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe(".setupExtendedTriplets", () => {
|
||||
let setStringPrefStub;
|
||||
let setExperimentActiveStub;
|
||||
|
||||
beforeEach(() => {
|
||||
setStringPrefStub = sandbox.stub(
|
||||
global.Services.prefs,
|
||||
"setStringPref"
|
||||
);
|
||||
setExperimentActiveStub = sandbox.stub(
|
||||
global.TelemetryEnvironment,
|
||||
"setExperimentActive"
|
||||
);
|
||||
});
|
||||
|
||||
it("should generates a control branch configuration and update Router.state", async () => {
|
||||
sandbox.stub(global.Sampling, "ratioSample").resolves(0); // 0 = control branch
|
||||
|
||||
await Router.setupExtendedTriplets();
|
||||
|
||||
assert.propertyVal(Router.state, "extendedTripletsInitialized", true);
|
||||
assert.propertyVal(Router.state, "showExtendedTriplets", true);
|
||||
assert.calledWith(
|
||||
setStringPrefStub,
|
||||
TRAILHEAD_CONFIG.EXTENDED_TRIPLETS_EXPERIMENT_PREF,
|
||||
"control"
|
||||
);
|
||||
assert.calledWith(
|
||||
setExperimentActiveStub,
|
||||
"activity-stream-extended-triplets",
|
||||
"control"
|
||||
);
|
||||
});
|
||||
it("should generates a test branch configuration and update Router.state", async () => {
|
||||
sandbox.stub(global.Sampling, "ratioSample").resolves(1); // 1 = holdback branch
|
||||
|
||||
await Router.setupExtendedTriplets();
|
||||
|
||||
assert.propertyVal(Router.state, "extendedTripletsInitialized", true);
|
||||
assert.propertyVal(Router.state, "showExtendedTriplets", false);
|
||||
assert.calledWith(
|
||||
setStringPrefStub,
|
||||
TRAILHEAD_CONFIG.EXTENDED_TRIPLETS_EXPERIMENT_PREF,
|
||||
"holdback"
|
||||
);
|
||||
assert.calledWith(
|
||||
setExperimentActiveStub,
|
||||
"activity-stream-extended-triplets",
|
||||
"holdback"
|
||||
);
|
||||
});
|
||||
it("should reuse the existing branch if it's already defined", async () => {
|
||||
getStringPrefStub.returns("control");
|
||||
|
||||
await Router.setupExtendedTriplets();
|
||||
|
||||
assert.notCalled(setStringPrefStub);
|
||||
});
|
||||
it("should only run once", async () => {
|
||||
sandbox.spy(Router, "setState");
|
||||
|
||||
await Router.setupExtendedTriplets();
|
||||
await Router.setupExtendedTriplets();
|
||||
await Router.setupExtendedTriplets();
|
||||
|
||||
assert.calledOnce(Router.setState);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe("chooseBranch", () => {
|
||||
|
|
|
@ -44,9 +44,12 @@ describe("<FirstRun>", () => {
|
|||
let message;
|
||||
let fakeDoc;
|
||||
let sandbox;
|
||||
let clock;
|
||||
let onBlockByIdStub;
|
||||
|
||||
async function setup() {
|
||||
sandbox = sinon.createSandbox();
|
||||
clock = sandbox.useFakeTimers();
|
||||
message = await getTestMessage("TRAILHEAD_1");
|
||||
fakeDoc = {
|
||||
body: document.createElement("body"),
|
||||
|
@ -55,6 +58,7 @@ describe("<FirstRun>", () => {
|
|||
getElementById: () => document.createElement("div"),
|
||||
activeElement: document.createElement("div"),
|
||||
};
|
||||
onBlockByIdStub = sandbox.stub();
|
||||
|
||||
sandbox
|
||||
.stub(global, "fetch")
|
||||
|
@ -71,6 +75,7 @@ describe("<FirstRun>", () => {
|
|||
document={fakeDoc}
|
||||
dispatch={() => {}}
|
||||
sendUserActionTelemetry={() => {}}
|
||||
onBlockById={onBlockByIdStub}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
@ -132,6 +137,16 @@ describe("<FirstRun>", () => {
|
|||
});
|
||||
});
|
||||
|
||||
it("should pass along executeAction appropriately", () => {
|
||||
const stub = sandbox.stub();
|
||||
wrapper = mount(
|
||||
<FirstRun message={message} document={fakeDoc} executeAction={stub} />
|
||||
);
|
||||
|
||||
assert.propertyVal(wrapper.find(Interrupt).props(), "executeAction", stub);
|
||||
assert.propertyVal(wrapper.find(Triplets).props(), "onAction", stub);
|
||||
});
|
||||
|
||||
it("should load flow params on mount if fxaEndpoint is defined", () => {
|
||||
const stub = sandbox.stub();
|
||||
wrapper = mount(
|
||||
|
@ -198,7 +213,7 @@ describe("<FirstRun>", () => {
|
|||
);
|
||||
});
|
||||
|
||||
it("should hide triplets when closeTriplets is called", () => {
|
||||
it("should hide triplets when closeTriplets is called and block extended triplets after 500ms", () => {
|
||||
// Simulate calling next scene
|
||||
wrapper
|
||||
.find(Triplets)
|
||||
|
@ -212,5 +227,9 @@ describe("<FirstRun>", () => {
|
|||
.hasClass("show"),
|
||||
"Show triplet content"
|
||||
);
|
||||
|
||||
assert.notCalled(onBlockByIdStub);
|
||||
clock.tick(500);
|
||||
assert.calledWith(onBlockByIdStub, "EXTENDED_TRIPLETS_1");
|
||||
});
|
||||
});
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
import { _ToolbarPanelHub } from "lib/ToolbarPanelHub.jsm";
|
||||
import { GlobalOverrider } from "test/unit/utils";
|
||||
import { OnboardingMessageProvider } from "lib/OnboardingMessageProvider.jsm";
|
||||
import { PanelTestProvider } from "lib/PanelTestProvider.jsm";
|
||||
|
||||
describe("ToolbarPanelHub", () => {
|
||||
|
@ -15,6 +16,7 @@ describe("ToolbarPanelHub", () => {
|
|||
let addObserverStub;
|
||||
let removeObserverStub;
|
||||
let getBoolPrefStub;
|
||||
let setBoolPrefStub;
|
||||
let waitForInitializedStub;
|
||||
let isBrowserPrivateStub;
|
||||
let fakeDispatch;
|
||||
|
@ -31,6 +33,7 @@ describe("ToolbarPanelHub", () => {
|
|||
appendChild: sandbox.stub(),
|
||||
addEventListener: sandbox.stub(),
|
||||
hasAttribute: sandbox.stub(),
|
||||
toggleAttribute: sandbox.stub(),
|
||||
};
|
||||
fakeDocument = {
|
||||
l10n: {
|
||||
|
@ -75,6 +78,7 @@ describe("ToolbarPanelHub", () => {
|
|||
addObserverStub = sandbox.stub();
|
||||
removeObserverStub = sandbox.stub();
|
||||
getBoolPrefStub = sandbox.stub();
|
||||
setBoolPrefStub = sandbox.stub();
|
||||
fakeDispatch = sandbox.stub();
|
||||
isBrowserPrivateStub = sandbox.stub();
|
||||
globals.set("EveryWindow", everyWindowStub);
|
||||
|
@ -84,6 +88,7 @@ describe("ToolbarPanelHub", () => {
|
|||
addObserver: addObserverStub,
|
||||
removeObserver: removeObserverStub,
|
||||
getBoolPref: getBoolPrefStub,
|
||||
setBoolPref: setBoolPrefStub,
|
||||
},
|
||||
});
|
||||
globals.set("PrivateBrowsingUtils", {
|
||||
|
@ -476,4 +481,48 @@ describe("ToolbarPanelHub", () => {
|
|||
});
|
||||
});
|
||||
});
|
||||
describe("#insertProtectionPanelMessage", () => {
|
||||
const fakeInsert = () =>
|
||||
instance.insertProtectionPanelMessage({
|
||||
target: { ownerGlobal: fakeWindow, ownerDocument: fakeDocument },
|
||||
});
|
||||
beforeEach(async () => {
|
||||
const onboardingMsgs = await OnboardingMessageProvider.getUntranslatedMessages();
|
||||
await instance.init(waitForInitializedStub, {
|
||||
dispatch: fakeDispatch,
|
||||
getMessages: () =>
|
||||
onboardingMsgs.find(msg => msg.template === "protections_panel"),
|
||||
});
|
||||
});
|
||||
it("should remember it showed", async () => {
|
||||
await fakeInsert();
|
||||
|
||||
assert.calledWithExactly(
|
||||
setBoolPrefStub,
|
||||
"browser.protections_panel.infoMessage.seen",
|
||||
true
|
||||
);
|
||||
});
|
||||
it("should toggle/expand when default collapsed/disabled", async () => {
|
||||
fakeElementById.hasAttribute.returns(true);
|
||||
|
||||
await fakeInsert();
|
||||
|
||||
assert.calledTwice(fakeElementById.toggleAttribute);
|
||||
});
|
||||
it("should toggle again when popup hides", async () => {
|
||||
fakeElementById.addEventListener.callsArg(1);
|
||||
|
||||
await fakeInsert();
|
||||
|
||||
assert.callCount(fakeElementById.toggleAttribute, 4);
|
||||
});
|
||||
it("should open link on click", async () => {
|
||||
await fakeInsert();
|
||||
|
||||
eventListeners.click();
|
||||
|
||||
assert.calledOnce(fakeWindow.ownerGlobal.openLinkIn);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -8,6 +8,9 @@ const LOCKWISE_URL = RPMGetStringPref(
|
|||
"browser.contentblocking.report.lockwise.url",
|
||||
""
|
||||
);
|
||||
const HOW_IT_WORKS_URL_PREF = RPMGetFormatURLPref(
|
||||
"browser.contentblocking.report.lockwise.how_it_works.url"
|
||||
);
|
||||
|
||||
export default class LockwiseCard {
|
||||
constructor(document) {
|
||||
|
@ -26,18 +29,25 @@ export default class LockwiseCard {
|
|||
RPMSendAsyncMessage("OpenAboutLogins");
|
||||
});
|
||||
|
||||
const syncLink = this.doc.querySelector(".synced-devices-text a");
|
||||
const syncLink = this.doc.getElementById("turn-on-sync");
|
||||
// Register a click handler for the anchor since it's not possible to navigate to about:preferences via href
|
||||
syncLink.addEventListener("click", () => {
|
||||
this.doc.sendTelemetryEvent("click", "lw_app_link");
|
||||
RPMSendAsyncMessage("OpenSyncPreferences");
|
||||
});
|
||||
const eventHandler = evt => {
|
||||
if (evt.keyCode == evt.DOM_VK_RETURN || evt.type == "click") {
|
||||
this.doc.sendTelemetryEvent("click", "lw_app_link");
|
||||
RPMSendAsyncMessage("OpenSyncPreferences");
|
||||
}
|
||||
};
|
||||
syncLink.addEventListener("click", eventHandler);
|
||||
syncLink.addEventListener("keydown", eventHandler);
|
||||
|
||||
// Attach link to Firefox Lockwise app page.
|
||||
const lockwiseAppLink = this.doc.getElementById("lockwise-inline-link");
|
||||
lockwiseAppLink.href = LOCKWISE_URL;
|
||||
lockwiseAppLink.addEventListener("click", () => {
|
||||
this.doc.sendTelemetryEvent("click", "lw_sync_link");
|
||||
});
|
||||
|
||||
// Attack link to Firefox Lockwise "How it works" page.
|
||||
const lockwiseReportLink = this.doc.getElementById("lockwise-how-it-works");
|
||||
lockwiseReportLink.addEventListener("click", () => {
|
||||
this.doc.sendTelemetryEvent("click", "lw_about_link");
|
||||
|
@ -115,6 +125,9 @@ export default class LockwiseCard {
|
|||
"lockwise-passwords-stored"
|
||||
);
|
||||
|
||||
const howItWorksLink = this.doc.getElementById("lockwise-how-it-works");
|
||||
howItWorksLink.href = HOW_IT_WORKS_URL_PREF;
|
||||
|
||||
// Set the text for the number of synced devices.
|
||||
const syncedDevicesBlock = container.querySelector(
|
||||
".number-of-synced-devices.block"
|
||||
|
@ -134,7 +147,7 @@ export default class LockwiseCard {
|
|||
}
|
||||
// Display the link for enabling sync if no synced devices are detected.
|
||||
if (syncedDevices === 0) {
|
||||
const syncLink = syncedDevicesText.querySelector("a");
|
||||
const syncLink = this.doc.getElementById("turn-on-sync");
|
||||
syncLink.classList.remove("hidden");
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,6 +8,9 @@ const MONITOR_SIGN_IN_URL = RPMGetStringPref(
|
|||
"browser.contentblocking.report.monitor.url",
|
||||
""
|
||||
);
|
||||
const HOW_IT_WORKS_URL_PREF = RPMGetFormatURLPref(
|
||||
"browser.contentblocking.report.monitor.how_it_works.url"
|
||||
);
|
||||
|
||||
export default class MonitorClass {
|
||||
constructor(document) {
|
||||
|
@ -15,6 +18,9 @@ export default class MonitorClass {
|
|||
}
|
||||
|
||||
init() {
|
||||
const monitorLinkTag = this.doc.getElementById("monitor-inline-link");
|
||||
monitorLinkTag.href = MONITOR_SIGN_IN_URL;
|
||||
|
||||
RPMAddMessageListener("SendUserLoginsData", ({ data }) => {
|
||||
// Wait for monitor data and display the card.
|
||||
this.getMonitorData(data);
|
||||
|
@ -111,6 +117,9 @@ export default class MonitorClass {
|
|||
);
|
||||
monitorCardBody.classList.remove("hidden");
|
||||
|
||||
const howItWorksLink = this.doc.getElementById("monitor-link");
|
||||
howItWorksLink.href = HOW_IT_WORKS_URL_PREF;
|
||||
|
||||
const storedEmail = this.doc.querySelector(
|
||||
"span[data-type='stored-emails']"
|
||||
);
|
||||
|
|
|
@ -526,6 +526,7 @@ label[for="tab-cryptominer"]:hover ~ #highlight-hover {
|
|||
.monitor-card #monitor-header-content > a {
|
||||
display: block;
|
||||
margin-block-start: 5px;
|
||||
width: max-content;
|
||||
}
|
||||
|
||||
.monitor-card.has-logins #monitor-body-content {
|
||||
|
|
|
@ -41,19 +41,19 @@ etp-card-content = Trackers follow you around online to collect information abou
|
|||
graph-today = Today
|
||||
|
||||
social-tab-title = Social Media Trackers
|
||||
social-tab-contant = Social media like, post, and comment buttons on other websites can track you — even if you don’t use them. Logging in to sites using your Facebook or Twitter account is another way they can track what you do on those sites. We remove these trackers so Facebook and Twitter see less of what you do online.
|
||||
social-tab-contant = Social media like, post, and comment buttons on other websites can track you — even if you don’t use them. Logging in to sites using your Facebook or Twitter account is another way they can track what you do on those sites. We remove these trackers so Facebook and Twitter see less of what you do online. <a data-l10n-name="learn-more-link">Learn more</a>
|
||||
|
||||
cookie-tab-title = Cross-Site Tracking Cookies
|
||||
cookie-tab-content = Cross-site tracking cookies follow you from site to site to collect data about your browsing habits. Advertisers and analytics companies gather this data to create a profile of your interests across many sites. Blocking them reduces the number of personalized ads that follow you around.
|
||||
cookie-tab-content = Cross-site tracking cookies follow you from site to site to collect data about your browsing habits. Advertisers and analytics companies gather this data to create a profile of your interests across many sites. Blocking them reduces the number of personalized ads that follow you around. <a data-l10n-name="learn-more-link">Learn more</a>
|
||||
|
||||
tracker-tab-title = Tracking Content
|
||||
tracker-tab-content = Websites may load outside ads, videos, and other content that contain hidden trackers. Blocking tracking content can make websites load faster, but some buttons, forms, and login fields might not work.
|
||||
tracker-tab-content = Websites may load outside ads, videos, and other content that contain hidden trackers. Blocking tracking content can make websites load faster, but some buttons, forms, and login fields might not work. <a data-l10n-name="learn-more-link">Learn more</a>
|
||||
|
||||
fingerprinter-tab-title = Fingerprinters
|
||||
fingerprinter-tab-content = Fingerprinting is a form of online tracking that’s different from your real fingerprints. Companies use it to create a unique profile of you using data about your browser, device, and other settings. We block ad trackers from fingerprinting your device.
|
||||
fingerprinter-tab-content = Fingerprinting is a form of online tracking that’s different from your real fingerprints. Companies use it to create a unique profile of you using data about your browser, device, and other settings. We block ad trackers from fingerprinting your device. <a data-l10n-name="learn-more-link">Learn more</a>
|
||||
|
||||
cryptominer-tab-title = Cryptominers
|
||||
cryptominer-tab-content = Some websites host hidden malware that secretly uses your system’s computing power to mine cryptocurrency, or digital money. It drains your battery, slows down your computer, and increases your energy bill. We block known cryptominers from using your computing resources to make money.
|
||||
cryptominer-tab-content = Some websites host hidden malware that secretly uses your system’s computing power to mine cryptocurrency, or digital money. It drains your battery, slows down your computer, and increases your energy bill. We block known cryptominers from using your computing resources to make money. <a data-l10n-name="learn-more-link">Learn more</a>
|
||||
|
||||
lockwise-title = Never forget a password again
|
||||
lockwise-title-logged-in = { -lockwise-brand-name }
|
||||
|
@ -133,3 +133,14 @@ go-to-privacy-settings = Go to Privacy Settings
|
|||
|
||||
# This is the title attribute describing the Lockwise card's link to about:logins
|
||||
go-to-saved-logins = Go to Saved Logins
|
||||
|
||||
bar-tooltip-social =
|
||||
.title = Social Media Trackers
|
||||
bar-tooltip-cookie =
|
||||
.title = Cross-Site Tracking Cookies
|
||||
bar-tooltip-tracker =
|
||||
.title = Tracking Content
|
||||
bar-tooltip-fingerprinter =
|
||||
.title = Fingerprinters
|
||||
bar-tooltip-cryptominer =
|
||||
.title = Cryptominers
|
||||
|
|
|
@ -57,23 +57,33 @@
|
|||
<div id=highlight-hover></div>
|
||||
<div id="social" class="tab-content">
|
||||
<p class="content-title" data-l10n-id="social-tab-title"></p>
|
||||
<p data-l10n-id="social-tab-contant"></p>
|
||||
<p data-l10n-id="social-tab-contant">
|
||||
<a target="_blank" id="social-link" data-l10n-name="learn-more-link"></a>
|
||||
</p>
|
||||
</div>
|
||||
<div id="cookie" class="tab-content">
|
||||
<p class="content-title" data-l10n-id="cookie-tab-title"></p>
|
||||
<p data-l10n-id="cookie-tab-content"></p>
|
||||
<p data-l10n-id="cookie-tab-content">
|
||||
<a target="_blank" id="cookie-link" data-l10n-name="learn-more-link"></a>
|
||||
</p>
|
||||
</div>
|
||||
<div id="tracker" class="tab-content">
|
||||
<p class="content-title" data-l10n-id="tracker-tab-title"></p>
|
||||
<p data-l10n-id="tracker-tab-content"></p>
|
||||
<p data-l10n-id="tracker-tab-content">
|
||||
<a target="_blank" id="tracker-link" data-l10n-name="learn-more-link"></a>
|
||||
</p>
|
||||
</div>
|
||||
<div id="fingerprinter" class="tab-content">
|
||||
<p class="content-title" data-l10n-id="fingerprinter-tab-title"></p>
|
||||
<p data-l10n-id="fingerprinter-tab-content"></p>
|
||||
<p data-l10n-id="fingerprinter-tab-content">
|
||||
<a target="_blank" id="fingerprinter-link" data-l10n-name="learn-more-link"></a>
|
||||
</p>
|
||||
</div>
|
||||
<div id="cryptominer" class="tab-content">
|
||||
<p class="content-title" data-l10n-id="cryptominer-tab-title"></p>
|
||||
<p data-l10n-id="cryptominer-tab-content"></p>
|
||||
<p data-l10n-id="cryptominer-tab-content">
|
||||
<a target="_blank" id="cryptominer-link" data-l10n-name="learn-more-link"></a>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -91,7 +101,7 @@
|
|||
<span>
|
||||
<!-- Insert Monitor header content here. -->
|
||||
</span>
|
||||
<a id="monitor-link" href="" data-l10n-id="monitor-link"></a>
|
||||
<a target="_blank" href="" id="monitor-link" data-l10n-id="monitor-link"></a>
|
||||
</p>
|
||||
<span class="inline-text-icon monitor-scanned-text" data-l10n-id="auto-scan"></span>
|
||||
</div>
|
||||
|
@ -130,14 +140,14 @@
|
|||
<span id="info-exposed-passwords" class="info-text"></span>
|
||||
</div>
|
||||
<div id="full-report-link" class="monitor-view-full-report" data-l10n-id="full-report-link">
|
||||
<a id="monitor-inline-link" data-l10n-name="monitor-inline-link" href=""></a>
|
||||
<a target="_blank" id="monitor-inline-link" data-l10n-name="monitor-inline-link" href=""></a>
|
||||
</div>
|
||||
<div class="monitor-breached-passwords hidden">
|
||||
<span data-type="breached-lockwise-passwords" class="number-of-breaches block">
|
||||
<!-- Display number of exposed stored passwords here. -->
|
||||
</span>
|
||||
<span id="password-warning">
|
||||
<a id="lockwise-link" href="" data-l10n-name="lockwise-link"></a>
|
||||
<a target="_blank" href="about:logins" id="lockwise-link" data-l10n-name="lockwise-link" data-l10n-title="go-to-saved-logins"></a>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -163,7 +173,7 @@
|
|||
<div class="no-logins hidden">
|
||||
<div class="lockwise-mobile-app-icon"></div>
|
||||
<span data-l10n-id="lockwise-no-logins-content">
|
||||
<a id="lockwise-inline-link" data-l10n-name="lockwise-inline-link" href=""></a>
|
||||
<a target="_blank" id="lockwise-inline-link" data-l10n-name="lockwise-inline-link" href=""></a>
|
||||
</span>
|
||||
</div>
|
||||
<div class="has-logins hidden">
|
||||
|
@ -172,7 +182,7 @@
|
|||
</span>
|
||||
<span id="lockwise-passwords-stored" class="inline-text-icon passwords-stored-text">
|
||||
<!-- Display message for stored logins here. -->
|
||||
<a id="lockwise-how-it-works" data-l10n-name="lockwise-how-it-works" href=""></a>
|
||||
<a target="_blank" id="lockwise-how-it-works" data-l10n-name="lockwise-how-it-works" href=""></a>
|
||||
</span>
|
||||
<span class="number-of-synced-devices block">
|
||||
<!-- Display number of synced devices here. -->
|
||||
|
@ -181,7 +191,7 @@
|
|||
<span>
|
||||
<!-- Display message for status of synced devices here. -->
|
||||
</span>
|
||||
<a id="turn-on-sync" class="hidden" href="" data-l10n-id="turn-on-sync"></a>
|
||||
<a id="turn-on-sync" tabindex="0" class="hidden" href="" data-l10n-id="turn-on-sync"></a>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -124,6 +124,7 @@ document.addEventListener("DOMContentLoaded", e => {
|
|||
div.className = `${type}-bar inner-bar`;
|
||||
div.setAttribute("data-type", type);
|
||||
div.style.height = `${dataHeight}%`;
|
||||
div.setAttribute("data-l10n-id", `bar-tooltip-${type}`);
|
||||
weekTypeCounts[type] += content[type];
|
||||
innerBar.appendChild(div);
|
||||
}
|
||||
|
@ -151,10 +152,15 @@ document.addEventListener("DOMContentLoaded", e => {
|
|||
graph.append(label);
|
||||
date.setDate(date.getDate() - 1);
|
||||
}
|
||||
// Set the total number of each type of tracker on the tabs
|
||||
// Set the total number of each type of tracker on the tabs as well as their
|
||||
// "Learn More" links
|
||||
for (let type of dataTypes) {
|
||||
document.querySelector(`label[data-type=${type}]`).textContent =
|
||||
weekTypeCounts[type];
|
||||
const learnMoreLink = document.getElementById(`${type}-link`);
|
||||
learnMoreLink.href = RPMGetFormatURLPref(
|
||||
`browser.contentblocking.report.${type}.url`
|
||||
);
|
||||
}
|
||||
|
||||
// Hide the trackers tab if the user is in standard and
|
||||
|
|
|
@ -137,6 +137,7 @@ add_task(async function checkTelemetryClickEvents() {
|
|||
}
|
||||
|
||||
const syncLink = await ContentTaskUtils.waitForCondition(() => {
|
||||
// Opens an extra tab
|
||||
return content.document.getElementById("turn-on-sync");
|
||||
}, "syncLink exists");
|
||||
|
||||
|
@ -154,6 +155,7 @@ add_task(async function checkTelemetryClickEvents() {
|
|||
|
||||
await ContentTask.spawn(tab.linkedBrowser, {}, async function() {
|
||||
const openAboutLogins = await ContentTaskUtils.waitForCondition(() => {
|
||||
// Opens an extra tab
|
||||
return content.document.getElementById("open-about-logins-button");
|
||||
}, "openAboutLogins exists");
|
||||
|
||||
|
@ -208,6 +210,7 @@ add_task(async function checkTelemetryClickEvents() {
|
|||
|
||||
await ContentTask.spawn(tab.linkedBrowser, {}, async function() {
|
||||
let openLockwise = await ContentTaskUtils.waitForCondition(() => {
|
||||
// Opens an extra tab
|
||||
return content.document.getElementById("lockwise-link");
|
||||
}, "openLockwise exists");
|
||||
|
||||
|
@ -279,7 +282,11 @@ add_task(async function checkTelemetryClickEvents() {
|
|||
is(events.length, 1, `recorded telemetry for mtr_signup_button`);
|
||||
|
||||
await BrowserTestUtils.removeTab(tab);
|
||||
// We open two extra tabs with the click events.
|
||||
// We open three extra tabs with the click events.
|
||||
// 1. Monitor's "Viewed Saved Logins" link (goes to about:logins)
|
||||
// 2. Lockwise's "Turn on sync..." link (goes to about:preferences#sync)
|
||||
// 3. Lockwise's "Open Nightly" button (goes to about:logins)
|
||||
await BrowserTestUtils.removeTab(gBrowser.selectedTab);
|
||||
await BrowserTestUtils.removeTab(gBrowser.selectedTab);
|
||||
await BrowserTestUtils.removeTab(gBrowser.selectedTab);
|
||||
});
|
||||
|
|
|
@ -0,0 +1,717 @@
|
|||
{
|
||||
"data": [
|
||||
{
|
||||
"engineName": "google",
|
||||
"orderHint": 1000,
|
||||
"webExtensionId": "google@search.mozilla.org",
|
||||
"searchUrlGetExtraCodes": "client=firefox-b-d",
|
||||
"appliesTo": [{
|
||||
"included": { "everywhere": true },
|
||||
"default": "yes"
|
||||
}, {
|
||||
"included": {
|
||||
"regions": ["ru", "tr", "by", "kz"],
|
||||
"locales": {
|
||||
"matches": ["ru", "tr", "be", "kk"],
|
||||
"startsWith": ["en"]
|
||||
}
|
||||
},
|
||||
"default": "no"
|
||||
}, {
|
||||
"included": {
|
||||
"regions": ["cn"],
|
||||
"locales": {
|
||||
"matches": ["zh-CN"]
|
||||
}
|
||||
},
|
||||
"default": "no"
|
||||
}, {
|
||||
"included": { "regions": ["us"] },
|
||||
"searchUrlGetExtraCodes": "client=firefox-b-1-d"
|
||||
}],
|
||||
"aliases": ["@google"]
|
||||
},
|
||||
{
|
||||
"engineName": "bing",
|
||||
"webExtensionId": "bing@search.mozilla.org",
|
||||
"appliesTo": [{
|
||||
"included": {
|
||||
"locales": {
|
||||
"matches": [
|
||||
"ach", "af", "an", "ar", "ast", "az", "ca", "cak", "da", "de",
|
||||
"dsb", "el", "eo", "es-CL", "es-ES",
|
||||
"es-MX", "eu", "fa", "ff", "fi", "fr", "fy-NL", "gn",
|
||||
"gu-IN", "hi-IN", "hr", "hsb", "ia", "is", "it",
|
||||
"ja-JP-mac", "ja", "ka", "kab", "km", "kn", "lij", "lo",
|
||||
"lt", "mai", "mk", "ml", "ms", "my", "nb-NO", "ne-NP", "nl",
|
||||
"nn-NO", "oc", "or", "pa-IN", "pt-BR", "rm", "ro", "son",
|
||||
"sq", "sr", "sv-SE", "th", "tl", "trs", "uk", "ur", "uz",
|
||||
"wo", "xh", "zh-CN"
|
||||
],
|
||||
"startsWith": ["bn", "en"]
|
||||
}
|
||||
}
|
||||
}],
|
||||
"aliases": ["@bing"]
|
||||
},
|
||||
{
|
||||
"engineName": "baidu",
|
||||
"webExtensionId": "baidu@search.mozilla.org",
|
||||
"appliesTo": [{
|
||||
"included": { "locales": { "matches": ["zh-CN"] } }
|
||||
}, {
|
||||
"included": {
|
||||
"regions": ["cn"],
|
||||
"locales": { "matches": ["zh-CN"] }
|
||||
},
|
||||
"default": "yes"
|
||||
}],
|
||||
"aliases": ["@\u767E\u5EA6", "@baidu"]
|
||||
},
|
||||
{
|
||||
"engineName": "amazon",
|
||||
"orderHint": 500,
|
||||
"webExtensionId": "amazondotcom@search.mozilla.org",
|
||||
"appliesTo": [{
|
||||
"included": {
|
||||
"locales": {
|
||||
"matches": [
|
||||
"ach", "af", "ar", "az", "bg", "cak", "en-US", "eo",
|
||||
"es-AR", "fa", "gn", "hy-AM", "ia", "is", "ka", "km",
|
||||
"lt", "mk", "ms", "my", "ro", "si", "th", "tl",
|
||||
"trs", "uz"
|
||||
]
|
||||
}
|
||||
}
|
||||
}, {
|
||||
"included": {
|
||||
"regions": ["au"],
|
||||
"locales": {
|
||||
"matches": [
|
||||
"ach", "af", "ar", "az", "bg", "cak", "en-US", "eo",
|
||||
"es-AR", "fa", "gn", "hy-AM", "ia", "is", "ka", "km",
|
||||
"lt", "mk", "ms", "my", "ro", "si", "th", "tl",
|
||||
"trs", "uz"
|
||||
]
|
||||
}
|
||||
},
|
||||
"webExtensionId": "amazon@search.mozilla.org",
|
||||
"webExtensionLocale": "au"
|
||||
}, {
|
||||
"included": {
|
||||
"regions": ["ca"],
|
||||
"locales": {
|
||||
"matches": [
|
||||
"ach", "af", "ar", "az", "bg", "cak", "en-US", "eo",
|
||||
"es-AR", "fa", "gn", "hy-AM", "ia", "is", "ka", "km",
|
||||
"lt", "mk", "ms", "my", "ro", "si", "th", "tl",
|
||||
"trs", "uz"
|
||||
]
|
||||
}
|
||||
},
|
||||
"webExtensionId": "amazon@search.mozilla.org",
|
||||
"webExtensionLocale": "ca"
|
||||
}, {
|
||||
"included": {
|
||||
"regions": ["fr"],
|
||||
"locales": {
|
||||
"matches": [
|
||||
"ach", "af", "ar", "az", "bg", "cak", "en-US", "eo",
|
||||
"es-AR", "fa", "gn", "hy-AM", "ia", "is", "ka", "km",
|
||||
"lt", "mk", "ms", "my", "ro", "si", "th", "tl",
|
||||
"trs", "uz"
|
||||
]
|
||||
}
|
||||
},
|
||||
"webExtensionId": "amazon@search.mozilla.org",
|
||||
"webExtensionLocale": "france"
|
||||
}, {
|
||||
"included": {
|
||||
"regions": ["gb"],
|
||||
"locales": {
|
||||
"matches": [
|
||||
"ach", "af", "ar", "az", "bg", "cak", "en-US", "eo",
|
||||
"es-AR", "fa", "gn", "hy-AM", "ia", "is", "ka", "km",
|
||||
"lt", "mk", "ms", "my", "ro", "si", "th", "tl",
|
||||
"trs", "uz"
|
||||
]
|
||||
}
|
||||
},
|
||||
"webExtensionId": "amazon@search.mozilla.org",
|
||||
"webExtensionLocale": "en-GB"
|
||||
}],
|
||||
"aliases": ["amazon"]
|
||||
},
|
||||
{
|
||||
"engineName": "amazon",
|
||||
"orderHint": 500,
|
||||
"webExtensionId": "amazon@search.mozilla.org",
|
||||
"appliesTo": [{
|
||||
"included": {
|
||||
"locales": { "matches": [
|
||||
"as", "bn", "bn-IN", "kn", "gu-IN", "mai", "ml", "mr",
|
||||
"or", "pa-IN", "ta", "te", "ur"
|
||||
]}
|
||||
},
|
||||
"webExtensionLocale": "in"
|
||||
}, {
|
||||
"included": {
|
||||
"locales": { "matches": ["br", "ff", "fr", "son", "wo"] }
|
||||
},
|
||||
"webExtensionLocale": "france"
|
||||
}, {
|
||||
"included": {
|
||||
"regions": ["ca"],
|
||||
"locales": { "matches": ["br", "ff", "fr", "son", "wo"] }
|
||||
},
|
||||
"webExtensionLocale": "ca"
|
||||
}, {
|
||||
"included": { "locales": { "matches": ["en-CA"] } },
|
||||
"webExtensionLocale": "ca"
|
||||
}, {
|
||||
"included": { "locales": { "matches": ["ja-JP-mac", "ja"] } },
|
||||
"webExtensionLocale": "jp"
|
||||
}, {
|
||||
"included": { "locales": { "matches": ["it", "lij"] } },
|
||||
"webExtensionLocale": "it"
|
||||
}, {
|
||||
"included": { "locales": { "matches": ["de", "dsb", "hsb"] } },
|
||||
"webExtensionLocale": "de"
|
||||
}, {
|
||||
"included": {
|
||||
"locales": {
|
||||
"matches": [
|
||||
"cy", "da", "el", "en-GB", "eu", "ga-IE", "gd", "gl", "hr",
|
||||
"nb-NO", "nn-NO", "pt-PT", "sq", "sr"
|
||||
]
|
||||
}
|
||||
},
|
||||
"webExtensionLocale": "en-GB"
|
||||
}, {
|
||||
"included": {
|
||||
"regions": ["au"],
|
||||
"locales": {
|
||||
"matches": [
|
||||
"cy", "da", "el", "en-GB", "eu", "ga-IE", "gd", "gl", "hr",
|
||||
"nb-NO", "nn-NO", "pt-PT", "sq", "sr"
|
||||
]
|
||||
}
|
||||
},
|
||||
"webExtensionLocale": "au"
|
||||
}],
|
||||
"aliases": ["amazon"]
|
||||
},
|
||||
{
|
||||
"engineName": "amazon",
|
||||
"orderHint": 500,
|
||||
"webExtensionId": "amazondotcn@search.mozilla.org",
|
||||
"appliesTo": [{
|
||||
"included": { "locales": { "matches": ["zh-CN"] } }
|
||||
}],
|
||||
"aliases": ["amazon"]
|
||||
},
|
||||
{
|
||||
"engineName": "ebay",
|
||||
"orderHint": 500,
|
||||
"webExtensionId": "ebay@search.mozilla.org",
|
||||
"appliesTo": [{
|
||||
"included": { "locales": { "matches": ["en-US"] } },
|
||||
"excluded": { "regions": ["ru", "tr", "by", "kz"] }
|
||||
}, {
|
||||
"included": {
|
||||
"locales": { "matches": ["en-US"] },
|
||||
"regions": ["au"]
|
||||
},
|
||||
"webExtensionLocale": "au"
|
||||
}, {
|
||||
"included": {
|
||||
"locales": { "matches": ["en-US"] },
|
||||
"regions": ["ie"]
|
||||
},
|
||||
"webExtensionLocale": "ie"
|
||||
}, {
|
||||
"included": {
|
||||
"locales": { "matches": ["en-US"] },
|
||||
"regions": ["be"]
|
||||
},
|
||||
"webExtensionLocale": "be"
|
||||
}, {
|
||||
"included": { "locales": {
|
||||
"matches": ["an", "ast", "ca", "es-ES", "eu", "gl"]
|
||||
}},
|
||||
"webExtensionLocale": "es"
|
||||
}, {
|
||||
"included": { "locales": { "matches": ["br", "fr", "wo"] }},
|
||||
"webExtensionLocale": "fr"
|
||||
}, {
|
||||
"included": {
|
||||
"locales": { "matches": ["br", "fr", "wo"] },
|
||||
"regions": ["be"]
|
||||
},
|
||||
"webExtensionLocale": "be"
|
||||
}, {
|
||||
"included": {
|
||||
"locales": { "matches": ["br", "fr", "wo"] },
|
||||
"regions": ["ca"]
|
||||
},
|
||||
"webExtensionLocale": "ca"
|
||||
}, {
|
||||
"included": {
|
||||
"locales": { "matches": ["br", "fr", "wo"] },
|
||||
"regions": ["ch"]
|
||||
},
|
||||
"webExtensionLocale": "ch"
|
||||
}, {
|
||||
"included": { "locales": { "matches": ["cy", "en-GB", "gd"] }},
|
||||
"webExtensionLocale": "uk"
|
||||
}, {
|
||||
"included": {
|
||||
"locales": { "matches": ["cy", "en-GB", "gd"] },
|
||||
"regions": ["au"]
|
||||
},
|
||||
"webExtensionLocale": "au"
|
||||
}, {
|
||||
"included": {
|
||||
"locales": { "matches": ["cy", "en-GB", "gd"] },
|
||||
"regions": ["ie"]
|
||||
},
|
||||
"webExtensionLocale": "ie"
|
||||
}, {
|
||||
"included": { "locales": { "matches": ["de", "dsb", "hsb"] }},
|
||||
"webExtensionLocale": "de"
|
||||
}, {
|
||||
"included": {
|
||||
"locales": { "matches": ["de", "dsb", "hsb"] },
|
||||
"regions": ["at"]
|
||||
},
|
||||
"webExtensionLocale": "at"
|
||||
}, {
|
||||
"included": {
|
||||
"locales": { "matches": ["de", "dsb", "hsb"] },
|
||||
"regions": ["ch"]
|
||||
},
|
||||
"webExtensionLocale": "ch"
|
||||
}, {
|
||||
"included": { "locales": { "matches": ["en-CA"] }},
|
||||
"webExtensionLocale": "ca"
|
||||
}, {
|
||||
"included": { "locales": { "matches": ["fy-NL", "nl"] }},
|
||||
"webExtensionLocale": "nl"
|
||||
}, {
|
||||
"included": {
|
||||
"locales": { "matches": ["fy-NL", "nl"] },
|
||||
"regions": ["be"]
|
||||
},
|
||||
"webExtensionLocale": "be"
|
||||
}, {
|
||||
"included": { "locales": { "matches": ["ga-IE"] }},
|
||||
"webExtensionLocale": "ie"
|
||||
}, {
|
||||
"included": { "locales": { "matches": ["it", "lij"] }},
|
||||
"webExtensionLocale": "it"
|
||||
}, {
|
||||
"included": { "locales": { "matches": ["rm"] }},
|
||||
"webExtensionLocale": "ch"
|
||||
}],
|
||||
"aliases": ["@ebay"]
|
||||
},
|
||||
{
|
||||
"engineName": "ddg",
|
||||
"orderHint": 500,
|
||||
"appliesTo": [{
|
||||
"webExtensionId": "ddg@search.mozilla.org",
|
||||
"included": {
|
||||
"everywhere": true
|
||||
}
|
||||
}],
|
||||
"aliases": ["@duckduckgo", "@ddg"]
|
||||
},
|
||||
{
|
||||
"engineName": "yandex",
|
||||
"webExtensionId": "yandex@search.mozilla.org",
|
||||
"appliesTo": [{
|
||||
"default": "yes",
|
||||
"included": {
|
||||
"regions": ["ru", "tr", "by", "kz"],
|
||||
"locales": {
|
||||
"matches": ["ru", "tr", "be", "kk"],
|
||||
"startsWith": ["en"]
|
||||
}
|
||||
},
|
||||
"webExtensionLocale": "en"
|
||||
}, {
|
||||
"included": { "locales": { "matches": ["az"] }},
|
||||
"webExtensionLocale": "az"
|
||||
}, {
|
||||
"included": { "locales": { "matches": ["be"] }},
|
||||
"webExtensionLocale": "by"
|
||||
}, {
|
||||
"included": { "locales": { "matches": ["kk"] }},
|
||||
"webExtensionLocale": "kk"
|
||||
}, {
|
||||
"included": { "locales": { "matches": ["ru"] }},
|
||||
"webExtensionLocale": "ru"
|
||||
}, {
|
||||
"included": { "locales": { "matches": ["tr"] }},
|
||||
"webExtensionLocale": "tr"
|
||||
}],
|
||||
"aliases": ["@\u044F\u043D\u0434\u0435\u043A\u0441", "@yandex"]
|
||||
},
|
||||
{
|
||||
"engineName": "allegro-pl",
|
||||
"webExtensionId": "allegro-pl@search.mozilla.org",
|
||||
"appliesTo": [{ "included": { "locales": { "matches": ["pl"]}}}]
|
||||
},
|
||||
{
|
||||
"engineName": "atlas-sk",
|
||||
"webExtensionId": "atlas-sk@search.mozilla.org",
|
||||
"appliesTo": [{ "included": { "locales": { "matches": ["sk"]}}}]
|
||||
},
|
||||
{
|
||||
"engineName": "azerdict",
|
||||
"webExtensionId": "azerdict@search.mozilla.org",
|
||||
"appliesTo": [{ "included": { "locales": { "matches": ["az"]}}}]
|
||||
},
|
||||
{
|
||||
"engineName": "azet-sk",
|
||||
"webExtensionId": "azet-sk@search.mozilla.org",
|
||||
"appliesTo": [{ "included": { "locales": { "matches": ["sk"]}}}]
|
||||
},
|
||||
{
|
||||
"engineName": "bbc-alba",
|
||||
"webExtensionId": "bbc-alba@search.mozilla.org",
|
||||
"appliesTo": [{ "included": { "locales": { "matches": ["gd"]}}}]
|
||||
},
|
||||
{
|
||||
"engineName": "bok-NO",
|
||||
"webExtensionId": "bok-NO@search.mozilla.org",
|
||||
"appliesTo": [{ "included": {
|
||||
"locales": { "matches": ["nb-NO", "nn-NO"]}
|
||||
}}]
|
||||
},
|
||||
{
|
||||
"engineName": "bolcom",
|
||||
"webExtensionId": "bolcom@search.mozilla.org",
|
||||
"appliesTo": [{
|
||||
"included": { "locales": { "matches": ["fy-NL"]}},
|
||||
"webExtensionLocale": "fy-NL"
|
||||
}, {
|
||||
"included": { "locales": { "matches": ["nl"]}},
|
||||
"webExtensionLocale": "nl"
|
||||
}]
|
||||
},
|
||||
{
|
||||
"engineName": "ceneji",
|
||||
"webExtensionId": "ceneji@search.mozilla.org",
|
||||
"appliesTo": [{ "included": { "locales": { "matches": ["sl"]}}}]
|
||||
},
|
||||
{
|
||||
"engineName": "chambers-en-GB",
|
||||
"webExtensionId": "chambers-en-GB@search.mozilla.org",
|
||||
"appliesTo": [{ "included": { "locales": { "matches": ["en-GB"]}}}]
|
||||
},
|
||||
{
|
||||
"engineName": "coccoc",
|
||||
"webExtensionId": "coccoc@search.mozilla.org",
|
||||
"appliesTo": [{ "included": { "locales": { "matches": ["vi"]}}}]
|
||||
},
|
||||
{
|
||||
"engineName": "daum-kr",
|
||||
"webExtensionId": "daum-kr@search.mozilla.org",
|
||||
"appliesTo": [{ "included": { "locales": { "matches": ["ko"]}}}]
|
||||
},
|
||||
{
|
||||
"engineName": "diec2",
|
||||
"webExtensionId": "diec2@search.mozilla.org",
|
||||
"appliesTo": [{ "included": { "locales": { "matches": ["ca"]}}}]
|
||||
},
|
||||
{
|
||||
"engineName": "drae",
|
||||
"webExtensionId": "drae@search.mozilla.org",
|
||||
"appliesTo": [{
|
||||
"included": { "locales": { "matches": ["es-AR", "es-CL", "es-ES"]}}
|
||||
}]
|
||||
},
|
||||
{
|
||||
"engineName": "ecosia",
|
||||
"webExtensionId": "ecosia@search.mozilla.org",
|
||||
"appliesTo": [{ "included": { "locales": { "matches": ["de"]}}}]
|
||||
},
|
||||
{
|
||||
"engineName": "eki-ee",
|
||||
"webExtensionId": "eki-ee@search.mozilla.org",
|
||||
"appliesTo": [{ "included": { "locales": { "matches": ["et"]}}}]
|
||||
},
|
||||
{
|
||||
"engineName": "eudict",
|
||||
"webExtensionId": "eudict@search.mozilla.org",
|
||||
"appliesTo": [{ "included": { "locales": { "matches": ["hr"]}}}]
|
||||
},
|
||||
{
|
||||
"engineName": "faclair-beag",
|
||||
"webExtensionId": "faclair-beag@search.mozilla.org",
|
||||
"appliesTo": [{ "included": { "locales": { "matches": ["gd"]}}}]
|
||||
},
|
||||
{
|
||||
"engineName": "flip",
|
||||
"webExtensionId": "flip@search.mozilla.org",
|
||||
"appliesTo": [{ "included": { "locales": { "matches": ["kk"]}}}]
|
||||
},
|
||||
{
|
||||
"engineName": "freelang",
|
||||
"webExtensionId": "freelang@search.mozilla.org",
|
||||
"appliesTo": [{ "included": { "locales": { "matches": ["br"]}}}]
|
||||
},
|
||||
{
|
||||
"engineName": "gulesider-NO",
|
||||
"webExtensionId": "gulesider-NO@search.mozilla.org",
|
||||
"appliesTo": [{ "included": { "locales": { "matches": ["nn-NO", "nb-NO"]}}}]
|
||||
},
|
||||
{
|
||||
"engineName": "heureka-cz",
|
||||
"webExtensionId": "heureka-cz@search.mozilla.org",
|
||||
"appliesTo": [{ "included": { "locales": { "matches": ["cs"]}}}]
|
||||
},
|
||||
{
|
||||
"engineName": "hotline-ua",
|
||||
"webExtensionId": "hotline-ua@search.mozilla.org",
|
||||
"appliesTo": [{ "included": { "locales": { "matches": ["uk"]}}}]
|
||||
},
|
||||
{
|
||||
"engineName": "kannadastore",
|
||||
"webExtensionId": "kannadastore@search.mozilla.org",
|
||||
"appliesTo": [{ "included": { "locales": { "matches": ["kn"]}}}]
|
||||
},
|
||||
{
|
||||
"engineName": "leo_ende_de",
|
||||
"webExtensionId": "leo_ende_de@search.mozilla.org",
|
||||
"appliesTo": [{ "included": { "locales": { "matches": ["de", "dsb", "hsb" , "rm"]}}}]
|
||||
},
|
||||
{
|
||||
"engineName": "list-am",
|
||||
"webExtensionId": "list-am@search.mozilla.org",
|
||||
"appliesTo": [{ "included": { "locales": { "matches": ["hy-AM"]}}}]
|
||||
},
|
||||
{
|
||||
"engineName": "longdo",
|
||||
"webExtensionId": "longdo@search.mozilla.org",
|
||||
"appliesTo": [{ "included": { "locales": { "matches": ["th"]}}}]
|
||||
},
|
||||
{
|
||||
"engineName": "mailru",
|
||||
"webExtensionId": "mailru@search.mozilla.org",
|
||||
"appliesTo": [{ "included": { "locales": { "matches": ["ru"]}}}]
|
||||
},
|
||||
{
|
||||
"engineName": "mapy-cz",
|
||||
"webExtensionId": "mapy-cz@search.mozilla.org",
|
||||
"appliesTo": [{ "included": { "locales": { "matches": ["cs"]}}}]
|
||||
},
|
||||
{
|
||||
"engineName": "marktplaats",
|
||||
"webExtensionId": "marktplaats@search.mozilla.org",
|
||||
"appliesTo": [{
|
||||
"included": { "locales": { "matches": ["fy-NL"]}},
|
||||
"webExtensionLocale": "fy-NL"
|
||||
}, {
|
||||
"included": { "locales": { "matches": ["nl"]}},
|
||||
"webExtensionLocale": "nl"
|
||||
}]
|
||||
},
|
||||
{
|
||||
"engineName": "mercadolibre",
|
||||
"webExtensionId": "mercadolibre@search.mozilla.org",
|
||||
"appliesTo": [{
|
||||
"included": { "locales": { "matches": ["es-AR"]}},
|
||||
"webExtensionLocale": "ar"
|
||||
}, {
|
||||
"included": { "locales": { "matches": ["es-CL"]}},
|
||||
"webExtensionLocale": "cl"
|
||||
}, {
|
||||
"included": { "locales": { "matches": ["es-MX"]}},
|
||||
"webExtensionLocale": "mx"
|
||||
}]
|
||||
},
|
||||
{
|
||||
"engineName": "mercadolivre",
|
||||
"webExtensionId": "mercadolivre@search.mozilla.org",
|
||||
"appliesTo": [{ "included": { "locales": { "matches": ["pt-BR"]}}}]
|
||||
},
|
||||
{
|
||||
"engineName": "morfix-dic",
|
||||
"webExtensionId": "morfix-dic@search.mozilla.org",
|
||||
"appliesTo": [{ "included": { "locales": { "matches": ["he"]}}}]
|
||||
},
|
||||
{
|
||||
"engineName": "najdi-si",
|
||||
"webExtensionId": "najdi-si@search.mozilla.org",
|
||||
"appliesTo": [{ "included": { "locales": { "matches": ["sl"]}}}]
|
||||
},
|
||||
{
|
||||
"engineName": "naver-kr",
|
||||
"webExtensionId": "naver-kr@search.mozilla.org",
|
||||
"appliesTo": [{ "included": { "locales": { "matches": ["ko"]}}}]
|
||||
},
|
||||
{
|
||||
"engineName": "neti-ee",
|
||||
"webExtensionId": "neti-ee@search.mozilla.org",
|
||||
"appliesTo": [{ "included": { "locales": { "matches": ["et"]}}}]
|
||||
},
|
||||
{
|
||||
"engineName": "odpiralni",
|
||||
"webExtensionId": "odpiralni@search.mozilla.org",
|
||||
"appliesTo": [{ "included": { "locales": { "matches": ["sl"]}}}]
|
||||
},
|
||||
{
|
||||
"engineName": "olx",
|
||||
"webExtensionId": "olx@search.mozilla.org",
|
||||
"appliesTo": [{ "included": { "locales": { "matches": ["bs"]}}}]
|
||||
},
|
||||
{
|
||||
"engineName": "oshiete-goo",
|
||||
"webExtensionId": "oshiete-goo@search.mozilla.org",
|
||||
"appliesTo": [{ "included": { "locales": { "matches": ["ja-JP-mac", "jp"]}}}]
|
||||
},
|
||||
{
|
||||
"engineName": "osta-ee",
|
||||
"webExtensionId": "osta-ee@search.mozilla.org",
|
||||
"appliesTo": [{ "included": { "locales": { "matches": ["et"]}}}]
|
||||
},
|
||||
{
|
||||
"engineName": "ozonru",
|
||||
"webExtensionId": "ozonru@search.mozilla.org",
|
||||
"appliesTo": [{ "included": { "locales": { "matches": ["ru"]}}}]
|
||||
},
|
||||
{
|
||||
"engineName": "palasprint",
|
||||
"webExtensionId": "palasprint@search.mozilla.org",
|
||||
"appliesTo": [{ "included": { "locales": { "matches": ["cy"]}}}]
|
||||
},
|
||||
{
|
||||
"engineName": "pazaruvaj",
|
||||
"webExtensionId": "pazaruvaj@search.mozilla.org",
|
||||
"appliesTo": [{ "included": { "locales": { "matches": ["bg"]}}}]
|
||||
},
|
||||
{
|
||||
"engineName": "pogodak",
|
||||
"webExtensionId": "pogodak@search.mozilla.org",
|
||||
"appliesTo": [{ "included": { "locales": { "matches": ["sr"]}}}]
|
||||
},
|
||||
{
|
||||
"engineName": "priberam",
|
||||
"webExtensionId": "priberam@search.mozilla.org",
|
||||
"appliesTo": [{ "included": { "locales": { "matches": ["pt-PT"]}}}]
|
||||
},
|
||||
{
|
||||
"engineName": "priceru",
|
||||
"webExtensionId": "priceru@search.mozilla.org",
|
||||
"appliesTo": [{ "included": { "locales": { "matches": ["ru"]}}}]
|
||||
},
|
||||
{
|
||||
"engineName": "prisjakt-sv-SE",
|
||||
"webExtensionId": "prisjakt-sv-SE@search.mozilla.org",
|
||||
"appliesTo": [{ "included": { "locales": { "matches": ["sv-SE"]}}}]
|
||||
},
|
||||
{
|
||||
"engineName": "pwn-pl",
|
||||
"webExtensionId": "pwn-pl@search.mozilla.org",
|
||||
"appliesTo": [{ "included": { "locales": { "matches": ["pl"]}}}]
|
||||
},
|
||||
{
|
||||
"engineName": "qwant",
|
||||
"webExtensionId": "qwant@search.mozilla.org",
|
||||
"appliesTo": [{ "included": { "locales": { "matches": ["fr"]}}}]
|
||||
},
|
||||
{
|
||||
"engineName": "qxl-NO",
|
||||
"webExtensionId": "qxl-NO@search.mozilla.org",
|
||||
"appliesTo": [{ "included": { "locales": { "matches": ["nb-NO", "nn-NO"]}}}]
|
||||
},
|
||||
{
|
||||
"engineName": "rakuten",
|
||||
"webExtensionId": "rakuten@search.mozilla.org",
|
||||
"appliesTo": [{ "included": { "locales": { "matches": ["ja-JP-mac", "jp"]}}}]
|
||||
},
|
||||
{
|
||||
"engineName": "readmoo",
|
||||
"webExtensionId": "readmoo@search.mozilla.org",
|
||||
"appliesTo": [{ "included": { "locales": { "matches": ["zh-TW"]}}}]
|
||||
},
|
||||
{
|
||||
"engineName": "salidzinilv",
|
||||
"webExtensionId": "salidzinilv@search.mozilla.org",
|
||||
"appliesTo": [{ "included": { "locales": { "matches": ["ltg", "lv"]}}}]
|
||||
},
|
||||
{
|
||||
"engineName": "seznam-cz",
|
||||
"webExtensionId": "seznam-cz@search.mozilla.org",
|
||||
"appliesTo": [{ "included": { "locales": { "matches": ["cs"]}}}]
|
||||
},
|
||||
{
|
||||
"engineName": "sslv",
|
||||
"webExtensionId": "sslv@search.mozilla.org",
|
||||
"appliesTo": [{ "included": { "locales": { "matches": ["ltg", "lv"]}}}]
|
||||
},
|
||||
{
|
||||
"engineName": "tearma",
|
||||
"webExtensionId": "tearma@search.mozilla.org",
|
||||
"appliesTo": [{ "included": { "locales": { "matches": ["ga-IE"]}}}]
|
||||
},
|
||||
{
|
||||
"engineName": "twitter",
|
||||
"webExtensionId": "twitter@search.mozilla.org",
|
||||
"appliesTo": [{
|
||||
"included": { "locales": { "matches": [
|
||||
"en-US", "ach", "an", "bs", "ca", "crh", "en-CA", "ga-IE",
|
||||
"gn", "hr", "ia", "ka", "kk", "km", "lo", "lt", "mai",
|
||||
"ms", "my", "ne-NP", "oc", "pt-BR", "sl", "tl", "tr",
|
||||
"ur", "uz", "wo"
|
||||
]}}
|
||||
}, {
|
||||
"included": { "locales": { "matches": ["ja-JP-mac", "ja"]}},
|
||||
"webExtensionLocale": "ja"
|
||||
}]
|
||||
},
|
||||
{
|
||||
"engineName": "tyda-sv-SE",
|
||||
"webExtensionId": "tyda-sv-SE@search.mozilla.org",
|
||||
"appliesTo": [{ "included": { "locales": { "matches": ["sv-SE"]}}}]
|
||||
},
|
||||
{
|
||||
"engineName": "vatera",
|
||||
"webExtensionId": "vatera@search.mozilla.org",
|
||||
"appliesTo": [{ "included": { "locales": { "matches": ["hu"]}}}]
|
||||
},
|
||||
{
|
||||
"engineName": "wiktionary",
|
||||
"webExtensionId": "wiktionary@search.mozilla.org",
|
||||
"appliesTo": [{
|
||||
"included": { "locales": { "matches": ["te"]}},
|
||||
"webExtensionLocale": "te"
|
||||
}, {
|
||||
"included": { "locales": { "matches": ["oc"]}},
|
||||
"webExtensionLocale": "oc"
|
||||
}]
|
||||
},
|
||||
{
|
||||
"engineName": "wolnelektury-pl",
|
||||
"webExtensionId": "wolnelektury-pl@search.mozilla.org",
|
||||
"appliesTo": [{ "included": { "locales": { "matches": ["pl"]}}}]
|
||||
},
|
||||
{
|
||||
"engineName": "yahoo-jp",
|
||||
"webExtensionId": "yahoo-jp@search.mozilla.org",
|
||||
"appliesTo": [{ "included": { "locales": { "matches": ["ja-JP-mac", "ja"]}}}]
|
||||
},
|
||||
{
|
||||
"engineName": "yahoo-jp-auctions",
|
||||
"webExtensionId": "yahoo-jp-auctions@search.mozilla.org",
|
||||
"appliesTo": [{ "included": { "locales": { "matches": ["ja-JP-mac", "ja"]}}}]
|
||||
},
|
||||
{
|
||||
"engineName": "zoznam-sk",
|
||||
"webExtensionId": "zoznam-sk@search.mozilla.org",
|
||||
"appliesTo": [{ "included": { "locales": { "matches": ["sk"]}}}]
|
||||
}
|
||||
]
|
||||
}
|
|
@ -304,9 +304,6 @@
|
|||
; gre location for now.
|
||||
@RESPATH@/defaults/pref/channel-prefs.js
|
||||
|
||||
; Services (gre) prefs
|
||||
@RESPATH@/defaults/pref/services-sync.js
|
||||
|
||||
; [Layout Engine Resources]
|
||||
; Style Sheets, Graphics and other Resources used by the layout engine.
|
||||
@RESPATH@/res/EditorOverride.css
|
||||
|
|
|
@ -2,8 +2,12 @@
|
|||
# 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/.
|
||||
|
||||
## These messages are used as headings in the recommendation doorhanger
|
||||
|
||||
cfr-doorhanger-extension-heading = Recommended Extension
|
||||
cfr-doorhanger-feature-heading = Recommended Feature
|
||||
cfr-doorhanger-pintab-heading = Try This: Pin Tab
|
||||
##
|
||||
|
||||
cfr-doorhanger-extension-sumo-link =
|
||||
.tooltiptext = Why am I seeing this
|
||||
|
@ -81,3 +85,25 @@ cfr-whatsnew-button =
|
|||
.tooltiptext = What’s New
|
||||
|
||||
cfr-whatsnew-panel-header = What’s New
|
||||
|
||||
## Bookmark Sync
|
||||
|
||||
cfr-doorhanger-sync-bookmarks-header = Get this bookmark on your phone
|
||||
cfr-doorhanger-sync-bookmarks-body = Take your bookmarks, passwords, history and more everywhere you’re signed into { -brand-product-name }.
|
||||
cfr-doorhanger-sync-bookmarks-ok-button = Turn on { -sync-brand-short-name }
|
||||
.accesskey = T
|
||||
|
||||
## Send Tab
|
||||
|
||||
cfr-doorhanger-send-tab-header = Read this on the go
|
||||
cfr-doorhanger-send-tab-recipe-header = Take this recipe to the kitchen
|
||||
cfr-doorhanger-send-tab-body = Send Tab lets you easily share this link to your phone or anywhere you’re signed in to { -brand-product-name }.
|
||||
cfr-doorhanger-send-tab-ok-button = Try Send Tab
|
||||
.accesskey = T
|
||||
|
||||
## Firefox Send
|
||||
|
||||
cfr-doorhanger-firefox-send-header = Share this PDF securely
|
||||
cfr-doorhanger-firefox-send-body = Keep your sensitive documents safe from prying eyes with end-to-end encryption and a link that disappears when you’re done.
|
||||
cfr-doorhanger-firefox-send-ok-button = Try { -send-brand-name }
|
||||
.accesskey = T
|
||||
|
|
|
@ -741,6 +741,9 @@ you can use these alternative items. Otherwise, their values should be empty. -
|
|||
|
||||
<!ENTITY protections.etpON.header "Enhanced Tracking Protection is ON for this site">
|
||||
<!ENTITY protections.etpOFF.header "Enhanced Tracking Protection is OFF for this site">
|
||||
<!-- LOCALIZATION NOTE:
|
||||
protections.etpMoreInfo.label: The text a screen reader speaks when focused on the info button. -->
|
||||
<!ENTITY protections.etpMoreInfo.label "More information about Enhanced Tracking Protection">
|
||||
<!ENTITY protections.settings.label "Protection Settings">
|
||||
<!ENTITY protections.report.label "Show Full Report">
|
||||
<!-- LOCALIZATION NOTE:
|
||||
|
|
|
@ -211,10 +211,16 @@
|
|||
}
|
||||
|
||||
#protections-popup > .panel-arrowcontainer > .panel-arrowbox > .panel-arrow {
|
||||
transition-property: fill;
|
||||
transition-timing-function: var(--animation-easing-function);
|
||||
transition-duration: var(--panelui-subview-transition-duration);
|
||||
}
|
||||
|
||||
#protections-popup[mainviewshowing] > .panel-arrowcontainer > .panel-arrowbox > .panel-arrow {
|
||||
fill: #0A51BF;
|
||||
}
|
||||
|
||||
:root[lwt-popup-brighttext] #protections-popup > .panel-arrowcontainer > .panel-arrowbox > .panel-arrow {
|
||||
:root[lwt-popup-brighttext] #protections-popup[mainviewshowing] > .panel-arrowcontainer > .panel-arrowbox > .panel-arrow {
|
||||
fill: #0CB0F5;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
<!-- This Source Code Form is subject to the terms of the Mozilla Public
|
||||
- License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
- file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
|
||||
<svg width="16" height="16" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><defs><path d="M.5.5h16v16H.5V.5zm12 8a4 4 0 1 0 0-8 4 4 0 0 0 0 8z" id="a"/><linearGradient x1="0%" y1=".107%" y2="99.893%" id="b"><stop stop-color="#C689FF" offset="0%"/><stop stop-color="#00B3F4" offset="100%"/></linearGradient></defs><g fill="none" fill-rule="evenodd"><g transform="translate(-.5 -.5)"><mask id="c" fill="#fff"><use xlink:href="#a"/></mask><path d="M6.14 5.02c.405.908.884 2.668-.016 2.455-.327-.078-.57-.13-.648-.153l-.005-.002a.016.016 0 0 0 .005.002c-1.145-.343-2.852-.487-3.696.088-.843.574-.44 1.091-.337 1.755-.68.748-.506 1.559.036 2.345-.44.896-.085 1.646.57 2.29-.212 1.308.59 1.772 1.904 2.121.16.043.49.055.862.055h.014c.52 0 1.117-.024 1.453-.025 1.43-.005 2.735-.178 4.175-.234 1.44-.055 3.037.243 4.506.256.013-1.989.015-4.004.028-6.003a79.917 79.917 0 0 0-1.385.001c-.534.003-1.068.006-1.608-.003-.226-.088-.74-.547-.826-.66-.085-.111-.1-.231-.1-.231s-.313-.663-.589-.938C9.347 7.003 8.49 5.021 8.023 3.386c-.313-.498.658-1.226-.583-1.379A.969.969 0 0 0 7.32 2C6.17 2 5.75 4.14 6.14 5.02" fill="url(#b)" mask="url(#c)"/></g><path d="M12 6.188c-.364 0-.702-.098-1.005-.256l2.937-2.937c.158.303.255.64.255 1.005 0 1.208-.979 2.188-2.187 2.188m0-4.375c.364 0 .702.097 1.005.255l-2.937 2.937A2.163 2.163 0 0 1 9.813 4c0-1.208.979-2.188 2.187-2.188M12 .5a3.5 3.5 0 1 0 0 7 3.5 3.5 0 0 0 0-7" fill="#ED1C24"/></g></svg>
|
||||
<svg width="16" height="16" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><defs><path d="M.5.5h16v16H.5V.5zm12 8a4 4 0 1 0 0-8 4 4 0 0 0 0 8z" id="a"/><linearGradient x1="62.533%" y1=".107%" x2="0%" y2="109.9%" id="b"><stop stop-color="#AB71FF" offset="0%"/><stop stop-color="#00B3F4" offset="100%"/></linearGradient></defs><g fill="none" fill-rule="evenodd"><g transform="translate(-.5 -.5)"><mask id="c" fill="#fff"><use xlink:href="#a"/></mask><path d="M6.14 5.02c.405.908.884 2.668-.016 2.455-.327-.078-.57-.13-.648-.153l-.005-.002a.016.016 0 0 0 .005.002c-1.145-.343-2.852-.487-3.696.088-.843.574-.44 1.091-.337 1.755-.68.748-.506 1.559.036 2.345-.44.896-.085 1.646.57 2.29-.212 1.308.59 1.772 1.904 2.121.16.043.49.055.862.055h.014c.52 0 1.117-.024 1.453-.025 1.43-.005 2.735-.178 4.175-.234 1.44-.055 3.037.243 4.506.256.013-1.989.015-4.004.028-6.003a79.917 79.917 0 0 0-1.385.001c-.534.003-1.068.006-1.608-.003-.226-.088-.74-.547-.826-.66-.085-.111-.1-.231-.1-.231s-.313-.663-.589-.938C9.347 7.003 8.49 5.021 8.023 3.386c-.313-.498.658-1.226-.583-1.379A.969.969 0 0 0 7.32 2C6.17 2 5.75 4.14 6.14 5.02" fill="url(#b)" fill-rule="nonzero" mask="url(#c)"/></g><path d="M12 6.188c-.364 0-.702-.098-1.005-.256l2.937-2.937c.158.303.255.64.255 1.005 0 1.208-.979 2.188-2.187 2.188m0-4.375c.364 0 .702.097 1.005.255l-2.937 2.937A2.163 2.163 0 0 1 9.813 4c0-1.208.979-2.188 2.187-2.188M12 .5a3.5 3.5 0 1 0 0 7 3.5 3.5 0 0 0 0-7" fill="#ED1C24"/></g></svg>
|
||||
|
|
До Ширина: | Высота: | Размер: 1.6 KiB После Ширина: | Высота: | Размер: 1.7 KiB |
|
@ -1,4 +1,4 @@
|
|||
<!-- This Source Code Form is subject to the terms of the Mozilla Public
|
||||
- License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
- file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
|
||||
<svg width="16" height="16" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><defs><path d="M.5.5h16v16H.5V.5zm12 8a4 4 0 1 0 0-8 4 4 0 0 0 0 8z" id="a"/><linearGradient x1="0%" y1=".107%" y2="99.893%" id="b"><stop stop-color="#9059FF" offset="0%"/><stop stop-color="#0250BB" offset="100%"/></linearGradient></defs><g fill="none" fill-rule="evenodd"><g transform="translate(-.5 -.5)"><mask id="c" fill="#fff"><use xlink:href="#a"/></mask><path d="M6.14 5.02c.405.908.884 2.668-.016 2.455-.327-.078-.57-.13-.648-.153l-.005-.002a.016.016 0 0 0 .005.002c-1.145-.343-2.852-.487-3.696.088-.843.574-.44 1.091-.337 1.755-.68.748-.506 1.559.036 2.345-.44.896-.085 1.646.57 2.29-.212 1.308.59 1.772 1.904 2.121.16.043.49.055.862.055h.014c.52 0 1.117-.024 1.453-.025 1.43-.005 2.735-.178 4.175-.234 1.44-.055 3.037.243 4.506.256.013-1.989.015-4.004.028-6.003a79.917 79.917 0 0 0-1.385.001c-.534.003-1.068.006-1.608-.003-.226-.088-.74-.547-.826-.66-.085-.111-.1-.231-.1-.231s-.313-.663-.589-.938C9.347 7.003 8.49 5.021 8.023 3.386c-.313-.498.658-1.226-.583-1.379A.969.969 0 0 0 7.32 2C6.17 2 5.75 4.14 6.14 5.02" fill="url(#b)" mask="url(#c)"/></g><path d="M12 6.188c-.364 0-.702-.098-1.005-.256l2.937-2.937c.158.303.255.64.255 1.005 0 1.208-.979 2.188-2.187 2.188m0-4.375c.364 0 .702.097 1.005.255l-2.937 2.937A2.163 2.163 0 0 1 9.813 4c0-1.208.979-2.188 2.187-2.188M12 .5a3.5 3.5 0 1 0 0 7 3.5 3.5 0 0 0 0-7" fill="#ED1C24"/></g></svg>
|
||||
<svg width="16" height="16" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><defs><path d="M.5.5h16v16H.5V.5zm12 8a4 4 0 1 0 0-8 4 4 0 0 0 0 8z" id="a"/><linearGradient x1="53.384%" y1=".107%" x2="0%" y2="113.918%" id="b"><stop stop-color="#7542E5" offset="0%"/><stop stop-color="#0060DF" offset="100%"/></linearGradient></defs><g fill="none" fill-rule="evenodd"><g transform="translate(-.5 -.5)"><mask id="c" fill="#fff"><use xlink:href="#a"/></mask><path d="M6.14 5.02c.405.908.884 2.668-.016 2.455-.327-.078-.57-.13-.648-.153l-.005-.002a.016.016 0 0 0 .005.002c-1.145-.343-2.852-.487-3.696.088-.843.574-.44 1.091-.337 1.755-.68.748-.506 1.559.036 2.345-.44.896-.085 1.646.57 2.29-.212 1.308.59 1.772 1.904 2.121.16.043.49.055.862.055h.014c.52 0 1.117-.024 1.453-.025 1.43-.005 2.735-.178 4.175-.234 1.44-.055 3.037.243 4.506.256.013-1.989.015-4.004.028-6.003a79.917 79.917 0 0 0-1.385.001c-.534.003-1.068.006-1.608-.003-.226-.088-.74-.547-.826-.66-.085-.111-.1-.231-.1-.231s-.313-.663-.589-.938C9.347 7.003 8.49 5.021 8.023 3.386c-.313-.498.658-1.226-.583-1.379A.969.969 0 0 0 7.32 2C6.17 2 5.75 4.14 6.14 5.02" fill="url(#b)" fill-rule="nonzero" mask="url(#c)"/></g><path d="M12 6.188c-.364 0-.702-.098-1.005-.256l2.937-2.937c.158.303.255.64.255 1.005 0 1.208-.979 2.188-2.187 2.188m0-4.375c.364 0 .702.097 1.005.255l-2.937 2.937A2.163 2.163 0 0 1 9.813 4c0-1.208.979-2.188 2.187-2.188M12 .5a3.5 3.5 0 1 0 0 7 3.5 3.5 0 0 0 0-7" fill="#ED1C24"/></g></svg>
|
||||
|
|
До Ширина: | Высота: | Размер: 1.6 KiB После Ширина: | Высота: | Размер: 1.7 KiB |
|
@ -161,19 +161,14 @@ js_option(env='MOZ_LD64_KNOWN_GOOD',
|
|||
|
||||
imply_option('MOZ_LD64_KNOWN_GOOD', depends_if('MOZ_AUTOMATION')(lambda _: True))
|
||||
|
||||
@depends('--enable-lto', 'MOZ_PGO', '--enable-profile-generate', c_compiler,
|
||||
'MOZ_LD64_KNOWN_GOOD', target)
|
||||
@depends('--enable-lto', c_compiler, 'MOZ_LD64_KNOWN_GOOD', target)
|
||||
@imports('multiprocessing')
|
||||
def lto(value, pgo, profile_generate, c_compiler, ld64_known_good, target):
|
||||
def lto(value, c_compiler, ld64_known_good, target):
|
||||
cflags = []
|
||||
ldflags = []
|
||||
enabled = None
|
||||
rust_lto = False
|
||||
|
||||
# MSVC's implementation of PGO implies LTO. Make clang-cl match this.
|
||||
if c_compiler.type == 'clang-cl' and pgo and not profile_generate and value.origin == 'default':
|
||||
value = ['cross']
|
||||
|
||||
if value:
|
||||
enabled = True
|
||||
# `cross` implies `thin`, but with Rust code participating in LTO
|
||||
|
|
|
@ -7,6 +7,7 @@ export MAKECAB=$TOOLTOOL_DIR/makecab.exe
|
|||
|
||||
if [ -z "$USE_ARTIFACT" ]; then
|
||||
if [ -n "$MOZ_PGO_PROFILE_USE" ]; then
|
||||
export MOZ_LTO=cross
|
||||
ac_add_options --enable-profile-use
|
||||
ac_add_options --with-pgo-jarlog="${WORKSPACE}/fetches/en-US.log"
|
||||
ac_add_options --with-pgo-profile-path="${WORKSPACE}/fetches"
|
||||
|
|
|
@ -14,7 +14,6 @@ const {
|
|||
} = require("devtools/client/shared/vendor/react");
|
||||
const ReactDOM = require("devtools/client/shared/vendor/react-dom");
|
||||
const { Provider } = require("devtools/client/shared/vendor/react-redux");
|
||||
const { combineReducers } = require("devtools/client/shared/vendor/redux");
|
||||
|
||||
// Accessibility Panel
|
||||
const MainFrame = createFactory(require("./components/MainFrame"));
|
||||
|
@ -23,11 +22,11 @@ const OldVersionDescription = createFactory(
|
|||
);
|
||||
|
||||
// Store
|
||||
const createStore = require("devtools/client/shared/redux/create-store")();
|
||||
const createStore = require("devtools/client/shared/redux/create-store");
|
||||
|
||||
// Reducers
|
||||
const { reducers } = require("./reducers/index");
|
||||
const store = createStore(combineReducers(reducers));
|
||||
const store = createStore(reducers);
|
||||
|
||||
// Actions
|
||||
const { reset } = require("./actions/ui");
|
||||
|
|
|
@ -28,7 +28,7 @@ window.onload = async function() {
|
|||
const { createFactory, createElement } =
|
||||
browserRequire("devtools/client/shared/vendor/react");
|
||||
const { Provider } = require("devtools/client/shared/vendor/react-redux");
|
||||
const createStore = require("devtools/client/shared/redux/create-store")();
|
||||
const createStore = require("devtools/client/shared/redux/create-store");
|
||||
const { Simulate } =
|
||||
browserRequire("devtools/client/shared/vendor/react-dom-test-utils");
|
||||
const Accessible = createFactory(
|
||||
|
@ -59,7 +59,13 @@ window.onload = async function() {
|
|||
let URL = "http://example.com";
|
||||
const mockStore = createStore((state, action) =>
|
||||
action ? { ...state, ...action } : state,
|
||||
{ details: { DOMNode: {}, accessible: { value: URL } }, ui: { supports: {} } });
|
||||
{
|
||||
initialState: {
|
||||
details: { DOMNode: {}, accessible: { value: URL } },
|
||||
ui: { supports: {} }
|
||||
},
|
||||
}
|
||||
);
|
||||
const provider = createElement(Provider, { store: mockStore }, a);
|
||||
const accessible = ReactDOM.render(provider, window.document.body);
|
||||
ok(accessible, "Should be able to mount Accessible instances");
|
||||
|
|
|
@ -26,7 +26,7 @@ window.onload = async function() {
|
|||
const { createFactory, createElement } =
|
||||
browserRequire("devtools/client/shared/vendor/react");
|
||||
const { Provider } = require("devtools/client/shared/vendor/react-redux");
|
||||
const createStore = require("devtools/client/shared/redux/create-store")();
|
||||
const createStore = require("devtools/client/shared/redux/create-store");
|
||||
const { Simulate } =
|
||||
browserRequire("devtools/client/shared/vendor/react-dom-test-utils");
|
||||
const Accessible = createFactory(
|
||||
|
@ -49,7 +49,7 @@ window.onload = async function() {
|
|||
};
|
||||
|
||||
const mockStore = createStore((state, action) =>
|
||||
action ? { ...state, ...action } : state, mockState);
|
||||
action ? { ...state, ...action } : state, { initialState: mockState });
|
||||
const provider = createElement(Provider, { store: mockStore }, a);
|
||||
const accessible = ReactDOM.render(provider, window.document.body);
|
||||
ok(accessible, "Should be able to mount Accessible instances");
|
||||
|
|
|
@ -28,7 +28,7 @@ window.onload = async function() {
|
|||
const { createFactory, createElement } =
|
||||
browserRequire("devtools/client/shared/vendor/react");
|
||||
const { Provider } = require("devtools/client/shared/vendor/react-redux");
|
||||
const createStore = require("devtools/client/shared/redux/create-store")();
|
||||
const createStore = require("devtools/client/shared/redux/create-store");
|
||||
const { Simulate } =
|
||||
browserRequire("devtools/client/shared/vendor/react-dom-test-utils");
|
||||
const AccessibilityRow = createFactory(
|
||||
|
@ -54,7 +54,7 @@ window.onload = async function() {
|
|||
|
||||
const accRow = AccessibilityRow(newProps);
|
||||
const mockStore = createStore((state, action) =>
|
||||
action ? { ...state, ...action } : state, newState);
|
||||
action ? { ...state, ...action } : state, { initialState: newState });
|
||||
const provider = createElement(Provider, { store: mockStore }, accRow);
|
||||
|
||||
container = document.createElement("div");
|
||||
|
|
|
@ -46,7 +46,7 @@ const SUITES = {
|
|||
type: TEST_TYPES.JEST,
|
||||
},
|
||||
webconsole: {
|
||||
path: "../webconsole/test",
|
||||
path: "../webconsole/test/node",
|
||||
type: TEST_TYPES.MOCHA,
|
||||
},
|
||||
};
|
||||
|
|
|
@ -18,3 +18,4 @@
|
|||
|
||||
[options]
|
||||
suppress_comment=\\(.\\|\n\\)*\\$FlowIgnore
|
||||
suppress_comment=\\(.\\|\n\\)*\\$FlowFixMe
|
||||
|
|
|
@ -0,0 +1,9 @@
|
|||
/* 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/>. */
|
||||
|
||||
// @flow
|
||||
|
||||
declare module "devtools/client/framework/store-provider" {
|
||||
declare module.exports: any;
|
||||
}
|
|
@ -71,6 +71,10 @@ DebuggerPanel.prototype = {
|
|||
return this._store.getState();
|
||||
},
|
||||
|
||||
getToolboxStore: function() {
|
||||
return this.toolbox.store;
|
||||
},
|
||||
|
||||
openLink: function(url) {
|
||||
openContentLink(url);
|
||||
},
|
||||
|
|
|
@ -382,4 +382,5 @@ export type Panel = {|
|
|||
openConsoleAndEvaluate: (input: string) => void,
|
||||
highlightDomElement: (grip: Object) => void,
|
||||
unHighlightDomElement: (grip: Object) => void,
|
||||
getToolboxStore: () => any,
|
||||
|};
|
||||
|
|
|
@ -101,7 +101,7 @@ export async function onConnect(
|
|||
client: client.clientCommands,
|
||||
});
|
||||
|
||||
bootstrapApp(store);
|
||||
bootstrapApp(store, panel);
|
||||
await connected;
|
||||
return { store, actions, selectors, client: commands };
|
||||
}
|
||||
|
|
|
@ -30,5 +30,8 @@ bootstrap(React, ReactDOM).then(connection => {
|
|||
console.log("highlighting dom element"),
|
||||
unHighlightDomElement: (grip: Object) =>
|
||||
console.log("unhighlighting dom element"),
|
||||
getToolboxStore: () => {
|
||||
throw new Error("Cannot connect to Toolbox store when running Launchpad");
|
||||
},
|
||||
});
|
||||
});
|
||||
|
|
|
@ -9,6 +9,7 @@ import { bindActionCreators, combineReducers } from "redux";
|
|||
import ReactDOM from "react-dom";
|
||||
const { Provider } = require("react-redux");
|
||||
|
||||
import ToolboxProvider from "devtools/client/framework/store-provider";
|
||||
import { isFirefoxPanel, isDevelopment, isTesting } from "devtools-environment";
|
||||
import SourceMaps, {
|
||||
startSourceMapWorker,
|
||||
|
@ -28,7 +29,7 @@ import type { Panel } from "../client/firefox/types";
|
|||
|
||||
let parser;
|
||||
|
||||
function renderPanel(component, store) {
|
||||
function renderPanel(component, store, panel: Panel) {
|
||||
const root = document.createElement("div");
|
||||
root.className = "launchpad-root theme-body";
|
||||
root.style.setProperty("flex", "1");
|
||||
|
@ -39,7 +40,15 @@ function renderPanel(component, store) {
|
|||
mount.appendChild(root);
|
||||
|
||||
ReactDOM.render(
|
||||
React.createElement(Provider, { store }, React.createElement(component)),
|
||||
React.createElement(
|
||||
Provider,
|
||||
{ store },
|
||||
React.createElement(
|
||||
ToolboxProvider,
|
||||
{ store: panel.getToolboxStore() },
|
||||
React.createElement(component)
|
||||
)
|
||||
),
|
||||
root
|
||||
);
|
||||
}
|
||||
|
@ -106,9 +115,9 @@ export function teardownWorkers() {
|
|||
search.stop();
|
||||
}
|
||||
|
||||
export function bootstrapApp(store: any) {
|
||||
export function bootstrapApp(store: any, panel: Panel) {
|
||||
if (isFirefoxPanel()) {
|
||||
renderPanel(App, store);
|
||||
renderPanel(App, store, panel);
|
||||
} else {
|
||||
const { renderRoot } = require("devtools-launchpad");
|
||||
renderRoot(React, ReactDOM, App, store);
|
||||
|
|
|
@ -8,10 +8,15 @@ import * as React from "react";
|
|||
|
||||
export function connect<Config, RSP: {}, MDP: {}>(
|
||||
mapStateToProps: (state: any, props: any) => RSP,
|
||||
mapDispatchToProps?: (Function => MDP) | MDP
|
||||
mapDispatchToProps?: (Function => MDP) | MDP,
|
||||
mergeProps?: void,
|
||||
opts?: ?{|
|
||||
storeKey?: string,
|
||||
|}
|
||||
): (
|
||||
Component: React.AbstractComponent<Config>
|
||||
) => React.AbstractComponent<$Diff<Config, RSP & MDP>> {
|
||||
// TODO: Bug 1572214 - We should use the standard type definitions directly.
|
||||
// $FlowFixMe
|
||||
return reduxConnect(mapStateToProps, mapDispatchToProps);
|
||||
return reduxConnect(mapStateToProps, mapDispatchToProps, null, opts);
|
||||
}
|
||||
|
|
|
@ -9,18 +9,15 @@
|
|||
const React = require("devtools/client/shared/vendor/react");
|
||||
const ReactDOM = require("devtools/client/shared/vendor/react-dom");
|
||||
const { Provider } = require("devtools/client/shared/vendor/react-redux");
|
||||
const { combineReducers } = require("devtools/client/shared/vendor/redux");
|
||||
|
||||
// DOM Panel
|
||||
const MainFrame = React.createFactory(require("./components/MainFrame"));
|
||||
|
||||
// Store
|
||||
const createStore = require("devtools/client/shared/redux/create-store")({
|
||||
log: false,
|
||||
});
|
||||
const createStore = require("devtools/client/shared/redux/create-store");
|
||||
|
||||
const { reducers } = require("./reducers/index");
|
||||
const store = createStore(combineReducers(reducers));
|
||||
const store = createStore(reducers);
|
||||
|
||||
/**
|
||||
* This object represents view of the DOM panel and is responsible
|
||||
|
|
|
@ -0,0 +1,144 @@
|
|||
/* 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 { assert } = require("devtools/shared/DevToolsUtils");
|
||||
const {
|
||||
getDOMMutationBreakpoint,
|
||||
getDOMMutationBreakpoints,
|
||||
} = require("devtools/client/framework/reducers/dom-mutation-breakpoints");
|
||||
|
||||
exports.registerWalkerListeners = registerWalkerListeners;
|
||||
function registerWalkerListeners(toolbox) {
|
||||
const { walker } = toolbox;
|
||||
|
||||
walker.on("mutations", mutations =>
|
||||
handleWalkerMutations(mutations, toolbox)
|
||||
);
|
||||
}
|
||||
|
||||
function handleWalkerMutations(mutations, toolbox) {
|
||||
// If we got BP updates for detach/unload, we want to drop those nodes from
|
||||
// the list of active DOM mutation breakpoints. We explicitly check these
|
||||
// cases because BP updates could also happen due to explicitly API
|
||||
// operations to add/remove bps.
|
||||
const mutationItems = mutations.filter(
|
||||
mutation => mutation.type === "mutationBreakpoint"
|
||||
);
|
||||
if (mutationItems.length > 0) {
|
||||
toolbox.store.dispatch(updateBreakpointsForMutations(mutationItems));
|
||||
}
|
||||
}
|
||||
|
||||
exports.createDOMMutationBreakpoint = createDOMMutationBreakpoint;
|
||||
function createDOMMutationBreakpoint(nodeFront, mutationType) {
|
||||
assert(typeof nodeFront === "object" && nodeFront);
|
||||
assert(typeof mutationType === "string");
|
||||
|
||||
return async function(dispatch) {
|
||||
const walker = nodeFront.parent();
|
||||
|
||||
dispatch({
|
||||
type: "ADD_DOM_MUTATION_BREAKPOINT",
|
||||
nodeFront,
|
||||
mutationType,
|
||||
});
|
||||
|
||||
await walker.setMutationBreakpoints(nodeFront, {
|
||||
[mutationType]: true,
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
exports.deleteDOMMutationBreakpoint = deleteDOMMutationBreakpoint;
|
||||
function deleteDOMMutationBreakpoint(nodeFront, mutationType) {
|
||||
assert(typeof nodeFront === "object" && nodeFront);
|
||||
assert(typeof mutationType === "string");
|
||||
|
||||
return async function(dispatch) {
|
||||
dispatch({
|
||||
type: "REMOVE_DOM_MUTATION_BREAKPOINT",
|
||||
nodeFront,
|
||||
mutationType,
|
||||
});
|
||||
|
||||
const walker = nodeFront.parent();
|
||||
await walker.setMutationBreakpoints(nodeFront, {
|
||||
[mutationType]: false,
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
function updateBreakpointsForMutations(mutationItems) {
|
||||
return async function(dispatch, getState) {
|
||||
const removedNodeFronts = [];
|
||||
const changedNodeFronts = new Set();
|
||||
|
||||
for (const { target: nodeFront, mutationReason } of mutationItems) {
|
||||
switch (mutationReason) {
|
||||
case "api":
|
||||
changedNodeFronts.add(nodeFront);
|
||||
break;
|
||||
default:
|
||||
console.error(
|
||||
"Unexpected mutation reason",
|
||||
mutationReason,
|
||||
", removing"
|
||||
);
|
||||
// Fall Through
|
||||
case "detach":
|
||||
case "unload":
|
||||
removedNodeFronts.push(nodeFront);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (removedNodeFronts.length > 0) {
|
||||
dispatch({
|
||||
type: "REMOVE_DOM_MUTATION_BREAKPOINTS_FOR_FRONTS",
|
||||
nodeFronts: removedNodeFronts,
|
||||
});
|
||||
}
|
||||
if (changedNodeFronts.length > 0) {
|
||||
const enabledStates = [];
|
||||
for (const {
|
||||
id,
|
||||
nodeFront,
|
||||
mutationType,
|
||||
enabled,
|
||||
} of getDOMMutationBreakpoints(getState())) {
|
||||
if (changedNodeFronts.has(nodeFront)) {
|
||||
const bpEnabledOnFront = nodeFront.mutationBreakpoints[mutationType];
|
||||
if (bpEnabledOnFront !== enabled) {
|
||||
// Sync the bp state from the front into the store.
|
||||
enabledStates.push([id, bpEnabledOnFront]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
dispatch({
|
||||
type: "SET_DOM_MUTATION_BREAKPOINTS_ENABLED_STATE",
|
||||
enabledStates,
|
||||
});
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
exports.toggleDOMMutationBreakpointState = toggleDOMMutationBreakpointState;
|
||||
function toggleDOMMutationBreakpointState(id, enabled) {
|
||||
assert(typeof id === "string");
|
||||
assert(typeof enabled === "boolean");
|
||||
|
||||
return async function(dispatch, getState) {
|
||||
const bp = getDOMMutationBreakpoint(getState(), id);
|
||||
if (!bp) {
|
||||
throw new Error(`No DOM mutation BP with ID ${id}`);
|
||||
}
|
||||
|
||||
const walker = bp.nodeFront.parent();
|
||||
await walker.setMutationBreakpoints(bp.nodeFront, {
|
||||
[bp.mutationType]: enabled,
|
||||
});
|
||||
};
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
"use strict";
|
||||
|
||||
module.exports = {
|
||||
...require("./dom-mutation-breakpoints"),
|
||||
};
|
|
@ -0,0 +1,11 @@
|
|||
# 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/.
|
||||
|
||||
DevToolsModules(
|
||||
'dom-mutation-breakpoints.js',
|
||||
'index.js',
|
||||
)
|
||||
|
||||
with Files('**'):
|
||||
BUG_COMPONENT = ('DevTools', 'Framework')
|
|
@ -17,6 +17,8 @@ XPCSHELL_TESTS_MANIFESTS += ['test/unit/xpcshell.ini']
|
|||
|
||||
DIRS += [
|
||||
'components',
|
||||
'actions',
|
||||
'reducers',
|
||||
]
|
||||
|
||||
DevToolsModules(
|
||||
|
@ -28,6 +30,8 @@ DevToolsModules(
|
|||
'selection.js',
|
||||
'sidebar.js',
|
||||
'source-map-url-service.js',
|
||||
'store-provider.js',
|
||||
'store.js',
|
||||
'target-from-url.js',
|
||||
'target.js',
|
||||
'toolbox-context-menu.js',
|
||||
|
|
|
@ -0,0 +1,115 @@
|
|||
/* 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 initialReducerState = {
|
||||
counter: 1,
|
||||
breakpoints: [],
|
||||
};
|
||||
|
||||
exports.reducer = domMutationBreakpointReducer;
|
||||
function domMutationBreakpointReducer(state = initialReducerState, action) {
|
||||
switch (action.type) {
|
||||
case "ADD_DOM_MUTATION_BREAKPOINT":
|
||||
const hasExistingBp = state.breakpoints.some(
|
||||
bp =>
|
||||
bp.nodeFront === action.nodeFront &&
|
||||
bp.mutationType === action.mutationType
|
||||
);
|
||||
|
||||
if (hasExistingBp) {
|
||||
break;
|
||||
}
|
||||
|
||||
state = {
|
||||
...state,
|
||||
counter: state.counter + 1,
|
||||
breakpoints: [
|
||||
...state.breakpoints,
|
||||
{
|
||||
id: `${state.counter}`,
|
||||
nodeFront: action.nodeFront,
|
||||
mutationType: action.mutationType,
|
||||
enabled: true,
|
||||
},
|
||||
],
|
||||
};
|
||||
break;
|
||||
case "REMOVE_DOM_MUTATION_BREAKPOINT":
|
||||
for (const [index, bp] of state.breakpoints.entries()) {
|
||||
if (
|
||||
bp.nodeFront === action.nodeFront &&
|
||||
bp.mutationType === action.mutationType
|
||||
) {
|
||||
state = {
|
||||
...state,
|
||||
breakpoints: [
|
||||
...state.breakpoints.slice(0, index),
|
||||
...state.breakpoints.slice(index + 1),
|
||||
],
|
||||
};
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case "REMOVE_DOM_MUTATION_BREAKPOINTS_FOR_FRONTS": {
|
||||
const { nodeFronts } = action;
|
||||
const nodeFrontSet = new Set(nodeFronts);
|
||||
|
||||
const breakpoints = state.breakpoints.filter(
|
||||
bp => !nodeFrontSet.has(bp.nodeFront)
|
||||
);
|
||||
|
||||
// Since we might not have made any actual changes, we verify first
|
||||
// to avoid unnecessary changes in the state.
|
||||
if (state.breakpoints.length !== breakpoints.length) {
|
||||
state = {
|
||||
...state,
|
||||
breakpoints,
|
||||
};
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case "SET_DOM_MUTATION_BREAKPOINTS_ENABLED_STATE": {
|
||||
const { enabledStates } = action;
|
||||
const toUpdateById = new Map(enabledStates);
|
||||
|
||||
const breakpoints = state.breakpoints.map(bp => {
|
||||
const newBpState = toUpdateById.get(bp.id);
|
||||
if (typeof newBpState === "boolean" && newBpState !== bp.enabled) {
|
||||
bp = {
|
||||
...bp,
|
||||
enabled: newBpState,
|
||||
};
|
||||
}
|
||||
|
||||
return bp;
|
||||
});
|
||||
|
||||
// Since we might not have made any actual changes, we verify first
|
||||
// to avoid unnecessary changes in the state.
|
||||
if (state.breakpoints.some((bp, i) => breakpoints[i] !== bp)) {
|
||||
state = {
|
||||
...state,
|
||||
breakpoints,
|
||||
};
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
return state;
|
||||
}
|
||||
|
||||
exports.getDOMMutationBreakpoints = getDOMMutationBreakpoints;
|
||||
function getDOMMutationBreakpoints(state) {
|
||||
return state.domMutationBreakpoints.breakpoints;
|
||||
}
|
||||
|
||||
exports.getDOMMutationBreakpoint = getDOMMutationBreakpoint;
|
||||
function getDOMMutationBreakpoint(state, id) {
|
||||
return (
|
||||
state.domMutationBreakpoints.breakpoints.find(v => v.id === id) || null
|
||||
);
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
"use strict";
|
||||
|
||||
module.exports = {
|
||||
domMutationBreakpoints: require("./dom-mutation-breakpoints").reducer,
|
||||
};
|
|
@ -0,0 +1,11 @@
|
|||
# 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/.
|
||||
|
||||
DevToolsModules(
|
||||
'dom-mutation-breakpoints.js',
|
||||
'index.js',
|
||||
)
|
||||
|
||||
with Files('**'):
|
||||
BUG_COMPONENT = ('DevTools', 'Framework')
|
|
@ -0,0 +1,8 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
"use strict";
|
||||
|
||||
const { createProvider } = require("devtools/client/shared/vendor/react-redux");
|
||||
|
||||
module.exports = createProvider("toolbox-store");
|
|
@ -0,0 +1,13 @@
|
|||
/* 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 createStore = require("devtools/client/shared/redux/create-store");
|
||||
const reducers = require("./reducers/index");
|
||||
|
||||
exports.createToolboxStore = () =>
|
||||
createStore(reducers, {
|
||||
// Uncomment this for logging in tests.
|
||||
// shouldLog: true,
|
||||
});
|
|
@ -25,6 +25,20 @@ var ChromeUtils = require("ChromeUtils");
|
|||
var { gDevTools } = require("devtools/client/framework/devtools");
|
||||
var EventEmitter = require("devtools/shared/event-emitter");
|
||||
var Telemetry = require("devtools/client/shared/telemetry");
|
||||
|
||||
loader.lazyRequireGetter(
|
||||
this,
|
||||
"createToolboxStore",
|
||||
"devtools/client/framework/store",
|
||||
true
|
||||
);
|
||||
loader.lazyRequireGetter(
|
||||
this,
|
||||
"registerWalkerListeners",
|
||||
"devtools/client/framework/actions/index",
|
||||
true
|
||||
);
|
||||
|
||||
const { getUnicodeUrl } = require("devtools/client/shared/unicode-url");
|
||||
var {
|
||||
DOMHelpers,
|
||||
|
@ -328,6 +342,13 @@ Toolbox.prototype = {
|
|||
SIDE_ENABLED: "devtools.toolbox.sideEnabled",
|
||||
},
|
||||
|
||||
get store() {
|
||||
if (!this._store) {
|
||||
this._store = createToolboxStore();
|
||||
}
|
||||
return this._store;
|
||||
},
|
||||
|
||||
get currentToolId() {
|
||||
return this._currentToolId;
|
||||
},
|
||||
|
@ -3321,6 +3342,7 @@ Toolbox.prototype = {
|
|||
this.walker.on("highlighter-ready", this._highlighterReady);
|
||||
this.walker.on("highlighter-hide", this._highlighterHidden);
|
||||
this._selection.on("new-node-front", this._onNewSelectedNodeFront);
|
||||
registerWalkerListeners(this);
|
||||
}.bind(this)();
|
||||
}
|
||||
return this._initInspector;
|
||||
|
|
|
@ -21,6 +21,18 @@ const MarkupReadOnlyContainer = require("devtools/client/inspector/markup/views/
|
|||
const MarkupTextContainer = require("devtools/client/inspector/markup/views/text-container");
|
||||
const RootContainer = require("devtools/client/inspector/markup/views/root-container");
|
||||
|
||||
loader.lazyRequireGetter(
|
||||
this,
|
||||
"createDOMMutationBreakpoint",
|
||||
"devtools/client/framework/actions/index",
|
||||
true
|
||||
);
|
||||
loader.lazyRequireGetter(
|
||||
this,
|
||||
"deleteDOMMutationBreakpoint",
|
||||
"devtools/client/framework/actions/index",
|
||||
true
|
||||
);
|
||||
loader.lazyRequireGetter(
|
||||
this,
|
||||
"MarkupContextMenu",
|
||||
|
@ -1270,11 +1282,14 @@ MarkupView.prototype = {
|
|||
return;
|
||||
}
|
||||
|
||||
const toolboxStore = this.inspector.toolbox.store;
|
||||
const nodeFront = this.inspector.selection.nodeFront;
|
||||
const mutationBreakpoints = nodeFront.mutationBreakpoints;
|
||||
await this.walker.setMutationBreakpoints(nodeFront, {
|
||||
[name]: !mutationBreakpoints[name],
|
||||
});
|
||||
|
||||
if (nodeFront.mutationBreakpoints[name]) {
|
||||
toolboxStore.dispatch(deleteDOMMutationBreakpoint(nodeFront, name));
|
||||
} else {
|
||||
toolboxStore.dispatch(createDOMMutationBreakpoint(nodeFront, name));
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
|
|
|
@ -4,30 +4,11 @@
|
|||
|
||||
"use strict";
|
||||
|
||||
const { combineReducers } = require("devtools/client/shared/vendor/redux");
|
||||
const createStore = require("devtools/client/shared/redux/create-store");
|
||||
const reducers = require("devtools/client/inspector/reducers");
|
||||
const flags = require("devtools/shared/flags");
|
||||
|
||||
module.exports = function() {
|
||||
let shouldLog = false;
|
||||
let history;
|
||||
|
||||
// If testing, store the action history in an array
|
||||
// we'll later attach to the store
|
||||
if (flags.testing) {
|
||||
history = [];
|
||||
shouldLog = true;
|
||||
}
|
||||
|
||||
const store = createStore({
|
||||
log: shouldLog,
|
||||
history,
|
||||
})(combineReducers(reducers), {});
|
||||
|
||||
if (history) {
|
||||
store.history = history;
|
||||
}
|
||||
|
||||
return store;
|
||||
};
|
||||
module.exports = () =>
|
||||
createStore(reducers, {
|
||||
// Uncomment this for logging in tests.
|
||||
shouldLog: true,
|
||||
});
|
||||
|
|
|
@ -240,6 +240,7 @@ devtools.jar:
|
|||
content/netmonitor/index.html (netmonitor/index.html)
|
||||
content/netmonitor/src/assets/styles/StatusCode.css (netmonitor/src/assets/styles/StatusCode.css)
|
||||
content/netmonitor/src/assets/styles/websockets.css (netmonitor/src/assets/styles/websockets.css)
|
||||
content/netmonitor/src/assets/styles/search.css (netmonitor/src/assets/styles/search.css)
|
||||
|
||||
# Application panel
|
||||
content/application/index.html (application/index.html)
|
||||
|
|
|
@ -739,6 +739,26 @@ netmonitor.ws.time.format=%1$S.%2$S
|
|||
# in the messages panel identifying the raw data.
|
||||
netmonitor.ws.rawData.header=Raw Data (%S)
|
||||
|
||||
# LOCALIZATION NOTE (netmonitor.search.toolbar.inputPlaceholder): This is the label
|
||||
# displayed in the search toolbar for the search input as the placeholder.
|
||||
netmonitor.search.toolbar.inputPlaceholder=Find in resources…
|
||||
|
||||
# LOCALIZATION NOTE (netmonitor.search.toolbar.close): This is the label
|
||||
# displayed in the search toolbar to close the search panel.
|
||||
netmonitor.search.toolbar.close=Close Search Panel
|
||||
|
||||
# LOCALIZATION NOTE (netmonitor.search.toolbar.clear): This is the label
|
||||
# displayed in the search toolbar to clear the search panel.
|
||||
netmonitor.search.toolbar.clear=Clear Search Results
|
||||
|
||||
# LOCALIZATION NOTE (netmonitor.search.labels.responseHeaders): This is the label
|
||||
# displayed in the search results as the label for the response headers
|
||||
netmonitor.search.labels.responseHeaders=Response Header
|
||||
|
||||
# LOCALIZATION NOTE (netmonitor.search.labels.requestHeaders): This is the label
|
||||
# displayed in the search results as the label for the request headers
|
||||
netmonitor.search.labels.requestHeaders=Request Header
|
||||
|
||||
# LOCALIZATION NOTE (netmonitor.tab.headers): This is the label displayed
|
||||
# in the network details pane identifying the headers tab.
|
||||
netmonitor.tab.headers=Headers
|
||||
|
|
|
@ -4,31 +4,11 @@
|
|||
|
||||
"use strict";
|
||||
|
||||
const { combineReducers } = require("../shared/vendor/redux");
|
||||
const createStore = require("../shared/redux/create-store");
|
||||
const reducers = require("./reducers");
|
||||
const flags = require("devtools/shared/flags");
|
||||
|
||||
module.exports = function() {
|
||||
const shouldLog = false;
|
||||
let history;
|
||||
|
||||
// If testing, store the action history in an array
|
||||
// we'll later attach to the store
|
||||
if (flags.testing) {
|
||||
history = [];
|
||||
// Uncomment this for TONS of logging in tests.
|
||||
// shouldLog = true;
|
||||
}
|
||||
|
||||
const store = createStore({
|
||||
log: shouldLog,
|
||||
history,
|
||||
})(combineReducers(reducers), {});
|
||||
|
||||
if (history) {
|
||||
store.history = history;
|
||||
}
|
||||
|
||||
return store;
|
||||
};
|
||||
module.exports = () =>
|
||||
createStore(reducers, {
|
||||
// Uncomment this for logging in tests.
|
||||
// shouldLog: true,
|
||||
});
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
@import "chrome://devtools/content/netmonitor/src/assets/styles/CustomRequestPanel.css";
|
||||
@import "chrome://devtools/content/netmonitor/src/assets/styles/StatusCode.css";
|
||||
@import "chrome://devtools/content/netmonitor/src/assets/styles/websockets.css";
|
||||
@import "chrome://devtools/content/netmonitor/src/assets/styles/search.css";
|
||||
|
||||
/* General */
|
||||
|
||||
|
|
|
@ -0,0 +1,68 @@
|
|||
/* 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/. */
|
||||
|
||||
.network-monitor .monitor-panel .request-list-container .requests-list-scroll {
|
||||
width: 100% !important;
|
||||
}
|
||||
|
||||
.search-panel {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.search-panel-content {
|
||||
width: 100%;
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
/* Custom tree styles for the Search results panel*/
|
||||
.search-panel .treeTable .treeLabelCell::after {
|
||||
content: "";
|
||||
}
|
||||
|
||||
/* Color for resource label */
|
||||
.search-panel .resourceCell {
|
||||
color: var(--theme-text-color-inactive);
|
||||
}
|
||||
|
||||
/* Color for search result label */
|
||||
.search-panel .resultCell {
|
||||
color: var(--table-text-color);
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
/* Color for search result label */
|
||||
.search-panel .treeLabel.resultLabel {
|
||||
color: var(--theme-text-color-inactive);
|
||||
}
|
||||
|
||||
/* Break the column layout and make the search result output more compact */
|
||||
.search-panel .treeTable tr {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.search-panel .treeTable {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
#devtools-network-search-close::before {
|
||||
background-image: url("chrome://devtools/skin/images/close.svg");
|
||||
}
|
||||
|
||||
#devtools-network-search-close > button {
|
||||
margin: 0 !important;
|
||||
border-radius: 0 !important;
|
||||
position: relative;
|
||||
min-width: 26px;
|
||||
}
|
||||
|
||||
/* Color for query matches */
|
||||
.search-panel .resultCell .query-match {
|
||||
background-color: var(--theme-selection-background);
|
||||
color: white;
|
||||
padding: 1px 4px;
|
||||
margin: 0 2px 0 2px;
|
||||
border-radius: 2px;
|
||||
}
|
|
@ -34,6 +34,10 @@ loader.lazyGetter(this, "NetworkDetailsPanel", function() {
|
|||
return createFactory(require("./NetworkDetailsPanel"));
|
||||
});
|
||||
|
||||
loader.lazyGetter(this, "SearchPanel", function() {
|
||||
return createFactory(require("./search/SearchPanel"));
|
||||
});
|
||||
|
||||
// MediaQueryList object responsible for switching sidebar splitter
|
||||
// between landscape and portrait mode (depending on browser window size).
|
||||
const MediaQueryVert = window.matchMedia("(min-width: 700px)");
|
||||
|
@ -62,6 +66,7 @@ class MonitorPanel extends Component {
|
|||
sourceMapService: PropTypes.object,
|
||||
openLink: PropTypes.func,
|
||||
updateRequest: PropTypes.func.isRequired,
|
||||
panelOpen: PropTypes.bool.isRequired,
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -80,6 +85,8 @@ class MonitorPanel extends Component {
|
|||
componentDidMount() {
|
||||
MediaQuerySingleRow.addListener(this.onLayoutChange);
|
||||
MediaQueryVert.addListener(this.onLayoutChange);
|
||||
this.persistDetailsPanelSize();
|
||||
this.persistSearchPanelSize();
|
||||
}
|
||||
|
||||
componentWillReceiveProps(nextProps) {
|
||||
|
@ -96,7 +103,11 @@ class MonitorPanel extends Component {
|
|||
componentWillUnmount() {
|
||||
MediaQuerySingleRow.removeListener(this.onLayoutChange);
|
||||
MediaQueryVert.removeListener(this.onLayoutChange);
|
||||
this.persistDetailsPanelSize();
|
||||
this.persistSearchPanelSize();
|
||||
}
|
||||
|
||||
persistDetailsPanelSize() {
|
||||
const { clientWidth, clientHeight } = findDOMNode(this.refs.endPanel) || {};
|
||||
|
||||
if (this.state.isVerticalSpliter && clientWidth) {
|
||||
|
@ -113,6 +124,23 @@ class MonitorPanel extends Component {
|
|||
}
|
||||
}
|
||||
|
||||
persistSearchPanelSize() {
|
||||
const { clientWidth, clientHeight } =
|
||||
findDOMNode(this.refs.searchPanel) || {};
|
||||
if (clientWidth) {
|
||||
Services.prefs.setIntPref(
|
||||
"devtools.netmonitor.panes-search-width",
|
||||
clientWidth
|
||||
);
|
||||
}
|
||||
if (clientHeight) {
|
||||
Services.prefs.setIntPref(
|
||||
"devtools.netmonitor.panes-search-height",
|
||||
clientHeight
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
onLayoutChange() {
|
||||
this.setState({
|
||||
isSingleRow: MediaQuerySingleRow.matches,
|
||||
|
@ -130,6 +158,32 @@ class MonitorPanel extends Component {
|
|||
);
|
||||
}
|
||||
|
||||
renderSearchPanel(connector) {
|
||||
const { isEmpty } = this.props;
|
||||
const initialWidth = Services.prefs.getIntPref(
|
||||
"devtools.netmonitor.panes-search-width"
|
||||
);
|
||||
const initialHeight = Services.prefs.getIntPref(
|
||||
"devtools.netmonitor.panes-search-height"
|
||||
);
|
||||
return SplitBox({
|
||||
className: "devtools-responsive-container",
|
||||
initialWidth,
|
||||
initialHeight,
|
||||
minSize: "50px",
|
||||
maxSize: "80%",
|
||||
splitterSize: 1,
|
||||
startPanel: SearchPanel({
|
||||
ref: "searchPanel",
|
||||
connector,
|
||||
}),
|
||||
endPanel: RequestList({ isEmpty, connector }),
|
||||
endPanelControl: false,
|
||||
vert: true,
|
||||
onControlledPanelResized: () => {},
|
||||
});
|
||||
}
|
||||
|
||||
render() {
|
||||
const {
|
||||
actions,
|
||||
|
@ -139,15 +193,21 @@ class MonitorPanel extends Component {
|
|||
openLink,
|
||||
openSplitConsole,
|
||||
sourceMapService,
|
||||
panelOpen,
|
||||
} = this.props;
|
||||
|
||||
const initialWidth = Services.prefs.getIntPref(
|
||||
"devtools.netmonitor.panes-network-details-width"
|
||||
);
|
||||
|
||||
const initialHeight = Services.prefs.getIntPref(
|
||||
"devtools.netmonitor.panes-network-details-height"
|
||||
);
|
||||
|
||||
const startPanel = panelOpen
|
||||
? this.renderSearchPanel(connector)
|
||||
: RequestList({ isEmpty, connector });
|
||||
|
||||
return div(
|
||||
{ className: "monitor-panel" },
|
||||
Toolbar({
|
||||
|
@ -163,7 +223,7 @@ class MonitorPanel extends Component {
|
|||
minSize: "50px",
|
||||
maxSize: "80%",
|
||||
splitterSize: networkDetailsOpen ? 1 : 0,
|
||||
startPanel: RequestList({ isEmpty, connector }),
|
||||
startPanel,
|
||||
endPanel:
|
||||
networkDetailsOpen &&
|
||||
NetworkDetailsPanel({
|
||||
|
@ -185,6 +245,7 @@ module.exports = connect(
|
|||
state => ({
|
||||
isEmpty: state.requests.requests.size == 0,
|
||||
networkDetailsOpen: state.ui.networkDetailsOpen,
|
||||
panelOpen: state.search.panelOpen,
|
||||
request: getSelectedRequest(state),
|
||||
selectedRequestVisible: isSelectedRequestVisible(state),
|
||||
}),
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
DIRS += [
|
||||
'search',
|
||||
'websockets',
|
||||
]
|
||||
|
||||
|
|
|
@ -0,0 +1,136 @@
|
|||
/* 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 {
|
||||
Component,
|
||||
createRef,
|
||||
createFactory,
|
||||
} = require("devtools/client/shared/vendor/react");
|
||||
const dom = require("devtools/client/shared/vendor/react-dom-factories");
|
||||
const { div, span } = dom;
|
||||
const Actions = require("devtools/client/netmonitor/src/actions/index");
|
||||
const PropTypes = require("devtools/client/shared/vendor/react-prop-types");
|
||||
const {
|
||||
connect,
|
||||
} = require("devtools/client/shared/redux/visibility-handler-connect");
|
||||
const TreeViewClass = require("devtools/client/shared/components/tree/TreeView");
|
||||
const TreeView = createFactory(TreeViewClass);
|
||||
const { SearchProvider } = require("./search-provider");
|
||||
const Toolbar = createFactory(require("./Toolbar"));
|
||||
|
||||
/**
|
||||
* This component is responsible for rendering all search results
|
||||
* coming from the current search.
|
||||
*/
|
||||
class SearchPanel extends Component {
|
||||
static get propTypes() {
|
||||
return {
|
||||
clearSearchResults: PropTypes.func.isRequired,
|
||||
openSearch: PropTypes.func.isRequired,
|
||||
closeSearch: PropTypes.func.isRequired,
|
||||
search: PropTypes.func.isRequired,
|
||||
connector: PropTypes.object.isRequired,
|
||||
addSearchQuery: PropTypes.func.isRequired,
|
||||
query: PropTypes.string.isRequired,
|
||||
results: PropTypes.array,
|
||||
};
|
||||
}
|
||||
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.searchboxRef = createRef();
|
||||
this.renderValue = this.renderValue.bind(this);
|
||||
}
|
||||
|
||||
renderTree() {
|
||||
const { results } = this.props;
|
||||
return TreeView({
|
||||
object: results,
|
||||
provider: SearchProvider,
|
||||
expandableStrings: false,
|
||||
renderValue: this.renderValue,
|
||||
columns: [
|
||||
{
|
||||
id: "value",
|
||||
width: "100%",
|
||||
},
|
||||
],
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Custom tree value rendering. This method is responsible for
|
||||
* rendering highlighted query string within the search result.
|
||||
*/
|
||||
renderValue(props) {
|
||||
const member = props.member;
|
||||
/**
|
||||
* Handle only second level (zero based) that displays
|
||||
* the search result. Find the query string inside the
|
||||
* search result value (`props.object`) and render it
|
||||
* within a span element with proper class name.
|
||||
*
|
||||
* level 0 = resource name
|
||||
*/
|
||||
if (member.level === 1) {
|
||||
const { query } = this.props;
|
||||
const indexStart = props.object.indexOf(query);
|
||||
const indexEnd = indexStart + query.length;
|
||||
|
||||
return span(
|
||||
{},
|
||||
span({}, props.object.substring(0, indexStart)),
|
||||
span({ className: "query-match" }, query),
|
||||
span({}, props.object.substring(indexEnd, props.object.length))
|
||||
);
|
||||
}
|
||||
|
||||
return props.object;
|
||||
}
|
||||
|
||||
render() {
|
||||
const {
|
||||
openSearch,
|
||||
closeSearch,
|
||||
clearSearchResults,
|
||||
connector,
|
||||
addSearchQuery,
|
||||
search,
|
||||
} = this.props;
|
||||
return div(
|
||||
{ className: "search-panel", style: { width: "100%" } },
|
||||
Toolbar({
|
||||
searchboxRef: this.searchboxRef,
|
||||
openSearch,
|
||||
closeSearch,
|
||||
clearSearchResults,
|
||||
addSearchQuery,
|
||||
search,
|
||||
connector,
|
||||
}),
|
||||
div(
|
||||
{ className: "search-panel-content", style: { width: "100%" } },
|
||||
this.renderTree()
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = connect(
|
||||
state => ({
|
||||
query: state.search.query,
|
||||
results: state.search.results,
|
||||
ongoingSearch: state.search.ongoingSearch,
|
||||
status: state.search.status,
|
||||
}),
|
||||
dispatch => ({
|
||||
closeSearch: () => dispatch(Actions.closeSearch()),
|
||||
openSearch: () => dispatch(Actions.openSearch()),
|
||||
search: () => dispatch(Actions.search()),
|
||||
clearSearchResults: () => dispatch(Actions.clearSearchResults()),
|
||||
addSearchQuery: query => dispatch(Actions.addSearchQuery(query)),
|
||||
})
|
||||
)(SearchPanel);
|
|
@ -0,0 +1,132 @@
|
|||
/* 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 {
|
||||
Component,
|
||||
createFactory,
|
||||
} = require("devtools/client/shared/vendor/react");
|
||||
const {
|
||||
connect,
|
||||
} = require("devtools/client/shared/redux/visibility-handler-connect");
|
||||
const { FILTER_SEARCH_DELAY } = require("../../constants");
|
||||
const PropTypes = require("devtools/client/shared/vendor/react-prop-types");
|
||||
const Actions = require("devtools/client/netmonitor/src/actions/index");
|
||||
const dom = require("devtools/client/shared/vendor/react-dom-factories");
|
||||
const { L10N } = require("devtools/client/netmonitor/src/utils/l10n.js");
|
||||
const { button, span, div } = dom;
|
||||
|
||||
// Components
|
||||
const SearchBox = createFactory(
|
||||
require("devtools/client/shared/components/SearchBox")
|
||||
);
|
||||
|
||||
/**
|
||||
* Network Search toolbar component.
|
||||
*
|
||||
* Provides tools for greater control over search.
|
||||
*/
|
||||
class Toolbar extends Component {
|
||||
static get propTypes() {
|
||||
return {
|
||||
searchboxRef: PropTypes.object.isRequired,
|
||||
clearSearchResults: PropTypes.func.isRequired,
|
||||
search: PropTypes.func.isRequired,
|
||||
closeSearch: PropTypes.func.isRequired,
|
||||
addSearchQuery: PropTypes.func.isRequired,
|
||||
connector: PropTypes.object.isRequired,
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Render a separator.
|
||||
*/
|
||||
renderSeparator() {
|
||||
return span({ className: "devtools-separator" });
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles what we do when key is pressed in search input.
|
||||
* @param event
|
||||
* @param conn
|
||||
*/
|
||||
onKeyDown(event, connector) {
|
||||
switch (event.key) {
|
||||
case "Escape":
|
||||
event.preventDefault();
|
||||
this.props.closeSearch();
|
||||
break;
|
||||
case "Enter":
|
||||
event.preventDefault();
|
||||
this.props.addSearchQuery(event.target.value);
|
||||
this.props.search(connector, event.target.value);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
renderCloseButton() {
|
||||
const { closeSearch } = this.props;
|
||||
return button({
|
||||
id: "devtools-network-search-close",
|
||||
className: "devtools-button",
|
||||
title: L10N.getStr("netmonitor.search.toolbar.close"),
|
||||
onClick: () => closeSearch(),
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Render a clear button to clear search results.
|
||||
*/
|
||||
renderClearButton() {
|
||||
return button({
|
||||
className:
|
||||
"devtools-button devtools-clear-icon ws-frames-list-clear-button",
|
||||
title: L10N.getStr("netmonitor.search.toolbar.clear"),
|
||||
onClick: () => {
|
||||
this.props.clearSearchResults();
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Render filter Search box.
|
||||
*/
|
||||
renderFilterBox() {
|
||||
const { addSearchQuery, connector } = this.props;
|
||||
return SearchBox({
|
||||
keyShortcut: "CmdOrCtrl+Shift+F",
|
||||
placeholder: L10N.getStr("netmonitor.search.toolbar.inputPlaceholder"),
|
||||
type: "search",
|
||||
delay: FILTER_SEARCH_DELAY,
|
||||
ref: this.props.searchboxRef,
|
||||
onChange: query => addSearchQuery(query),
|
||||
onKeyDown: event => this.onKeyDown(event, connector),
|
||||
});
|
||||
}
|
||||
|
||||
render() {
|
||||
return div(
|
||||
{
|
||||
id: "netmonitor-toolbar-container",
|
||||
className: "devtools-toolbar devtools-input-toolbar",
|
||||
},
|
||||
this.renderClearButton(),
|
||||
this.renderSeparator(),
|
||||
this.renderFilterBox(),
|
||||
this.renderCloseButton()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = connect(
|
||||
state => ({}),
|
||||
dispatch => ({
|
||||
closeSearch: () => dispatch(Actions.closeSearch()),
|
||||
openSearch: () => dispatch(Actions.openSearch()),
|
||||
clearSearchResults: () => dispatch(Actions.clearSearchResults()),
|
||||
search: (connector, query) => dispatch(Actions.search(connector, query)),
|
||||
addSearchQuery: query => dispatch(Actions.addSearchQuery(query)),
|
||||
})
|
||||
)(Toolbar);
|
|
@ -0,0 +1,9 @@
|
|||
# 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/.
|
||||
|
||||
DevToolsModules(
|
||||
'search-provider.js',
|
||||
'SearchPanel.js',
|
||||
'Toolbar.js',
|
||||
)
|
|
@ -0,0 +1,123 @@
|
|||
/* 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 { L10N } = require("devtools/client/netmonitor/src/utils/l10n");
|
||||
const {
|
||||
ObjectProvider,
|
||||
} = require("devtools/client/shared/components/tree/ObjectProvider");
|
||||
const {
|
||||
getFileName,
|
||||
} = require("devtools/client/netmonitor/src/utils/request-utils");
|
||||
|
||||
/**
|
||||
* This provider is responsible for providing data from the
|
||||
* search reducer to the SearchPanel.
|
||||
*/
|
||||
const SearchProvider = {
|
||||
...ObjectProvider,
|
||||
|
||||
getChildren(object) {
|
||||
if (Array.isArray(object)) {
|
||||
return object;
|
||||
} else if (object.resource) {
|
||||
return object.results;
|
||||
} else if (object.type) {
|
||||
return [];
|
||||
}
|
||||
return ObjectProvider.getLabel(object);
|
||||
},
|
||||
|
||||
hasChildren(object) {
|
||||
return this.getChildren(object).length > 0;
|
||||
},
|
||||
|
||||
getLabel(object) {
|
||||
if (object.resource) {
|
||||
return this.getResourceLabel(object);
|
||||
} else if (object.type) {
|
||||
switch (object.type) {
|
||||
case "url":
|
||||
return this.getUrlLabel(object);
|
||||
case "responseContent":
|
||||
return this.getResponseContent(object);
|
||||
case "requestCookies":
|
||||
return this.getRequestCookies();
|
||||
case "responseCookies":
|
||||
return this.getResponseCookies();
|
||||
case "requestHeaders":
|
||||
return this.getRequestHeaders();
|
||||
case "responseHeaders":
|
||||
return this.getResponseHeaders();
|
||||
}
|
||||
}
|
||||
return ObjectProvider.getLabel(object);
|
||||
},
|
||||
|
||||
getValue(object) {
|
||||
if (object.resource) {
|
||||
return object.resource.url;
|
||||
} else if (object.type) {
|
||||
return object.value;
|
||||
}
|
||||
return ObjectProvider.getValue(object);
|
||||
},
|
||||
|
||||
getKey(object) {
|
||||
if (object.resource) {
|
||||
return object.resource.id;
|
||||
} else if (object.type) {
|
||||
return object.key;
|
||||
}
|
||||
return ObjectProvider.getKey(object);
|
||||
},
|
||||
|
||||
getType(object) {
|
||||
if (object.resource) {
|
||||
return "resource";
|
||||
} else if (object.type) {
|
||||
return "result";
|
||||
}
|
||||
return ObjectProvider.getType(object);
|
||||
},
|
||||
|
||||
getResourceLabel(object) {
|
||||
const resourceLabel =
|
||||
getFileName(object.resource.urlDetails.baseNameWithQuery) ||
|
||||
object.resource.urlDetails.host;
|
||||
if (resourceLabel.length > 30) {
|
||||
return resourceLabel.substring(0, 30) + "…";
|
||||
}
|
||||
return resourceLabel;
|
||||
},
|
||||
|
||||
getUrlLabel(object) {
|
||||
return object.label.substring(0, 100);
|
||||
},
|
||||
|
||||
getResponseContent(object) {
|
||||
return object.line + "";
|
||||
},
|
||||
|
||||
getRequestCookies() {
|
||||
return "Set-Cookie";
|
||||
},
|
||||
|
||||
getResponseCookies() {
|
||||
return "Cookie";
|
||||
},
|
||||
|
||||
getRequestHeaders() {
|
||||
return L10N.getStr("netmonitor.search.labels.requestHeaders");
|
||||
},
|
||||
|
||||
getResponseHeaders() {
|
||||
return L10N.getStr("netmonitor.search.labels.responseHeaders");
|
||||
},
|
||||
};
|
||||
|
||||
module.exports = {
|
||||
SearchProvider,
|
||||
};
|
|
@ -15,7 +15,7 @@ const { require } = BrowserLoader({
|
|||
const Perf = require("devtools/client/performance-new/components/Perf");
|
||||
const ReactDOM = require("devtools/client/shared/vendor/react-dom");
|
||||
const React = require("devtools/client/shared/vendor/react");
|
||||
const createStore = require("devtools/client/shared/redux/create-store")();
|
||||
const createStore = require("devtools/client/shared/redux/create-store");
|
||||
const selectors = require("devtools/client/performance-new/store/selectors");
|
||||
const reducers = require("devtools/client/performance-new/store/reducers");
|
||||
const actions = require("devtools/client/performance-new/store/actions");
|
||||
|
|
|
@ -183,7 +183,7 @@ function createPerfComponent() {
|
|||
const React = require("devtools/client/shared/vendor/react");
|
||||
const ReactDOM = require("devtools/client/shared/vendor/react-dom");
|
||||
const ReactRedux = require("devtools/client/shared/vendor/react-redux");
|
||||
const createStore = require("devtools/client/shared/redux/create-store")();
|
||||
const createStore = require("devtools/client/shared/redux/create-store");
|
||||
const reducers = require("devtools/client/performance-new/store/reducers");
|
||||
const actions = require("devtools/client/performance-new/store/actions");
|
||||
const selectors = require("devtools/client/performance-new/store/selectors");
|
||||
|
|
|
@ -400,3 +400,8 @@ pref("devtools.aboutdebugging.collapsibilities.temporaryExtension", false);
|
|||
|
||||
// Map top-level await expressions in the console
|
||||
pref("devtools.debugger.features.map-await-expression", true);
|
||||
|
||||
// Disable autohide for DevTools popups and tooltips.
|
||||
// This is currently not exposed by any UI to avoid making
|
||||
// about:devtools-toolbox tabs unusable by mistake.
|
||||
pref("devtools.popup.disable_autohide", false);
|
||||
|
|
|
@ -4,30 +4,11 @@
|
|||
|
||||
"use strict";
|
||||
|
||||
const { combineReducers } = require("devtools/client/shared/vendor/redux");
|
||||
const createStore = require("devtools/client/shared/redux/create-store");
|
||||
const reducers = require("./reducers");
|
||||
const flags = require("devtools/shared/flags");
|
||||
|
||||
module.exports = function() {
|
||||
let shouldLog = false;
|
||||
let history;
|
||||
|
||||
// If testing, store the action history in an array
|
||||
// we'll later attach to the store
|
||||
if (flags.testing) {
|
||||
history = [];
|
||||
shouldLog = true;
|
||||
}
|
||||
|
||||
const store = createStore({
|
||||
log: shouldLog,
|
||||
history,
|
||||
})(combineReducers(reducers), {});
|
||||
|
||||
if (history) {
|
||||
store.history = history;
|
||||
}
|
||||
|
||||
return store;
|
||||
};
|
||||
module.exports = () =>
|
||||
createStore(reducers, {
|
||||
// Uncomment this for logging in tests.
|
||||
shouldLog: true,
|
||||
});
|
||||
|
|
|
@ -47,8 +47,8 @@ define(function(require, exports, module) {
|
|||
static get propTypes() {
|
||||
return {
|
||||
member: PropTypes.shape({
|
||||
object: PropTypes.obSject,
|
||||
name: PropTypes.sring,
|
||||
object: PropTypes.object,
|
||||
name: PropTypes.string,
|
||||
type: PropTypes.string.isRequired,
|
||||
rowClass: PropTypes.string.isRequired,
|
||||
level: PropTypes.number.isRequired,
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
"use strict";
|
||||
|
||||
const {
|
||||
combineReducers,
|
||||
createStore,
|
||||
applyMiddleware,
|
||||
} = require("devtools/client/shared/vendor/redux");
|
||||
|
@ -11,6 +12,7 @@ const { thunk } = require("./middleware/thunk");
|
|||
const { waitUntilService } = require("./middleware/wait-service");
|
||||
const { task } = require("./middleware/task");
|
||||
const { promise } = require("./middleware/promise");
|
||||
const flags = require("devtools/shared/flags");
|
||||
|
||||
loader.lazyRequireGetter(
|
||||
this,
|
||||
|
@ -36,7 +38,7 @@ loader.lazyRequireGetter(
|
|||
* used in tests.
|
||||
* - middleware: array of middleware to be included in the redux store
|
||||
*/
|
||||
module.exports = (opts = {}) => {
|
||||
const createStoreWithMiddleware = (opts = {}) => {
|
||||
const middleware = [
|
||||
task,
|
||||
thunk,
|
||||
|
@ -63,3 +65,30 @@ module.exports = (opts = {}) => {
|
|||
|
||||
return applyMiddleware(...middleware)(createStore);
|
||||
};
|
||||
|
||||
module.exports = (
|
||||
reducers,
|
||||
{ shouldLog = false, initialState = undefined } = {}
|
||||
) => {
|
||||
const reducer =
|
||||
typeof reducers === "function" ? reducers : combineReducers(reducers);
|
||||
|
||||
let historyEntries;
|
||||
|
||||
// If testing, store the action history in an array
|
||||
// we'll later attach to the store
|
||||
if (flags.testing) {
|
||||
historyEntries = [];
|
||||
}
|
||||
|
||||
const store = createStoreWithMiddleware({
|
||||
log: flags.testing && shouldLog,
|
||||
history: historyEntries,
|
||||
})(reducer, initialState);
|
||||
|
||||
if (history) {
|
||||
store.history = historyEntries;
|
||||
}
|
||||
|
||||
return store;
|
||||
};
|
||||
|
|
|
@ -754,7 +754,7 @@ HTMLTooltip.prototype = {
|
|||
*/
|
||||
async hide({ fromMouseup = false } = {}) {
|
||||
// Exit if the disable autohide setting is in effect.
|
||||
if (Services.prefs.getBoolPref("ui.popup.disable_autohide", false)) {
|
||||
if (Services.prefs.getBoolPref("devtools.popup.disable_autohide", false)) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,29 +1,30 @@
|
|||
# Console Tests
|
||||
|
||||
The console panel uses currently two different frameworks for tests:
|
||||
|
||||
* Mochitest - [Mochitest](https://developer.mozilla.org/en-US/docs/Mozilla/Projects/Mochitest) is an automated testing framework built on top of the MochiKit JavaScript libraries. It's just one of the automated regression testing frameworks used by Mozilla.
|
||||
- Mochitest - [Mochitest](https://developer.mozilla.org/en-US/docs/Mozilla/Projects/Mochitest) is an automated testing framework built on top of the MochiKit JavaScript libraries. It's just one of the automated regression testing frameworks used by Mozilla.
|
||||
|
||||
Mochitests are located in `devtools/client/webconsole/test/mochitest/` and can be run with the following command:
|
||||
Mochitests are located in `devtools/client/webconsole/test/browser/` and can be run with the following command:
|
||||
|
||||
```sh
|
||||
./mach test devtools/client/webconsole/test/mochitest/
|
||||
./mach test devtools/client/webconsole/test/browser/
|
||||
```
|
||||
|
||||
These tests can be run on CI when pushing to TRY. Not all tests are enabled at the moment since they were copied over from the old frontend (See Bug 1400847).
|
||||
|
||||
* Mocha + Enzyme - [mocha](https://mochajs.org/) Mocha is JavaScript test framework running on Node.js
|
||||
[Enzyme](http://airbnb.io/enzyme/) is a JavaScript Testing utility for React that makes it easier to assert, manipulate, and traverse your React Components' output.
|
||||
- Mocha + Enzyme - [mocha](https://mochajs.org/) Mocha is JavaScript test framework running on Node.js
|
||||
[Enzyme](http://airbnb.io/enzyme/) is a JavaScript Testing utility for React that makes it easier to assert, manipulate, and traverse your React Components' output.
|
||||
|
||||
These tests are located in `test/components/` and `test/store/`, and can be run with the following command:
|
||||
These tests are located in `tests/node/`, and can be run with the following command:
|
||||
|
||||
```sh
|
||||
cd devtools/client/webconsole/test/ && npm install && npm test
|
||||
cd devtools/client/webconsole/test/node && npm install && npm test
|
||||
```
|
||||
|
||||
or using yarn with
|
||||
|
||||
```sh
|
||||
cd devtools/client/webconsole/test/ && yarn && yarn test
|
||||
cd devtools/client/webconsole/test/node && yarn && yarn test
|
||||
```
|
||||
|
||||
---
|
||||
|
@ -32,51 +33,29 @@ The team is leaning towards Enzyme since it's well known and suitable for React.
|
|||
It's also easier to contribute to tests written on top of Enzyme.
|
||||
|
||||
# Stubs
|
||||
|
||||
Many tests depends on fix data structures (aka stubs) that mimic
|
||||
<abbr title="Remote Debugging Protocol">RDP<abbr> packets that represents Console logs.
|
||||
Stubs are stored in `test/fixtures` directory and you might automatically generate them.
|
||||
|
||||
## Append new Console API stubs
|
||||
See how to generate stubs for Console API calls.
|
||||
## Append new stubs
|
||||
|
||||
* Append new entry into `consoleApiCommands` array. The array is defined in this module:
|
||||
`\test\fixtures\stub-generators\stub-snippets.js`
|
||||
* Generate stubs with existing mochitest:
|
||||
`\test\fixtures\stub-generators\browser_webconsole_check_stubs_console_api.js`
|
||||
- Append new entry into the `getCommands` function return value in on of the `\tests\browser\browser_webconsole_stubs_*.js`
|
||||
and run the generator using `mach` command, with the `WEBCONSOLE_STUBS_UPDATE=true` environment variable.
|
||||
|
||||
Run the generator using `mach` command.
|
||||
`./mach test devtools/client/webconsole/test/fixtures/stub-generators/browser_webconsole_check_stubs_console_api.js --headless`
|
||||
For console API stubs, you can do:
|
||||
|
||||
This will override `test/fixtures/stubs/consoleApi.js`.
|
||||
`./mach test devtools/client/webconsole/test/browser/browser_webconsole_stubs_console_api.js --headless --setenv WEBCONSOLE_STUBS_UPDATE=true`
|
||||
|
||||
## Append new CSS Messages stubs
|
||||
See how to generate stubs for CSS messages.
|
||||
This will override `tests/node/fixtures/stubs/consoleApi.js`.
|
||||
|
||||
* Append new entry into `cssMessage` map into `stub-snippets.js`
|
||||
* Generate stubs with: `browser_webconsole_check_stubs_css_message.js`
|
||||
The same can be done in:
|
||||
|
||||
This will override `test/fixtures/stubs/cssMessage.js`.
|
||||
- `browser_webconsole_stubs_css_message.js` (writes to `tests/node/fixtures/stubs/cssMessage.js`)
|
||||
- `browser_webconsole_stubs_evaluation_result.js` (writes to `tests/node/fixtures/stubs/evaluationResult.js`)
|
||||
- `browser_webconsole_stubs_network_event.js` (writes to `tests/node/fixtures/stubs/networkEvent.js`)
|
||||
- `browser_webconsole_stubs_page_error.js` (writes to `tests/node/fixtures/stubs/pageError.js`)
|
||||
|
||||
## Append new Evaluation Result stubs
|
||||
See how to generate stubs for evaluation results.
|
||||
If you made some changes that impact all stubs, you can update all at once using:
|
||||
|
||||
* Append new entry into `evaluationResultCommands` map into `stub-snippets.js`
|
||||
* Generate stubs with: `browser_webconsole_check_stubs_evaluation_result.js`
|
||||
|
||||
This will override `test/fixtures/stubs/evaluationResult.js`.
|
||||
|
||||
## Append new Network Events stubs
|
||||
See how to generate stubs for network events
|
||||
|
||||
* Append new entry into `networkEvent` map into `stub-snippets.js`
|
||||
* Generate stubs with: `browser_webconsole_update_stubs_network_event.js`
|
||||
|
||||
This will override `test/fixtures/stubs/networkEvent.js`.
|
||||
|
||||
## Append new Page Error stubs
|
||||
See how to generate stubs for page errors.
|
||||
|
||||
* Append new entry into `pageError` array into `stub-snippets.js`
|
||||
* Generate stubs with: `browser_webconsole_update_stubs_page_error.js`
|
||||
|
||||
This will override `test/fixtures/stubs/pageError.js`.
|
||||
`./mach test devtools/client/webconsole/test/browser/browser_webconsole_stubs --headless --setenv WEBCONSOLE_STUBS_UPDATE=true`
|
||||
|
|
|
@ -155,7 +155,7 @@ support-files =
|
|||
skip-if = !e10s # This test is only valid in e10s
|
||||
[browser_console_clear_cache.js]
|
||||
[browser_console_clear_method.js]
|
||||
skip-if = true # Bug 1437843
|
||||
skip-if = true # Bug XXX # Bug 1437843
|
||||
[browser_console_consolejsm_output.js]
|
||||
[browser_console_context_menu_entries.js]
|
||||
skip-if = os == "linux" # Bug 1440059, disabled for all build types
|
||||
|
@ -285,7 +285,7 @@ skip-if = fission
|
|||
[browser_webconsole_close_unfocused_window.js]
|
||||
[browser_webconsole_closing_after_completion.js]
|
||||
[browser_webconsole_close_sidebar.js]
|
||||
skip-if = true # Bug 1405250
|
||||
skip-if = true # Bug XXX # Bug 1405250
|
||||
[browser_webconsole_console_api_iframe.js]
|
||||
[browser_webconsole_console_dir.js]
|
||||
[browser_webconsole_console_dir_uninspectable.js]
|
||||
|
@ -334,7 +334,7 @@ skip-if = fission
|
|||
[browser_webconsole_execution_scope.js]
|
||||
[browser_webconsole_external_script_errors.js]
|
||||
[browser_webconsole_file_uri.js]
|
||||
skip-if = true # Bug 1404382
|
||||
skip-if = true # Bug XXX # Bug 1404382
|
||||
[browser_webconsole_filter_buttons_overflow.js]
|
||||
[browser_webconsole_filter_by_input.js]
|
||||
[browser_webconsole_filter_by_regex_input.js]
|
||||
|
@ -377,7 +377,7 @@ skip-if = fission
|
|||
[browser_webconsole_network_message_close_on_escape.js]
|
||||
[browser_webconsole_network_message_ctrl_click.js]
|
||||
[browser_webconsole_network_messages_expand.js]
|
||||
skip-if = true # Bug 1438979
|
||||
skip-if = true # Bug XXX # Bug 1438979
|
||||
[browser_webconsole_network_messages_openinnet.js]
|
||||
fail-if = fission
|
||||
[browser_webconsole_network_messages_resend_request.js]
|
||||
|
@ -451,6 +451,16 @@ skip-if = verify
|
|||
[browser_webconsole_stacktrace_location_scratchpad_link.js]
|
||||
[browser_webconsole_strict_mode_errors.js]
|
||||
[browser_webconsole_string.js]
|
||||
[browser_webconsole_stubs_console_api.js]
|
||||
skip-if = true # Bug 1572667
|
||||
[browser_webconsole_stubs_css_message.js]
|
||||
skip-if = true # Bug 1572667
|
||||
[browser_webconsole_stubs_evaluation_result.js]
|
||||
skip-if = true # Bug 1572667
|
||||
[browser_webconsole_stubs_network_event.js]
|
||||
skip-if = true # Bug 1572667
|
||||
[browser_webconsole_stubs_page_error.js]
|
||||
skip-if = true # Bug 1572667
|
||||
[browser_webconsole_telemetry_js_errors.js]
|
||||
[browser_webconsole_telemetry_filters_changed.js]
|
||||
[browser_webconsole_telemetry_persist_toggle_changed.js]
|
|
@ -9,11 +9,11 @@
|
|||
|
||||
const TEST_URI =
|
||||
"http://example.com/browser/devtools/client/webconsole/" +
|
||||
"test/mochitest/test-console.html?" +
|
||||
"test/browser/test-console.html?" +
|
||||
Date.now();
|
||||
const TEST_FILE =
|
||||
"chrome://mochitests/content/browser/devtools/client/" +
|
||||
"webconsole/test/mochitest/" +
|
||||
"webconsole/test/browser/" +
|
||||
"test-cu-reporterror.js";
|
||||
|
||||
const TEST_XHR_ERROR_URI = `http://example.com/404.html?${Date.now()}`;
|
|
@ -7,7 +7,7 @@
|
|||
|
||||
const TEST_URI =
|
||||
"http://example.com/browser/devtools/client/webconsole/" +
|
||||
"test/mochitest/test-console.html";
|
||||
"test/browser/test-console.html";
|
||||
|
||||
add_task(async function() {
|
||||
await pushPref("devtools.browserconsole.contentMessages", true);
|
Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше
Загрузка…
Ссылка в новой задаче