Merge mozilla-central to inbound. a=merge CLOSED TREE
|
@ -2,25 +2,23 @@
|
|||
# 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/.
|
||||
|
||||
import imp
|
||||
from __future__ import absolute_import, print_function
|
||||
import json
|
||||
import os
|
||||
import shlex
|
||||
import subprocess
|
||||
import sys
|
||||
try:
|
||||
from StringIO import StringIO
|
||||
except ImportError:
|
||||
from io import StringIO
|
||||
|
||||
old_bytecode = sys.dont_write_bytecode
|
||||
sys.dont_write_bytecode = True
|
||||
|
||||
path = os.path.join(os.path.dirname(__file__), 'mach')
|
||||
path = os.path.abspath(os.path.join(os.path.dirname(__file__), 'mach'))
|
||||
|
||||
# If mach is not here, we're on the objdir go to the srcdir.
|
||||
if not os.path.exists(path):
|
||||
path = os.path.join(os.path.dirname(__file__), 'config.status')
|
||||
config = imp.load_module('_buildconfig', open(path), path, ('', 'r', imp.PY_SOURCE))
|
||||
path = os.path.join(config.topsrcdir, 'mach')
|
||||
mach_module = imp.load_module('_mach', open(path), path, ('', 'r', imp.PY_SOURCE))
|
||||
with open(os.path.join(os.path.dirname(__file__), 'mozinfo.json')) as info:
|
||||
config = json.loads(info.read())
|
||||
path = os.path.join(config['topsrcdir'], 'mach')
|
||||
|
||||
sys.dont_write_bytecode = old_bytecode
|
||||
|
||||
|
@ -35,16 +33,10 @@ def _is_likely_cpp_header(filename):
|
|||
return os.path.exists(cpp_file)
|
||||
|
||||
def FlagsForFile(filename):
|
||||
mach = mach_module.get_mach()
|
||||
out = StringIO()
|
||||
output = subprocess.check_output([path, 'compileflags', filename])
|
||||
output = output.decode('utf-8')
|
||||
|
||||
# Mach calls sys.stdout.fileno(), so we need to fake it when capturing it.
|
||||
# Returning an invalid file descriptor does the trick.
|
||||
out.fileno = lambda: -1
|
||||
out.encoding = None
|
||||
mach.run(['compileflags', filename], stdout=out, stderr=out)
|
||||
|
||||
flag_list = shlex.split(out.getvalue())
|
||||
flag_list = shlex.split(output)
|
||||
|
||||
# This flag is added by Fennec for android build and causes ycmd to fail to parse the file.
|
||||
# Removing this flag is a workaround until ycmd starts to handle this flag properly.
|
||||
|
@ -58,3 +50,6 @@ def FlagsForFile(filename):
|
|||
'flags': final_flags,
|
||||
'do_cache': True
|
||||
}
|
||||
|
||||
if __name__ == '__main__':
|
||||
print(FlagsForFile(sys.argv[1]))
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<?xml version='1.0' encoding='UTF-8'?>
|
||||
<blocklist lastupdate="1547658828472" xmlns="http://www.mozilla.org/2006/addons-blocklist">
|
||||
<blocklist lastupdate="1548198338831" xmlns="http://www.mozilla.org/2006/addons-blocklist">
|
||||
<emItems>
|
||||
<emItem blockID="i334" id="{0F827075-B026-42F3-885D-98981EE7B1AE}">
|
||||
<prefs/>
|
||||
|
@ -2452,6 +2452,22 @@
|
|||
<prefs/>
|
||||
<versionRange minVersion="0" maxVersion="*" severity="3"/>
|
||||
</emItem>
|
||||
<emItem blockID="a15e8d7e-0726-4190-8187-c75e2b46d429" id="/^((\{94f608b3-76b6-4b7b-8cef-7360df22a930\})|(\{9648b74f-35ea-4218-acf0-ec2191f509f6\}))$/">
|
||||
<prefs/>
|
||||
<versionRange minVersion="0" maxVersion="*" severity="3"/>
|
||||
</emItem>
|
||||
<emItem blockID="c69997df-0b61-4de5-a351-b640123a9c3b" id="/^((xtera@soravem\.net)|(nozl@ssave\.net))$/">
|
||||
<prefs/>
|
||||
<versionRange minVersion="0" maxVersion="*" severity="3"/>
|
||||
</emItem>
|
||||
<emItem blockID="1e2ae4c0-66cd-40bc-9cf6-5ca0ce9548f7" id="hlper@xero.com">
|
||||
<prefs/>
|
||||
<versionRange minVersion="0" maxVersion="*" severity="3"/>
|
||||
</emItem>
|
||||
<emItem blockID="87c17ce6-aaef-4d47-a662-588efff34041" id="/^((\{feff5ea4-ed4a-46a3-9331-12fec01d52a9\})|(\{8ffc339c-0ca1-46e3-acb3-3bfd889f9a21\})|(\{1fe481b5-baad-44e9-b410-082cf0f2acbb\})|(\{92c85192-b325-4599-82e2-a110f193eae6\})|(\{5bc21266-26f1-469a-bc1a-a49d7b70ecb9\})|(\{dc2dd143-f2e7-4f46-a8ff-4dc1a985e889\})|(\{c1233bb6-31a9-4c7d-8469-f8f44adee9ba\})|(\{d0d48905-1065-43dc-ab96-434d100602ed\})|(\{11deae99-2675-4d5e-86cd-7bd55b88daf2\})|(\{a7014e8e-eacf-4ba0-9047-c897c4ed3387\})|(\{b9c545a5-0ffa-490a-8071-2fee09478cfe\})|(\{39e8eebb-4d9e-4a03-93a8-4468fdd7a186\})|(\{8ccc00b1-2010-4155-a07c-f4d7c4d6dec2\})|(\{a1056511-4919-43b7-a9e5-ac2b770de810\})|(\{90a6da19-9165-44c1-819c-e3b53409f9c9\})|(\{e3862078-8f9f-4f8e-99dc-55ba558f0619\})|(\{d89fcf34-2615-4efc-a267-1e83ab6a19d0\})|(\{588151ce-eab4-4acf-83a7-bb5ccaf4d867\})|(\{6ab6312d-5fd4-42a9-ab10-08b954e53f9d\})|(\{24a6cbde-be68-4b7d-9f1b-d4d5dfd178a3\})|(\{55ae1a08-105f-4f7f-9d4e-e448b517db2b\})|(\{74fe9d83-df17-4812-bd3f-27b84b0086b7\})|(\{21140e51-713a-4bf8-865b-e2ee07282409\})|(\{24f39610-2958-4dc8-a73b-75cc9665bffa\})|(\{c50a45a5-efa4-44af-8946-6f20e4748d47\})|(\{41d0b7e0-0d93-4f67-bed9-da6d7688ad16\})|(\{c2bee222-2163-4c0f-89f5-4ac502f06810\})|(\{4be4602e-2b20-473f-8f2b-85e8c53d17dc\})|(\{dec2e9b5-e787-4fb5-a7bc-5894f80f7367\})|(\{179526e1-1824-49f7-afb3-49fdaadaa503\})|(\{4f07d826-ca9e-4370-a508-b984f54758de\})|(\{d0558df2-714f-4793-9d85-d2d648de4f2e\})|(\{daf1a69b-f47b-4936-bd25-5ac21f4e27ec\}))$/">
|
||||
<prefs/>
|
||||
<versionRange minVersion="0" maxVersion="*" severity="3"/>
|
||||
</emItem>
|
||||
</emItems>
|
||||
<pluginItems>
|
||||
<pluginItem blockID="p332">
|
||||
|
|
|
@ -190,11 +190,6 @@ XPCOMUtils.defineLazyGetter(this, "gURLBar", () => {
|
|||
return element;
|
||||
}
|
||||
|
||||
// Re-focus the input field if it was focused before switching bindings.
|
||||
if (element.hasAttribute("focused")) {
|
||||
element.inputField.focus();
|
||||
}
|
||||
|
||||
return new UrlbarInput({
|
||||
textbox: element,
|
||||
panel: document.getElementById("urlbar-results"),
|
||||
|
|
|
@ -111,6 +111,27 @@ add_task(async function testExecuteScript() {
|
|||
|
||||
await extension.awaitFinish("removeCSS");
|
||||
|
||||
// Verify that scripts created by tabs.removeCSS are not added to the content scripts
|
||||
// that requires cleanup (Bug 1464711).
|
||||
await ContentTask.spawn(tab.linkedBrowser, extension.id, async (extId) => {
|
||||
const {
|
||||
DocumentManager,
|
||||
} = ChromeUtils.import("resource://gre/modules/ExtensionContent.jsm", {});
|
||||
|
||||
let contentScriptContext = Array.from(
|
||||
DocumentManager.getContexts(content.window).values()
|
||||
).find(context => context.extension.id === extId);
|
||||
|
||||
for (let script of contentScriptContext.scripts) {
|
||||
if (script.matcher.removeCSS && script.requiresCleanup) {
|
||||
throw new Error("tabs.removeCSS scripts should not require cleanup");
|
||||
}
|
||||
}
|
||||
}).catch(err => {
|
||||
// Log the error so that it is easy to see where the failure is coming from.
|
||||
ok(false, err);
|
||||
});
|
||||
|
||||
await extension.unload();
|
||||
|
||||
BrowserTestUtils.removeTab(tab);
|
||||
|
|
|
@ -48,6 +48,7 @@ for (const type of [
|
|||
"DISCOVERY_STREAM_SPOCS_ENDPOINT",
|
||||
"DISCOVERY_STREAM_SPOCS_UPDATE",
|
||||
"DOWNLOAD_CHANGED",
|
||||
"FAKE_FOCUS_SEARCH",
|
||||
"FILL_SEARCH_TERM",
|
||||
"HANDOFF_SEARCH_TO_AWESOMEBAR",
|
||||
"HIDE_SEARCH",
|
||||
|
|
|
@ -60,11 +60,15 @@ const INITIAL_STATE = {
|
|||
spocs_endpoint: "",
|
||||
lastUpdated: null,
|
||||
data: {}, // {spocs: []}
|
||||
loaded: false,
|
||||
},
|
||||
},
|
||||
Search: {
|
||||
// Pretend the search box is focused after handing off to AwesomeBar.
|
||||
focus: false,
|
||||
// When search hand-off is enabled, we render a big button that is styled to
|
||||
// look like a search textbox. If the button is clicked, we style
|
||||
// the button as if it was a focused search box and show a fake cursor but
|
||||
// really focus the awesomebar without the focus styles ("hidden focus").
|
||||
fakeFocus: false,
|
||||
// Hide the search box after handing off to AwesomeBar and user starts typing.
|
||||
hide: false,
|
||||
},
|
||||
|
@ -478,6 +482,7 @@ function DiscoveryStream(prevState = INITIAL_STATE.DiscoveryStream, action) {
|
|||
...prevState.spocs,
|
||||
lastUpdated: action.data.lastUpdated,
|
||||
data: action.data.spocs,
|
||||
loaded: true,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
@ -491,8 +496,10 @@ function Search(prevState = INITIAL_STATE.Search, action) {
|
|||
switch (action.type) {
|
||||
case at.HIDE_SEARCH:
|
||||
return Object.assign({...prevState, hide: true});
|
||||
case at.FAKE_FOCUS_SEARCH:
|
||||
return Object.assign({...prevState, fakeFocus: true});
|
||||
case at.SHOW_SEARCH:
|
||||
return Object.assign({...prevState, hide: false});
|
||||
return Object.assign({...prevState, hide: false, fakeFocus: false});
|
||||
default:
|
||||
return prevState;
|
||||
}
|
||||
|
|
|
@ -159,6 +159,8 @@ export class ASRouterUISurface extends React.PureComponent {
|
|||
case "CLEAR_MESSAGE":
|
||||
if (action.data.id === this.state.message.id) {
|
||||
this.setState({message: {}});
|
||||
// Remove any styles related to the RTAMO message
|
||||
document.body.classList.remove("welcome", "hide-main", "amo");
|
||||
}
|
||||
break;
|
||||
case "CLEAR_PROVIDER":
|
||||
|
|
|
@ -14,8 +14,6 @@ export class ReturnToAMO extends React.PureComponent {
|
|||
|
||||
onClickAddExtension() {
|
||||
this.props.onAction(this.props.content.primary_button.action);
|
||||
this.props.onBlock();
|
||||
document.body.classList.remove("welcome", "hide-main", "amo");
|
||||
}
|
||||
|
||||
onBlockButton() {
|
||||
|
|
|
@ -115,6 +115,14 @@ export class _DiscoveryStreamBase extends React.PureComponent {
|
|||
|
||||
renderComponent(component) {
|
||||
let rows;
|
||||
const {spocs} = this.props.DiscoveryStream;
|
||||
|
||||
// TODO: Can we make this a bit better visually while it loads?
|
||||
// If this component expects spocs,
|
||||
// wait until spocs are loaded before attempting to use it.
|
||||
if (component.spocs && !spocs.loaded) {
|
||||
return null;
|
||||
}
|
||||
|
||||
switch (component.type) {
|
||||
case "TopSites":
|
||||
|
|
|
@ -25,15 +25,12 @@ $excerpt-line-height: 20;
|
|||
|
||||
.img-wrapper {
|
||||
width: 100%;
|
||||
border: 0.5px solid $black-10;
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
.img {
|
||||
@include image-as-background;
|
||||
height: 0;
|
||||
padding-top: 50%; // 2:1 aspect ratio
|
||||
background-repeat: no-repeat;
|
||||
background-size: cover;
|
||||
}
|
||||
|
||||
.meta {
|
||||
|
|
|
@ -1,8 +1,6 @@
|
|||
.ds-hero {
|
||||
.img {
|
||||
border: 0.5px solid $black-10;
|
||||
box-sizing: border-box;
|
||||
border-radius: 4px;
|
||||
@include image-as-background;
|
||||
}
|
||||
|
||||
.ds-card {
|
||||
|
@ -28,8 +26,16 @@
|
|||
color: $grey-50;
|
||||
margin: 18px 0;
|
||||
padding: 20px 0;
|
||||
border-top: 1px solid transparentize($grey-40, 0.64);
|
||||
border-bottom: 1px solid transparentize($grey-40, 0.64);
|
||||
border-top: $border-secondary;
|
||||
border-bottom: $border-secondary;
|
||||
|
||||
&:hover .meta header {
|
||||
color: $blue-60;
|
||||
}
|
||||
|
||||
&:active .meta header {
|
||||
color: $blue-70;
|
||||
}
|
||||
|
||||
.img-wrapper {
|
||||
width: 100%;
|
||||
|
@ -38,23 +44,12 @@
|
|||
.img {
|
||||
height: 0;
|
||||
padding-top: 50%; // 2:1 aspect ratio
|
||||
background-repeat: no-repeat;
|
||||
background-size: cover;
|
||||
background-color: $grey-30;
|
||||
}
|
||||
|
||||
.meta {
|
||||
header {
|
||||
font-size: 22px;
|
||||
color: $grey-90;
|
||||
|
||||
&:hover {
|
||||
color: $blue-60;
|
||||
}
|
||||
|
||||
&:active {
|
||||
color: $blue-70;
|
||||
}
|
||||
}
|
||||
|
||||
p {
|
||||
|
|
|
@ -3,7 +3,7 @@ import React from "react";
|
|||
export class HorizontalRule extends React.PureComponent {
|
||||
render() {
|
||||
return (
|
||||
<hr />
|
||||
<hr className="ds-hr" />
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
.ds-hr {
|
||||
border: 0;
|
||||
height: 0;
|
||||
border-top: $border-secondary;
|
||||
}
|
|
@ -39,11 +39,9 @@ export class ListItem extends React.PureComponent {
|
|||
{this.props.title}
|
||||
</b>
|
||||
</div>
|
||||
<div className="ds-list-item-info">
|
||||
{`${this.props.domain} · TODO:Topic`}
|
||||
</div>
|
||||
<div className="ds-list-item-info">{this.props.domain}</div>
|
||||
</div>
|
||||
<img className="ds-list-image" src={this.props.image_src} />
|
||||
<div className="ds-list-image" style={{backgroundImage: `url(${this.props.image_src})`}} />
|
||||
</a>
|
||||
</li>
|
||||
);
|
||||
|
|
|
@ -3,7 +3,10 @@ $item-font-size: 13;
|
|||
$item-line-height: 20;
|
||||
|
||||
.ds-list-border {
|
||||
border: 1px solid $grey-40-36;
|
||||
border: 0;
|
||||
border-top: $border-secondary;
|
||||
|
||||
padding-top: 1px;
|
||||
|
||||
// Instead of using margin, we need to use these to override stuff that comes
|
||||
// by default from <hr>.
|
||||
|
@ -80,6 +83,10 @@ $item-line-height: 20;
|
|||
&:hover::before {
|
||||
background-color: var(--newtab-link-primary-color);
|
||||
}
|
||||
|
||||
&:active::before {
|
||||
background-color: $blue-70;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -88,8 +95,8 @@ $item-line-height: 20;
|
|||
// Unfortunately the border needs to go _above_ the row gap as currently
|
||||
// set up, which means that some refactoring will be required to do this.
|
||||
.ds-list-item:nth-child(-n+3) { // all but the last three items
|
||||
border-bottom: 2px solid $grey-40-36;
|
||||
margin-bottom: -2px; // cancel out the 2 pixels we used for the border
|
||||
border-bottom: $border-secondary;
|
||||
margin-bottom: -1px; // cancel out the pixel we used for the border
|
||||
|
||||
padding-bottom: 2px;
|
||||
}
|
||||
|
@ -134,13 +141,26 @@ $item-line-height: 20;
|
|||
}
|
||||
|
||||
.ds-list-image {
|
||||
display: none;
|
||||
width: 72px;
|
||||
height: 72px;
|
||||
object-fit: cover;
|
||||
$image-size: 72px;
|
||||
|
||||
border: 0.5px solid $black-12;
|
||||
box-sizing: border-box;
|
||||
border-radius: 4px;
|
||||
@include image-as-background;
|
||||
display: none;
|
||||
height: $image-size;
|
||||
margin-inline-start: $item-font-size * 1px;
|
||||
min-height: $image-size;
|
||||
min-width: $image-size;
|
||||
width: $image-size;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
.ds-list-item-title {
|
||||
color: var(--newtab-link-primary-color);
|
||||
}
|
||||
}
|
||||
|
||||
&:active {
|
||||
.ds-list-item-title {
|
||||
color: $blue-70;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,11 +12,10 @@ export class _Search extends React.PureComponent {
|
|||
super(props);
|
||||
this.onSearchClick = this.onSearchClick.bind(this);
|
||||
this.onSearchHandoffClick = this.onSearchHandoffClick.bind(this);
|
||||
this.onSearchHandoffKeyDown = this.onSearchHandoffKeyDown.bind(this);
|
||||
this.onSearchHandoffPaste = this.onSearchHandoffPaste.bind(this);
|
||||
this.onSearchHandoffDrop = this.onSearchHandoffDrop.bind(this);
|
||||
this.onInputMount = this.onInputMount.bind(this);
|
||||
this.onSearchHandoffButtonMount = this.onSearchHandoffButtonMount.bind(this);
|
||||
this.cancelEvent = this.cancelEvent.bind(this);
|
||||
}
|
||||
|
||||
handleEvent(event) {
|
||||
|
@ -32,64 +31,36 @@ export class _Search extends React.PureComponent {
|
|||
|
||||
doSearchHandoff(text) {
|
||||
this.props.dispatch(ac.OnlyToMain({type: at.HANDOFF_SEARCH_TO_AWESOMEBAR, data: {text}}));
|
||||
this.props.dispatch({type: at.FAKE_FOCUS_SEARCH});
|
||||
this.props.dispatch(ac.UserEvent({event: "SEARCH_HANDOFF"}));
|
||||
if (text) {
|
||||
// We don't hide the in-content search if there is no text (user hit <Enter>)
|
||||
this.props.dispatch({type: at.HIDE_SEARCH});
|
||||
}
|
||||
}
|
||||
|
||||
onSearchHandoffClick(event) {
|
||||
// When search hand-off is enabled, we render a big button that is styled to
|
||||
// look like a search textbox. If the button is clicked with the mouse, we
|
||||
// focus it. If the user types, transfer focus to awesomebar.
|
||||
// If the button is clicked from the keyboard, we focus the awesomebar normally.
|
||||
// This is to minimize confusion with users navigating with the keyboard and
|
||||
// users using assistive technologoy.
|
||||
// look like a search textbox. If the button is clicked, we style
|
||||
// the button as if it was a focused search box and show a fake cursor but
|
||||
// really focus the awesomebar without the focus styles ("hidden focus").
|
||||
event.preventDefault();
|
||||
const isKeyboardClick = event.clientX === 0 && event.clientY === 0;
|
||||
if (isKeyboardClick) {
|
||||
this.doSearchHandoff();
|
||||
} else {
|
||||
this._searchHandoffButton.focus();
|
||||
}
|
||||
}
|
||||
|
||||
onSearchHandoffKeyDown(event) {
|
||||
if (event.key.length === 1 && !event.altKey && !event.ctrlKey && !event.metaKey) {
|
||||
// We only care about key strokes that will produce a character.
|
||||
this.doSearchHandoff(event.key);
|
||||
}
|
||||
this.doSearchHandoff();
|
||||
}
|
||||
|
||||
onSearchHandoffPaste(event) {
|
||||
if (!this._searchHandoffButton ||
|
||||
!this._searchHandoffButton.contains(global.document.activeElement)) {
|
||||
// Don't handle every paste on the document. Filter out those that are
|
||||
// not on the Search Hand-off button.
|
||||
return;
|
||||
}
|
||||
event.preventDefault();
|
||||
this.doSearchHandoff(event.clipboardData.getData("Text"));
|
||||
}
|
||||
|
||||
cancelEvent(event) {
|
||||
onSearchHandoffDrop(event) {
|
||||
event.preventDefault();
|
||||
}
|
||||
|
||||
componentWillMount() {
|
||||
if (global.document) {
|
||||
// We need to listen to paste events that bubble up from the Search Hand-off
|
||||
// button. Adding the paste listener to the button itself or it's parent
|
||||
// doesn't work consistently until the page is clicked on.
|
||||
global.document.addEventListener("paste", this.onSearchHandoffPaste);
|
||||
let text = event.dataTransfer.getData("text");
|
||||
if (text) {
|
||||
this.doSearchHandoff(text);
|
||||
}
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
if (global.document) {
|
||||
global.document.removeEventListener("paste", this.onDocumentPaste);
|
||||
}
|
||||
delete window.gContentSearchController;
|
||||
}
|
||||
|
||||
|
@ -135,6 +106,7 @@ export class _Search extends React.PureComponent {
|
|||
const wrapperClassName = [
|
||||
"search-wrapper",
|
||||
this.props.hide && "search-hidden",
|
||||
this.props.fakeFocus && "fake-focus",
|
||||
].filter(v => v).join(" ");
|
||||
|
||||
return (<div className={wrapperClassName}>
|
||||
|
@ -171,10 +143,10 @@ export class _Search extends React.PureComponent {
|
|||
className="search-handoff-button"
|
||||
ref={this.onSearchHandoffButtonMount}
|
||||
onClick={this.onSearchHandoffClick}
|
||||
onKeyDown={this.onSearchHandoffKeyDown}
|
||||
tabIndex="-1"
|
||||
title={this.props.intl.formatMessage({id: "search_web_placeholder"})}>
|
||||
<div className="fake-textbox">{this.props.intl.formatMessage({id: "search_web_placeholder"})}</div>
|
||||
<div className="fake-editable" tabIndex="-1" aria-hidden="true" contentEditable="" onDrop={this.cancelEvent} />
|
||||
<div className="fake-editable" tabIndex="-1" aria-hidden="true" contentEditable="" onDrop={this.onSearchHandoffDrop} onPaste={this.onSearchHandoffPaste} />
|
||||
<div className="fake-caret" />
|
||||
</button>
|
||||
{/*
|
||||
|
|
|
@ -160,7 +160,7 @@ $glyph-forward: url('chrome://browser/skin/forward.svg');
|
|||
box-shadow: $shadow-secondary, 0 0 0 1px $black-25;
|
||||
}
|
||||
|
||||
&:focus {
|
||||
.fake-focus & {
|
||||
border: $input-border-active;
|
||||
box-shadow: var(--newtab-textbox-focus-boxshadow);
|
||||
|
||||
|
|
|
@ -1,3 +1,14 @@
|
|||
// Shared styling of article images shown as background
|
||||
@mixin image-as-background {
|
||||
background-color: var(--newtab-card-placeholder-color);
|
||||
background-position: center;
|
||||
background-repeat: no-repeat;
|
||||
background-size: cover;
|
||||
border-radius: 4px;
|
||||
border: 0.5px solid $black-10;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
// Note: lineHeight and fontSize should be unitless but can be derived from pixel values
|
||||
@mixin limit-visibile-lines($line-count, $line-height, $font-size) {
|
||||
max-height: 1em * $line-count * $line-height / $font-size;
|
||||
|
|
|
@ -71,6 +71,7 @@ body {
|
|||
--newtab-card-active-outline-color: #{$grey-30};
|
||||
--newtab-card-background-color: #{$white};
|
||||
--newtab-card-hairline-color: #{$black-10};
|
||||
--newtab-card-placeholder-color: #{$grey-30};
|
||||
--newtab-card-shadow: 0 1px 4px 0 #{$grey-90-10};
|
||||
|
||||
// Snippets
|
||||
|
@ -129,6 +130,7 @@ body {
|
|||
--newtab-card-active-outline-color: #{$grey-60};
|
||||
--newtab-card-background-color: #{$grey-70};
|
||||
--newtab-card-hairline-color: #{$grey-10-10};
|
||||
--newtab-card-placeholder-color: #{$grey-60};
|
||||
--newtab-card-shadow: 0 1px 8px 0 #{$grey-90-20};
|
||||
|
||||
// Snippets
|
||||
|
|
|
@ -29,7 +29,6 @@ $grey-10-95: rgba($grey-10, 0.95);
|
|||
$grey-20-60: rgba($grey-20, 0.6);
|
||||
$grey-20-80: rgba($grey-20, 0.8);
|
||||
$grey-30-60: rgba($grey-30, 0.6);
|
||||
$grey-40-36: rgba($grey-40, 0.36);
|
||||
$grey-60-60: rgba($grey-60, 0.6);
|
||||
$grey-60-70: rgba($grey-60, 0.7);
|
||||
$grey-80-95: rgba($grey-80, 0.95);
|
||||
|
|
|
@ -64,6 +64,7 @@ body {
|
|||
--newtab-card-active-outline-color: #D7D7DB;
|
||||
--newtab-card-background-color: #FFF;
|
||||
--newtab-card-hairline-color: rgba(0, 0, 0, 0.1);
|
||||
--newtab-card-placeholder-color: #D7D7DB;
|
||||
--newtab-card-shadow: 0 1px 4px 0 rgba(12, 12, 13, 0.1);
|
||||
--newtab-snippets-background-color: #FFF;
|
||||
--newtab-snippets-hairline-color: transparent; }
|
||||
|
@ -107,6 +108,7 @@ body {
|
|||
--newtab-card-active-outline-color: #4A4A4F;
|
||||
--newtab-card-background-color: #38383D;
|
||||
--newtab-card-hairline-color: rgba(249, 249, 250, 0.1);
|
||||
--newtab-card-placeholder-color: #4A4A4F;
|
||||
--newtab-card-shadow: 0 1px 8px 0 rgba(12, 12, 13, 0.2);
|
||||
--newtab-snippets-background-color: #38383D;
|
||||
--newtab-snippets-hairline-color: rgba(255, 255, 255, 0.1); }
|
||||
|
@ -1066,10 +1068,10 @@ main {
|
|||
background-position-x: right 12px; }
|
||||
.search-handoff-button:hover {
|
||||
box-shadow: 0 1px 4px 0 rgba(12, 12, 13, 0.2), 0 0 0 1px rgba(0, 0, 0, 0.25); }
|
||||
.search-handoff-button:focus {
|
||||
.fake-focus .search-handoff-button {
|
||||
border: 1px solid var(--newtab-textbox-focus-color);
|
||||
box-shadow: var(--newtab-textbox-focus-boxshadow); }
|
||||
.search-handoff-button:focus .fake-caret {
|
||||
.fake-focus .search-handoff-button .fake-caret {
|
||||
display: block; }
|
||||
.search-hidden .search-handoff-button {
|
||||
opacity: 0;
|
||||
|
@ -1845,9 +1847,13 @@ main {
|
|||
grid-template-columns: repeat(3, 1fr); }
|
||||
|
||||
.ds-hero .img {
|
||||
background-color: var(--newtab-card-placeholder-color);
|
||||
background-position: center;
|
||||
background-repeat: no-repeat;
|
||||
background-size: cover;
|
||||
border-radius: 4px;
|
||||
border: 0.5px solid rgba(0, 0, 0, 0.1);
|
||||
box-sizing: border-box;
|
||||
border-radius: 4px; }
|
||||
box-sizing: border-box; }
|
||||
|
||||
.ds-hero .ds-card {
|
||||
border: 0; }
|
||||
|
@ -1865,23 +1871,20 @@ main {
|
|||
color: #737373;
|
||||
margin: 18px 0;
|
||||
padding: 20px 0;
|
||||
border-top: 1px solid rgba(177, 177, 179, 0.36);
|
||||
border-bottom: 1px solid rgba(177, 177, 179, 0.36); }
|
||||
border-top: 1px solid var(--newtab-border-secondary-color);
|
||||
border-bottom: 1px solid var(--newtab-border-secondary-color); }
|
||||
.ds-hero .wrapper:hover .meta header {
|
||||
color: #0060DF; }
|
||||
.ds-hero .wrapper:active .meta header {
|
||||
color: #003EAA; }
|
||||
.ds-hero .wrapper .img-wrapper {
|
||||
width: 100%; }
|
||||
.ds-hero .wrapper .img {
|
||||
height: 0;
|
||||
padding-top: 50%;
|
||||
background-repeat: no-repeat;
|
||||
background-size: cover;
|
||||
background-color: #D7D7DB; }
|
||||
padding-top: 50%; }
|
||||
.ds-hero .wrapper .meta header {
|
||||
font-size: 22px;
|
||||
color: #0C0C0D; }
|
||||
.ds-hero .wrapper .meta header:hover {
|
||||
color: #0060DF; }
|
||||
.ds-hero .wrapper .meta header:active {
|
||||
color: #003EAA; }
|
||||
.ds-hero .wrapper .meta p {
|
||||
font-size: 13px; }
|
||||
.ds-hero .wrapper .meta p.context {
|
||||
|
@ -1952,8 +1955,15 @@ main {
|
|||
grid-template-columns: repeat(4, 1fr);
|
||||
grid-column-gap: 24px; }
|
||||
|
||||
.ds-hr {
|
||||
border: 0;
|
||||
height: 0;
|
||||
border-top: 1px solid var(--newtab-border-secondary-color); }
|
||||
|
||||
.ds-list-border {
|
||||
border: 1px solid rgba(177, 177, 179, 0.36);
|
||||
border: 0;
|
||||
border-top: 1px solid var(--newtab-border-secondary-color);
|
||||
padding-top: 1px;
|
||||
margin-block-start: 8px;
|
||||
margin-block-end: 8px; }
|
||||
|
||||
|
@ -2000,10 +2010,12 @@ main {
|
|||
width: 33px; }
|
||||
.ds-list-numbers .ds-list-item-link:hover::before {
|
||||
background-color: var(--newtab-link-primary-color); }
|
||||
.ds-list-numbers .ds-list-item-link:active::before {
|
||||
background-color: #003EAA; }
|
||||
|
||||
.ds-list-item:nth-child(-n+3) {
|
||||
border-bottom: 2px solid rgba(177, 177, 179, 0.36);
|
||||
margin-bottom: -2px;
|
||||
border-bottom: 1px solid var(--newtab-border-secondary-color);
|
||||
margin-bottom: -1px;
|
||||
padding-bottom: 2px; }
|
||||
|
||||
.ds-list-item {
|
||||
|
@ -2030,13 +2042,23 @@ main {
|
|||
display: flex;
|
||||
flex-direction: column; }
|
||||
.ds-list-item .ds-list-image {
|
||||
display: none;
|
||||
width: 72px;
|
||||
height: 72px;
|
||||
object-fit: cover;
|
||||
border: 0.5px solid rgba(0, 0, 0, 0.12);
|
||||
background-color: var(--newtab-card-placeholder-color);
|
||||
background-position: center;
|
||||
background-repeat: no-repeat;
|
||||
background-size: cover;
|
||||
border-radius: 4px;
|
||||
border: 0.5px solid rgba(0, 0, 0, 0.1);
|
||||
box-sizing: border-box;
|
||||
border-radius: 4px; }
|
||||
display: none;
|
||||
height: 72px;
|
||||
margin-inline-start: 13px;
|
||||
min-height: 72px;
|
||||
min-width: 72px;
|
||||
width: 72px; }
|
||||
.ds-list-item:hover .ds-list-item-title {
|
||||
color: var(--newtab-link-primary-color); }
|
||||
.ds-list-item:active .ds-list-item-title {
|
||||
color: #003EAA; }
|
||||
|
||||
.ds-navigation.ds-navigation-centered {
|
||||
text-align: center; }
|
||||
|
@ -2160,14 +2182,17 @@ main {
|
|||
.ds-card:active header {
|
||||
color: #003EAA; }
|
||||
.ds-card .img-wrapper {
|
||||
width: 100%;
|
||||
border: 0.5px solid rgba(0, 0, 0, 0.1);
|
||||
border-radius: 4px; }
|
||||
width: 100%; }
|
||||
.ds-card .img {
|
||||
height: 0;
|
||||
padding-top: 50%;
|
||||
background-color: var(--newtab-card-placeholder-color);
|
||||
background-position: center;
|
||||
background-repeat: no-repeat;
|
||||
background-size: cover; }
|
||||
background-size: cover;
|
||||
border-radius: 4px;
|
||||
border: 0.5px solid rgba(0, 0, 0, 0.1);
|
||||
box-sizing: border-box;
|
||||
height: 0;
|
||||
padding-top: 50%; }
|
||||
.ds-card .meta {
|
||||
padding: 16px; }
|
||||
.ds-card .meta .title {
|
||||
|
|
|
@ -67,6 +67,7 @@ body {
|
|||
--newtab-card-active-outline-color: #D7D7DB;
|
||||
--newtab-card-background-color: #FFF;
|
||||
--newtab-card-hairline-color: rgba(0, 0, 0, 0.1);
|
||||
--newtab-card-placeholder-color: #D7D7DB;
|
||||
--newtab-card-shadow: 0 1px 4px 0 rgba(12, 12, 13, 0.1);
|
||||
--newtab-snippets-background-color: #FFF;
|
||||
--newtab-snippets-hairline-color: transparent; }
|
||||
|
@ -110,6 +111,7 @@ body {
|
|||
--newtab-card-active-outline-color: #4A4A4F;
|
||||
--newtab-card-background-color: #38383D;
|
||||
--newtab-card-hairline-color: rgba(249, 249, 250, 0.1);
|
||||
--newtab-card-placeholder-color: #4A4A4F;
|
||||
--newtab-card-shadow: 0 1px 8px 0 rgba(12, 12, 13, 0.2);
|
||||
--newtab-snippets-background-color: #38383D;
|
||||
--newtab-snippets-hairline-color: rgba(255, 255, 255, 0.1); }
|
||||
|
@ -1069,10 +1071,10 @@ main {
|
|||
background-position-x: right 12px; }
|
||||
.search-handoff-button:hover {
|
||||
box-shadow: 0 1px 4px 0 rgba(12, 12, 13, 0.2), 0 0 0 1px rgba(0, 0, 0, 0.25); }
|
||||
.search-handoff-button:focus {
|
||||
.fake-focus .search-handoff-button {
|
||||
border: 1px solid var(--newtab-textbox-focus-color);
|
||||
box-shadow: var(--newtab-textbox-focus-boxshadow); }
|
||||
.search-handoff-button:focus .fake-caret {
|
||||
.fake-focus .search-handoff-button .fake-caret {
|
||||
display: block; }
|
||||
.search-hidden .search-handoff-button {
|
||||
opacity: 0;
|
||||
|
@ -1848,9 +1850,13 @@ main {
|
|||
grid-template-columns: repeat(3, 1fr); }
|
||||
|
||||
.ds-hero .img {
|
||||
background-color: var(--newtab-card-placeholder-color);
|
||||
background-position: center;
|
||||
background-repeat: no-repeat;
|
||||
background-size: cover;
|
||||
border-radius: 4px;
|
||||
border: 0.5px solid rgba(0, 0, 0, 0.1);
|
||||
box-sizing: border-box;
|
||||
border-radius: 4px; }
|
||||
box-sizing: border-box; }
|
||||
|
||||
.ds-hero .ds-card {
|
||||
border: 0; }
|
||||
|
@ -1868,23 +1874,20 @@ main {
|
|||
color: #737373;
|
||||
margin: 18px 0;
|
||||
padding: 20px 0;
|
||||
border-top: 1px solid rgba(177, 177, 179, 0.36);
|
||||
border-bottom: 1px solid rgba(177, 177, 179, 0.36); }
|
||||
border-top: 1px solid var(--newtab-border-secondary-color);
|
||||
border-bottom: 1px solid var(--newtab-border-secondary-color); }
|
||||
.ds-hero .wrapper:hover .meta header {
|
||||
color: #0060DF; }
|
||||
.ds-hero .wrapper:active .meta header {
|
||||
color: #003EAA; }
|
||||
.ds-hero .wrapper .img-wrapper {
|
||||
width: 100%; }
|
||||
.ds-hero .wrapper .img {
|
||||
height: 0;
|
||||
padding-top: 50%;
|
||||
background-repeat: no-repeat;
|
||||
background-size: cover;
|
||||
background-color: #D7D7DB; }
|
||||
padding-top: 50%; }
|
||||
.ds-hero .wrapper .meta header {
|
||||
font-size: 22px;
|
||||
color: #0C0C0D; }
|
||||
.ds-hero .wrapper .meta header:hover {
|
||||
color: #0060DF; }
|
||||
.ds-hero .wrapper .meta header:active {
|
||||
color: #003EAA; }
|
||||
.ds-hero .wrapper .meta p {
|
||||
font-size: 13px; }
|
||||
.ds-hero .wrapper .meta p.context {
|
||||
|
@ -1955,8 +1958,15 @@ main {
|
|||
grid-template-columns: repeat(4, 1fr);
|
||||
grid-column-gap: 24px; }
|
||||
|
||||
.ds-hr {
|
||||
border: 0;
|
||||
height: 0;
|
||||
border-top: 1px solid var(--newtab-border-secondary-color); }
|
||||
|
||||
.ds-list-border {
|
||||
border: 1px solid rgba(177, 177, 179, 0.36);
|
||||
border: 0;
|
||||
border-top: 1px solid var(--newtab-border-secondary-color);
|
||||
padding-top: 1px;
|
||||
margin-block-start: 8px;
|
||||
margin-block-end: 8px; }
|
||||
|
||||
|
@ -2003,10 +2013,12 @@ main {
|
|||
width: 33px; }
|
||||
.ds-list-numbers .ds-list-item-link:hover::before {
|
||||
background-color: var(--newtab-link-primary-color); }
|
||||
.ds-list-numbers .ds-list-item-link:active::before {
|
||||
background-color: #003EAA; }
|
||||
|
||||
.ds-list-item:nth-child(-n+3) {
|
||||
border-bottom: 2px solid rgba(177, 177, 179, 0.36);
|
||||
margin-bottom: -2px;
|
||||
border-bottom: 1px solid var(--newtab-border-secondary-color);
|
||||
margin-bottom: -1px;
|
||||
padding-bottom: 2px; }
|
||||
|
||||
.ds-list-item {
|
||||
|
@ -2033,13 +2045,23 @@ main {
|
|||
display: flex;
|
||||
flex-direction: column; }
|
||||
.ds-list-item .ds-list-image {
|
||||
display: none;
|
||||
width: 72px;
|
||||
height: 72px;
|
||||
object-fit: cover;
|
||||
border: 0.5px solid rgba(0, 0, 0, 0.12);
|
||||
background-color: var(--newtab-card-placeholder-color);
|
||||
background-position: center;
|
||||
background-repeat: no-repeat;
|
||||
background-size: cover;
|
||||
border-radius: 4px;
|
||||
border: 0.5px solid rgba(0, 0, 0, 0.1);
|
||||
box-sizing: border-box;
|
||||
border-radius: 4px; }
|
||||
display: none;
|
||||
height: 72px;
|
||||
margin-inline-start: 13px;
|
||||
min-height: 72px;
|
||||
min-width: 72px;
|
||||
width: 72px; }
|
||||
.ds-list-item:hover .ds-list-item-title {
|
||||
color: var(--newtab-link-primary-color); }
|
||||
.ds-list-item:active .ds-list-item-title {
|
||||
color: #003EAA; }
|
||||
|
||||
.ds-navigation.ds-navigation-centered {
|
||||
text-align: center; }
|
||||
|
@ -2163,14 +2185,17 @@ main {
|
|||
.ds-card:active header {
|
||||
color: #003EAA; }
|
||||
.ds-card .img-wrapper {
|
||||
width: 100%;
|
||||
border: 0.5px solid rgba(0, 0, 0, 0.1);
|
||||
border-radius: 4px; }
|
||||
width: 100%; }
|
||||
.ds-card .img {
|
||||
height: 0;
|
||||
padding-top: 50%;
|
||||
background-color: var(--newtab-card-placeholder-color);
|
||||
background-position: center;
|
||||
background-repeat: no-repeat;
|
||||
background-size: cover; }
|
||||
background-size: cover;
|
||||
border-radius: 4px;
|
||||
border: 0.5px solid rgba(0, 0, 0, 0.1);
|
||||
box-sizing: border-box;
|
||||
height: 0;
|
||||
padding-top: 50%; }
|
||||
.ds-card .meta {
|
||||
padding: 16px; }
|
||||
.ds-card .meta .title {
|
||||
|
|
|
@ -64,6 +64,7 @@ body {
|
|||
--newtab-card-active-outline-color: #D7D7DB;
|
||||
--newtab-card-background-color: #FFF;
|
||||
--newtab-card-hairline-color: rgba(0, 0, 0, 0.1);
|
||||
--newtab-card-placeholder-color: #D7D7DB;
|
||||
--newtab-card-shadow: 0 1px 4px 0 rgba(12, 12, 13, 0.1);
|
||||
--newtab-snippets-background-color: #FFF;
|
||||
--newtab-snippets-hairline-color: transparent; }
|
||||
|
@ -107,6 +108,7 @@ body {
|
|||
--newtab-card-active-outline-color: #4A4A4F;
|
||||
--newtab-card-background-color: #38383D;
|
||||
--newtab-card-hairline-color: rgba(249, 249, 250, 0.1);
|
||||
--newtab-card-placeholder-color: #4A4A4F;
|
||||
--newtab-card-shadow: 0 1px 8px 0 rgba(12, 12, 13, 0.2);
|
||||
--newtab-snippets-background-color: #38383D;
|
||||
--newtab-snippets-hairline-color: rgba(255, 255, 255, 0.1); }
|
||||
|
@ -1066,10 +1068,10 @@ main {
|
|||
background-position-x: right 12px; }
|
||||
.search-handoff-button:hover {
|
||||
box-shadow: 0 1px 4px 0 rgba(12, 12, 13, 0.2), 0 0 0 1px rgba(0, 0, 0, 0.25); }
|
||||
.search-handoff-button:focus {
|
||||
.fake-focus .search-handoff-button {
|
||||
border: 1px solid var(--newtab-textbox-focus-color);
|
||||
box-shadow: var(--newtab-textbox-focus-boxshadow); }
|
||||
.search-handoff-button:focus .fake-caret {
|
||||
.fake-focus .search-handoff-button .fake-caret {
|
||||
display: block; }
|
||||
.search-hidden .search-handoff-button {
|
||||
opacity: 0;
|
||||
|
@ -1845,9 +1847,13 @@ main {
|
|||
grid-template-columns: repeat(3, 1fr); }
|
||||
|
||||
.ds-hero .img {
|
||||
background-color: var(--newtab-card-placeholder-color);
|
||||
background-position: center;
|
||||
background-repeat: no-repeat;
|
||||
background-size: cover;
|
||||
border-radius: 4px;
|
||||
border: 0.5px solid rgba(0, 0, 0, 0.1);
|
||||
box-sizing: border-box;
|
||||
border-radius: 4px; }
|
||||
box-sizing: border-box; }
|
||||
|
||||
.ds-hero .ds-card {
|
||||
border: 0; }
|
||||
|
@ -1865,23 +1871,20 @@ main {
|
|||
color: #737373;
|
||||
margin: 18px 0;
|
||||
padding: 20px 0;
|
||||
border-top: 1px solid rgba(177, 177, 179, 0.36);
|
||||
border-bottom: 1px solid rgba(177, 177, 179, 0.36); }
|
||||
border-top: 1px solid var(--newtab-border-secondary-color);
|
||||
border-bottom: 1px solid var(--newtab-border-secondary-color); }
|
||||
.ds-hero .wrapper:hover .meta header {
|
||||
color: #0060DF; }
|
||||
.ds-hero .wrapper:active .meta header {
|
||||
color: #003EAA; }
|
||||
.ds-hero .wrapper .img-wrapper {
|
||||
width: 100%; }
|
||||
.ds-hero .wrapper .img {
|
||||
height: 0;
|
||||
padding-top: 50%;
|
||||
background-repeat: no-repeat;
|
||||
background-size: cover;
|
||||
background-color: #D7D7DB; }
|
||||
padding-top: 50%; }
|
||||
.ds-hero .wrapper .meta header {
|
||||
font-size: 22px;
|
||||
color: #0C0C0D; }
|
||||
.ds-hero .wrapper .meta header:hover {
|
||||
color: #0060DF; }
|
||||
.ds-hero .wrapper .meta header:active {
|
||||
color: #003EAA; }
|
||||
.ds-hero .wrapper .meta p {
|
||||
font-size: 13px; }
|
||||
.ds-hero .wrapper .meta p.context {
|
||||
|
@ -1952,8 +1955,15 @@ main {
|
|||
grid-template-columns: repeat(4, 1fr);
|
||||
grid-column-gap: 24px; }
|
||||
|
||||
.ds-hr {
|
||||
border: 0;
|
||||
height: 0;
|
||||
border-top: 1px solid var(--newtab-border-secondary-color); }
|
||||
|
||||
.ds-list-border {
|
||||
border: 1px solid rgba(177, 177, 179, 0.36);
|
||||
border: 0;
|
||||
border-top: 1px solid var(--newtab-border-secondary-color);
|
||||
padding-top: 1px;
|
||||
margin-block-start: 8px;
|
||||
margin-block-end: 8px; }
|
||||
|
||||
|
@ -2000,10 +2010,12 @@ main {
|
|||
width: 33px; }
|
||||
.ds-list-numbers .ds-list-item-link:hover::before {
|
||||
background-color: var(--newtab-link-primary-color); }
|
||||
.ds-list-numbers .ds-list-item-link:active::before {
|
||||
background-color: #003EAA; }
|
||||
|
||||
.ds-list-item:nth-child(-n+3) {
|
||||
border-bottom: 2px solid rgba(177, 177, 179, 0.36);
|
||||
margin-bottom: -2px;
|
||||
border-bottom: 1px solid var(--newtab-border-secondary-color);
|
||||
margin-bottom: -1px;
|
||||
padding-bottom: 2px; }
|
||||
|
||||
.ds-list-item {
|
||||
|
@ -2030,13 +2042,23 @@ main {
|
|||
display: flex;
|
||||
flex-direction: column; }
|
||||
.ds-list-item .ds-list-image {
|
||||
display: none;
|
||||
width: 72px;
|
||||
height: 72px;
|
||||
object-fit: cover;
|
||||
border: 0.5px solid rgba(0, 0, 0, 0.12);
|
||||
background-color: var(--newtab-card-placeholder-color);
|
||||
background-position: center;
|
||||
background-repeat: no-repeat;
|
||||
background-size: cover;
|
||||
border-radius: 4px;
|
||||
border: 0.5px solid rgba(0, 0, 0, 0.1);
|
||||
box-sizing: border-box;
|
||||
border-radius: 4px; }
|
||||
display: none;
|
||||
height: 72px;
|
||||
margin-inline-start: 13px;
|
||||
min-height: 72px;
|
||||
min-width: 72px;
|
||||
width: 72px; }
|
||||
.ds-list-item:hover .ds-list-item-title {
|
||||
color: var(--newtab-link-primary-color); }
|
||||
.ds-list-item:active .ds-list-item-title {
|
||||
color: #003EAA; }
|
||||
|
||||
.ds-navigation.ds-navigation-centered {
|
||||
text-align: center; }
|
||||
|
@ -2160,14 +2182,17 @@ main {
|
|||
.ds-card:active header {
|
||||
color: #003EAA; }
|
||||
.ds-card .img-wrapper {
|
||||
width: 100%;
|
||||
border: 0.5px solid rgba(0, 0, 0, 0.1);
|
||||
border-radius: 4px; }
|
||||
width: 100%; }
|
||||
.ds-card .img {
|
||||
height: 0;
|
||||
padding-top: 50%;
|
||||
background-color: var(--newtab-card-placeholder-color);
|
||||
background-position: center;
|
||||
background-repeat: no-repeat;
|
||||
background-size: cover; }
|
||||
background-size: cover;
|
||||
border-radius: 4px;
|
||||
border: 0.5px solid rgba(0, 0, 0, 0.1);
|
||||
box-sizing: border-box;
|
||||
height: 0;
|
||||
padding-top: 50%; }
|
||||
.ds-card .meta {
|
||||
padding: 16px; }
|
||||
.ds-card .meta .title {
|
||||
|
|
|
@ -211,7 +211,7 @@ const globalImportContext = typeof Window === "undefined" ? BACKGROUND_PROCESS :
|
|||
// }
|
||||
const actionTypes = {};
|
||||
|
||||
for (const type of ["ADDONS_INFO_REQUEST", "ADDONS_INFO_RESPONSE", "ARCHIVE_FROM_POCKET", "AS_ROUTER_INITIALIZED", "AS_ROUTER_PREF_CHANGED", "AS_ROUTER_TELEMETRY_USER_EVENT", "BLOCK_URL", "BOOKMARK_URL", "COPY_DOWNLOAD_LINK", "DELETE_BOOKMARK_BY_ID", "DELETE_FROM_POCKET", "DELETE_HISTORY_URL", "DIALOG_CANCEL", "DIALOG_OPEN", "DISCOVERY_STREAM_CONFIG_CHANGE", "DISCOVERY_STREAM_CONFIG_SETUP", "DISCOVERY_STREAM_CONFIG_SET_VALUE", "DISCOVERY_STREAM_FEEDS_UPDATE", "DISCOVERY_STREAM_LAYOUT_RESET", "DISCOVERY_STREAM_LAYOUT_UPDATE", "DISCOVERY_STREAM_SPOCS_ENDPOINT", "DISCOVERY_STREAM_SPOCS_UPDATE", "DOWNLOAD_CHANGED", "FILL_SEARCH_TERM", "HANDOFF_SEARCH_TO_AWESOMEBAR", "HIDE_SEARCH", "INIT", "MIGRATION_CANCEL", "MIGRATION_COMPLETED", "MIGRATION_START", "NEW_TAB_INIT", "NEW_TAB_INITIAL_STATE", "NEW_TAB_LOAD", "NEW_TAB_REHYDRATED", "NEW_TAB_STATE_REQUEST", "NEW_TAB_UNLOAD", "OPEN_DOWNLOAD_FILE", "OPEN_LINK", "OPEN_NEW_WINDOW", "OPEN_PRIVATE_WINDOW", "OPEN_WEBEXT_SETTINGS", "PAGE_PRERENDERED", "PLACES_BOOKMARK_ADDED", "PLACES_BOOKMARK_REMOVED", "PLACES_HISTORY_CLEARED", "PLACES_LINKS_CHANGED", "PLACES_LINK_BLOCKED", "PLACES_LINK_DELETED", "PLACES_SAVED_TO_POCKET", "POCKET_CTA", "POCKET_LOGGED_IN", "POCKET_WAITING_FOR_SPOC", "PREFS_INITIAL_VALUES", "PREF_CHANGED", "PREVIEW_REQUEST", "PREVIEW_REQUEST_CANCEL", "PREVIEW_RESPONSE", "REMOVE_DOWNLOAD_FILE", "RICH_ICON_MISSING", "SAVE_SESSION_PERF_DATA", "SAVE_TO_POCKET", "SCREENSHOT_UPDATED", "SECTION_DEREGISTER", "SECTION_DISABLE", "SECTION_ENABLE", "SECTION_MOVE", "SECTION_OPTIONS_CHANGED", "SECTION_REGISTER", "SECTION_UPDATE", "SECTION_UPDATE_CARD", "SETTINGS_CLOSE", "SETTINGS_OPEN", "SET_PREF", "SHOW_DOWNLOAD_FILE", "SHOW_FIREFOX_ACCOUNTS", "SHOW_SEARCH", "SKIPPED_SIGNIN", "SNIPPETS_BLOCKLIST_CLEARED", "SNIPPETS_BLOCKLIST_UPDATED", "SNIPPETS_DATA", "SNIPPETS_PREVIEW_MODE", "SNIPPETS_RESET", "SNIPPET_BLOCKED", "SUBMIT_EMAIL", "SYSTEM_TICK", "TELEMETRY_IMPRESSION_STATS", "TELEMETRY_PERFORMANCE_EVENT", "TELEMETRY_UNDESIRED_EVENT", "TELEMETRY_USER_EVENT", "TOP_SITES_CANCEL_EDIT", "TOP_SITES_CLOSE_SEARCH_SHORTCUTS_MODAL", "TOP_SITES_EDIT", "TOP_SITES_INSERT", "TOP_SITES_OPEN_SEARCH_SHORTCUTS_MODAL", "TOP_SITES_PIN", "TOP_SITES_PREFS_UPDATED", "TOP_SITES_UNPIN", "TOP_SITES_UPDATED", "TOTAL_BOOKMARKS_REQUEST", "TOTAL_BOOKMARKS_RESPONSE", "UNINIT", "UPDATE_PINNED_SEARCH_SHORTCUTS", "UPDATE_SEARCH_SHORTCUTS", "UPDATE_SECTION_PREFS", "WEBEXT_CLICK", "WEBEXT_DISMISS"]) {
|
||||
for (const type of ["ADDONS_INFO_REQUEST", "ADDONS_INFO_RESPONSE", "ARCHIVE_FROM_POCKET", "AS_ROUTER_INITIALIZED", "AS_ROUTER_PREF_CHANGED", "AS_ROUTER_TELEMETRY_USER_EVENT", "BLOCK_URL", "BOOKMARK_URL", "COPY_DOWNLOAD_LINK", "DELETE_BOOKMARK_BY_ID", "DELETE_FROM_POCKET", "DELETE_HISTORY_URL", "DIALOG_CANCEL", "DIALOG_OPEN", "DISCOVERY_STREAM_CONFIG_CHANGE", "DISCOVERY_STREAM_CONFIG_SETUP", "DISCOVERY_STREAM_CONFIG_SET_VALUE", "DISCOVERY_STREAM_FEEDS_UPDATE", "DISCOVERY_STREAM_LAYOUT_RESET", "DISCOVERY_STREAM_LAYOUT_UPDATE", "DISCOVERY_STREAM_SPOCS_ENDPOINT", "DISCOVERY_STREAM_SPOCS_UPDATE", "DOWNLOAD_CHANGED", "FAKE_FOCUS_SEARCH", "FILL_SEARCH_TERM", "HANDOFF_SEARCH_TO_AWESOMEBAR", "HIDE_SEARCH", "INIT", "MIGRATION_CANCEL", "MIGRATION_COMPLETED", "MIGRATION_START", "NEW_TAB_INIT", "NEW_TAB_INITIAL_STATE", "NEW_TAB_LOAD", "NEW_TAB_REHYDRATED", "NEW_TAB_STATE_REQUEST", "NEW_TAB_UNLOAD", "OPEN_DOWNLOAD_FILE", "OPEN_LINK", "OPEN_NEW_WINDOW", "OPEN_PRIVATE_WINDOW", "OPEN_WEBEXT_SETTINGS", "PAGE_PRERENDERED", "PLACES_BOOKMARK_ADDED", "PLACES_BOOKMARK_REMOVED", "PLACES_HISTORY_CLEARED", "PLACES_LINKS_CHANGED", "PLACES_LINK_BLOCKED", "PLACES_LINK_DELETED", "PLACES_SAVED_TO_POCKET", "POCKET_CTA", "POCKET_LOGGED_IN", "POCKET_WAITING_FOR_SPOC", "PREFS_INITIAL_VALUES", "PREF_CHANGED", "PREVIEW_REQUEST", "PREVIEW_REQUEST_CANCEL", "PREVIEW_RESPONSE", "REMOVE_DOWNLOAD_FILE", "RICH_ICON_MISSING", "SAVE_SESSION_PERF_DATA", "SAVE_TO_POCKET", "SCREENSHOT_UPDATED", "SECTION_DEREGISTER", "SECTION_DISABLE", "SECTION_ENABLE", "SECTION_MOVE", "SECTION_OPTIONS_CHANGED", "SECTION_REGISTER", "SECTION_UPDATE", "SECTION_UPDATE_CARD", "SETTINGS_CLOSE", "SETTINGS_OPEN", "SET_PREF", "SHOW_DOWNLOAD_FILE", "SHOW_FIREFOX_ACCOUNTS", "SHOW_SEARCH", "SKIPPED_SIGNIN", "SNIPPETS_BLOCKLIST_CLEARED", "SNIPPETS_BLOCKLIST_UPDATED", "SNIPPETS_DATA", "SNIPPETS_PREVIEW_MODE", "SNIPPETS_RESET", "SNIPPET_BLOCKED", "SUBMIT_EMAIL", "SYSTEM_TICK", "TELEMETRY_IMPRESSION_STATS", "TELEMETRY_PERFORMANCE_EVENT", "TELEMETRY_UNDESIRED_EVENT", "TELEMETRY_USER_EVENT", "TOP_SITES_CANCEL_EDIT", "TOP_SITES_CLOSE_SEARCH_SHORTCUTS_MODAL", "TOP_SITES_EDIT", "TOP_SITES_INSERT", "TOP_SITES_OPEN_SEARCH_SHORTCUTS_MODAL", "TOP_SITES_PIN", "TOP_SITES_PREFS_UPDATED", "TOP_SITES_UNPIN", "TOP_SITES_UPDATED", "TOTAL_BOOKMARKS_REQUEST", "TOTAL_BOOKMARKS_RESPONSE", "UNINIT", "UPDATE_PINNED_SEARCH_SHORTCUTS", "UPDATE_SEARCH_SHORTCUTS", "UPDATE_SECTION_PREFS", "WEBEXT_CLICK", "WEBEXT_DISMISS"]) {
|
||||
actionTypes[type] = type;
|
||||
}
|
||||
|
||||
|
@ -1107,6 +1107,8 @@ class ASRouterUISurface extends react__WEBPACK_IMPORTED_MODULE_7___default.a.Pur
|
|||
case "CLEAR_MESSAGE":
|
||||
if (action.data.id === this.state.message.id) {
|
||||
this.setState({ message: {} });
|
||||
// Remove any styles related to the RTAMO message
|
||||
document.body.classList.remove("welcome", "hide-main", "amo");
|
||||
}
|
||||
break;
|
||||
case "CLEAR_PROVIDER":
|
||||
|
@ -1766,8 +1768,6 @@ class ReturnToAMO extends react__WEBPACK_IMPORTED_MODULE_0___default.a.PureCompo
|
|||
|
||||
onClickAddExtension() {
|
||||
this.props.onAction(this.props.content.primary_button.action);
|
||||
this.props.onBlock();
|
||||
document.body.classList.remove("welcome", "hide-main", "amo");
|
||||
}
|
||||
|
||||
onBlockButton() {
|
||||
|
@ -6236,7 +6236,7 @@ var PrerenderData = new _PrerenderData({
|
|||
|
||||
"use strict";
|
||||
__webpack_require__.r(__webpack_exports__);
|
||||
/* WEBPACK VAR INJECTION */(function(global) {/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "_Search", function() { return _Search; });
|
||||
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "_Search", function() { return _Search; });
|
||||
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Search", function() { return Search; });
|
||||
/* harmony import */ var common_Actions_jsm__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(2);
|
||||
/* harmony import */ var react_intl__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(5);
|
||||
|
@ -6260,11 +6260,10 @@ class _Search extends react__WEBPACK_IMPORTED_MODULE_4___default.a.PureComponent
|
|||
super(props);
|
||||
this.onSearchClick = this.onSearchClick.bind(this);
|
||||
this.onSearchHandoffClick = this.onSearchHandoffClick.bind(this);
|
||||
this.onSearchHandoffKeyDown = this.onSearchHandoffKeyDown.bind(this);
|
||||
this.onSearchHandoffPaste = this.onSearchHandoffPaste.bind(this);
|
||||
this.onSearchHandoffDrop = this.onSearchHandoffDrop.bind(this);
|
||||
this.onInputMount = this.onInputMount.bind(this);
|
||||
this.onSearchHandoffButtonMount = this.onSearchHandoffButtonMount.bind(this);
|
||||
this.cancelEvent = this.cancelEvent.bind(this);
|
||||
}
|
||||
|
||||
handleEvent(event) {
|
||||
|
@ -6280,63 +6279,36 @@ class _Search extends react__WEBPACK_IMPORTED_MODULE_4___default.a.PureComponent
|
|||
|
||||
doSearchHandoff(text) {
|
||||
this.props.dispatch(common_Actions_jsm__WEBPACK_IMPORTED_MODULE_0__["actionCreators"].OnlyToMain({ type: common_Actions_jsm__WEBPACK_IMPORTED_MODULE_0__["actionTypes"].HANDOFF_SEARCH_TO_AWESOMEBAR, data: { text } }));
|
||||
this.props.dispatch({ type: common_Actions_jsm__WEBPACK_IMPORTED_MODULE_0__["actionTypes"].FAKE_FOCUS_SEARCH });
|
||||
this.props.dispatch(common_Actions_jsm__WEBPACK_IMPORTED_MODULE_0__["actionCreators"].UserEvent({ event: "SEARCH_HANDOFF" }));
|
||||
if (text) {
|
||||
// We don't hide the in-content search if there is no text (user hit <Enter>)
|
||||
this.props.dispatch({ type: common_Actions_jsm__WEBPACK_IMPORTED_MODULE_0__["actionTypes"].HIDE_SEARCH });
|
||||
}
|
||||
}
|
||||
|
||||
onSearchHandoffClick(event) {
|
||||
// When search hand-off is enabled, we render a big button that is styled to
|
||||
// look like a search textbox. If the button is clicked with the mouse, we
|
||||
// focus it. If the user types, transfer focus to awesomebar.
|
||||
// If the button is clicked from the keyboard, we focus the awesomebar normally.
|
||||
// This is to minimize confusion with users navigating with the keyboard and
|
||||
// users using assistive technologoy.
|
||||
// look like a search textbox. If the button is clicked, we style
|
||||
// the button as if it was a focused search box and show a fake cursor but
|
||||
// really focus the awesomebar without the focus styles ("hidden focus").
|
||||
event.preventDefault();
|
||||
const isKeyboardClick = event.clientX === 0 && event.clientY === 0;
|
||||
if (isKeyboardClick) {
|
||||
this.doSearchHandoff();
|
||||
} else {
|
||||
this._searchHandoffButton.focus();
|
||||
}
|
||||
}
|
||||
|
||||
onSearchHandoffKeyDown(event) {
|
||||
if (event.key.length === 1 && !event.altKey && !event.ctrlKey && !event.metaKey) {
|
||||
// We only care about key strokes that will produce a character.
|
||||
this.doSearchHandoff(event.key);
|
||||
}
|
||||
this.doSearchHandoff();
|
||||
}
|
||||
|
||||
onSearchHandoffPaste(event) {
|
||||
if (!this._searchHandoffButton || !this._searchHandoffButton.contains(global.document.activeElement)) {
|
||||
// Don't handle every paste on the document. Filter out those that are
|
||||
// not on the Search Hand-off button.
|
||||
return;
|
||||
}
|
||||
event.preventDefault();
|
||||
this.doSearchHandoff(event.clipboardData.getData("Text"));
|
||||
}
|
||||
|
||||
cancelEvent(event) {
|
||||
onSearchHandoffDrop(event) {
|
||||
event.preventDefault();
|
||||
}
|
||||
|
||||
componentWillMount() {
|
||||
if (global.document) {
|
||||
// We need to listen to paste events that bubble up from the Search Hand-off
|
||||
// button. Adding the paste listener to the button itself or it's parent
|
||||
// doesn't work consistently until the page is clicked on.
|
||||
global.document.addEventListener("paste", this.onSearchHandoffPaste);
|
||||
let text = event.dataTransfer.getData("text");
|
||||
if (text) {
|
||||
this.doSearchHandoff(text);
|
||||
}
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
if (global.document) {
|
||||
global.document.removeEventListener("paste", this.onDocumentPaste);
|
||||
}
|
||||
delete window.gContentSearchController;
|
||||
}
|
||||
|
||||
|
@ -6378,7 +6350,7 @@ class _Search extends react__WEBPACK_IMPORTED_MODULE_4___default.a.PureComponent
|
|||
* in order to execute searches in various tests
|
||||
*/
|
||||
render() {
|
||||
const wrapperClassName = ["search-wrapper", this.props.hide && "search-hidden"].filter(v => v).join(" ");
|
||||
const wrapperClassName = ["search-wrapper", this.props.hide && "search-hidden", this.props.fakeFocus && "fake-focus"].filter(v => v).join(" ");
|
||||
|
||||
return react__WEBPACK_IMPORTED_MODULE_4___default.a.createElement(
|
||||
"div",
|
||||
|
@ -6431,14 +6403,14 @@ class _Search extends react__WEBPACK_IMPORTED_MODULE_4___default.a.PureComponent
|
|||
className: "search-handoff-button",
|
||||
ref: this.onSearchHandoffButtonMount,
|
||||
onClick: this.onSearchHandoffClick,
|
||||
onKeyDown: this.onSearchHandoffKeyDown,
|
||||
tabIndex: "-1",
|
||||
title: this.props.intl.formatMessage({ id: "search_web_placeholder" }) },
|
||||
react__WEBPACK_IMPORTED_MODULE_4___default.a.createElement(
|
||||
"div",
|
||||
{ className: "fake-textbox" },
|
||||
this.props.intl.formatMessage({ id: "search_web_placeholder" })
|
||||
),
|
||||
react__WEBPACK_IMPORTED_MODULE_4___default.a.createElement("div", { className: "fake-editable", tabIndex: "-1", "aria-hidden": "true", contentEditable: "", onDrop: this.cancelEvent }),
|
||||
react__WEBPACK_IMPORTED_MODULE_4___default.a.createElement("div", { className: "fake-editable", tabIndex: "-1", "aria-hidden": "true", contentEditable: "", onDrop: this.onSearchHandoffDrop, onPaste: this.onSearchHandoffPaste }),
|
||||
react__WEBPACK_IMPORTED_MODULE_4___default.a.createElement("div", { className: "fake-caret" })
|
||||
),
|
||||
react__WEBPACK_IMPORTED_MODULE_4___default.a.createElement("input", {
|
||||
|
@ -6451,7 +6423,6 @@ class _Search extends react__WEBPACK_IMPORTED_MODULE_4___default.a.PureComponent
|
|||
}
|
||||
|
||||
const Search = Object(react_redux__WEBPACK_IMPORTED_MODULE_2__["connect"])()(Object(react_intl__WEBPACK_IMPORTED_MODULE_1__["injectIntl"])(_Search));
|
||||
/* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(1)))
|
||||
|
||||
/***/ }),
|
||||
/* 47 */
|
||||
|
@ -7276,7 +7247,7 @@ Hero_Hero.defaultProps = {
|
|||
|
||||
class HorizontalRule_HorizontalRule extends external_React_default.a.PureComponent {
|
||||
render() {
|
||||
return external_React_default.a.createElement("hr", null);
|
||||
return external_React_default.a.createElement("hr", { className: "ds-hr" });
|
||||
}
|
||||
}
|
||||
// EXTERNAL MODULE: ./content-src/components/DiscoveryStreamImpressionStats/ImpressionStats.jsx
|
||||
|
@ -7338,10 +7309,10 @@ class List_ListItem extends external_React_default.a.PureComponent {
|
|||
external_React_default.a.createElement(
|
||||
"div",
|
||||
{ className: "ds-list-item-info" },
|
||||
`${this.props.domain} · TODO:Topic`
|
||||
this.props.domain
|
||||
)
|
||||
),
|
||||
external_React_default.a.createElement("img", { className: "ds-list-image", src: this.props.image_src })
|
||||
external_React_default.a.createElement("div", { className: "ds-list-image", style: { backgroundImage: `url(${this.props.image_src})` } })
|
||||
)
|
||||
);
|
||||
}
|
||||
|
@ -7756,6 +7727,14 @@ class DiscoveryStreamBase_DiscoveryStreamBase extends external_React_default.a.P
|
|||
|
||||
renderComponent(component) {
|
||||
let rows;
|
||||
const { spocs } = this.props.DiscoveryStream;
|
||||
|
||||
// TODO: Can we make this a bit better visually while it loads?
|
||||
// If this component expects spocs,
|
||||
// wait until spocs are loaded before attempting to use it.
|
||||
if (component.spocs && !spocs.loaded) {
|
||||
return null;
|
||||
}
|
||||
|
||||
switch (component.type) {
|
||||
case "TopSites":
|
||||
|
@ -11365,12 +11344,16 @@ const INITIAL_STATE = {
|
|||
spocs: {
|
||||
spocs_endpoint: "",
|
||||
lastUpdated: null,
|
||||
data: {} // {spocs: []}
|
||||
data: {}, // {spocs: []}
|
||||
loaded: false
|
||||
}
|
||||
},
|
||||
Search: {
|
||||
// Pretend the search box is focused after handing off to AwesomeBar.
|
||||
focus: false,
|
||||
// When search hand-off is enabled, we render a big button that is styled to
|
||||
// look like a search textbox. If the button is clicked, we style
|
||||
// the button as if it was a focused search box and show a fake cursor but
|
||||
// really focus the awesomebar without the focus styles ("hidden focus").
|
||||
fakeFocus: false,
|
||||
// Hide the search box after handing off to AwesomeBar and user starts typing.
|
||||
hide: false
|
||||
}
|
||||
|
@ -11780,7 +11763,8 @@ function DiscoveryStream(prevState = INITIAL_STATE.DiscoveryStream, action) {
|
|||
return Object.assign({}, prevState, {
|
||||
spocs: Object.assign({}, prevState.spocs, {
|
||||
lastUpdated: action.data.lastUpdated,
|
||||
data: action.data.spocs
|
||||
data: action.data.spocs,
|
||||
loaded: true
|
||||
})
|
||||
});
|
||||
}
|
||||
|
@ -11794,8 +11778,10 @@ function Search(prevState = INITIAL_STATE.Search, action) {
|
|||
switch (action.type) {
|
||||
case Actions["actionTypes"].HIDE_SEARCH:
|
||||
return Object.assign(Object.assign({}, prevState, { hide: true }));
|
||||
case Actions["actionTypes"].FAKE_FOCUS_SEARCH:
|
||||
return Object.assign(Object.assign({}, prevState, { fakeFocus: true }));
|
||||
case Actions["actionTypes"].SHOW_SEARCH:
|
||||
return Object.assign(Object.assign({}, prevState, { hide: false }));
|
||||
return Object.assign(Object.assign({}, prevState, { hide: false, fakeFocus: false }));
|
||||
default:
|
||||
return prevState;
|
||||
}
|
||||
|
|
|
@ -253,7 +253,9 @@ const MessageLoaderUtils = {
|
|||
null, null, null, null, amTelemetryInfo);
|
||||
await AddonManager.installAddonFromWebpage("application/x-xpinstall", browser,
|
||||
systemPrincipal, install);
|
||||
} catch (e) {}
|
||||
} catch (e) {
|
||||
Cu.reportError(e);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
|
@ -906,6 +908,16 @@ class _ASRouter {
|
|||
}
|
||||
}
|
||||
|
||||
// Ensure we switch to the Onboarding message after RTAMO addon was installed
|
||||
_updateOnboardingState() {
|
||||
let addonInstallObs = (subject, topic) => {
|
||||
Services.obs.removeObserver(addonInstallObs, "webextension-install-notify");
|
||||
this.messageChannel.sendAsyncMessage(OUTGOING_MESSAGE_NAME, {type: "CLEAR_MESSAGE", data: {id: "RETURN_TO_AMO_1"}});
|
||||
this.blockMessageById("RETURN_TO_AMO_1");
|
||||
};
|
||||
Services.obs.addObserver(addonInstallObs, "webextension-install-notify");
|
||||
}
|
||||
|
||||
_loadSnippetsWhitelistHosts() {
|
||||
let additionalHosts = [];
|
||||
const whitelistPrefValue = Services.prefs.getStringPref(SNIPPETS_ENDPOINT_WHITELIST, "");
|
||||
|
@ -1025,6 +1037,7 @@ class _ASRouter {
|
|||
UITour.showMenu(target.browser.ownerGlobal, action.data.args);
|
||||
break;
|
||||
case ra.INSTALL_ADDON_FROM_URL:
|
||||
this._updateOnboardingState();
|
||||
await MessageLoaderUtils.installAddonFromURL(target.browser, action.data.url);
|
||||
break;
|
||||
case ra.SHOW_FIREFOX_ACCOUNTS:
|
||||
|
|
|
@ -218,7 +218,7 @@ const PREFS_CONFIG = new Map([
|
|||
value: JSON.stringify({
|
||||
enabled: false,
|
||||
// This is currently an exmple layout used for dev purposes.
|
||||
layout_endpoint: "https://getpocket.com/v3/newtab/layout?version=1&consumer_key=40249-e88c401e1b1f2242d9e441c4&layout_variant=control",
|
||||
layout_endpoint: "https://getpocket.com/v3/newtab/layout?version=1&consumer_key=40249-e88c401e1b1f2242d9e441c4&layout_variant=basic",
|
||||
}),
|
||||
}],
|
||||
]);
|
||||
|
|
|
@ -168,6 +168,8 @@ this.DiscoveryStreamFeed = class DiscoveryStreamFeed {
|
|||
await this.cache.set("spocs", spocs);
|
||||
} else {
|
||||
Cu.reportError("No response for spocs_endpoint prop");
|
||||
// Use old data if we have it, otherwise nothing.
|
||||
spocs = spocs || {};
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -283,34 +283,69 @@ class PlacesFeed {
|
|||
_target.browser.ownerGlobal.gURLBar.search(`${data.label} `);
|
||||
}
|
||||
|
||||
handoffSearchToAwesomebar({_target, data, meta}) {
|
||||
const urlBar = _target.browser.ownerGlobal.gURLBar;
|
||||
_getSearchPrefix() {
|
||||
const searchAliases = Services.search.defaultEngine.wrappedJSObject.__internalAliases;
|
||||
if (searchAliases && searchAliases.length > 0) {
|
||||
return `${searchAliases[0]} `;
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
if (!data.text) {
|
||||
// Do a normal focus of awesomebar.
|
||||
urlBar.focus();
|
||||
// We are done here. return early.
|
||||
return;
|
||||
handoffSearchToAwesomebar({_target, data, meta}) {
|
||||
const searchAlias = this._getSearchPrefix();
|
||||
const urlBar = _target.browser.ownerGlobal.gURLBar;
|
||||
let isFirstChange = true;
|
||||
|
||||
if (!data || !data.text) {
|
||||
urlBar.setHiddenFocus();
|
||||
} else {
|
||||
// Pass the provided text to the awesomebar. Prepend the @engine shortcut.
|
||||
urlBar.search(`${searchAlias}${data.text}`);
|
||||
isFirstChange = false;
|
||||
}
|
||||
|
||||
// Pass the provided text to the awesomebar.
|
||||
urlBar.search(data.text);
|
||||
|
||||
const onDone = () => {
|
||||
// When done, let's cleanup everything.
|
||||
this.store.dispatch(ac.OnlyToOneContent({type: at.SHOW_SEARCH}, meta.fromTarget));
|
||||
urlBar.removeEventListener("mousedown", onDone);
|
||||
urlBar.removeEventListener("blur", onDone);
|
||||
};
|
||||
const onKeydown = event => {
|
||||
// If the Esc button is pressed, we are done. Show in-content search and cleanup.
|
||||
if (event.key === "Escape") {
|
||||
onDone();
|
||||
const checkFirstChange = () => {
|
||||
// Check if this is the first change since we hidden focused. If it is,
|
||||
// remove hidden focus styles, prepend the search alias and hide the
|
||||
// in-content search.
|
||||
if (isFirstChange) {
|
||||
isFirstChange = false;
|
||||
urlBar.removeHiddenFocus();
|
||||
urlBar.search(searchAlias);
|
||||
this.store.dispatch(ac.OnlyToOneContent({type: at.HIDE_SEARCH}, meta.fromTarget));
|
||||
urlBar.removeEventListener("compositionstart", checkFirstChange);
|
||||
urlBar.removeEventListener("paste", checkFirstChange);
|
||||
}
|
||||
};
|
||||
|
||||
const onKeydown = ev => {
|
||||
// Check if the keydown will cause a value change.
|
||||
if (ev.key.length === 1 && !ev.altKey && !ev.ctrlKey && !ev.metaKey) {
|
||||
checkFirstChange();
|
||||
}
|
||||
// If the Esc button is pressed, we are done. Show in-content search and cleanup.
|
||||
if (ev.key === "Escape") {
|
||||
onDone(); // eslint-disable-line no-use-before-define
|
||||
}
|
||||
};
|
||||
|
||||
const onDone = () => {
|
||||
// We are done. Show in-content search again and cleanup.
|
||||
this.store.dispatch(ac.OnlyToOneContent({type: at.SHOW_SEARCH}, meta.fromTarget));
|
||||
urlBar.removeHiddenFocus();
|
||||
|
||||
urlBar.removeEventListener("keydown", onKeydown);
|
||||
urlBar.removeEventListener("mousedown", onDone);
|
||||
urlBar.removeEventListener("blur", onDone);
|
||||
urlBar.removeEventListener("compositionstart", checkFirstChange);
|
||||
urlBar.removeEventListener("paste", checkFirstChange);
|
||||
};
|
||||
|
||||
urlBar.addEventListener("keydown", onKeydown);
|
||||
urlBar.addEventListener("mousedown", onDone);
|
||||
urlBar.addEventListener("blur", onDone);
|
||||
urlBar.addEventListener("compositionstart", checkFirstChange);
|
||||
urlBar.addEventListener("paste", checkFirstChange);
|
||||
}
|
||||
|
||||
onAction(action) {
|
||||
|
|
|
@ -93,6 +93,8 @@ prefs_home_header=Obsah domovské stránky Firefoxu
|
|||
prefs_home_description=Vyberte obsah, který chcete mít na výchozí domovské stránce Firefoxu.
|
||||
|
||||
prefs_content_discovery_header=Domovská stránka Firefoxu
|
||||
prefs_content_discovery_description=Doporučování obsahu na domovské stránce obsahu vám nabídne kvalitní a relevantní články z celého internetu.
|
||||
prefs_content_discovery_button=Vypnout doporučování obsahu
|
||||
|
||||
# LOCALIZATION NOTE (prefs_section_rows_option): This is a semi-colon list of
|
||||
# plural forms used in a drop down of multiple row options (1 row, 2 rows).
|
||||
|
|
|
@ -91,6 +91,10 @@ section_disclaimer_topstories_buttontext=Εντάξει, το 'πιασα
|
|||
# what is shown for the homepage, new windows, and new tabs.
|
||||
prefs_home_header=Περιεχόμενο αρχικής σελίδας Firefox
|
||||
prefs_home_description=Επιλέξτε τι περιεχόμενο θέλετε στην αρχική σελίδα του Firefox σας.
|
||||
|
||||
prefs_content_discovery_header=Αρχική Firefox
|
||||
prefs_content_discovery_button=Απενεργοποίηση ανακάλυψης περιεχομένου
|
||||
|
||||
# LOCALIZATION NOTE (prefs_section_rows_option): This is a semi-colon list of
|
||||
# plural forms used in a drop down of multiple row options (1 row, 2 rows).
|
||||
# See: http://developer.mozilla.org/en/docs/Localization_and_Plurals
|
||||
|
|
|
@ -91,6 +91,9 @@ section_disclaimer_topstories_buttontext=알겠습니다.
|
|||
# what is shown for the homepage, new windows, and new tabs.
|
||||
prefs_home_header=Firefox 홈 콘텐츠
|
||||
prefs_home_description=Firefox 홈 화면에 나올 콘텐츠를 선택하세요.
|
||||
|
||||
prefs_content_discovery_header=Firefox 홈
|
||||
|
||||
# LOCALIZATION NOTE (prefs_section_rows_option): This is a semi-colon list of
|
||||
# plural forms used in a drop down of multiple row options (1 row, 2 rows).
|
||||
# See: http://developer.mozilla.org/en/docs/Localization_and_Plurals
|
||||
|
@ -144,7 +147,6 @@ pocket_read_more=인기 주제:
|
|||
# end of the list of popular topic links.
|
||||
pocket_read_even_more=더 많은 이야기 보기
|
||||
pocket_more_reccommendations=더 많은 추천
|
||||
pocket_learn_more=자세히 보기
|
||||
pocket_how_it_works=사용 방법
|
||||
pocket_cta_button=Pocket 받기
|
||||
pocket_cta_text=좋아하는 이야기를 Pocket에 저장하고 재미있게 읽어 보세요.
|
||||
|
|
|
@ -73,7 +73,7 @@ search_header=Pesquisa {search_engine_name}
|
|||
|
||||
# LOCALIZATION NOTE (search_web_placeholder): This is shown in the searchbox when
|
||||
# the user hasn't typed anything yet.
|
||||
search_web_placeholder=Pesquisar na Web
|
||||
search_web_placeholder=Pesquisar na web
|
||||
|
||||
# LOCALIZATION NOTE (section_disclaimer_topstories): This is shown below
|
||||
# the topstories section title to provide additional information about
|
||||
|
|
|
@ -91,6 +91,11 @@ section_disclaimer_topstories_buttontext=Ok, chapì
|
|||
# what is shown for the homepage, new windows, and new tabs.
|
||||
prefs_home_header=Cuntegn da la pagina da partenza da Firefox
|
||||
prefs_home_description=Tscherna il cuntegn che ti vuls vesair sin la pagina da partenza da Firefox.
|
||||
|
||||
prefs_content_discovery_header=Pagina da partenza da Firefox
|
||||
prefs_content_discovery_description=La vitrina da cuntegn pussibilitescha da scuvrir artitgels relevants da gronda qualitad en il web.
|
||||
prefs_content_discovery_button=Deactivar la vitrina da cuntegn
|
||||
|
||||
# LOCALIZATION NOTE (prefs_section_rows_option): This is a semi-colon list of
|
||||
# plural forms used in a drop down of multiple row options (1 row, 2 rows).
|
||||
# See: http://developer.mozilla.org/en/docs/Localization_and_Plurals
|
||||
|
@ -144,7 +149,6 @@ pocket_read_more=Temas populars:
|
|||
# end of the list of popular topic links.
|
||||
pocket_read_even_more=Mussar dapli artitgels
|
||||
pocket_more_reccommendations=Dapli propostas
|
||||
pocket_learn_more=Ulteriuras infurmaziuns
|
||||
pocket_how_it_works=Co ch'i funcziuna
|
||||
pocket_cta_button=Obtegnair Pocket
|
||||
pocket_cta_text=Memorisescha ils artitgels che ta plaschan en Pocket e procura per inspiraziun cuntinuanta cun lectura fascinanta.
|
||||
|
|
|
@ -91,6 +91,11 @@ section_disclaimer_topstories_buttontext=Tamam, anladım
|
|||
# what is shown for the homepage, new windows, and new tabs.
|
||||
prefs_home_header=Firefox giriş sayfası içeriği
|
||||
prefs_home_description=Firefox giriş sayfasında görmek istediğiniz içerikleri seçin.
|
||||
|
||||
prefs_content_discovery_header=Firefox Başlangıç
|
||||
prefs_content_discovery_description=Firefox giriş sayfasındaki içerik keşfi özelliği, internetteki kaliteli ve ilginizi çekebilecek yazıları keşfetmenizi sağlar.
|
||||
prefs_content_discovery_button=İçerik keşfini kapat
|
||||
|
||||
# LOCALIZATION NOTE (prefs_section_rows_option): This is a semi-colon list of
|
||||
# plural forms used in a drop down of multiple row options (1 row, 2 rows).
|
||||
# See: http://developer.mozilla.org/en/docs/Localization_and_Plurals
|
||||
|
@ -144,7 +149,6 @@ pocket_read_more=Popüler konular:
|
|||
# end of the list of popular topic links.
|
||||
pocket_read_even_more=Daha fazla yazı göster
|
||||
pocket_more_reccommendations=Daha fazla öneri
|
||||
pocket_learn_more=Daha fazla bilgi al
|
||||
pocket_how_it_works=Nasıl çalışıyor?
|
||||
pocket_cta_button=Pocket’ı edinin
|
||||
pocket_cta_text=Sevdiğiniz yazıları Pocket’a kaydedin, aklınız okumaya değer şeylerle doldurun.
|
||||
|
|
|
@ -41,8 +41,8 @@ window.gActivityStreamStrings = {
|
|||
"prefs_home_header": "Obsah domovské stránky Firefoxu",
|
||||
"prefs_home_description": "Vyberte obsah, který chcete mít na výchozí domovské stránce Firefoxu.",
|
||||
"prefs_content_discovery_header": "Domovská stránka Firefoxu",
|
||||
"prefs_content_discovery_description": "Content Discovery in Firefox Home allows you to discover high-quality, relevant articles from across the web.",
|
||||
"prefs_content_discovery_button": "Turn Off Content Discovery",
|
||||
"prefs_content_discovery_description": "Doporučování obsahu na domovské stránce obsahu vám nabídne kvalitní a relevantní články z celého internetu.",
|
||||
"prefs_content_discovery_button": "Vypnout doporučování obsahu",
|
||||
"prefs_section_rows_option": "{num} řádek;{num} řádky;{num} řádků",
|
||||
"prefs_search_header": "Vyhledávání na webu",
|
||||
"prefs_topsites_description": "Nejnavštěvovanější stránky",
|
||||
|
|
|
@ -40,9 +40,9 @@ window.gActivityStreamStrings = {
|
|||
"section_disclaimer_topstories_buttontext": "Εντάξει, το 'πιασα",
|
||||
"prefs_home_header": "Περιεχόμενο αρχικής σελίδας Firefox",
|
||||
"prefs_home_description": "Επιλέξτε τι περιεχόμενο θέλετε στην αρχική σελίδα του Firefox σας.",
|
||||
"prefs_content_discovery_header": "Firefox Home",
|
||||
"prefs_content_discovery_header": "Αρχική Firefox",
|
||||
"prefs_content_discovery_description": "Content Discovery in Firefox Home allows you to discover high-quality, relevant articles from across the web.",
|
||||
"prefs_content_discovery_button": "Turn Off Content Discovery",
|
||||
"prefs_content_discovery_button": "Απενεργοποίηση ανακάλυψης περιεχομένου",
|
||||
"prefs_section_rows_option": "{num} σειρά;{num} σειρές",
|
||||
"prefs_search_header": "Διαδικτυακή αναζήτηση",
|
||||
"prefs_topsites_description": "Οι ιστοσελίδες που επισκέπτεστε περισσότερο",
|
||||
|
|
|
@ -40,7 +40,7 @@ window.gActivityStreamStrings = {
|
|||
"section_disclaimer_topstories_buttontext": "알겠습니다.",
|
||||
"prefs_home_header": "Firefox 홈 콘텐츠",
|
||||
"prefs_home_description": "Firefox 홈 화면에 나올 콘텐츠를 선택하세요.",
|
||||
"prefs_content_discovery_header": "Firefox Home",
|
||||
"prefs_content_discovery_header": "Firefox 홈",
|
||||
"prefs_content_discovery_description": "Content Discovery in Firefox Home allows you to discover high-quality, relevant articles from across the web.",
|
||||
"prefs_content_discovery_button": "Turn Off Content Discovery",
|
||||
"prefs_section_rows_option": "{num} 행",
|
||||
|
@ -110,6 +110,5 @@ window.gActivityStreamStrings = {
|
|||
"firstrun_privacy_notice": "개인 정보 보호 정책",
|
||||
"firstrun_continue_to_login": "계속",
|
||||
"firstrun_skip_login": "단계 건너뛰기",
|
||||
"context_menu_title": "메뉴 열기",
|
||||
"pocket_learn_more": "자세히 보기"
|
||||
"context_menu_title": "메뉴 열기"
|
||||
};
|
||||
|
|
|
@ -34,7 +34,7 @@ window.gActivityStreamStrings = {
|
|||
"menu_action_remove_download": "Remover do histórico",
|
||||
"search_button": "Pesquisar",
|
||||
"search_header": "Pesquisa {search_engine_name}",
|
||||
"search_web_placeholder": "Pesquisar na Web",
|
||||
"search_web_placeholder": "Pesquisar na web",
|
||||
"section_disclaimer_topstories": "As histórias mais interessantes na web, selecionadas baseadas no que você lê. Do Pocket, agora parte da Mozilla.",
|
||||
"section_disclaimer_topstories_linktext": "Saiba como funciona.",
|
||||
"section_disclaimer_topstories_buttontext": "Ok, entendi",
|
||||
|
|
|
@ -40,9 +40,9 @@ window.gActivityStreamStrings = {
|
|||
"section_disclaimer_topstories_buttontext": "Ok, chapì",
|
||||
"prefs_home_header": "Cuntegn da la pagina da partenza da Firefox",
|
||||
"prefs_home_description": "Tscherna il cuntegn che ti vuls vesair sin la pagina da partenza da Firefox.",
|
||||
"prefs_content_discovery_header": "Firefox Home",
|
||||
"prefs_content_discovery_description": "Content Discovery in Firefox Home allows you to discover high-quality, relevant articles from across the web.",
|
||||
"prefs_content_discovery_button": "Turn Off Content Discovery",
|
||||
"prefs_content_discovery_header": "Pagina da partenza da Firefox",
|
||||
"prefs_content_discovery_description": "La vitrina da cuntegn pussibilitescha da scuvrir artitgels relevants da gronda qualitad en il web.",
|
||||
"prefs_content_discovery_button": "Deactivar la vitrina da cuntegn",
|
||||
"prefs_section_rows_option": "{num} lingia;{num} lingias",
|
||||
"prefs_search_header": "Tschertga web",
|
||||
"prefs_topsites_description": "Las paginas che ti visitas il pli savens",
|
||||
|
@ -110,6 +110,5 @@ window.gActivityStreamStrings = {
|
|||
"firstrun_privacy_notice": "Infurmaziuns davart la protecziun da datas",
|
||||
"firstrun_continue_to_login": "Cuntinuar",
|
||||
"firstrun_skip_login": "Sursiglir quest pass",
|
||||
"context_menu_title": "Avrir il menu",
|
||||
"pocket_learn_more": "Ulteriuras infurmaziuns"
|
||||
"context_menu_title": "Avrir il menu"
|
||||
};
|
||||
|
|
|
@ -40,9 +40,9 @@ window.gActivityStreamStrings = {
|
|||
"section_disclaimer_topstories_buttontext": "Tamam, anladım",
|
||||
"prefs_home_header": "Firefox giriş sayfası içeriği",
|
||||
"prefs_home_description": "Firefox giriş sayfasında görmek istediğiniz içerikleri seçin.",
|
||||
"prefs_content_discovery_header": "Firefox Home",
|
||||
"prefs_content_discovery_description": "Content Discovery in Firefox Home allows you to discover high-quality, relevant articles from across the web.",
|
||||
"prefs_content_discovery_button": "Turn Off Content Discovery",
|
||||
"prefs_content_discovery_header": "Firefox Başlangıç",
|
||||
"prefs_content_discovery_description": "Firefox giriş sayfasındaki içerik keşfi özelliği, internetteki kaliteli ve ilginizi çekebilecek yazıları keşfetmenizi sağlar.",
|
||||
"prefs_content_discovery_button": "İçerik keşfini kapat",
|
||||
"prefs_section_rows_option": "{num} satır;{num} satır",
|
||||
"prefs_search_header": "Web araması",
|
||||
"prefs_topsites_description": "En çok ziyaret ettiğiniz siteler",
|
||||
|
@ -110,6 +110,5 @@ window.gActivityStreamStrings = {
|
|||
"firstrun_privacy_notice": "Gizlilik Bildirimini",
|
||||
"firstrun_continue_to_login": "Devam et",
|
||||
"firstrun_skip_login": "Bu adımı atla",
|
||||
"context_menu_title": "Menüyü aç",
|
||||
"pocket_learn_more": "Daha fazla bilgi al"
|
||||
"context_menu_title": "Menüyü aç"
|
||||
};
|
||||
|
|
|
@ -80,11 +80,12 @@ window.gActivityStreamPrerenderedState = {
|
|||
"spocs": {
|
||||
"spocs_endpoint": "",
|
||||
"lastUpdated": null,
|
||||
"data": {}
|
||||
"data": {},
|
||||
"loaded": false
|
||||
}
|
||||
},
|
||||
"Search": {
|
||||
"focus": false,
|
||||
"fakeFocus": false,
|
||||
"hide": false
|
||||
}
|
||||
};
|
||||
|
|
|
@ -25,7 +25,7 @@ test_newtab({
|
|||
},
|
||||
test: async function test_hr_override() {
|
||||
const hr = await ContentTaskUtils.waitForCondition(() => content.document.querySelector("hr"));
|
||||
ok(content.getComputedStyle(hr).borderBottomWidth.match(/11.?\d*px/), "applied and normalized hr component width override");
|
||||
ok(content.getComputedStyle(hr).borderTopWidth.match(/11.?\d*px/), "applied and normalized hr component width override");
|
||||
},
|
||||
});
|
||||
|
||||
|
|
|
@ -903,6 +903,27 @@ describe("ASRouter", () => {
|
|||
assert.calledOnce(MessageLoaderUtils.installAddonFromURL);
|
||||
assert.calledWithExactly(MessageLoaderUtils.installAddonFromURL, msg.target.browser, "foo.com");
|
||||
});
|
||||
it("should add/remove observers for `webextension-install-notify`", async () => {
|
||||
sandbox.spy(global.Services.obs, "addObserver");
|
||||
sandbox.spy(global.Services.obs, "removeObserver");
|
||||
sandbox.spy(Router, "blockMessageById");
|
||||
|
||||
sandbox.stub(MessageLoaderUtils, "installAddonFromURL").resolves(null);
|
||||
const msg = fakeExecuteUserAction({type: "INSTALL_ADDON_FROM_URL", data: {url: "foo.com"}});
|
||||
|
||||
await Router.onMessage(msg);
|
||||
|
||||
assert.calledOnce(global.Services.obs.addObserver);
|
||||
|
||||
const [cb] = global.Services.obs.addObserver.firstCall.args;
|
||||
|
||||
cb();
|
||||
|
||||
assert.calledOnce(global.Services.obs.removeObserver);
|
||||
assert.calledOnce(channel.sendAsyncMessage);
|
||||
assert.calledOnce(Router.blockMessageById);
|
||||
assert.calledWithExactly(Router.blockMessageById, "RETURN_TO_AMO_1");
|
||||
});
|
||||
});
|
||||
|
||||
describe("#dispatch(action, target)", () => {
|
||||
|
|
|
@ -682,6 +682,7 @@ describe("Reducers", () => {
|
|||
spocs_endpoint: "",
|
||||
data: [1, 2, 3],
|
||||
lastUpdated: 123,
|
||||
loaded: true,
|
||||
});
|
||||
});
|
||||
it("should handle no data from DISCOVERY_STREAM_SPOCS_UPDATE", () => {
|
||||
|
@ -698,8 +699,13 @@ describe("Reducers", () => {
|
|||
const nextState = Search(undefined, {type: "HIDE_SEARCH"});
|
||||
assert.propertyVal(nextState, "hide", true);
|
||||
});
|
||||
it("should set focus to true on FAKE_FOCUS_SEARCH", () => {
|
||||
const nextState = Search(undefined, {type: "FAKE_FOCUS_SEARCH"});
|
||||
assert.propertyVal(nextState, "fakeFocus", true);
|
||||
});
|
||||
it("should set focus and hide to false on SHOW_SEARCH", () => {
|
||||
const nextState = Search(undefined, {type: "SHOW_SEARCH"});
|
||||
assert.propertyVal(nextState, "fakeFocus", false);
|
||||
assert.propertyVal(nextState, "hide", false);
|
||||
});
|
||||
});
|
||||
|
|
|
@ -76,10 +76,10 @@ describe("<ListItem> presentation component", () => {
|
|||
assert.lengthOf(anchors, 1);
|
||||
});
|
||||
|
||||
it("should include an img with a src of props.image_src", () => {
|
||||
it("should include an background image of props.image_src", () => {
|
||||
const wrapper = shallow(<ListItem {...ValidListItemProps} />);
|
||||
|
||||
const anchors = wrapper.find(`img[src="${ValidListItemProps.image_src}"]`);
|
||||
assert.lengthOf(anchors, 1);
|
||||
const imageStyle = wrapper.find(".ds-list-image").prop("style");
|
||||
assert.propertyVal(imageStyle, "backgroundImage", `url(${ValidListItemProps.image_src})`);
|
||||
});
|
||||
});
|
||||
|
|
|
@ -80,60 +80,21 @@ describe("<Search>", () => {
|
|||
assert.ok(wrapper.exists());
|
||||
assert.equal(wrapper.find(".search-handoff-button").length, 1);
|
||||
});
|
||||
it("should focus search hand-off button when clicked with mouse", () => {
|
||||
it("should hand-off search when button is clicked", () => {
|
||||
const dispatch = sinon.spy();
|
||||
const wrapper = shallowWithIntl(<Search {...DEFAULT_PROPS} handoffEnabled={true} dispatch={dispatch} />);
|
||||
wrapper.instance()._searchHandoffButton = {focus: sinon.spy()};
|
||||
wrapper.find(".search-handoff-button").simulate("click", {clientX: 101, clientY: 102, preventDefault: () => {}});
|
||||
assert.calledOnce(wrapper.instance()._searchHandoffButton.focus);
|
||||
});
|
||||
it("should hand-off search when button is clicked with keyboard", () => {
|
||||
const dispatch = sinon.spy();
|
||||
const wrapper = shallowWithIntl(<Search {...DEFAULT_PROPS} handoffEnabled={true} dispatch={dispatch} />);
|
||||
wrapper.find(".search-handoff-button").simulate("click", {clientX: 0, clientY: 0, preventDefault: () => {}});
|
||||
assert.calledTwice(dispatch);
|
||||
wrapper.find(".search-handoff-button").simulate("click", {preventDefault: () => {}});
|
||||
assert.calledThrice(dispatch);
|
||||
assert.calledWith(dispatch, {
|
||||
data: {text: undefined},
|
||||
meta: {from: "ActivityStream:Content", skipLocal: true, to: "ActivityStream:Main"},
|
||||
type: "HANDOFF_SEARCH_TO_AWESOMEBAR",
|
||||
});
|
||||
const [action] = dispatch.secondCall.args;
|
||||
assert.calledWith(dispatch, {type: "FAKE_FOCUS_SEARCH"});
|
||||
const [action] = dispatch.thirdCall.args;
|
||||
assert.isUserEventAction(action);
|
||||
assert.propertyVal(action.data, "event", "SEARCH_HANDOFF");
|
||||
});
|
||||
it("should hand-off search when user types", () => {
|
||||
const dispatch = sinon.spy();
|
||||
const wrapper = shallowWithIntl(<Search {...DEFAULT_PROPS} handoffEnabled={true} dispatch={dispatch} />);
|
||||
wrapper.find(".search-handoff-button").simulate("keydown", {key: "f"});
|
||||
assert.calledThrice(dispatch);
|
||||
assert.calledWith(dispatch, {
|
||||
data: {text: "f"},
|
||||
meta: {from: "ActivityStream:Content", skipLocal: true, to: "ActivityStream:Main"},
|
||||
type: "HANDOFF_SEARCH_TO_AWESOMEBAR",
|
||||
});
|
||||
assert.calledWith(dispatch, {type: "HIDE_SEARCH"});
|
||||
const [action] = dispatch.secondCall.args;
|
||||
assert.isUserEventAction(action);
|
||||
assert.propertyVal(action.data, "event", "SEARCH_HANDOFF");
|
||||
});
|
||||
it("should NOT hand-off search when user types with with ctrl pressed", () => {
|
||||
const dispatch = sinon.spy();
|
||||
const wrapper = shallowWithIntl(<Search {...DEFAULT_PROPS} handoffEnabled={true} dispatch={dispatch} />);
|
||||
wrapper.find(".search-handoff-button").simulate("keydown", {key: "f", ctrlKey: true});
|
||||
assert.notCalled(dispatch);
|
||||
});
|
||||
it("should NOT hand-off search when user types with with alt pressed", () => {
|
||||
const dispatch = sinon.spy();
|
||||
const wrapper = shallowWithIntl(<Search {...DEFAULT_PROPS} handoffEnabled={true} dispatch={dispatch} />);
|
||||
wrapper.find(".search-handoff-button").simulate("keydown", {key: "f", altKey: true});
|
||||
assert.notCalled(dispatch);
|
||||
});
|
||||
it("should NOT hand-off search when user types with with meta pressed", () => {
|
||||
const dispatch = sinon.spy();
|
||||
const wrapper = shallowWithIntl(<Search {...DEFAULT_PROPS} handoffEnabled={true} dispatch={dispatch} />);
|
||||
wrapper.find(".search-handoff-button").simulate("keydown", {key: "f", metaKey: true});
|
||||
assert.notCalled(dispatch);
|
||||
});
|
||||
it("should hand-off search on paste", () => {
|
||||
const dispatch = sinon.spy();
|
||||
const wrapper = mountWithIntl(<Search {...DEFAULT_PROPS} handoffEnabled={true} dispatch={dispatch} />);
|
||||
|
@ -144,22 +105,35 @@ describe("<Search>", () => {
|
|||
},
|
||||
preventDefault: () => {},
|
||||
});
|
||||
assert.calledThrice(dispatch);
|
||||
assert.equal(dispatch.callCount, 4);
|
||||
assert.calledWith(dispatch, {
|
||||
data: {text: "some copied text"},
|
||||
meta: {from: "ActivityStream:Content", skipLocal: true, to: "ActivityStream:Main"},
|
||||
type: "HANDOFF_SEARCH_TO_AWESOMEBAR",
|
||||
});
|
||||
assert.calledWith(dispatch, {type: "HIDE_SEARCH"});
|
||||
const [action] = dispatch.secondCall.args;
|
||||
const [action] = dispatch.thirdCall.args;
|
||||
assert.isUserEventAction(action);
|
||||
assert.propertyVal(action.data, "event", "SEARCH_HANDOFF");
|
||||
});
|
||||
it("should not accept drop events", () => {
|
||||
const wrapper = shallowWithIntl(<Search {...DEFAULT_PROPS} handoffEnabled={true} />);
|
||||
it("should properly handle drop events", () => {
|
||||
const dispatch = sinon.spy();
|
||||
const wrapper = mountWithIntl(<Search {...DEFAULT_PROPS} handoffEnabled={true} dispatch={dispatch} />);
|
||||
const preventDefault = sinon.spy();
|
||||
wrapper.find(".fake-editable").simulate("drop", {preventDefault});
|
||||
assert.calledOnce(preventDefault);
|
||||
wrapper.find(".fake-editable").simulate("drop", {
|
||||
dataTransfer: {getData: () => "dropped text"},
|
||||
preventDefault,
|
||||
});
|
||||
assert.equal(dispatch.callCount, 4);
|
||||
assert.calledWith(dispatch, {
|
||||
data: {text: "dropped text"},
|
||||
meta: {from: "ActivityStream:Content", skipLocal: true, to: "ActivityStream:Main"},
|
||||
type: "HANDOFF_SEARCH_TO_AWESOMEBAR",
|
||||
});
|
||||
assert.calledWith(dispatch, {type: "HIDE_SEARCH"});
|
||||
const [action] = dispatch.thirdCall.args;
|
||||
assert.isUserEventAction(action);
|
||||
assert.propertyVal(action.data, "event", "SEARCH_HANDOFF");
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -327,7 +327,7 @@ describe("PlacesFeed", () => {
|
|||
fakeUrlBar = {
|
||||
focus: sinon.spy(),
|
||||
search: sinon.spy(),
|
||||
hiddenFocus: sinon.spy(),
|
||||
setHiddenFocus: sinon.spy(),
|
||||
removeHiddenFocus: sinon.spy(),
|
||||
addEventListener: (ev, cb) => {
|
||||
listeners[ev] = cb;
|
||||
|
@ -336,24 +336,41 @@ describe("PlacesFeed", () => {
|
|||
};
|
||||
listeners = {};
|
||||
});
|
||||
it("should properly handle normal focus (no text passed in)", () => {
|
||||
it("should properly handle handoff with no text passed in", () => {
|
||||
feed.handoffSearchToAwesomebar({
|
||||
_target: {browser: {ownerGlobal: {gURLBar: fakeUrlBar}}},
|
||||
data: {},
|
||||
meta: {fromTarget: {}},
|
||||
});
|
||||
assert.calledOnce(fakeUrlBar.focus);
|
||||
assert.calledOnce(fakeUrlBar.setHiddenFocus);
|
||||
assert.notCalled(fakeUrlBar.search);
|
||||
assert.notCalled(feed.store.dispatch);
|
||||
|
||||
// Now type a character.
|
||||
listeners.keydown({key: "f"});
|
||||
assert.calledOnce(fakeUrlBar.search);
|
||||
assert.calledOnce(fakeUrlBar.removeHiddenFocus);
|
||||
assert.calledOnce(feed.store.dispatch);
|
||||
assert.calledWith(feed.store.dispatch, {
|
||||
meta: {
|
||||
from: "ActivityStream:Main",
|
||||
skipMain: true,
|
||||
to: "ActivityStream:Content",
|
||||
toTarget: {},
|
||||
},
|
||||
type: "HIDE_SEARCH",
|
||||
});
|
||||
});
|
||||
it("should properly handle text data passed in", () => {
|
||||
it("should properly handle handoff with text data passed in", () => {
|
||||
feed.handoffSearchToAwesomebar({
|
||||
_target: {browser: {ownerGlobal: {gURLBar: fakeUrlBar}}},
|
||||
data: {text: "f"},
|
||||
data: {text: "foo"},
|
||||
meta: {fromTarget: {}},
|
||||
});
|
||||
assert.calledOnce(fakeUrlBar.search);
|
||||
assert.calledWith(fakeUrlBar.search, "f");
|
||||
assert.calledWith(fakeUrlBar.search, "@google foo");
|
||||
assert.notCalled(fakeUrlBar.focus);
|
||||
assert.notCalled(fakeUrlBar.setHiddenFocus);
|
||||
|
||||
// Now call blur listener.
|
||||
listeners.blur();
|
||||
|
@ -371,11 +388,11 @@ describe("PlacesFeed", () => {
|
|||
it("should SHOW_SEARCH on ESC keydown", () => {
|
||||
feed.handoffSearchToAwesomebar({
|
||||
_target: {browser: {ownerGlobal: {gURLBar: fakeUrlBar}}},
|
||||
data: {text: "f"},
|
||||
data: {text: "foo"},
|
||||
meta: {fromTarget: {}},
|
||||
});
|
||||
assert.calledOnce(fakeUrlBar.search);
|
||||
assert.calledWith(fakeUrlBar.search, "f");
|
||||
assert.calledWith(fakeUrlBar.search, "@google foo");
|
||||
assert.notCalled(fakeUrlBar.focus);
|
||||
|
||||
// Now call ESC keydown.
|
||||
|
@ -391,6 +408,16 @@ describe("PlacesFeed", () => {
|
|||
type: "SHOW_SEARCH",
|
||||
});
|
||||
});
|
||||
it("should properly handle no defined search alias", () => {
|
||||
global.Services.search.defaultEngine.wrappedJSObject.__internalAliases = [];
|
||||
feed.handoffSearchToAwesomebar({
|
||||
_target: {browser: {ownerGlobal: {gURLBar: fakeUrlBar}}},
|
||||
data: {text: "foo"},
|
||||
meta: {fromTarget: {}},
|
||||
});
|
||||
assert.calledOnce(fakeUrlBar.search);
|
||||
assert.calledWith(fakeUrlBar.search, "foo");
|
||||
});
|
||||
});
|
||||
|
||||
describe("#observe", () => {
|
||||
|
|
|
@ -225,7 +225,13 @@ const TEST_GLOBAL = {
|
|||
search: {
|
||||
init(cb) { cb(); },
|
||||
getVisibleEngines: () => [{identifier: "google"}, {identifier: "bing"}],
|
||||
defaultEngine: {identifier: "google", searchForm: "https://www.google.com/search?q=&ie=utf-8&oe=utf-8&client=firefox-b"},
|
||||
defaultEngine: {
|
||||
identifier: "google",
|
||||
searchForm: "https://www.google.com/search?q=&ie=utf-8&oe=utf-8&client=firefox-b",
|
||||
wrappedJSObject: {
|
||||
__internalAliases: ["@google"],
|
||||
},
|
||||
},
|
||||
currentEngine: {identifier: "google", searchForm: "https://www.google.com/search?q=&ie=utf-8&oe=utf-8&client=firefox-b"},
|
||||
},
|
||||
scriptSecurityManager: {
|
||||
|
|
|
@ -120,7 +120,7 @@ const kBuiltInInputs = {
|
|||
callback: () => execCommand("Browser:OpenLocation", "OpenLocation"),
|
||||
},
|
||||
Focus: {
|
||||
title: "focus",
|
||||
title: "close-window",
|
||||
image: "private-browsing.pdf",
|
||||
type: "mainButton",
|
||||
callback: () => execCommand("cmd_closeWindow", "Focus"),
|
||||
|
|
|
@ -105,19 +105,18 @@ class UrlbarController {
|
|||
/**
|
||||
* Cancels an in-progress query. Note, queries may continue running if they
|
||||
* can't be canceled.
|
||||
*
|
||||
* @param {UrlbarQueryContext} queryContext The query details.
|
||||
*/
|
||||
cancelQuery(queryContext) {
|
||||
if (queryContext === this._lastQueryContext) {
|
||||
delete this._lastQueryContext;
|
||||
cancelQuery() {
|
||||
if (!this._lastQueryContext) {
|
||||
return;
|
||||
}
|
||||
|
||||
TelemetryStopwatch.cancel(TELEMETRY_1ST_RESULT, queryContext);
|
||||
TelemetryStopwatch.cancel(TELEMETRY_6_FIRST_RESULTS, queryContext);
|
||||
TelemetryStopwatch.cancel(TELEMETRY_1ST_RESULT, this._lastQueryContext);
|
||||
TelemetryStopwatch.cancel(TELEMETRY_6_FIRST_RESULTS, this._lastQueryContext);
|
||||
|
||||
this.manager.cancelQuery(queryContext);
|
||||
this._notify("onQueryCancelled", queryContext);
|
||||
this.manager.cancelQuery(this._lastQueryContext);
|
||||
this._notify("onQueryCancelled", this._lastQueryContext);
|
||||
delete this._lastQueryContext;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -62,7 +62,7 @@ class UrlbarInput {
|
|||
// Forward textbox methods and properties.
|
||||
const METHODS = ["addEventListener", "removeEventListener",
|
||||
"setAttribute", "hasAttribute", "removeAttribute", "getAttribute",
|
||||
"focus", "blur", "select"];
|
||||
"select"];
|
||||
const READ_ONLY_PROPERTIES = ["inputField", "editor"];
|
||||
const READ_WRITE_PROPERTIES = ["placeholder", "readOnly",
|
||||
"selectionStart", "selectionEnd"];
|
||||
|
@ -137,9 +137,18 @@ class UrlbarInput {
|
|||
}
|
||||
|
||||
closePopup() {
|
||||
this.controller.cancelQuery();
|
||||
this.view.close();
|
||||
}
|
||||
|
||||
focus() {
|
||||
this.inputField.focus();
|
||||
}
|
||||
|
||||
blur() {
|
||||
this.inputField.blur();
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts an internal URI (e.g. a wyciwyg URI) into one which we can
|
||||
* expose to the user.
|
||||
|
@ -856,6 +865,7 @@ class UrlbarInput {
|
|||
|
||||
_on_blur(event) {
|
||||
this.formatValue();
|
||||
this.closePopup();
|
||||
}
|
||||
|
||||
_on_focus(event) {
|
||||
|
|
|
@ -41,6 +41,8 @@ class UrlbarView {
|
|||
this._rows.addEventListener("overflow", this);
|
||||
this._rows.addEventListener("underflow", this);
|
||||
|
||||
this.panel.addEventListener("popuphiding", this);
|
||||
|
||||
this.controller.setView(this);
|
||||
this.controller.addQueryListener(this);
|
||||
}
|
||||
|
@ -400,4 +402,8 @@ class UrlbarView {
|
|||
event.target.toggleAttribute("overflow", false);
|
||||
}
|
||||
}
|
||||
|
||||
_on_popuphiding(event) {
|
||||
this.controller.cancelQuery();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15,10 +15,8 @@ support-files = file_bug562649.html
|
|||
support-files =
|
||||
redirect_bug623155.sjs
|
||||
[browser_bug783614.js]
|
||||
skip-if = true # Bug 1521490
|
||||
[browser_bug1025195_switchToTabHavingURI_aOpenParams.js]
|
||||
[browser_locationBarExternalLoad.js]
|
||||
skip-if = true # Bug 1521490
|
||||
[browser_moz_action_link.js]
|
||||
[browser_populateAfterPushState.js]
|
||||
[browser_urlbar_blanking.js]
|
||||
|
|
|
@ -172,8 +172,13 @@ add_task(function test_handle_query_starts_search_sets_enableAutofill() {
|
|||
});
|
||||
|
||||
add_task(function test_cancel_query() {
|
||||
// Ensure the controller doesn't have any previous queries.
|
||||
delete controller._lastQueryContext;
|
||||
|
||||
const context = createContext();
|
||||
controller.cancelQuery(context);
|
||||
controller.startQuery(context);
|
||||
|
||||
controller.cancelQuery();
|
||||
|
||||
Assert.equal(fPM.cancelQuery.callCount, 1,
|
||||
"Should have called cancelQuery once");
|
||||
|
|
|
@ -24,4 +24,6 @@ ac_add_options --with-branding=browser/branding/nightly
|
|||
|
||||
. $topsrcdir/build/win64-aarch64/mozconfig.vs-latest
|
||||
|
||||
unset ENABLE_CLANG_PLUGIN
|
||||
|
||||
. "$topsrcdir/build/mozconfig.common.override"
|
||||
|
|
|
@ -1,3 +0,0 @@
|
|||
. "$topsrcdir/browser/config/mozconfigs/win64-aarch64/debug"
|
||||
|
||||
unset ENABLE_CLANG_PLUGIN
|
|
@ -5,6 +5,8 @@
|
|||
ac_add_options --enable-verify-mar
|
||||
ac_add_options --enable-dmd
|
||||
|
||||
ac_add_options --enable-lto
|
||||
|
||||
ac_add_options --with-branding=browser/branding/nightly
|
||||
|
||||
unset ENABLE_CLANG_PLUGIN
|
||||
|
|
|
@ -17,4 +17,4 @@ reader-view = Reader View
|
|||
# Meant to match the string displayed in an empty URL bar.
|
||||
open-location = Search or enter address
|
||||
share = Share
|
||||
focus = Close
|
||||
close-window = Close Window
|
||||
|
|
|
@ -10,8 +10,8 @@
|
|||
"win32",
|
||||
"win32-devedition",
|
||||
"win64",
|
||||
"win64-aarch64-msvc",
|
||||
"win64-aarch64-msvc-devedition",
|
||||
"win64-aarch64",
|
||||
"win64-aarch64-devedition",
|
||||
"win64-devedition"
|
||||
],
|
||||
"revision": "default"
|
||||
|
@ -27,8 +27,8 @@
|
|||
"win32",
|
||||
"win32-devedition",
|
||||
"win64",
|
||||
"win64-aarch64-msvc",
|
||||
"win64-aarch64-msvc-devedition",
|
||||
"win64-aarch64",
|
||||
"win64-aarch64-devedition",
|
||||
"win64-devedition"
|
||||
],
|
||||
"revision": "default"
|
||||
|
@ -44,8 +44,8 @@
|
|||
"win32",
|
||||
"win32-devedition",
|
||||
"win64",
|
||||
"win64-aarch64-msvc",
|
||||
"win64-aarch64-msvc-devedition",
|
||||
"win64-aarch64",
|
||||
"win64-aarch64-devedition",
|
||||
"win64-devedition"
|
||||
],
|
||||
"revision": "default"
|
||||
|
@ -59,8 +59,8 @@
|
|||
"win32",
|
||||
"win32-devedition",
|
||||
"win64",
|
||||
"win64-aarch64-msvc",
|
||||
"win64-aarch64-msvc-devedition",
|
||||
"win64-aarch64",
|
||||
"win64-aarch64-devedition",
|
||||
"win64-devedition"
|
||||
],
|
||||
"revision": "default"
|
||||
|
|
|
@ -1,16 +0,0 @@
|
|||
AArch64 Windows uses a five-argument __va_start, just like ARM.
|
||||
|
||||
https://bugs.llvm.org/show_bug.cgi?id=39090
|
||||
|
||||
diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp
|
||||
index 22483f8..53d9cb2 100644
|
||||
--- a/clang/lib/Sema/SemaChecking.cpp
|
||||
+++ b/clang/lib/Sema/SemaChecking.cpp
|
||||
@@ -917,6 +917,7 @@ Sema::CheckBuiltinFunctionCall(FunctionDecl *FDecl, unsigned BuiltinID,
|
||||
switch (Context.getTargetInfo().getTriple().getArch()) {
|
||||
case llvm::Triple::arm:
|
||||
case llvm::Triple::thumb:
|
||||
+ case llvm::Triple::aarch64:
|
||||
if (SemaBuiltinVAStartARMMicrosoft(TheCall))
|
||||
return ExprError();
|
||||
break;
|
|
@ -1,27 +1,22 @@
|
|||
{
|
||||
"llvm_revision": "349247",
|
||||
"llvm_revision": "352000",
|
||||
"stages": "3",
|
||||
"build_libcxx": false,
|
||||
"build_type": "Release",
|
||||
"assertions": false,
|
||||
"llvm_repo": "https://llvm.org/svn/llvm-project/llvm/tags/RELEASE_701/final",
|
||||
"clang_repo": "https://llvm.org/svn/llvm-project/cfe/tags/RELEASE_701/final",
|
||||
"lld_repo": "https://llvm.org/svn/llvm-project/lld/tags/RELEASE_701/final",
|
||||
"compiler_repo": "https://llvm.org/svn/llvm-project/compiler-rt/tags/RELEASE_701/final",
|
||||
"libcxx_repo": "https://llvm.org/svn/llvm-project/libcxx/tags/RELEASE_701/final",
|
||||
"llvm_repo": "https://llvm.org/svn/llvm-project/llvm/tags/RELEASE_800/rc1",
|
||||
"clang_repo": "https://llvm.org/svn/llvm-project/cfe/tags/RELEASE_800/rc1",
|
||||
"lld_repo": "https://llvm.org/svn/llvm-project/lld/tags/RELEASE_800/rc1",
|
||||
"compiler_repo": "https://llvm.org/svn/llvm-project/compiler-rt/tags/RELEASE_800/rc1",
|
||||
"libcxx_repo": "https://llvm.org/svn/llvm-project/libcxx/tags/RELEASE_800/rc1",
|
||||
"python_path": "c:/mozilla-build/python/python.exe",
|
||||
"cc": "cl.exe",
|
||||
"cxx": "cl.exe",
|
||||
"ml": "ml64.exe",
|
||||
"patches": [
|
||||
"workaround-issue38586.patch",
|
||||
"r342649-hotpatch-8-byte-nops.patch",
|
||||
"r342652-unpoison-thread-stacks.patch",
|
||||
"r343123-pin-asan-dll.patch",
|
||||
"aarch64-vastart-checking.patch",
|
||||
"unpoison-thread-stacks.patch",
|
||||
"downgrade-mangling-error.patch",
|
||||
"r346300-compiler-rt-windows-mmap.patch",
|
||||
"loosen-msvc-detection.patch",
|
||||
"r350774.patch"
|
||||
"loosen-msvc-detection.patch"
|
||||
]
|
||||
}
|
||||
|
|
|
@ -1,30 +0,0 @@
|
|||
[winasan] Reduce hotpatch prefix check to 8 bytes
|
||||
|
||||
Same idea as r310419: The 8 byte nop is a suffix of the 9 byte nop, and we need at most 6 bytes.
|
||||
|
||||
Differential Revision: https://reviews.llvm.org/D51788
|
||||
|
||||
--- a/compiler-rt/lib/interception/interception_win.cc (revision 342648)
|
||||
+++ b/compiler-rt/lib/interception/interception_win.cc (revision 342649)
|
||||
@@ -223,8 +223,8 @@
|
||||
return true;
|
||||
}
|
||||
|
||||
-static const u8 kHintNop9Bytes[] = {
|
||||
- 0x66, 0x0F, 0x1F, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00
|
||||
+static const u8 kHintNop8Bytes[] = {
|
||||
+ 0x0F, 0x1F, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00
|
||||
};
|
||||
|
||||
template<class T>
|
||||
@@ -239,8 +239,8 @@
|
||||
static bool FunctionHasPadding(uptr address, uptr size) {
|
||||
if (IsMemoryPadding(address - size, size))
|
||||
return true;
|
||||
- if (size <= sizeof(kHintNop9Bytes) &&
|
||||
- FunctionHasPrefix(address, kHintNop9Bytes))
|
||||
+ if (size <= sizeof(kHintNop8Bytes) &&
|
||||
+ FunctionHasPrefix(address, kHintNop8Bytes))
|
||||
return true;
|
||||
return false;
|
||||
}
|
|
@ -1,27 +0,0 @@
|
|||
------------------------------------------------------------------------
|
||||
r343123 | dmajor | 2018-09-26 12:28:39 -0400 (Wed, 26 Sep 2018) | 5 lines
|
||||
|
||||
[winasan] Pin the ASan DLL to prevent unloading
|
||||
|
||||
Differential Revision: https://reviews.llvm.org/D52505
|
||||
|
||||
===================================================================
|
||||
--- a/compiler-rt/lib/asan/asan_win.cc (revision 343122)
|
||||
+++ b/compiler-rt/lib/asan/asan_win.cc (revision 343123)
|
||||
@@ -167,6 +167,14 @@
|
||||
namespace __asan {
|
||||
|
||||
void InitializePlatformInterceptors() {
|
||||
+ // The interceptors were not designed to be removable, so we have to keep this
|
||||
+ // module alive for the life of the process.
|
||||
+ HMODULE pinned;
|
||||
+ CHECK(GetModuleHandleExW(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS |
|
||||
+ GET_MODULE_HANDLE_EX_FLAG_PIN,
|
||||
+ (LPCWSTR)&InitializePlatformInterceptors,
|
||||
+ &pinned));
|
||||
+
|
||||
ASAN_INTERCEPT_FUNC(CreateThread);
|
||||
ASAN_INTERCEPT_FUNC(SetUnhandledExceptionFilter);
|
||||
CHECK(::__interception::OverrideFunction("NtTerminateThread",
|
||||
|
||||
------------------------------------------------------------------------
|
|
@ -1,149 +0,0 @@
|
|||
From 0b881f23c6f2a637ab97d71e964cc3743fef98b8 Mon Sep 17 00:00:00 2001
|
||||
From: Marco Castelluccio <mcastelluccio@mozilla.com>
|
||||
Date: Wed, 7 Nov 2018 09:38:26 +0000
|
||||
Subject: [PATCH] [GCOV] Close file mapping handle on Windows, so flushed gcda
|
||||
files can be removed while the process is in execution
|
||||
|
||||
git-svn-id: https://llvm.org/svn/llvm-project/compiler-rt/trunk@346300 91177308-0d34-0410-b5e6-96231b3b80d8
|
||||
---
|
||||
lib/profile/GCDAProfiling.c | 49 +++++++++++++++++++
|
||||
lib/profile/WindowsMMap.c | 8 ---
|
||||
lib/profile/WindowsMMap.h | 8 +++
|
||||
.../instrprof-gcov-__gcov_flush-multiple.c | 16 ++++++
|
||||
...nstrprof-gcov-__gcov_flush-multiple.c.gcov | 21 ++++++++
|
||||
.../instrprof-gcov-__gcov_flush-multiple.test | 10 ++++
|
||||
6 files changed, 104 insertions(+), 8 deletions(-)
|
||||
create mode 100644 test/profile/Inputs/instrprof-gcov-__gcov_flush-multiple.c
|
||||
create mode 100644 test/profile/Inputs/instrprof-gcov-__gcov_flush-multiple.c.gcov
|
||||
create mode 100644 test/profile/instrprof-gcov-__gcov_flush-multiple.test
|
||||
|
||||
diff --git a/compiler-rt/lib/profile/GCDAProfiling.c b/compiler-rt/lib/profile/GCDAProfiling.c
|
||||
index cbca36551..0665a680c 100644
|
||||
--- a/compiler-rt/lib/profile/GCDAProfiling.c
|
||||
+++ b/compiler-rt/lib/profile/GCDAProfiling.c
|
||||
@@ -29,6 +29,8 @@
|
||||
#include <string.h>
|
||||
|
||||
#if defined(_WIN32)
|
||||
+#define WIN32_LEAN_AND_MEAN
|
||||
+#include <windows.h>
|
||||
#include "WindowsMMap.h"
|
||||
#else
|
||||
#include <sys/mman.h>
|
||||
@@ -86,6 +88,9 @@ static uint64_t cur_buffer_size = 0;
|
||||
static uint64_t cur_pos = 0;
|
||||
static uint64_t file_size = 0;
|
||||
static int new_file = 0;
|
||||
+#if defined(_WIN32)
|
||||
+static HANDLE mmap_handle = NULL;
|
||||
+#endif
|
||||
static int fd = -1;
|
||||
|
||||
typedef void (*fn_ptr)();
|
||||
@@ -255,6 +260,28 @@ static int map_file() {
|
||||
if (file_size == 0)
|
||||
return -1;
|
||||
|
||||
+#if defined(_WIN32)
|
||||
+ HANDLE mmap_fd;
|
||||
+ if (fd == -1)
|
||||
+ mmap_fd = INVALID_HANDLE_VALUE;
|
||||
+ else
|
||||
+ mmap_fd = (HANDLE)_get_osfhandle(fd);
|
||||
+
|
||||
+ mmap_handle = CreateFileMapping(mmap_fd, NULL, PAGE_READWRITE, DWORD_HI(file_size), DWORD_LO(file_size), NULL);
|
||||
+ if (mmap_handle == NULL) {
|
||||
+ fprintf(stderr, "profiling: %s: cannot create file mapping: %d\n", filename,
|
||||
+ GetLastError());
|
||||
+ return -1;
|
||||
+ }
|
||||
+
|
||||
+ write_buffer = MapViewOfFile(mmap_handle, FILE_MAP_WRITE, 0, 0, file_size);
|
||||
+ if (write_buffer == NULL) {
|
||||
+ fprintf(stderr, "profiling: %s: cannot map: %d\n", filename,
|
||||
+ GetLastError());
|
||||
+ CloseHandle(mmap_handle);
|
||||
+ return -1;
|
||||
+ }
|
||||
+#else
|
||||
write_buffer = mmap(0, file_size, PROT_READ | PROT_WRITE,
|
||||
MAP_FILE | MAP_SHARED, fd, 0);
|
||||
if (write_buffer == (void *)-1) {
|
||||
@@ -263,10 +290,30 @@ static int map_file() {
|
||||
strerror(errnum));
|
||||
return -1;
|
||||
}
|
||||
+#endif
|
||||
+
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void unmap_file() {
|
||||
+#if defined(_WIN32)
|
||||
+ if (!FlushViewOfFile(write_buffer, file_size)) {
|
||||
+ fprintf(stderr, "profiling: %s: cannot flush mapped view: %d\n", filename,
|
||||
+ GetLastError());
|
||||
+ }
|
||||
+
|
||||
+ if (!UnmapViewOfFile(write_buffer)) {
|
||||
+ fprintf(stderr, "profiling: %s: cannot unmap mapped view: %d\n", filename,
|
||||
+ GetLastError());
|
||||
+ }
|
||||
+
|
||||
+ if (!CloseHandle(mmap_handle)) {
|
||||
+ fprintf(stderr, "profiling: %s: cannot close file mapping handle: %d\n", filename,
|
||||
+ GetLastError());
|
||||
+ }
|
||||
+
|
||||
+ mmap_handle = NULL;
|
||||
+#else
|
||||
if (msync(write_buffer, file_size, MS_SYNC) == -1) {
|
||||
int errnum = errno;
|
||||
fprintf(stderr, "profiling: %s: cannot msync: %s\n", filename,
|
||||
@@ -277,6 +324,8 @@ static void unmap_file() {
|
||||
* is written and we don't care.
|
||||
*/
|
||||
(void)munmap(write_buffer, file_size);
|
||||
+#endif
|
||||
+
|
||||
write_buffer = NULL;
|
||||
file_size = 0;
|
||||
}
|
||||
diff --git a/compiler-rt/lib/profile/WindowsMMap.c b/compiler-rt/lib/profile/WindowsMMap.c
|
||||
index dc87a888a..41cc67f41 100644
|
||||
--- a/compiler-rt/lib/profile/WindowsMMap.c
|
||||
+++ b/compiler-rt/lib/profile/WindowsMMap.c
|
||||
@@ -24,14 +24,6 @@
|
||||
|
||||
#include "InstrProfiling.h"
|
||||
|
||||
-#ifdef __USE_FILE_OFFSET64
|
||||
-# define DWORD_HI(x) (x >> 32)
|
||||
-# define DWORD_LO(x) ((x) & 0xffffffff)
|
||||
-#else
|
||||
-# define DWORD_HI(x) (0)
|
||||
-# define DWORD_LO(x) (x)
|
||||
-#endif
|
||||
-
|
||||
COMPILER_RT_VISIBILITY
|
||||
void *mmap(void *start, size_t length, int prot, int flags, int fd, off_t offset)
|
||||
{
|
||||
diff --git a/compiler-rt/lib/profile/WindowsMMap.h b/compiler-rt/lib/profile/WindowsMMap.h
|
||||
index ac2c911c8..51a130b31 100644
|
||||
--- a/compiler-rt/lib/profile/WindowsMMap.h
|
||||
+++ b/compiler-rt/lib/profile/WindowsMMap.h
|
||||
@@ -45,6 +45,14 @@
|
||||
#define LOCK_NB 4 /* don't block when locking */
|
||||
#define LOCK_UN 8 /* unlock */
|
||||
|
||||
+#ifdef __USE_FILE_OFFSET64
|
||||
+# define DWORD_HI(x) (x >> 32)
|
||||
+# define DWORD_LO(x) ((x) & 0xffffffff)
|
||||
+#else
|
||||
+# define DWORD_HI(x) (0)
|
||||
+# define DWORD_LO(x) (x)
|
||||
+#endif
|
||||
+
|
||||
void *mmap(void *start, size_t length, int prot, int flags, int fd,
|
||||
off_t offset);
|
||||
|
|
@ -21,8 +21,8 @@ Differential Revision: https://reviews.llvm.org/D52091
|
|||
// }}}
|
||||
|
||||
namespace __asan {
|
||||
@@ -161,7 +169,9 @@
|
||||
void InitializePlatformInterceptors() {
|
||||
@@ -169,7 +177,9 @@
|
||||
|
||||
ASAN_INTERCEPT_FUNC(CreateThread);
|
||||
ASAN_INTERCEPT_FUNC(SetUnhandledExceptionFilter);
|
||||
-
|
|
@ -843,11 +843,7 @@ def default_c_compilers(host_or_target, other_c_compiler=None):
|
|||
def default_c_compilers(host_or_target, target, toolchain_prefix,
|
||||
android_clang_compiler, *other_c_compiler):
|
||||
if host_or_target.kernel == 'WINNT':
|
||||
# Prefer MSVC for aarch64 for now.
|
||||
if host_or_target.cpu == 'aarch64':
|
||||
supported = types = ('msvc', 'clang-cl', 'gcc', 'clang')
|
||||
else:
|
||||
supported = types = ('clang-cl', 'msvc', 'gcc', 'clang')
|
||||
supported = types = ('clang-cl', 'msvc', 'gcc', 'clang')
|
||||
elif host_or_target.kernel == 'Darwin':
|
||||
types = ('clang',)
|
||||
supported = ('clang', 'gcc')
|
||||
|
@ -1605,6 +1601,8 @@ def lto(value, pgo, c_compiler):
|
|||
cflags.append("-flto")
|
||||
else:
|
||||
cflags.append("-flto=thin")
|
||||
# Workaround for https://bugs.llvm.org/show_bug.cgi?id=40414
|
||||
cflags.append("-fsplit-lto-unit")
|
||||
# With clang-cl, -flto can only be used with -c or -fuse-ld=lld.
|
||||
# AC_TRY_LINKs during configure don't have -c, so pass -fuse-ld=lld.
|
||||
cflags.append("-fuse-ld=lld");
|
||||
|
|
|
@ -1 +1,3 @@
|
|||
. $topsrcdir/build/win64-aarch64/mozconfig.vs2017
|
||||
. "$topsrcdir/build/mozconfig.clang-cl"
|
||||
. "$topsrcdir/build/mozconfig.lld-link"
|
||||
|
|
|
@ -20,15 +20,7 @@ if [ -d "${VSPATH}" ]; then
|
|||
|
||||
# We need to declare host and target tools separately.
|
||||
arm_bin="${VSPATH}/VC/bin/Hostx64/arm64"
|
||||
export CC="${arm_bin}/cl.exe"
|
||||
export CXX="${arm_bin}/cl.exe"
|
||||
export AS="${arm_bin}/armasm64.exe"
|
||||
export LINKER="${arm_bin}/link.exe"
|
||||
|
||||
x64_bin="${VSPATH}/VC/bin/Hostx64/x64"
|
||||
export HOST_CC="${x64_bin}/cl.exe"
|
||||
export HOST_CXX="${x64_bin}/cl.exe"
|
||||
export HOST_LINKER="${x64_bin}/link.exe"
|
||||
|
||||
# We provided LIB, above, but we also need to provide HOST_LDFLAGS so host
|
||||
# links are not completely confused. LIBPATH wants its argument with
|
||||
|
|
|
@ -50,7 +50,8 @@ DebuggerPanel.prototype = {
|
|||
.setNodeFront(front, { reason: "debugger" });
|
||||
|
||||
return Promise.all([onNodeFrontSet, onInspectorUpdated]);
|
||||
}.bind(this)
|
||||
}.bind(this),
|
||||
onReload: this.onReload.bind(this)
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -124,6 +125,10 @@ DebuggerPanel.prototype = {
|
|||
return this._selectors.getSourceByURL(this._getState(), sourceURL);
|
||||
},
|
||||
|
||||
onReload: function() {
|
||||
this.emit("reloaded");
|
||||
},
|
||||
|
||||
destroy: function() {
|
||||
this.panelWin.Debugger.destroy();
|
||||
this.emit("destroyed");
|
||||
|
|
|
@ -75,11 +75,15 @@ export function connect(url: string, actor: string, canRewind: boolean) {
|
|||
* @static
|
||||
*/
|
||||
export function navigated() {
|
||||
return async function({ dispatch, getState, client }: ThunkArgs) {
|
||||
return async function({ dispatch, getState, client, onReload }: ThunkArgs) {
|
||||
// this time out is used to wait for sources. If we have 0 sources, it is likely
|
||||
// that the sources are being loaded from the bfcache, and we should make an explicit
|
||||
// request to the server to load them.
|
||||
await waitForMs(100);
|
||||
if (Object.keys(getSources(getState())).length == 0) {
|
||||
const sources = await client.fetchSources();
|
||||
dispatch(newSources(sources));
|
||||
}
|
||||
onReload();
|
||||
};
|
||||
}
|
||||
|
|
|
@ -42,7 +42,8 @@ export type ThunkArgs = {
|
|||
sourceMaps: any,
|
||||
openLink: (url: string) => void,
|
||||
openWorkerToolbox: (worker: Worker) => void,
|
||||
openElementInInspector: (grip: Object) => void
|
||||
openElementInInspector: (grip: Object) => void,
|
||||
onReload: () => void
|
||||
};
|
||||
|
||||
export type Thunk = ThunkArgs => any;
|
||||
|
|
|
@ -831,12 +831,14 @@ class Target extends EventEmitter {
|
|||
* The text to log.
|
||||
* @param {String} category
|
||||
* The category of the message. @see nsIScriptError.
|
||||
* @returns {Promise}
|
||||
*/
|
||||
logErrorInPage(text, category) {
|
||||
if (this.activeTab && this.activeTab.traits.logInPage) {
|
||||
const errorFlag = 0;
|
||||
this.activeTab.logInPage({ text, category, flags: errorFlag });
|
||||
return this.activeTab.logInPage({ text, category, flags: errorFlag });
|
||||
}
|
||||
return Promise.resolve();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -846,12 +848,14 @@ class Target extends EventEmitter {
|
|||
* The text to log.
|
||||
* @param {String} category
|
||||
* The category of the message. @see nsIScriptError.
|
||||
* @returns {Promise}
|
||||
*/
|
||||
logWarningInPage(text, category) {
|
||||
if (this.activeTab && this.activeTab.traits.logInPage) {
|
||||
const warningFlag = 1;
|
||||
this.activeTab.logInPage({ text, category, flags: warningFlag });
|
||||
return this.activeTab.logInPage({ text, category, flags: warningFlag });
|
||||
}
|
||||
return Promise.resolve();
|
||||
}
|
||||
}
|
||||
exports.Target = Target;
|
||||
|
|
|
@ -20,6 +20,7 @@ function test() {
|
|||
const NAME_3 = "Toolbox test for title update";
|
||||
|
||||
let toolbox;
|
||||
let panel;
|
||||
|
||||
addTab(URL_1).then(async function() {
|
||||
let target = await TargetFactory.forTab(gBrowser.selectedTab);
|
||||
|
@ -39,25 +40,29 @@ function test() {
|
|||
.then(checkTitle.bind(null, NAME_1, URL_1, "toolbox undocked"))
|
||||
|
||||
// switch to different tool and check title
|
||||
.then(() => {
|
||||
.then(async () => {
|
||||
const onTitleChanged = waitForTitleChange(toolbox);
|
||||
toolbox.selectTool(TOOL_ID_2);
|
||||
panel = await toolbox.selectTool(TOOL_ID_2);
|
||||
return onTitleChanged;
|
||||
})
|
||||
.then(checkTitle.bind(null, NAME_1, URL_1, "tool changed"))
|
||||
|
||||
// navigate to different local url and check title
|
||||
.then(function() {
|
||||
.then(async function() {
|
||||
const onTitleChanged = waitForTitleChange(toolbox);
|
||||
const waitForReloaded = panel.once("reloaded");
|
||||
BrowserTestUtils.loadURI(gBrowser, URL_2);
|
||||
await waitForReloaded;
|
||||
return onTitleChanged;
|
||||
})
|
||||
.then(checkTitle.bind(null, NAME_2, URL_2, "url changed"))
|
||||
|
||||
// navigate to a real url and check title
|
||||
.then(() => {
|
||||
.then(async () => {
|
||||
const onTitleChanged = waitForTitleChange(toolbox);
|
||||
const waitForReloaded = panel.once("reloaded");
|
||||
BrowserTestUtils.loadURI(gBrowser, URL_3);
|
||||
await waitForReloaded;
|
||||
return onTitleChanged;
|
||||
})
|
||||
.then(checkTitle.bind(null, NAME_3, URL_3, "url changed"))
|
||||
|
|
|
@ -159,6 +159,7 @@ devtools.jar:
|
|||
skin/components-h-split-box.css (themes/components-h-split-box.css)
|
||||
skin/jit-optimizations.css (themes/jit-optimizations.css)
|
||||
skin/images/filter.svg (themes/images/filter.svg)
|
||||
skin/images/filter-small.svg (themes/images/filter-small.svg)
|
||||
skin/images/search.svg (themes/images/search.svg)
|
||||
skin/images/item-toggle.svg (themes/images/item-toggle.svg)
|
||||
skin/images/item-arrow-dark-rtl.svg (themes/images/item-arrow-dark-rtl.svg)
|
||||
|
|
|
@ -18,11 +18,57 @@ add_task(async function() {
|
|||
await hideColumn(monitor, "status");
|
||||
await hideColumn(monitor, "waterfall");
|
||||
|
||||
const onRequestsFinished = waitForRequestsFinished(monitor);
|
||||
EventUtils.sendMouseEvent({ type: "contextmenu" },
|
||||
document.querySelector("#requests-list-contentSize-button"));
|
||||
|
||||
parent.document.querySelector("#request-list-header-reset-columns").click();
|
||||
await onRequestsFinished;
|
||||
|
||||
ok(JSON.stringify(prefBefore) === JSON.stringify(Prefs.visibleColumns),
|
||||
"Reset columns item should reset columns pref");
|
||||
});
|
||||
|
||||
/**
|
||||
* Helper function for waiting for all events to fire before resolving a promise.
|
||||
*
|
||||
* @param monitor subject
|
||||
* The event emitter object that is being listened to.
|
||||
* @return {Promise}
|
||||
* Returns a promise that resolves upon the last event being fired.
|
||||
*/
|
||||
function waitForRequestsFinished(monitor, event) {
|
||||
const window = monitor.panelWin;
|
||||
|
||||
return new Promise(resolve => {
|
||||
// Key is the request id, value is a boolean - is request finished or not?
|
||||
const requests = new Map();
|
||||
|
||||
function onRequest(id) {
|
||||
info(`Request ${id} not yet done, keep waiting...`);
|
||||
requests.set(id, false);
|
||||
}
|
||||
|
||||
function onEventRequest(id) {
|
||||
info(`Request ${id} `);
|
||||
requests.set(id, true);
|
||||
maybeResolve();
|
||||
}
|
||||
|
||||
function maybeResolve() {
|
||||
// Have all the requests in the map finished yet?
|
||||
if ([...requests.values()].some(finished => !finished)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// All requests are done - unsubscribe from events and resolve!
|
||||
window.api.off(EVENTS.NETWORK_EVENT, onRequest);
|
||||
window.api.off(EVENTS.RECEIVED_EVENT_TIMINGS, onEventRequest);
|
||||
info("All requests finished");
|
||||
resolve();
|
||||
}
|
||||
|
||||
window.api.on(EVENTS.NETWORK_EVENT, onRequest);
|
||||
window.api.on(EVENTS.RECEIVED_EVENT_TIMINGS, onEventRequest);
|
||||
});
|
||||
}
|
||||
|
|
|
@ -330,6 +330,9 @@ pref("devtools.responsive.reloadConditions.userAgent", false);
|
|||
pref("devtools.responsive.reloadNotification.enabled", true);
|
||||
// Whether or not touch simulation is enabled.
|
||||
pref("devtools.responsive.touchSimulation.enabled", false);
|
||||
// Whether or not meta viewport is enabled, if and only if touchSimulation
|
||||
// is also enabled.
|
||||
pref("devtools.responsive.metaViewport.enabled", false);
|
||||
// The user agent of the viewport.
|
||||
pref("devtools.responsive.userAgent", "");
|
||||
|
||||
|
|
|
@ -716,22 +716,31 @@ ResponsiveUI.prototype = {
|
|||
},
|
||||
|
||||
/**
|
||||
* Set or clear touch simulation.
|
||||
* Set or clear touch simulation. When setting to true, this method will
|
||||
* additionally set meta viewport override if the pref
|
||||
* "devtools.responsive.metaViewport.enabled" is true. When setting to
|
||||
* false, this method will clear all touch simulation and meta viewport
|
||||
* overrides, returning to default behavior for both settings.
|
||||
*
|
||||
* @return boolean
|
||||
* Whether a reload is needed to apply the change.
|
||||
* Whether a reload is needed to apply the override change(s).
|
||||
*/
|
||||
updateTouchSimulation(enabled) {
|
||||
async updateTouchSimulation(enabled) {
|
||||
let reloadNeeded;
|
||||
if (enabled) {
|
||||
reloadNeeded = this.emulationFront.setTouchEventsOverride(
|
||||
Ci.nsIDocShell.TOUCHEVENTS_OVERRIDE_ENABLED
|
||||
).then(() => this.emulationFront.setMetaViewportOverride(
|
||||
Ci.nsIDocShell.META_VIEWPORT_OVERRIDE_ENABLED
|
||||
));
|
||||
const metaViewportEnabled =
|
||||
Services.prefs.getBoolPref("devtools.responsive.metaViewport.enabled", false);
|
||||
|
||||
reloadNeeded = await this.emulationFront.setTouchEventsOverride(
|
||||
Ci.nsIDocShell.TOUCHEVENTS_OVERRIDE_ENABLED);
|
||||
|
||||
if (metaViewportEnabled) {
|
||||
reloadNeeded |= await this.emulationFront.setMetaViewportOverride(
|
||||
Ci.nsIDocShell.META_VIEWPORT_OVERRIDE_ENABLED);
|
||||
}
|
||||
} else {
|
||||
reloadNeeded = this.emulationFront.clearTouchEventsOverride()
|
||||
.then(() => this.emulationFront.clearMetaViewportOverride());
|
||||
reloadNeeded = await this.emulationFront.clearTouchEventsOverride();
|
||||
reloadNeeded |= await this.emulationFront.clearMetaViewportOverride();
|
||||
}
|
||||
return reloadNeeded;
|
||||
},
|
||||
|
|
|
@ -44,10 +44,13 @@ async function testTargetScopedActor(client, form) {
|
|||
}
|
||||
|
||||
async function closeTab(client, form) {
|
||||
await removeTab(gBrowser.selectedTab);
|
||||
await Assert.rejects(
|
||||
// We need to start listening for the rejection before removing the tab
|
||||
/* eslint-disable-next-line mozilla/rejects-requires-await*/
|
||||
const onReject = Assert.rejects(
|
||||
client.request({ to: form.testOneActor, type: "ping" }),
|
||||
err => err.message === `'ping' active request packet to '${form.testOneActor}' ` +
|
||||
`can't be sent as the connection just closed.`,
|
||||
"testOneActor went away.");
|
||||
await removeTab(gBrowser.selectedTab);
|
||||
await onReject;
|
||||
}
|
||||
|
|
|
@ -473,8 +473,8 @@ checkbox:-moz-focusring {
|
|||
padding: 0;
|
||||
padding-inline-start: 22px;
|
||||
padding-inline-end: 4px;
|
||||
background-position: 8px center;
|
||||
background-size: 11px;
|
||||
background-position: 7px center;
|
||||
background-size: 12px;
|
||||
background-repeat: no-repeat;
|
||||
font-size: inherit;
|
||||
-moz-context-properties: fill;
|
||||
|
@ -495,14 +495,14 @@ checkbox:-moz-focusring {
|
|||
}
|
||||
|
||||
.devtools-filterinput {
|
||||
background-image: url(chrome://devtools/skin/images/filter.svg);
|
||||
background-image: url(chrome://devtools/skin/images/filter-small.svg);
|
||||
}
|
||||
|
||||
.devtools-searchinput:-moz-locale-dir(rtl),
|
||||
.devtools-searchinput:dir(rtl),
|
||||
.devtools-filterinput:-moz-locale-dir(rtl),
|
||||
.devtools-filterinput:dir(rtl) {
|
||||
background-position-x: right 8px;
|
||||
background-position-x: right 7px;
|
||||
}
|
||||
|
||||
.devtools-searchinput .textbox-input::placeholder,
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
<!-- This Source Code Form is subject to the terms of the Mozilla Public
|
||||
- License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
- file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16" fill="context-fill #0c0c0d">
|
||||
<path d="M8.3 2.9l4.9 4.9c.2.2.5.4.8.1.2-.2.1-.5-.1-.8L11.6 5l1.8-1.8c.2-.2.4-.5.1-.8-.2-.2-.5-.1-.8.1L11 4.3l-2.1-2c-.2-.3-.5-.4-.8-.2-.2.3-.1.6.2.8zM10.4 7.4l-6.1 6-2.4.8.7-2.4 6.2-6.1-.7-.7L2 11c-.1.1-.2.3-.2.4L1 13.7s-.1.7.1 1c.3.3.9.3 1.2.2l2.3-.8c.2-.1.3-.1.4-.3L11 8l-.6-.6z"/>
|
||||
<path opacity="0.5" d="M7.1 7.1l-4.2 3.8-1.4 3.5 2.9-.6 2.8-2.7z"/>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" width="16" height="16">
|
||||
<path fill="context-fill" fill-rule="evenodd" d="M1.146 14.854c.748.747 1.96.747 2.708 0l6.542-6.543.897.896a1 1 0 1 0 1.414-1.414l-.9-.9 3.047-3.04a1.914 1.914 0 0 0-2.708-2.707L9.107 4.193l-.9-.9a1 1 0 0 0-1.414 1.414l.896.897-6.543 6.542a1.914 1.914 0 0 0 0 2.708zm.708-2a.914.914 0 1 0 1.292 1.292L9.69 7.604 8.396 6.31l-6.542 6.543z"/>
|
||||
</svg>
|
||||
|
|
До Ширина: | Высота: | Размер: 688 B После Ширина: | Высота: | Размер: 646 B |
|
@ -0,0 +1,7 @@
|
|||
<!-- This Source Code Form is subject to the terms of the Mozilla Public
|
||||
- License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
- file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 12 12">
|
||||
<path fill="context-fill" opacity=".4" d="M5 9.2l2 1.6V6.1L8.55 4h-5.1L5 6.1v3.1z"/>
|
||||
<path fill="context-fill" d="M1.18 2.6A1 1 0 0 1 2 1H10a1 1 0 0 1 .8 1.6L8 6.4v4.82c0 .63-.72.98-1.22.6l-2.5-1.99A.75.75 0 0 1 4 9.25V6.41L1.18 2.6zM2 2L5 6.09v3.04l2 1.59V6.09L10.01 2H2z"/>
|
||||
</svg>
|
После Ширина: | Высота: | Размер: 560 B |
|
@ -1,7 +1,7 @@
|
|||
<!-- This Source Code Form is subject to the terms of the Mozilla Public
|
||||
- License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
- file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16" fill="context-fill">
|
||||
<path fill-opacity=".3" d="M6.6 8.4c0-.6-1.7.3-1.7-.3 0-.4-1.7-2.7-1.7-2.7H13s-1.8 2-1.8 2.7c0 .3-2.1-.1-2.1.3v6.1H7s-.4-4.1-.4-6.1z"/>
|
||||
<path d="M2 2v2.3L4.7 9H6v5.4l2.1 1 1.8-.9V9h1.3L14 4.3V2H2zm11 2l-2.2 4H9v5.8l-.9.4-1.1-.5V8H5.2L3 4V3h10v1z"/>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" width="16" height="16">
|
||||
<path fill="context-fill" opacity=".4" d="M7 11.5L9 13V8.2L10.53 6H5.47L7 8.2v3.3z"/>
|
||||
<path fill="context-fill" d="M1.22 3.35A1.5 1.5 0 0 1 2.45 1h11.1a1.5 1.5 0 0 1 1.23 2.35L11 8.81v5.69a1.25 1.25 0 0 1-2 1l-3.5-2.63c-.31-.23-.5-.6-.5-1V8.81L1.22 3.35zM3.41 3L7 8.19v3.31L9 13V8.19L12.6 3H3.4z"/>
|
||||
</svg>
|
||||
|
|
До Ширина: | Высота: | Размер: 576 B После Ширина: | Высота: | Размер: 606 B |
|
@ -1,6 +1,7 @@
|
|||
<!-- 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" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg" fill="context-fill">
|
||||
<path d="M10.716 10.032C11.516 9.077 12 7.845 12 6.5 12 3.462 9.538 1 6.5 1S1 3.462 1 6.5 3.462 12 6.5 12c1.345 0 2.577-.483 3.532-1.284l4.143 4.142c.19.19.495.19.683 0 .19-.188.19-.494 0-.683l-4.142-4.143zM6.5 11C8.985 11 11 8.985 11 6.5S8.985 2 6.5 2 2 4.015 2 6.5 4.015 11 6.5 11z" fill-rule="evenodd"/>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" width="16" height="16">
|
||||
<path fill="context-fill" d="M15.707 14.293l-5-5-1.414 1.414 5 5a1 1 0 0 0 1.414-1.414z"/>
|
||||
<path fill="context-fill" fill-rule="evenodd" d="M6 10a4 4 0 1 0 0-8 4 4 0 0 0 0 8zm0 2A6 6 0 1 0 6 0a6 6 0 0 0 0 12z"/>
|
||||
</svg>
|
||||
|
|
До Ширина: | Высота: | Размер: 632 B После Ширина: | Высота: | Размер: 519 B |
|
@ -301,12 +301,20 @@
|
|||
}
|
||||
|
||||
.ruleview-overridden-rule-filter {
|
||||
background-image: url(chrome://devtools/skin/images/filter.svg#filterinput);
|
||||
background-size: 11px 11px;
|
||||
margin-inline-start: 5px;
|
||||
display: inline-block;
|
||||
width: 11px;
|
||||
height: 11px;
|
||||
width: 14px;
|
||||
height: 14px;
|
||||
margin-inline-start: 3px;
|
||||
background-image: url(chrome://devtools/skin/images/filter-small.svg);
|
||||
background-position: center;
|
||||
background-repeat: no-repeat;
|
||||
background-size: 12px;
|
||||
-moz-context-properties: fill;
|
||||
fill: var(--theme-icon-dimmed-color);
|
||||
}
|
||||
|
||||
.ruleview-overridden-rule-filter:hover {
|
||||
fill: var(--theme-icon-color);
|
||||
}
|
||||
|
||||
.ruleview-ruleopen {
|
||||
|
@ -632,10 +640,3 @@
|
|||
#class-panel-toggle::before {
|
||||
content: ".cls";
|
||||
}
|
||||
|
||||
.ruleview-overridden-rule-filter {
|
||||
opacity: 0.8;
|
||||
}
|
||||
.ruleview-overridden-rule-filter:hover {
|
||||
opacity: 1;
|
||||
}
|
||||
|
|
|
@ -29,7 +29,7 @@
|
|||
color: currentColor;
|
||||
background-image: url(chrome://devtools/skin/images/search.svg);
|
||||
background-repeat: no-repeat;
|
||||
background-size: 12px 12px;
|
||||
background-size: 12px;
|
||||
background-position: 10px 2px;
|
||||
-moz-context-properties: fill;
|
||||
fill: var(--theme-icon-dimmed-color);
|
||||
|
|
|
@ -78,6 +78,12 @@ WebConsoleConnectionProxy.prototype = {
|
|||
*/
|
||||
connected: false,
|
||||
|
||||
/**
|
||||
* Tells if the console is attached.
|
||||
* @type boolean
|
||||
*/
|
||||
isAttached: null,
|
||||
|
||||
/**
|
||||
* Timer used for the connection.
|
||||
* @private
|
||||
|
@ -128,7 +134,7 @@ WebConsoleConnectionProxy.prototype = {
|
|||
if (this.target.isBrowsingContext) {
|
||||
this.webConsoleFrame.onLocationChange(this.target.url, this.target.title);
|
||||
}
|
||||
this._attachConsole();
|
||||
this.isAttached = this._attachConsole();
|
||||
|
||||
return connPromise;
|
||||
},
|
||||
|
@ -149,6 +155,7 @@ WebConsoleConnectionProxy.prototype = {
|
|||
/**
|
||||
* Attach to the Web Console actor.
|
||||
* @private
|
||||
* @returns Promise
|
||||
*/
|
||||
_attachConsole: function() {
|
||||
const listeners = ["PageError", "ConsoleAPI", "NetworkActivity"];
|
||||
|
@ -157,7 +164,7 @@ WebConsoleConnectionProxy.prototype = {
|
|||
if (this.target.chrome && !this.target.isAddon) {
|
||||
listeners.push("ContentProcessMessages");
|
||||
}
|
||||
this.webConsoleClient.startListeners(listeners)
|
||||
return this.webConsoleClient.startListeners(listeners)
|
||||
.then(this._onAttachConsole, error => {
|
||||
console.error("attachConsole failed: " + error);
|
||||
this._connectDefer.reject(error);
|
||||
|
@ -228,7 +235,7 @@ WebConsoleConnectionProxy.prototype = {
|
|||
* @param object response
|
||||
* The JSON response object received from the server.
|
||||
*/
|
||||
_onCachedMessages: function(response) {
|
||||
_onCachedMessages: async function(response) {
|
||||
if (response.error) {
|
||||
console.error("Web Console getCachedMessages error: " + response.error +
|
||||
" " + response.message);
|
||||
|
@ -248,7 +255,7 @@ WebConsoleConnectionProxy.prototype = {
|
|||
|
||||
this.dispatchMessagesAdd(messages);
|
||||
if (!this.webConsoleClient.hasNativeConsoleAPI) {
|
||||
this.webConsoleFrame.logWarningAboutReplacedAPI();
|
||||
await this.webConsoleFrame.logWarningAboutReplacedAPI();
|
||||
}
|
||||
|
||||
this.connected = true;
|
||||
|
@ -395,13 +402,17 @@ WebConsoleConnectionProxy.prototype = {
|
|||
* @return object
|
||||
* A promise object that is resolved when disconnect completes.
|
||||
*/
|
||||
disconnect: function() {
|
||||
disconnect: async function() {
|
||||
if (this._disconnecter) {
|
||||
return this._disconnecter.promise;
|
||||
}
|
||||
|
||||
this._disconnecter = defer();
|
||||
|
||||
// allow the console to finish attaching if it started.
|
||||
if (this.isAttached) {
|
||||
await this.isAttached;
|
||||
}
|
||||
if (!this.client) {
|
||||
this._disconnecter.resolve(null);
|
||||
return this._disconnecter.promise;
|
||||
|
|
|
@ -154,7 +154,7 @@ WebConsoleFrame.prototype = {
|
|||
},
|
||||
|
||||
logWarningAboutReplacedAPI() {
|
||||
this.owner.target.logWarningInPage(l10n.getStr("ConsoleAPIDisabled"),
|
||||
return this.owner.target.logWarningInPage(l10n.getStr("ConsoleAPIDisabled"),
|
||||
"ConsoleAPIDisabled");
|
||||
},
|
||||
|
||||
|
|
|
@ -328,39 +328,6 @@ WebConsoleActor.prototype =
|
|||
* Destroy the current WebConsoleActor instance.
|
||||
*/
|
||||
destroy() {
|
||||
if (this.consoleServiceListener) {
|
||||
this.consoleServiceListener.destroy();
|
||||
this.consoleServiceListener = null;
|
||||
}
|
||||
if (this.netmonitors) {
|
||||
for (const { messageManager } of this.netmonitors) {
|
||||
messageManager.sendAsyncMessage("debug:destroy-network-monitor", {
|
||||
actorID: this.actorID,
|
||||
});
|
||||
}
|
||||
this.netmonitors = null;
|
||||
}
|
||||
if (this.consoleAPIListener) {
|
||||
this.consoleAPIListener.destroy();
|
||||
this.consoleAPIListener = null;
|
||||
}
|
||||
if (this.stackTraceCollector) {
|
||||
this.stackTraceCollector.destroy();
|
||||
this.stackTraceCollector = null;
|
||||
}
|
||||
if (this.consoleProgressListener) {
|
||||
this.consoleProgressListener.destroy();
|
||||
this.consoleProgressListener = null;
|
||||
}
|
||||
if (this.consoleReflowListener) {
|
||||
this.consoleReflowListener.destroy();
|
||||
this.consoleReflowListener = null;
|
||||
}
|
||||
if (this.contentProcessListener) {
|
||||
this.contentProcessListener.destroy();
|
||||
this.contentProcessListener = null;
|
||||
}
|
||||
|
||||
EventEmitter.off(this.parentActor, "changed-toplevel-document",
|
||||
this._onChangedToplevelDocument);
|
||||
|
||||
|
@ -375,6 +342,7 @@ WebConsoleActor.prototype =
|
|||
this.dbg.onConsoleMessage = null;
|
||||
}
|
||||
|
||||
this.stopListeners({ listeners: null });
|
||||
this._actorPool = null;
|
||||
this._webConsoleCommandsCache = null;
|
||||
this._lastConsoleInputEvaluation = null;
|
||||
|
@ -740,8 +708,8 @@ WebConsoleActor.prototype =
|
|||
// If no specific listeners are requested to be detached, we stop all
|
||||
// listeners.
|
||||
const toDetach = request.listeners ||
|
||||
["PageError", "ConsoleAPI", "NetworkActivity",
|
||||
"FileActivity", "ContentProcessMessages"];
|
||||
["PageError", "ConsoleAPI", "NetworkActivity", "FileActivity",
|
||||
"ReflowActivity", "ContentProcessMessages", "DocumentEvents"];
|
||||
|
||||
while (toDetach.length > 0) {
|
||||
const listener = toDetach.shift();
|
||||
|
|
|
@ -329,6 +329,11 @@ DebuggerClient.prototype = {
|
|||
client.detach(detachClients);
|
||||
return;
|
||||
}
|
||||
if (client.destroy) {
|
||||
client.destroy();
|
||||
detachClients();
|
||||
return;
|
||||
}
|
||||
detachClients();
|
||||
};
|
||||
detachClients();
|
||||
|
|
|
@ -668,13 +668,13 @@ WebConsoleClient.prototype = {
|
|||
* @return request
|
||||
* Request object that implements both Promise and EventEmitter interfaces
|
||||
*/
|
||||
stopListeners: function(listeners, onResponse) {
|
||||
stopListeners: function(listeners) {
|
||||
const packet = {
|
||||
to: this.actorID,
|
||||
type: "stopListeners",
|
||||
listeners: listeners,
|
||||
};
|
||||
return this._client.request(packet, onResponse);
|
||||
return this._client.request(packet);
|
||||
},
|
||||
|
||||
/**
|
||||
|
@ -696,20 +696,18 @@ WebConsoleClient.prototype = {
|
|||
},
|
||||
|
||||
/**
|
||||
* Close the WebConsoleClient. This stops all the listeners on the server and
|
||||
* detaches from the console actor.
|
||||
* Close the WebConsoleClient.
|
||||
*
|
||||
* @param function onResponse
|
||||
* Function to invoke when the server response is received.
|
||||
*/
|
||||
detach: function(onResponse) {
|
||||
destroy: function() {
|
||||
this._client.removeListener("evaluationResult", this.onEvaluationResult);
|
||||
this._client.removeListener("networkEvent", this.onNetworkEvent);
|
||||
this._client.removeListener("networkEventUpdate",
|
||||
this.onNetworkEventUpdate);
|
||||
this._client.removeListener("inspectObject", this.onInspectObject);
|
||||
this._client.removeListener("documentEvent", this.onDocEvent);
|
||||
this.stopListeners(null, onResponse);
|
||||
this._longStrings = null;
|
||||
this._client = null;
|
||||
this.pendingEvaluationResults.clear();
|
||||
|
|
|
@ -46,8 +46,8 @@ function onStartPageErrorAndConsoleAPI(aState, aResponse)
|
|||
ok(!aResponse.nativeConsoleAPI, "!nativeConsoleAPI");
|
||||
|
||||
top.console = top.console_;
|
||||
aState.client.stopListeners(["ConsoleAPI", "foo"],
|
||||
onStopConsoleAPI.bind(null, aState));
|
||||
aState.client.stopListeners(["ConsoleAPI", "foo"])
|
||||
.then(onStopConsoleAPI.bind(null, aState));
|
||||
}
|
||||
|
||||
function onStopConsoleAPI(aState, aResponse)
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||
* You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "WebAuthnCoseIdentifiers.h"
|
||||
#include "mozilla/dom/U2FHIDTokenManager.h"
|
||||
#include "mozilla/dom/WebAuthnUtil.h"
|
||||
#include "mozilla/ipc/BackgroundParent.h"
|
||||
|
@ -140,6 +141,31 @@ RefPtr<U2FRegisterPromise> U2FHIDTokenManager::Register(
|
|||
if (requirePlatformAttachment) {
|
||||
registerFlags |= U2F_FLAG_REQUIRE_PLATFORM_ATTACHMENT;
|
||||
}
|
||||
|
||||
nsTArray<CoseAlg> coseAlgos;
|
||||
for (const auto& coseAlg : extra.coseAlgs()) {
|
||||
switch (static_cast<CoseAlgorithmIdentifier>(coseAlg.alg())) {
|
||||
case CoseAlgorithmIdentifier::ES256:
|
||||
coseAlgos.AppendElement(coseAlg);
|
||||
break;
|
||||
default:
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
// Only if no algorithms were specified, default to the only CTAP 1 / U2F
|
||||
// protocol-supported algorithm. Ultimately this logic must move into
|
||||
// u2f-hid-rs in a fashion that doesn't break the tests.
|
||||
if (extra.coseAlgs().IsEmpty()) {
|
||||
coseAlgos.AppendElement(
|
||||
static_cast<int32_t>(CoseAlgorithmIdentifier::ES256));
|
||||
}
|
||||
|
||||
// If there are no acceptable/supported algorithms, reject the promise.
|
||||
if (coseAlgos.IsEmpty()) {
|
||||
return U2FRegisterPromise::CreateAndReject(NS_ERROR_DOM_NOT_SUPPORTED_ERR,
|
||||
__func__);
|
||||
}
|
||||
}
|
||||
|
||||
CryptoBuffer rpIdHash, clientDataHash;
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||
* You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "WebAuthnCoseIdentifiers.h"
|
||||
#include "mozilla/dom/U2FSoftTokenManager.h"
|
||||
#include "CryptoBuffer.h"
|
||||
#include "mozilla/Base64.h"
|
||||
|
@ -602,6 +603,30 @@ RefPtr<U2FRegisterPromise> U2FSoftTokenManager::Register(
|
|||
return U2FRegisterPromise::CreateAndReject(NS_ERROR_DOM_NOT_ALLOWED_ERR,
|
||||
__func__);
|
||||
}
|
||||
|
||||
nsTArray<CoseAlg> coseAlgos;
|
||||
for (const auto& coseAlg : extra.coseAlgs()) {
|
||||
switch (static_cast<CoseAlgorithmIdentifier>(coseAlg.alg())) {
|
||||
case CoseAlgorithmIdentifier::ES256:
|
||||
coseAlgos.AppendElement(coseAlg);
|
||||
break;
|
||||
default:
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
// Only if no algorithms were specified, default to the one the soft token
|
||||
// supports.
|
||||
if (extra.coseAlgs().IsEmpty()) {
|
||||
coseAlgos.AppendElement(
|
||||
static_cast<int32_t>(CoseAlgorithmIdentifier::ES256));
|
||||
}
|
||||
|
||||
// If there are no acceptable/supported algorithms, reject the promise.
|
||||
if (coseAlgos.IsEmpty()) {
|
||||
return U2FRegisterPromise::CreateAndReject(NS_ERROR_DOM_NOT_SUPPORTED_ERR,
|
||||
__func__);
|
||||
}
|
||||
}
|
||||
|
||||
CryptoBuffer rpIdHash, clientDataHash;
|
||||
|
|