Merge mozilla-central to mozilla-inbound. a=merge

This commit is contained in:
Cosmin Sabou 2018-08-24 00:46:31 +03:00
Родитель c7f063aba4 3211507dfb
Коммит b69e48dda2
79 изменённых файлов: 1336 добавлений и 1966 удалений

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

@ -1,5 +1,5 @@
<?xml version='1.0' encoding='UTF-8'?>
<blocklist lastupdate="1534336165428" xmlns="http://www.mozilla.org/2006/addons-blocklist">
<blocklist lastupdate="1534781959544" xmlns="http://www.mozilla.org/2006/addons-blocklist">
<emItems>
<emItem blockID="i334" id="{0F827075-B026-42F3-885D-98981EE7B1AE}">
<prefs/>
@ -2320,6 +2320,22 @@
<prefs/>
<versionRange minVersion="0" maxVersion="*" severity="3"/>
</emItem>
<emItem blockID="df852b6a-28be-4b10-9285-869f4761f111" id="/^((@svuznnqyxinw)|(myprivacytools@besttools\.com)|(powertools@penprivacy\.com)|(privacypro@mybestprivacy\.com)|(realsecure@top10\.com)|(rlbvpdfrlbgx@scoutee\.net)|(vfjkurlfijwz@scoutee\.net))$/">
<prefs/>
<versionRange minVersion="0" maxVersion="*" severity="3"/>
</emItem>
<emItem blockID="202fbae4-e904-430a-a244-63b0fb04385f" id="/^((de\.firefoxextension12345@asdf\.pl)|(deex1@de\.com)|(esex1@ese\.com)|(estrellach@protonmail\.com)|(fifi312@protonmail\.com)|(finex1@fin\.com)|(firefoxextension123@asdf\.pl)|(firefoxextension1234@asdf\.pl)|(firefoxextension12345@asdf\.pl)|(firefoxextension123456@asdf\.pl)|(frexff1@frexff1\.com)|(frexff2@frexff2\.com)|(frexff3@frexff3\.com)|(ind@niepodam\.pl)|(jacob4311@protonmail\.com)|(javonnu144@protonmail\.com)|(keellon33-ff@protonmail\.com)|(keellon33@protonmail\.com)|(masetoo4113@protonmail\.com)|(mikecosenti11@protonmail\.com)|(paigecho@protonmail\.com)|(salooo12@protonmail\.com)|(swex1@swe\.com)|(swex2@swe\.com)|(swex3@swe\.com)|(willburpoor@protonmail\.com)|(williamhibburn@protonmail\.com)|)$/">
<prefs/>
<versionRange minVersion="0" maxVersion="*" severity="3"/>
</emItem>
<emItem blockID="96b2e7d5-d4e4-425e-b275-086dc7ccd6ad" id="/^((firefox@browser-security\.de)|(firefox@smarttube\.io)|({0fde9597-0508-47ff-ad8a-793fa059c4e7})|(info@browser-privacy\.com)|({d3b98a68-fd64-4763-8b66-e15e47ef000a})|({36ea170d-2586-45fb-9f48-5f6b6fd59da7})|(youtubemp3converter@yttools\.io)|(simplysearch@dirtylittlehelpers\.com)|(extreme@smarttube\.io)|(selfdestructingcookies@dirtylittlehelpers\.com)|({27a1b6d8-c6c9-4ddd-bf20-3afa0ccf5040})|({2e9cae8b-ee3f-4762-a39e-b53d31dffd37})|(adblock@smarttube\.io)|({a659bdfa-dbbe-4e58-baf8-70a6975e47d0})|({f9455ec1-203a-4fe8-95b6-f6c54a9e56af})|({8c85526d-1be9-4b96-9462-aa48a811f4cf})|(mail@quick-buttons\.de)|(youtubeadblocker@yttools\.io)|(extension@browser-safety\.org)|(contact@web-security\.com)|(videodownloader@dirtylittlehelpers\.com)|(googlenotrack@dirtylittlehelpers\.com)|(develop@quick-amz\.com))$/">
<prefs/>
<versionRange minVersion="0" maxVersion="*" severity="3"/>
</emItem>
<emItem blockID="01c22882-868b-43e1-bb23-29d5dc7bc11b" id="/(({a4d84dae-7906-4064-911b-3ad2b1ec178b})|({d7e388c5-1cd0-4aa6-8888-9172f90951fb})|({a67f4004-855f-4e6f-8ef0-2ac735614967})|({25230eb3-db35-4613-8c03-e9a3912b7004})|({37384122-9046-4ff9-a31f-963767d9fe33})|({f1479b0b-0762-4ba2-97fc-010ea9dd4e73})|({53804e15-69e5-4b24-8883-c8f68bd98cf6})|({0f2aec80-aade-46b8-838c-54eeb595aa96})|({b65d6378-6840-4da6-b30e-dee113f680aa})|({e8fc3f33-14b7-41aa-88a1-d0d7b5641a50})|({c49ee246-d3d2-4e88-bfdb-4a3b4de9f974}))$/">
<prefs/>
<versionRange minVersion="0" maxVersion="*" severity="3"/>
</emItem>
</emItems>
<pluginItems>
<pluginItem blockID="p332">

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

@ -111,6 +111,9 @@ afterEvaluate {
"-Xlint:-deprecation",
// Serial, because we don't use Java serialization.
"-Xlint:-serial",
// Classfile, because javac has a bug with MethodParameters attributes
// with Java 7. https://bugs.openjdk.java.net/browse/JDK-8190452
"-Xlint:-classfile",
// Turn all remaining warnings into errors,
// unless marked by @SuppressWarnings.
"-Werror"]

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

@ -130,7 +130,6 @@ devtools.jar:
skin/images/filetypes/dir-close.svg (themes/images/filetypes/dir-close.svg)
skin/images/filetypes/dir-open.svg (themes/images/filetypes/dir-open.svg)
skin/images/filetypes/globe.svg (themes/images/filetypes/globe.svg)
skin/images/commandline-icon.svg (themes/images/commandline-icon.svg)
skin/images/alerticon-warning.png (themes/images/alerticon-warning.png)
skin/images/alerticon-warning@2x.png (themes/images/alerticon-warning@2x.png)
skin/rules.css (themes/rules.css)
@ -151,6 +150,10 @@ devtools.jar:
skin/images/breakpoint.svg (themes/images/breakpoint.svg)
skin/webconsole.css (themes/webconsole.css)
skin/images/webconsole.svg (themes/images/webconsole.svg)
skin/images/webconsole/alert.svg (themes/images/webconsole/alert.svg)
skin/images/webconsole/info.svg (themes/images/webconsole/info.svg)
skin/images/webconsole/input.svg (themes/images/webconsole/input.svg)
skin/images/webconsole/return.svg (themes/images/webconsole/return.svg)
skin/images/breadcrumbs-scrollbutton.svg (themes/images/breadcrumbs-scrollbutton.svg)
skin/animation.css (themes/animation.css)
skin/animationinspector.css (themes/animationinspector.css)
@ -303,6 +306,7 @@ devtools.jar:
content/netmonitor/src/assets/styles/Toolbar.css (netmonitor/src/assets/styles/Toolbar.css)
content/netmonitor/src/assets/styles/variables.css (netmonitor/src/assets/styles/variables.css)
content/netmonitor/src/assets/icons/play.svg (netmonitor/src/assets/icons/play.svg)
content/netmonitor/src/assets/icons/shield.svg (netmonitor/src/assets/icons/shield.svg)
content/netmonitor/index.html (netmonitor/index.html)
# Application panel

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

@ -868,6 +868,10 @@ netmonitor.security.connection=Connection:
# in the security tab describing the server certificate section.
netmonitor.security.certificate=Certificate:
# LOCALIZATION NOTE (netmonitor.trackingResource.tooltip): This is the label used
# in the Network monitor panel as a tooltip for tracking resource icon.
netmonitor.trackingResource.tooltip=This URL matches a known tracker and it would be blocked with Content Blocking enabled.
# LOCALIZATION NOTE (netmonitor.context.copy): This is the label displayed
# for the copy sub-menu in the context menu for a request
netmonitor.context.copy=Copy

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

@ -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 16 16">
<defs><style>.cls-1{fill:#737373;}</style></defs>
<path class="cls-1" d="M12.08,7.21a7.27,7.27,0,0,1-1.39,4.18A4.42,4.42,0,0,1,8,13.07a4.48,4.48,0,0,1-2.29-1.21l-.65.65A5.17,5.17,0,0,0,7.94,14h.11a5.22,5.22,0,0,0,3.38-2.05A8.16,8.16,0,0,0,13,7.29c.05-.61.07-1.85.07-2.79l-.93.93C12.13,6.11,12.12,6.81,12.08,7.21Z"/><path class="cls-1" d="M8,11.84V9.57L6.65,10.92A2.87,2.87,0,0,0,8,11.84Zm5.86-9.7a.46.46,0,0,0-.65,0l-.73.72A1.3,1.3,0,0,0,12,2.69L8,2,4,2.69a1.24,1.24,0,0,0-1,1.23c0,.93,0,2.62.07,3.37a8.69,8.69,0,0,0,1.11,4l-2,2a.46.46,0,1,0,.65.66h0L13.86,2.79A.46.46,0,0,0,13.86,2.14ZM5.23,4.67c0,1,0,1.83.07,2.21a9.66,9.66,0,0,0,.52,2.65l-1,1a8.12,8.12,0,0,1-.87-3.35c-.07-.74-.07-2.55-.07-3.29A.32.32,0,0,1,4.1,3.6L8,2.93l3.77.65L8,7.35V4.19Z"/>
</svg>

После

Ширина:  |  Высота:  |  Размер: 1.0 KiB

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

@ -386,6 +386,16 @@
background-image: url(chrome://devtools/skin/images/globe.svg);
}
.tracking-resource {
display: inline-block;
width: 16px;
height: 16px;
margin: 0 3px 0 -3px;
vertical-align: text-bottom;
background-image: url(chrome://devtools/content/netmonitor/src/assets/icons/shield.svg);
background-repeat: no-repeat;
}
/* RemoteIP column */
.requests-list-remoteip {

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

@ -33,10 +33,6 @@
align-items: center;
}
.devtools-toolbar-group .devtools-separator {
height: 24px;
}
.devtools-toolbar-two-rows-1,
.devtools-toolbar-two-rows-2,
.devtools-toolbar-single-row {

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

@ -55,6 +55,10 @@ class RequestListColumnDomain extends Component {
onMouseDown: onSecurityIconMouseDown,
title: iconTitle,
}),
item.isTrackingResource && div({
className: "tracking-resource",
title: L10N.getStr("netmonitor.trackingResource.tooltip"),
}),
host,
)
);

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

@ -71,6 +71,7 @@ class FirefoxDataProvider {
startedDateTime,
fromCache,
fromServiceWorker,
isTrackingResource,
} = data;
if (this.actionsEnabled && this.actions.addRequest) {
@ -89,6 +90,7 @@ class FirefoxDataProvider {
fromCache,
fromServiceWorker,
isTrackingResource,
}, true);
}
@ -323,6 +325,7 @@ class FirefoxDataProvider {
url,
},
startedDateTime,
isTrackingResource,
} = networkInfo;
await this.addRequest(actor, {
@ -333,6 +336,7 @@ class FirefoxDataProvider {
method,
startedDateTime,
url,
isTrackingResource,
});
this.emit(EVENTS.NETWORK_EVENT, actor);
@ -351,7 +355,9 @@ class FirefoxDataProvider {
switch (updateType) {
case "securityInfo":
this.pushRequestToQueue(actor, { securityState: networkInfo.securityState });
this.pushRequestToQueue(actor, {
securityState: networkInfo.securityState
});
break;
case "responseStart":
this.pushRequestToQueue(actor, {

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

@ -146,6 +146,7 @@ const UPDATE_PROPS = [
"responseCacheAvailable",
"formDataSections",
"stacktrace",
"isTrackingResource",
];
const PANELS = {

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

@ -37,6 +37,7 @@ support-files =
html_sorting-test-page.html
html_statistics-test-page.html
html_status-codes-test-page.html
html_tracking-protection.html
html_api-calls-test-page.html
html_copy-as-curl.html
html_curl-utils.html
@ -194,6 +195,7 @@ skip-if = true # Bug 1373558
[browser_net_timeline_ticks.js]
skip-if = true # TODO: fix the test
[browser_net_timing-division.js]
[browser_net_tracking-resources.js]
[browser_net_truncate.js]
[browser_net_view-source-debugger.js]
[browser_net_waterfall-click.js]

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

@ -0,0 +1,39 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
"use strict";
const { UrlClassifierTestUtils } =
ChromeUtils.import("resource://testing-common/UrlClassifierTestUtils.jsm", {});
const TEST_URI = "http://tracking.example.org/browser/devtools/client/" +
"netmonitor/test/html_tracking-protection.html";
registerCleanupFunction(function() {
UrlClassifierTestUtils.cleanupTestTrackers();
});
/**
* Test that tracking resources are properly marked in the Network panel.
*/
add_task(async function() {
await UrlClassifierTestUtils.addTestTrackers();
const { tab, monitor } = await initNetMonitor(TEST_URI);
info("Starting test...");
const { document, store, windowRequire } = monitor.panelWin;
const Actions = windowRequire("devtools/client/netmonitor/src/actions/index");
store.dispatch(Actions.batchEnable(false));
// Reload the page
const wait = waitForAllRequestsFinished(monitor);
tab.linkedBrowser.reload();
await wait;
const requests = document.querySelectorAll(".request-list-item .tracking-resource");
is(requests.length, 1, "There should be one tracking request");
await teardown(monitor);
});

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

@ -0,0 +1,12 @@
<!DOCTYPE HTML>
<!-- This Source Code Form is subject to the terms of the Mozilla Public
- License, v. 2.0. If a copy of the MPL was not distributed with this
- file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
<html dir="ltr" xml:lang="en-US" lang="en-US">
<head>
<meta charset="utf8">
</head>
<body>
<iframe src="http://tracking.example.com/"></iframe>
</body>
</html>

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

@ -780,6 +780,12 @@ checkbox:-moz-focusring {
transform: scaleX(1);
}
@media (prefers-reduced-motion) {
.devtools-tab-line {
transition: none;
}
}
.devtools-tab:not(.selected):focus .devtools-tab-line {
background: var(--tab-line-hover-color);
opacity: 1;

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

@ -285,10 +285,16 @@
}
.dbg-expression-arrow {
background-image: var(--theme-command-line-image-focus);
width: 16px;
height: 16px;
margin: 2px;
background-image: var(--theme-console-input-image);
width: 12px;
height: 12px;
margin: 4px;
-moz-context-properties: fill;
fill: #75BFFF;
}
.theme-light .dbg-expression-arrow {
fill: #0060DF;
}
.dbg-expression-input {

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

@ -2,6 +2,6 @@
- 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 #0b0b0b">
<path d="M5 3h3V2c0-.003-3 0-3 0-.002 0 0 1 0 1zm-5 .5A.5.5 0 0 1 .494 3h12.012a.5.5 0 0 1 0 1H.494A.502.502 0 0 1 0 3.5zM4 3V2c0-.553.444-1 1-1h3c.552 0 1 .443 1 1v1H4zM5 11V6a.5.5 0 0 0-1 0v5a.5.5 0 1 0 1 0zM7 11V6a.5.5 0 0 0-1 0v5a.5.5 0 1 0 1 0zM9 11V6a.5.5 0 0 0-1 0v5a.5.5 0 1 0 1 0z"/>
<path d="M3 4v9h7V4H3zm0-1h7a1 1 0 0 1 1 1v9a1 1 0 0 1-1 1H3a1 1 0 0 1-1-1V4a1 1 0 0 1 1-1z"/>
<path d="M6 3h3V2H6v1zm-5 .5c0-.3.2-.5.5-.5h12a.5.5 0 1 1 0 1h-12a.5.5 0 0 1-.5-.5zM5 3V2c0-.6.4-1 1-1h3c.6 0 1 .4 1 1v1H5zm1 8V6a.5.5 0 0 0-1 0v5a.5.5 0 1 0 1 0zm2 0V6a.5.5 0 0 0-1 0v5a.5.5 0 1 0 1 0zm2 0V6a.5.5 0 0 0-1 0v5a.5.5 0 1 0 1 0z"/>
<path d="M4 4v9h7V4H4zm0-1h7c.6 0 1 .4 1 1v9c0 .6-.4 1-1 1H4a1 1 0 0 1-1-1V4c0-.6.4-1 1-1z"/>
</svg>

До

Ширина:  |  Высота:  |  Размер: 723 B

После

Ширина:  |  Высота:  |  Размер: 673 B

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

@ -1,42 +0,0 @@
<!-- This Source Code Form is subject to the terms of the Mozilla Public
- License, v. 2.0. If a copy of the MPL was not distributed with this
- file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
<svg width="16px" height="16px" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
<defs>
<style>
g {
display: none;
}
#light-theme:target,
#light-theme-focus:target ~ #light-theme,
#dark-theme:target,
#dark-theme-focus:target ~ #dark-theme {
display: inline;
}
#light-theme-focus:target ~ #light-theme {
fill: #0060DF;
}
#dark-theme-focus:target ~ #dark-theme {
fill: #75BFFF;
}
/* Unfocused states */
#light-theme,
#dark-theme {
fill: rgba(128, 128, 128, .5);
}
</style>
</defs>
<g id="light-theme-focus"/>
<g id="light-theme">
<path d="M7.29 13.907l7-5a.5.5 0 0 0 .033-.789l-6.5-5.5a.5.5 0 1 0-.646.764l6.5 5.5.032-.789-7 5a.5.5 0 1 0 .582.814z"/>
<path d="M2.29 13.907l7-5a.5.5 0 0 0 .033-.789l-6.5-5.5a.5.5 0 1 0-.646.764l6.5 5.5.032-.789-7 5a.5.5 0 1 0 .582.814z"/>
</g>
<g id="dark-theme-focus"/>
<g id="dark-theme">
<path d="M7.29 13.907l7-5a.5.5 0 0 0 .033-.789l-6.5-5.5a.5.5 0 1 0-.646.764l6.5 5.5.032-.789-7 5a.5.5 0 1 0 .582.814z"/>
<path d="M2.29 13.907l7-5a.5.5 0 0 0 .033-.789l-6.5-5.5a.5.5 0 1 0-.646.764l6.5 5.5.032-.789-7 5a.5.5 0 1 0 .582.814z"/>
</g>
</svg>

До

Ширина:  |  Высота:  |  Размер: 1.4 KiB

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

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- This Source Code Form is subject to the terms of the Mozilla Public
- License, v. 2.0. If a copy of the MPL was not distributed with this
- file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 12 12" fill="context-fill #0b0b0b">
<path d="M1.12 9.4L5 1.6c.41-.81 1.58-.81 2 0l3.88 7.78a1.11 1.11 0 0 1-1 1.61H2.11a1.11 1.11 0 0 1-1-1.6zM6 8.4c-.55 0-1 .4-1 .9s.45.9 1 .9 1-.4 1-.9-.45-.9-1-.9zm0-4.9c-.55 0-1 .36-1 .8v2.4c0 .44.45.8 1 .8s1-.36 1-.8V4.3c0-.44-.45-.8-1-.8z"/>
</svg>

После

Ширина:  |  Высота:  |  Размер: 594 B

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

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- This Source Code Form is subject to the terms of the Mozilla Public
- License, v. 2.0. If a copy of the MPL was not distributed with this
- file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 12 12" fill="context-fill #0b0b0b">
<path d="M6 1a5 5 0 1 1 0 10A5 5 0 0 1 6 1zm0 1.5a1 1 0 1 1 0 2 1 1 0 0 1 0-2zm0 3c.55 0 1 .36 1 .8v2.4c0 .44-.45.8-1 .8s-1-.36-1-.8V6.3c0-.44.45-.8 1-.8z" fill-rule="evenodd"/>
</svg>

После

Ширина:  |  Высота:  |  Размер: 527 B

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

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- This Source Code Form is subject to the terms of the Mozilla Public
- License, v. 2.0. If a copy of the MPL was not distributed with this
- file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 12 12" fill="context-fill #0b0b0b">
<path d="M11.04 5.46L7.29 1.71a.75.75 0 0 0-1.06 1.06L9.45 6 6.23 9.21a.75.75 0 1 0 1.06 1.06l3.75-3.75c.3-.3.3-.77 0-1.06z"/>
<path d="M6.04 5.46L2.29 1.71a.75.75 0 0 0-1.06 1.06L4.45 6 1.23 9.21a.75.75 0 1 0 1.06 1.06l3.75-3.75c.3-.3.3-.77 0-1.06z"/>
</svg>

После

Ширина:  |  Высота:  |  Размер: 604 B

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

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- This Source Code Form is subject to the terms of the Mozilla Public
- License, v. 2.0. If a copy of the MPL was not distributed with this
- file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 12 12" fill="context-fill #0b0b0b">
<path d="M3.87 5.25h5.88a.75.75 0 1 1 0 1.5H3.89l2.46 2.46a.75.75 0 1 1-1.06 1.06L1.54 6.52a.75.75 0 0 1 0-1.06l3.75-3.75a.75.75 0 0 1 1.06 1.06L3.87 5.25z"/>
</svg>

После

Ширина:  |  Высота:  |  Размер: 508 B

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

@ -489,10 +489,6 @@ html, body, #app, #memory-tool {
vertical-align: middle;
}
.heap-tree-item-name .frame-link {
display: inline-block;
}
/**
* Heap tree view subcolumns
*/

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

@ -4,17 +4,20 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
/* CSS Variables specific to the devtools toolbar that aren't defined by the themes */
:root {
--magnifying-glass-image: url(chrome://devtools/skin/images/search.svg);
--filter-image: url(chrome://devtools/skin/images/filter.svg);
--tool-options-image: url(chrome://devtools/skin/images/tool-options.svg);
--separator-block-margin: 4px;
--separator-inline-margin: 1px;
}
.theme-light {
--searchbox-background-color: var(--theme-highlight-yellow);
--searchbox-border-color: #ffbf00;
--searcbox-no-match-background-color: #ffe5e5;
--searcbox-no-match-border-color: #e52e2e;
--magnifying-glass-image: url(chrome://devtools/skin/images/search.svg);
--filter-image: url(chrome://devtools/skin/images/filter.svg);
--tool-options-image: url(chrome://devtools/skin/images/tool-options.svg);
--separator-border-image: linear-gradient(transparent 4px, rgba(0,0,0,.1) 4px, rgba(0,0,0,.1) calc(100% - 4px), transparent calc(100% - 4px));
--separator-border-color: rgba(0,0,0,.1);
}
.theme-dark {
@ -22,12 +25,7 @@
--searchbox-border-color: #d99f2b;
--searcbox-no-match-background-color: #402325;
--searcbox-no-match-border-color: #cc3d3d;
--magnifying-glass-image: url(chrome://devtools/skin/images/search.svg);
--filter-image: url(chrome://devtools/skin/images/filter.svg);
--tool-options-image: url(chrome://devtools/skin/images/tool-options.svg);
--separator-border-image: linear-gradient(transparent 4px, rgba(100%,100%,100%,.2) 4px, rgba(100%,100%,100%,.2) calc(100% - 4px), transparent calc(100% - 4px));
--separator-border-color: rgba(100%,100%,100%,.2);
}
/* Toolbars */
@ -73,10 +71,20 @@
border-bottom: none;
}
/* Expected space around a separator:
* -----------------------
* 4
* [button] 2 | 2 [button]
* 4
* -----------------------
* We're using a 1px horizontal margin, since buttons already have their own
* 1px horizontal margin, and margins don't collapse between flex items.
* Some separators may be using a bigger, 6px horizontal margin.
*/
.devtools-separator {
border-inline-start: 1px solid;
border-image: var(--separator-border-image) 1 1;
height: inherit;
border-inline-start: 1px solid var(--separator-border-color);
height: calc(100% - 2 * var(--separator-block-margin));
margin: var(--separator-block-margin) var(--separator-inline-margin);
}
/* In-tools sidebar */

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

@ -205,9 +205,12 @@
margin-inline-end: 3px;
}
#toolbox-buttons-start > .devtools-separator {
--separator-inline-margin: 0;
}
#toolbox-buttons-end > .devtools-separator {
margin-inline-start: 5px;
margin-inline-end: 5px;
--separator-inline-margin: 5px;
}
#toolbox-close {

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

@ -102,10 +102,6 @@
--theme-arrowpanel-dimmed-further: hsla(0,0%,80%,.45);
--theme-arrowpanel-disabled-color: GrayText;
/* Command line */
--theme-command-line-image: url(chrome://devtools/skin/images/commandline-icon.svg#light-theme);
--theme-command-line-image-focus: url(chrome://devtools/skin/images/commandline-icon.svg#light-theme-focus);
--theme-codemirror-gutter-background: #f4f4f4;
--theme-messageCloseButtonFilter: invert(0);
}
@ -209,10 +205,6 @@
--theme-arrowpanel-dimmed-further: rgba(249,249,250,.15);
--theme-arrowpanel-disabled-color: rgba(249,249,250,.5);
/* Command line */
--theme-command-line-image: url(chrome://devtools/skin/images/commandline-icon.svg#dark-theme);
--theme-command-line-image-focus: url(chrome://devtools/skin/images/commandline-icon.svg#dark-theme-focus);
--theme-codemirror-gutter-background: #262b37;
--theme-messageCloseButtonFilter: invert(1);
}
@ -244,6 +236,10 @@
--select-arrow-image: url(chrome://devtools/skin/images/select-arrow.svg);
--theme-pane-collapse-image: url(chrome://devtools/skin/images/pane-collapse.svg);
--theme-pane-expand-image: url(chrome://devtools/skin/images/pane-expand.svg);
--theme-console-alert-image: url(chrome://devtools/skin/images/webconsole/alert.svg);
--theme-console-info-image: url(chrome://devtools/skin/images/webconsole/info.svg);
--theme-console-input-image: url(chrome://devtools/skin/images/webconsole/input.svg);
--theme-console-return-image: url(chrome://devtools/skin/images/webconsole/return.svg);
/* Firefox Colors CSS Variables v1.0.3
* Colors are taken from: https://github.com/FirefoxUX/design-tokens */

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

@ -3,10 +3,52 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
/* Webconsole specific theme variables */
:root {
/* Output rows should be 20px tall for a single line of text;
* 20 = 3 (top padding) + 14 (line-height) + 3 (bottom padding)
*/
--console-output-font-size: 11px;
--console-output-line-height: calc(14 / 11);
--console-output-vertical-padding: 3px;
/* Width of the left gutter where icons appear */
--console-inline-start-gutter: 32px;
/* Icons perfectly centered in the left gutter "feel" closer to the window
* edge than to message text. This value pushes them slightly to the right. */
--console-icon-horizontal-offset: 1px;
}
.theme-dark {
--console-arrow-color: hsl(210, 6%, 52%);
--console-input-icon-color: hsl(0, 0%, 50%, 0.5);
--console-input-icon-focused: hsl(210, 100%, 73%);
--console-output-icon-info: hsl(210, 6%, 52%);
--console-output-icon-input: hsl(210, 6%, 76%);
--console-output-icon-error: hsl(0, 100%, 65%);
--console-output-icon-warning: hsl(36, 100%, 60%);
--console-output-indent-border-color: var(--theme-highlight-blue);
--error-color: hsl(0, 100%, 79%);
--error-background-color: hsl(352, 79%, 62%, 0.17);
--warning-color: hsl(43, 94%, 81%);
--warning-background-color: hsl(42, 37%, 19%);
--console-output-color: white;
--repeat-bubble-background-color: var(--blue-60);
}
.theme-light {
--error-color: #FF0000;
--error-background-color: #FFEBEB;
--warning-background-color: #FFFFC8;
--console-arrow-color: hsl(210, 6%, 67%);
--console-input-icon-color: hsl(210, 6%, 75%);
--console-input-icon-focused: hsl(210, 100%, 44%);
--console-output-icon-info: hsl(210, 6%, 67%);
--console-output-icon-input: hsl(210, 6%, 34%);
--console-output-icon-error: hsl(0, 90%, 45%);
--console-output-icon-warning: hsl(36, 100%, 45%);
--console-output-indent-border-color: var(--theme-highlight-blue);
--error-color: var(--red-70);
--error-background-color: hsl(344, 73%, 97%);
--warning-color: var(--yellow-80);
--warning-background-color: hsl(54, 100%, 92%);
--console-output-color: var(--grey-90);
--repeat-bubble-background-color: var(--theme-highlight-blue);
}
/* General output styles */
@ -27,78 +69,136 @@ a {
.message {
display: flex;
padding: 0 7px;
width: 100%;
box-sizing: border-box;
/* Avoid vertical padding, so that we can draw full-height items (e.g. indent guides).
* Use vertical margins on children instead. */
padding-inline-start: 1px;
padding-inline-end: 8px;
border-inline-start: solid 3px transparent;
font-size: var(--console-output-font-size);
line-height: var(--console-output-line-height);
}
.message:hover {
border-inline-start-color: var(--theme-highlight-blue);
}
.message.error {
color: var(--error-color);
background-color: var(--error-background-color);
}
.message.warn {
color: var(--warning-color);
background-color: var(--warning-background-color);
}
.message.startGroup,
.message.startGroupCollapsed {
--console-output-indent-border-color: transparent;
}
.message > .prefix,
.message > .timestamp {
flex: none;
color: var(--theme-comment);
margin: 3px 6px 0 0;
margin: var(--console-output-vertical-padding) 4px;
}
@media (max-width: 500px) {
.message > .timestamp {
display: none;
}
}
.message > .indent {
flex: none;
display: inline-block;
margin-inline-start: 12px;
border-inline-end: solid 1px var(--console-output-indent-border-color);
}
.message > .indent[data-indent="0"] {
display: none;
}
/* Center first level indent within the left gutter */
.message:not(.startGroup):not(.startGroupCollapsed) > .indent[data-indent="1"] {
margin-inline-start: calc(1px + var(--console-icon-horizontal-offset));
margin-inline-end: calc(11px - var(--console-icon-horizontal-offset));
}
.message > .icon {
flex: none;
margin: 3px 6px 0 0;
padding: 0 4px;
height: 1em;
align-self: flex-start;
}
.theme-light .message.error {
color: var(--error-color);
background-color: var(--error-background-color);
}
.theme-light .message.warn {
background-color: var(--warning-background-color);
}
.message > .icon::before {
content: "";
background-image: url(chrome://devtools/skin/images/webconsole.svg);
background-position: 12px 12px;
/* Width and height must be a multiples of 2px to avoid blurry images.
* Height should match the text's line-height for optimal vertical alignment */
width: 14px;
height: 14px;
margin: var(--console-output-vertical-padding) 4px;
background-image: none;
background-position: 50% 50%;
background-repeat: no-repeat;
background-size: 72px 60px;
width: 12px;
height: 12px;
display: inline-block;
background-size: 12px 12px;
-moz-context-properties: fill;
fill: currentColor;
}
.theme-light .message > .icon::before {
background-image: url(chrome://devtools/skin/images/webconsole.svg#light-icons);
/* Icon on unindented row should be centered within the left gutter */
.message > .indent[data-indent="0"] + .icon {
width: 24px;
margin-inline-start: var(--console-icon-horizontal-offset);
margin-inline-end: calc(4px - var(--console-icon-horizontal-offset));
}
.message.command > .icon {
color: var(--console-output-icon-input);
background-image: var(--theme-console-input-image);
}
.message.result > .icon {
color: var(--console-output-icon-info);
background-image: var(--theme-console-return-image);
}
.message.info > .icon {
color: var(--console-output-icon-info);
background-image: var(--theme-console-info-image);
}
.message.error > .icon {
color: var(--console-output-icon-error);
background-image: var(--theme-console-alert-image);
}
.message.warn > .icon {
color: var(--console-output-icon-warning);
background-image: var(--theme-console-alert-image);
}
.message > .message-body-wrapper {
flex: auto;
min-width: 0px;
margin: 3px;
margin: var(--console-output-vertical-padding) 0;
}
.message-body-wrapper .table-widget-body {
overflow: visible;
}
/* The red bubble that shows the number of times a message is repeated */
/* The bubble that shows the number of times a message is repeated */
.message-repeats {
-moz-user-select: none;
flex-shrink: 0;
margin: 2px 6px;
margin: 2px 5px;
padding: 0 6px;
height: 1.25em;
color: white;
background-color: red;
background-color: var(--repeat-bubble-background-color);
border-radius: 40px;
font: message-box;
font-size: 0.9em;
font-weight: 600;
margin-inline-start: 5px;
font-size: 0.8em;
font-weight: normal;
}
.message-repeats[value="1"] {
@ -157,10 +257,6 @@ a {
/* Network styles */
.theme-dark .message.error {
background-color: rgba(235, 83, 104, 0.17);
}
.console-string {
color: var(--theme-highlight-lightorange);
}
@ -172,10 +268,6 @@ a {
color: #f5f7fa !important; /* Selection Text Color */
}
.message.network.error > .icon::before {
background-position: -12px 0;
}
.message.network > .message-body {
display: flex;
flex-wrap: wrap;
@ -221,54 +313,6 @@ a {
margin-inline-end: 1ex;
}
/* CSS styles */
.message.cssparser > .indent {
border-inline-end: solid #00b6f0 6px;
}
.message.cssparser.error > .icon::before {
background-position: -12px -12px;
}
.message.cssparser.warn > .icon::before {
background-position: -24px -12px;
}
/* JS styles */
.message.exception > .indent {
border-inline-end: solid #fb9500 6px;
}
.message.exception.error > .icon::before {
background-position: -12px -24px;
}
.message.exception.warn > .icon::before {
background-position: -24px -24px;
}
/* Web Developer styles */
.message.console-api > .indent {
border-inline-end: solid #cbcbcb 6px;
}
/* Input and output styles */
.message.command > .indent,
.message.result > .indent {
border-inline-end: solid #808080 6px;
}
.message.command > .icon::before {
background-position: -48px -36px;
}
.message.result > .icon::before {
background-position: -60px -36px;
}
/* JSTerm Styles */
html .jsterm-input-node-html,
@ -284,13 +328,17 @@ html #webconsole-notificationbox {
}
.jsterm-input-node {
background-image: var(--theme-command-line-image);
background-repeat: no-repeat;
background-size: 16px 16px;
background-position: 4px 4px;
color: var(--theme-content-color1);
box-sizing: border-box;
height: 100%;
color: var(--theme-content-color1);
/* input icon */
background-image: var(--theme-console-input-image);
background-position-x: calc(10px + var(--console-icon-horizontal-offset));
background-position-y: 7px;
background-repeat: no-repeat;
background-size: 12px 12px;
-moz-context-properties: fill;
fill: var(--console-input-icon-color);
}
.jsterm-complete-node {
@ -314,8 +362,8 @@ textarea.jsterm-complete-node {
font-size: inherit;
line-height: 16px;
overflow-x: hidden;
padding: 4px 0;
padding-inline-start: 20px;
padding: 5px 0;
padding-inline-start: var(--console-inline-start-gutter);
}
textarea.jsterm-complete-node {
@ -327,25 +375,29 @@ textarea.jsterm-complete-node {
}
textarea.jsterm-input-node:focus {
background-image: var(--theme-command-line-image-focus);
fill: var(--console-input-icon-focused);
box-shadow: none;
outline: none;
}
/* CodeMirror-powered JsTerm */
.jsterm-cm .jsterm-input-container > .CodeMirror {
font-size: inherit;
line-height: 16px;
padding-inline-start: 20px;
font-size: var(--console-output-font-size);
line-height: var(--console-output-line-height);
/* aim for a 32px left space (a descendent has 4px padding) */
padding-inline-start: calc(var(--console-inline-start-gutter) - 4px);
/* input icon */
background-image: var(--theme-command-line-image);
background-image: var(--theme-console-input-image);
background-position-x: calc(10px + var(--console-icon-horizontal-offset));
background-position-y: 5px;
background-repeat: no-repeat;
background-size: 16px 16px;
background-position: 4px 4px;
background-size: 12px 12px;
-moz-context-properties: fill;
fill: var(--console-input-icon-color);
}
.jsterm-cm .jsterm-input-container > .CodeMirror-focused {
background-image: var(--theme-command-line-image-focus);
fill: var(--console-input-icon-focused);
}
.jsterm-cm .cm-auto-complete-shadow-text::after {
@ -355,24 +407,12 @@ textarea.jsterm-input-node:focus {
/* Security styles */
.message.security > .indent {
border-inline-end: solid red 6px;
}
.message.security.error > .icon::before {
background-position: -12px -48px;
}
.message.security.warn > .icon::before {
background-position: -24px -48px;
}
.navigation-marker {
color: #aaa;
background: linear-gradient(#aaa, #aaa) no-repeat left 50%;
background-size: 100% 2px;
margin-top: 6px;
margin-bottom: 6px;
margin-block-start: 6px;
margin-block-end: 6px;
font-size: 0.9em;
}
@ -388,11 +428,14 @@ textarea.jsterm-input-node:focus {
.stacktrace {
display: none;
padding: 5px 10px;
margin: 5px 0 0 0;
overflow-y: auto;
border: 1px solid var(--theme-splitter-color);
border-radius: 3px;
margin-block-start: 5px;
margin-block-end: var(--attachment-margin-block-end);
padding-inline-start: 4px;
}
.message.open .stacktrace {
display: block;
}
.consoletable {
@ -409,24 +452,9 @@ textarea.jsterm-input-node:focus {
line-height: 1.25em;
}
.theme-light .message.error .stacktrace {
background-color: rgba(255, 255, 255, 0.5);
}
.theme-dark .message.error .stacktrace {
background-color: rgba(0, 0, 0, 0.5);
}
.message.open .stacktrace {
display: block;
}
.message .theme-twisty {
position: relative;
top: 0.1em;
}
/*Do not mirror the twisty because container force to ltr */
/* Do not mirror the twisty because container force to ltr
* (theme-twisty still used in network request details)
*/
.message .theme-twisty:dir(rtl),
.message .theme-twisty:-moz-locale-dir(rtl) {
transform: none;
@ -449,8 +477,8 @@ a.learn-more-link.webconsole-learn-more-link {
/* Open DOMNode in inspector button */
.open-inspector {
background: url("chrome://devtools/skin/images/vview-open-inspector.png") no-repeat 0 0;
padding-left: 16px;
margin-left: 5px;
padding-inline-start: 16px;
margin-inline-start: 5px;
cursor: pointer;
}
@ -462,35 +490,10 @@ a.learn-more-link.webconsole-learn-more-link {
filter: var(--theme-icon-checked-filter) brightness(0.9);
}
@media (max-width: 500px) {
.message > .timestamp {
display: none;
}
}
#output-container {
height: 100%;
}
/* Webconsole specific theme variables */
.theme-light .webconsole-output-wrapper {
--error-color: var(--red-70);
--error-background-color: #FDF2F5;
--warning-color: var(--yellow-80);
--warning-background-color: #FFFBD5;
--console-output-color: var(--grey-90);
--repeat-bubble-background-color: var(--theme-highlight-blue);
}
.theme-dark .webconsole-output-wrapper {
--error-color: #FF9494;
--error-background-color: #442923;
--warning-color: #FCE19F;
--warning-background-color: #44391F;
--console-output-color: white;
--repeat-bubble-background-color: var(--blue-60);
}
/*
This element contains the different toolbars in the console
- primary, containing the clear messages button and the text search input.
@ -538,6 +541,7 @@ a.learn-more-link.webconsole-learn-more-link {
}
.devtools-toolbar.webconsole-filterbar-secondary {
--separator-inline-margin: 5px;
display: flex;
width: 100%;
align-items: center;
@ -569,7 +573,7 @@ a.learn-more-link.webconsole-learn-more-link {
.webconsole-filterbar-primary .devtools-plaininput {
flex: 1 1 100%;
align-self: stretch;
margin-left: 1px;
margin-inline-start: 1px;
padding-inline-start: 4px;
border: 1px solid transparent;
}
@ -588,10 +592,6 @@ a.learn-more-link.webconsole-learn-more-link {
-moz-user-select: none;
}
.webconsole-filterbar-secondary .devtools-separator {
margin: 0 5px;
}
.webconsole-filterbar-filtered-messages {
/* Needed so the bar takes the whole horizontal space when it is wrapped */
flex-grow: 1;
@ -623,27 +623,6 @@ a.learn-more-link.webconsole-learn-more-link {
margin-inline-start: 0.5em;
}
.webconsole-output-wrapper .message {
--border-size: 3px;
border-inline-start: var(--border-size) solid transparent;
}
.webconsole-output-wrapper .message:hover {
border-inline-start-color: var(--theme-highlight-blue);
}
.webconsole-output-wrapper .message.warn.warn {
background-color: var(--warning-background-color);
}
.webconsole-output-wrapper .message.error .message-body {
color: var(--error-color);
}
.webconsole-output-wrapper .message.warn .message-body {
color: var(--warning-color);
}
/* Special casing String reps so they are legible */
.webconsole-output-wrapper .message .message-body > .objectBox-string {
color: currentColor;
@ -684,44 +663,6 @@ a.learn-more-link.webconsole-learn-more-link {
font-weight: bold;
}
.webconsole-output-wrapper .message > .icon {
margin: var(--icon-top-margin) 0 0 0;
padding: 0 0 0 6px;
}
.webconsole-output-wrapper .message.error > .icon::before {
/* Red warning icon */
background-position: -24px -48px;
}
.webconsole-output-wrapper .message.warn > .icon::before {
/* Yellow warning icon */
background-position: -24px -24px;
}
.webconsole-output-wrapper .message .theme-twisty {
margin: calc(var(--icon-top-margin) - 1px) 0 0 0;
}
.message.error > .icon::before {
background-position: -12px -36px;
}
.message.warn > .icon::before {
background-position: -24px -36px;
}
.message.info > .icon::before {
background-position: -36px -36px;
}
/* The bubble that shows the number of times a message is repeated */
.webconsole-output-wrapper .message-repeats {
background-color: var(--repeat-bubble-background-color);
font-weight: normal;
font-size: 0.8em;
}
/* Prefix text that can be set by ConsoleAPI option */
.webconsole-output-wrapper .console-message-prefix {
color: var(--theme-comment);
@ -784,7 +725,8 @@ a.learn-more-link.webconsole-learn-more-link {
.network.message .network-info {
display: none;
margin-top: 8px;
margin-block-start: 6px;
margin-block-end: 2px;
border: solid 1px var(--theme-splitter-color);
}
@ -808,27 +750,6 @@ a.learn-more-link.webconsole-learn-more-link {
flex-wrap: wrap;
}
/* Output Wrapper */
.webconsole-output-wrapper .message .indent {
display: inline-block;
border-inline-end: solid 1px var(--console-output-indent-border-color);
}
.webconsole-output-wrapper .message .indent[data-indent="0"] {
border-inline-end: none;
}
.message.startGroup .indent,
.message.startGroupCollapsed .indent {
border-inline-end-color: transparent;
margin-inline-end: 5px;
}
.message.startGroup .icon,
.message.startGroupCollapsed .icon {
display: none;
}
/*
* Open DOMNode in inspector button. Style need to be reset in the new
* console since its style is already defined in reps.css .
@ -837,19 +758,6 @@ a.learn-more-link.webconsole-learn-more-link {
background-image: unset;
}
/* Stacktraces */
.webconsole-output-wrapper .stacktrace {
border: none;
margin-block-end: var(--attachment-margin-block-end);
padding: 0 0 0 4px;
}
.theme-dark .webconsole-output-wrapper .message.error .stacktrace,
.theme-light .webconsole-output-wrapper .message.error .stacktrace {
/* Removing specificity from the old console */
background-color: inherit;
}
/* console.table() */
.new-consoletable {
width: 100%;
@ -932,10 +840,6 @@ body #output-container {
* +------------------------------+--------------+
*/
.webconsole-output-wrapper {
-moz-user-focus: normal;
color: var(--console-output-color);
--console-output-indent-border-color: var(--theme-selection-background);
--icon-top-margin: 3px;
--object-inspector-hover-background: transparent;
--attachment-margin-block-end: 3px;
--primary-toolbar-height: 29px;
@ -946,6 +850,8 @@ body #output-container {
height: 100vh !important;
width: 100vw;
overflow: hidden;
color: var(--console-output-color);
-moz-user-focus: normal;
}
.webconsole-flex-wrapper {
@ -968,7 +874,6 @@ body #output-container {
min-height: 19px;
}
.webconsole-output-wrapper #webconsole-notificationbox {
flex-shrink: 0;
}
@ -976,7 +881,10 @@ body #output-container {
.webconsole-output-wrapper .jsterm-input-container {
min-height: 28px;
overflow: auto;
padding-top: 1px;
}
.jsterm-cm .jsterm-input-container {
padding-block-start: 2px;
}
.webconsole-flex-wrapper > .webconsole-output:empty ~ .jsterm-input-container {
@ -1006,45 +914,69 @@ body #output-container {
* used in the ObjectInspector (same background-image, width, transition).
* Properties were copied from devtools/client/shared/components/reps/reps.css.
*/
.webconsole-output-wrapper img.collapse-button.arrow {
.collapse-button {
flex: none;
align-self: flex-start;
margin-block-start: var(--console-output-vertical-padding);
margin-inline-start: -3px;
margin-inline-end: 0;
padding: 2px 4px;
border: none;
background: transparent;
}
.collapse-button::before {
content: "";
display: block;
width: 10px;
height: 10px;
mask: url("chrome://devtools/skin/images/devtools-components/arrow.svg") no-repeat;
mask-size: 100%;
width: 9px;
height: 9px;
margin-block-start: 5px;
margin-inline-start: 4px;
margin-inline-end: 1px;
transform: rotate(-90deg);
transition: transform 0.125s ease;
background-color: var(--console-arrow-color);
}
/*
* We need to override the margin for group arrow in order to keep the alignment
* with the indent border.
*/
.webconsole-output-wrapper .message.startGroup img.collapse-button.arrow,
.webconsole-output-wrapper .message.startGroupCollapsed img.collapse-button.arrow {
margin-inline-start: 2px;
.collapse-button[aria-expanded="true"]::before {
transform: rotate(0);
}
html[dir="rtl"] .webconsole-output-wrapper img.collapse-button.arrow:not(.expanded) {
transform: rotate(90deg);
.collapse-button::-moz-focus-inner {
border: none;
}
.webconsole-output-wrapper img.collapse-button.arrow.expanded {
transform: rotate(0deg);
/* Larger collapse buttons for groups and network requests */
.message.network > .collapse-button,
.message.startGroup .collapse-button,
.message.startGroupCollapsed .collapse-button {
margin-inline-start: 0;
padding-inline-start: 6px;
padding-inline-end: 6px;
}
/* Apply the same color to both message arrows and ObjectInspector ones. */
.webconsole-output-wrapper .message img.arrow,
.webconsole-output-wrapper .sidebar img.arrow {
background-color: #AFA8AB;
/* Hide the icon, so that we can use the collapse-button in its place */
.message.network > .icon,
.message.startGroup > .icon,
.message.startGroupCollapsed > .icon {
display: none;
}
.theme-dark .webconsole-output-wrapper .message img.arrow,
.theme-dark .webconsole-output-wrapper .sidebar img.arrow {
background-color: #7F7E81;
/* Center the collapse button in the left gutter (first-level only) */
.message.network > .collapse-button,
.message.startGroup > .indent[data-indent="0"] ~ .collapse-button,
.message.message.startGroupCollapsed > .indent[data-indent="0"] ~ .collapse-button {
margin-inline-start: calc(1px + var(--console-icon-horizontal-offset));
margin-inline-end: calc(5px - var(--console-icon-horizontal-offset));
}
/* Apply a style similar to collapse-button for the object tree arrows */
.webconsole-output-wrapper .tree .arrow,
.webconsole-output-wrapper .object-inspector .tree-node .arrow {
width: 10px;
height: 10px;
vertical-align: 0px;
line-height: 1;
background-color: var(--console-arrow-color);
}
/* Sidebar */
@ -1084,7 +1016,8 @@ html[dir="rtl"] .webconsole-output-wrapper img.collapse-button.arrow:not(.expand
.sidebar-contents {
grid-row: 2 / 3;
overflow: scroll;
overflow: auto;
max-height: 100%;
}
.webconsole-sidebar-toolbar .sidebar-close-button {
@ -1101,10 +1034,6 @@ html[dir="rtl"] .webconsole-output-wrapper img.collapse-button.arrow:not(.expand
min-width: 100%;
}
.theme-twisty {
cursor: default;
}
#split-console-close-button::before {
fill: var(--theme-toolbar-photon-icon-color);
background-image: var(--close-button-image);

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

@ -18,14 +18,10 @@ function CollapseButton(props) {
title = messageToggleDetails,
} = props;
const classes = ["arrow", "collapse-button"];
if (open) {
classes.push("expanded");
}
return dom.img({
className: classes.join(" "),
return dom.button({
"aria-expanded": open ? "true" : "false",
"aria-label": title,
className: "arrow collapse-button",
onClick,
title: title,
});

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

@ -266,6 +266,7 @@ stubPackets.set(`GET request`, {
"timings": {},
"updates": [],
"private": false,
"isTrackingResource": false,
"from": "server1.conn0.child1/consoleActor2"
});
@ -317,6 +318,7 @@ stubPackets.set(`XHR GET request`, {
"timings": {},
"updates": [],
"private": false,
"isTrackingResource": false,
"from": "server1.conn1.child1/consoleActor2"
});
@ -368,6 +370,7 @@ stubPackets.set(`XHR POST request`, {
"timings": {},
"updates": [],
"private": false,
"isTrackingResource": false,
"from": "server1.conn2.child1/consoleActor2"
});

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

@ -350,6 +350,7 @@ skip-if = verify
[browser_webconsole_shows_reqs_from_netmonitor.js]
[browser_webconsole_shows_reqs_in_netmonitor.js]
[browser_webconsole_sidebar_object_expand_when_message_pruned.js]
[browser_webconsole_sidebar_scroll.js]
[browser_webconsole_sourcemap_css.js]
[browser_webconsole_sourcemap_error.js]
[browser_webconsole_sourcemap_invalid.js]

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

@ -0,0 +1,39 @@
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
/* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/ */
// Test that the sidebar can be scrolled.
"use strict";
const TEST_URI = `data:text/html;charset=utf8,Test sidebar scroll`;
add_task(async function() {
// Should be removed when sidebar work is complete
await pushPref("devtools.webconsole.sidebarToggle", true);
const isMacOS = Services.appinfo.OS === "Darwin";
const hud = await openNewTabAndConsole(TEST_URI);
const onMessage = waitForMessage(hud, "Document");
ContentTask.spawn(gBrowser.selectedBrowser, null, function() {
content.wrappedJSObject.console.log(content.wrappedJSObject.document);
});
const {node} = await onMessage;
const object = node.querySelector(".object-inspector .node");
info("Ctrl+click on an object to put it in the sidebar");
const onSidebarShown = waitFor(() => hud.ui.document.querySelector(".sidebar"));
EventUtils.sendMouseEvent({
type: "click",
[isMacOS ? "metaKey" : "ctrlKey"]: true
}, object, hud.ui.window);
await onSidebarShown;
const sidebarContents = hud.ui.document.querySelector(".sidebar-contents");
// Let's wait until the object is fully expanded.
await waitFor(() => sidebarContents.querySelectorAll(".node").length > 1);
ok(sidebarContents.scrollHeight > sidebarContents.clientHeight, "Sidebar overflows");
});

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

@ -65,6 +65,7 @@ const NetworkEventActor = protocol.ActorClassWithSpec(networkEventSpec, {
fromCache: this._fromCache,
fromServiceWorker: this._fromServiceWorker,
private: this._private,
isTrackingResource: this._isTrackingResource,
};
},
@ -103,6 +104,7 @@ const NetworkEventActor = protocol.ActorClassWithSpec(networkEventSpec, {
this._cause = networkEvent.cause;
this._fromCache = networkEvent.fromCache;
this._fromServiceWorker = networkEvent.fromServiceWorker;
this._isTrackingResource = networkEvent.isTrackingResource;
this._channelId = networkEvent.channelId;
// Stack trace info isn't sent automatically. The client

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

@ -313,7 +313,7 @@ NetworkObserver.prototype = {
this.openResponses.set(channel, response);
if (topic === "http-on-examine-cached-response") {
// Service worker requests emits cached-reponse notification on non-e10s,
// Service worker requests emits cached-response notification on non-e10s,
// and we fake one on e10s.
const fromServiceWorker = this.interceptedChannels.has(channel);
this.interceptedChannels.delete(channel);
@ -491,6 +491,7 @@ NetworkObserver.prototype = {
.toISOString();
event.fromCache = fromCache;
event.fromServiceWorker = fromServiceWorker;
event.isTrackingResource = channel.isTrackingResource;
httpActivity.fromServiceWorker = fromServiceWorker;
if (extraStringData) {

Разница между файлами не показана из-за своего большого размера Загрузить разницу

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

@ -203,28 +203,14 @@ const WalkerFront = FrontClassWithSpec(walkerSpec, {
* @param {String} query
* @param {Object} options
* - "reverse": search backwards
* - "selectorOnly": treat input as a selector string (don't search text
* tags, attributes, etc)
*/
search: custom(async function(query, options = { }) {
let nodeList;
let searchType;
const searchData = this.searchData = this.searchData || { };
const selectorOnly = !!options.selectorOnly;
if (selectorOnly) {
searchType = "selector";
nodeList = await this.multiFrameQuerySelectorAll(query);
} else {
searchType = "search";
const result = await this._search(query, options);
nodeList = result.list;
}
const nodeList = result.list;
// If this is a new search, start at the beginning.
if (searchData.query !== query ||
searchData.selectorOnly !== selectorOnly) {
searchData.selectorOnly = selectorOnly;
if (searchData.query !== query) {
searchData.query = query;
searchData.index = -1;
}
@ -246,7 +232,7 @@ const WalkerFront = FrontClassWithSpec(walkerSpec, {
// Send back the single node, along with any relevant search data
const node = await nodeList.item(searchData.index);
return {
type: searchType,
type: "search",
node: node,
resultsLength: nodeList.length,
resultsIndex: searchData.index,

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

@ -110,7 +110,8 @@ WebConsoleClient.prototype = {
updates: [],
private: actor.private,
fromCache: actor.fromCache,
fromServiceWorker: actor.fromServiceWorker
fromServiceWorker: actor.fromServiceWorker,
isTrackingResource: actor.isTrackingResource,
};
this._networkRequests.set(actor.actor, networkInfo);

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

@ -1,4 +1,8 @@
function testScript(script) {
function makeWrapperUrl(wrapper) {
return wrapper + "?script=" + script;
}
let workerWrapperUrl = makeWrapperUrl("worker_wrapper.js");
// The framework runs the entire test in many different configurations.
// On slow platforms and builds this can make the tests likely to
@ -24,7 +28,7 @@ function testScript(script) {
function workerTest() {
return new Promise(function(resolve, reject) {
var worker = new Worker("worker_wrapper.js");
var worker = new Worker(workerWrapperUrl);
worker.onmessage = function(event) {
if (event.data.context != "Worker") {
return;
@ -45,7 +49,7 @@ function testScript(script) {
function nestedWorkerTest() {
return new Promise(function(resolve, reject) {
var worker = new Worker("nested_worker_wrapper.js");
var worker = new Worker(makeWrapperUrl("nested_worker_wrapper.js"));
worker.onmessage = function(event) {
if (event.data.context != "NestedWorker") {
return;
@ -104,7 +108,7 @@ function testScript(script) {
document.body.appendChild(iframe);
}
navigator.serviceWorker.register("worker_wrapper.js", {scope: "."})
navigator.serviceWorker.register(workerWrapperUrl, {scope: "."})
.then(setupSW);
});
}

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

@ -1,10 +1,14 @@
function getScriptUrl() {
return new URL(location.href).searchParams.get('script');
}
// Hold the nested worker alive until this parent worker closes.
var worker;
addEventListener('message', function nestedWorkerWrapperOnMessage(evt) {
removeEventListener('message', nestedWorkerWrapperOnMessage);
worker = new Worker('worker_wrapper.js');
worker = new Worker('worker_wrapper.js?script=' + getScriptUrl());
worker.addEventListener('message', function(evt) {
self.postMessage({

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

@ -1723,7 +1723,7 @@ function testReferrer() {
var dict = {
'Referer': referrer
};
return fetch(corsServerPath + "headers=" + dict.toSource()).then(function(res) {
return fetch(corsServerPath + "headers=" + encodeURIComponent(dict.toSource())).then(function(res) {
is(res.status, 200, "expected correct referrer header to be sent");
dump(res.statusText);
}, function(e) {

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

@ -1,4 +1,11 @@
importScripts("utils.js");
function getScriptUrl() {
return new URL(location.href).searchParams.get('script');
}
importScripts(getScriptUrl());
var client;
var context;
@ -12,20 +19,17 @@ function is(a, b, msg) {
msg: a + " === " + b + ": " + msg, context: context});
}
var completeInstall;
addEventListener('message', function workerWrapperOnMessage(e) {
removeEventListener('message', workerWrapperOnMessage);
var data = e.data;
function loadTest(event) {
function runTestAndReportToClient(event) {
var done = function(res) {
client.postMessage({ type: 'finish', context: context });
return res;
}
try {
importScripts(data.script);
// runTest() is provided by the test.
var result = runTest().then(done, done);
if ('waitUntil' in event) {
@ -35,7 +39,7 @@ addEventListener('message', function workerWrapperOnMessage(e) {
client.postMessage({
type: 'status',
status: false,
msg: 'worker failed to import ' + data.script + "; error: " + e.message,
msg: 'worker failed to run ' + data.script + "; error: " + e.message,
context: context
});
done();
@ -57,16 +61,11 @@ addEventListener('message', function workerWrapperOnMessage(e) {
dump("We couldn't find the message_receiver window, the test will fail\n");
}
context = "ServiceWorker";
loadTest(e);
completeInstall();
runTestAndReportToClient(e);
}));
} else {
client = self;
context = "Worker";
loadTest(e);
runTestAndReportToClient(e);
}
});
addEventListener("install", e => {
e.waitUntil(new Promise(resolve => completeInstall = resolve));
});

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

@ -11,7 +11,7 @@
function run_test()
{
SpecialPowers.pushPrefEnv({"set": [
["dom.datatransfer.moz", false],
["dom.datatransfer.mozAtAPIs", false],
]}, function() {
let hiddenMethods = ["mozTypesAt", "mozClearDataAt", "mozGetDataAt", "mozSetDataAt", "mozItemCount"];
let exposedMethods = Object.getOwnPropertyNames(DataTransfer.prototype);

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

@ -1196,10 +1196,14 @@ HTMLEditor::TabInTable(bool inIsShift,
getter_AddRefs(cell),
nullptr, nullptr,
&row, nullptr);
NS_ENSURE_SUCCESS(rv, rv);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
if (NS_WARN_IF(!tblElement)) {
return NS_ERROR_FAILURE;
}
// ...so that we can ask for first cell in that row...
rv = GetCellAt(tblElement, row, 0, getter_AddRefs(cell));
NS_ENSURE_SUCCESS(rv, rv);
cell = GetTableCellElementAt(*tblElement, row, 0);
// ...and then set selection there. (Note that normally you should use
// CollapseSelectionToDeepestNonTableFirstChild(), but we know cell is an
// empty new cell, so this works fine)

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

@ -1065,6 +1065,68 @@ protected: // Shouldn't be used by friend classes
ErrorResult& aRv);
};
/**
* TableSize stores and computes number of rows and columns of a <table>
* element.
*/
struct MOZ_STACK_CLASS TableSize final
{
int32_t mRowCount;
int32_t mColumnCount;
/**
* @param aHTMLEditor The editor which creates the instance.
* @param aTableOrElementInTable If a <table> element, computes number
* of rows and columns of it.
* If another element in a <table> element,
* computes number of rows and columns
* of nearest ancestor <table> element.
* Otherwise, i.e., non-<table> element
* not in <table>, returns error.
* @param aRv Returns error if the element is not
* in <table> or layout information is
* not available.
*/
TableSize(HTMLEditor& aHTMLEditor, Element& aTableOrElementInTable,
ErrorResult& aRv)
: mRowCount(-1)
, mColumnCount(-1)
{
MOZ_ASSERT(!aRv.Failed());
Update(aHTMLEditor, aTableOrElementInTable, aRv);
}
/**
* Update mRowCount and mColumnCount for aTableOrElementInTable.
* See above for the detail.
*/
void Update(HTMLEditor& aHTMLEditor, Element& aTableOrElementInTable,
ErrorResult& aRv);
};
/**
* GetTableCellElementAt() returns a <td> or <th> element of aTableElement
* if there is a cell at the indexes.
*
* @param aTableElement Must be a <table> element.
* @param aCellIndexes Indexes of cell which you want.
* If rowspan and/or colspan is specified 2 or
* larger, any indexes are allowed to retrieve
* the cell in the area.
* @return The cell element if there is in the <table>.
* Returns nullptr without error if the indexes
* are out of bounds.
*/
Element* GetTableCellElementAt(Element& aTableElement,
const CellIndexes& aCellIndexes) const
{
return GetTableCellElementAt(aTableElement, aCellIndexes.mRow,
aCellIndexes.mColumn);
}
Element* GetTableCellElementAt(Element& aTableElement,
int32_t aRowIndex,
int32_t aColumnIndex) const;
/**
* PasteInternal() pasts text with replacing selected content.
* This tries to dispatch ePaste event first. If its defaultPrevent() is
@ -1345,7 +1407,7 @@ protected: // Shouldn't be used by friend classes
/**
* Helper used to get nsTableWrapperFrame for a table.
*/
nsTableWrapperFrame* GetTableFrame(Element* aTable);
static nsTableWrapperFrame* GetTableFrame(Element* aTable);
/**
* Needed to do appropriate deleting when last cell or row is about to be

Разница между файлами не показана из-за своего большого размера Загрузить разницу

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

@ -289,8 +289,10 @@ skip-if = toolkit == 'android' && debug # bug 1480702, causes permanent failure
skip-if = toolkit == 'android' && debug # bug 1480702, causes permanent failure of non-related test
[test_nsIHTMLEditor_setCaretAfterElement.html]
skip-if = toolkit == 'android' && debug # bug 1480702, causes permanent failure of non-related test
[test_nsITableEditor_getCellAt.html]
[test_nsITableEditor_getCellIndexes.html]
[test_nsITableEditor_getFirstRow.html]
[test_nsITableEditor_getTableSize.html]
[test_resizers_appearance.html]
[test_resizers_resizing_elements.html]
skip-if = android_version == '18' || (verify && debug && os == 'win') # bug 1147989

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

@ -0,0 +1,139 @@
<!DOCTYPE>
<html>
<head>
<title>Test for nsITableEditor.getCellAt()</title>
<script src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" href="/tests/SimpleTest/test.css">
</head>
<body>
<div id="display">
</div>
<div id="content" contenteditable></div>
<pre id="test">
</pre>
<script class="testbody" type="application/javascript">
SimpleTest.waitForExplicitFinish();
SimpleTest.waitForFocus(function() {
let editor = document.getElementById("content");
let selection = document.getSelection();
try {
let cell = SpecialPowers.unwrap(getTableEditor().getCellAt(undefined, 0, 0));
ok(false, "nsITableEditor.getCellAt(undefined) should cause throwing an exception when editor does not have Selection");
} catch (e) {
ok(true, "nsITableEditor.getCellAt(undefined) should cause throwing an exception when editor does not have Selection");
}
try {
let cell = SpecialPowers.unwrap(getTableEditor().getTableSize(null, 0, 0));
ok(false, "nsITableEditor.getCellAt(null) should cause throwing an exception when editor does not have Selection");
} catch (e) {
ok(true, "nsITableEditor.getCellAt(null) should cause throwing an exception when editor does not have Selection");
}
// XXX This is inconsistent behavior with other APIs.
try {
let cell = SpecialPowers.unwrap(getTableEditor().getCellAt(editor, 0, 0));
ok(true, "nsITableEditor.getCellAt() should not cause throwing exception even if given node is not a <table>");
is(cell, null, "nsITableEditor.getCellAt() should return null if given node is not a <table>");
} catch (e) {
ok(false, "nsITableEditor.getCellAt() should not cause throwing exception even if given node is not a <table>");
}
editor.innerHTML =
'<table id="table">' +
'<tr><td id="c1-1">cell1-1</td><td id="c1-2">cell1-2</td><td id="c1-3">cell1-3</td><td id="c1-4" colspan="2" rowspan="2">cell1-4</td></tr>' +
'<tr><td id="c2-1" rowspan="2">cell2-1</td><td id="c2-2">cell2-2<td id="c2-3">cell2-3</td></tr>' +
'<tr><td id="c3-2">cell3-2</td><td id="c3-3">cell3-3</td><td id="c3-4" colspan="2">cell3-4</td></tr>' +
'<tr><td id="c4-1" rowspan="4">cell4-1</td><td id="c4-2">' +
'<table id="inner-table"><tr><td id="c2-1-1">cell2-1-1</td><td id="c2-1-2">cell2-1-2</td></tr>' +
'<tr><td id="c2-2-1">cell2-2-1</td><td id="c2-2-2">cell2-2-2</td></table>' +
'</td><td id="c4-3">cell4-3</td><td id="c4-4">cell4-4</td><td id="c4-5">cell4-5</td></tr>' +
'<tr><td id="c5-2">cell5-2</td><td id="c5-3" colspan="2">cell5-3</td><td id="c5-5">cell5-5</td></tr>' +
'<tr><td id="c6-2">cell6-2</td><td id="c6-3">cell6-3</td><td id="c6-4"><p>cell6-4</p></td><td id="c6-5">cell6-5</td></tr>' +
'<tr><td id="c7-2" colspan="4">cell7-2</td></tr>' +
'</table>';
editor.scrollTop; // compute layout now.
const kTestsInParent = [
{ row: 0, column: 0, expected: "c1-1" },
{ row: 0, column: 3, expected: "c1-4" },
{ row: 0, column: 4, expected: "c1-4" },
{ row: 1, column: 3, expected: "c1-4" },
{ row: 1, column: 4, expected: "c1-4" },
{ row: 1, column: 0, expected: "c2-1" },
{ row: 2, column: 0, expected: "c2-1" },
{ row: 3, column: 0, expected: "c4-1" },
{ row: 4, column: 0, expected: "c4-1" },
{ row: 5, column: 0, expected: "c4-1" },
{ row: 6, column: 0, expected: "c4-1" },
{ row: 4, column: 2, expected: "c5-3" },
{ row: 4, column: 3, expected: "c5-3" },
{ row: 4, column: 4, expected: "c5-5" },
{ row: 6, column: 1, expected: "c7-2" },
{ row: 6, column: 2, expected: "c7-2" },
{ row: 6, column: 3, expected: "c7-2" },
{ row: 6, column: 4, expected: "c7-2" },
{ row: 6, column: 5, expected: null },
];
let table = document.getElementById("table");
for (const kTest of kTestsInParent) {
let cell = SpecialPowers.unwrap(getTableEditor().getCellAt(table, kTest.row, kTest.column));
if (kTest.expected === null) {
is(cell, null,
`Specified the parent <table> element directly (${kTest.row} - ${kTest.column})`);
} else {
is(cell.getAttribute("id"), kTest.expected,
`Specified the parent <table> element directly (${kTest.row} - ${kTest.column})`);
}
if (cell && cell.firstChild && cell.firstChild.nodeType == Node.TEXT_NODE) {
selection.collapse(cell.firstChild, 0);
cell = getTableEditor().getCellAt(null, kTest.row, kTest.column);
is(cell.getAttribute("id"), kTest.expected,
`Selection is collapsed in a cell element in the parent <table> (${kTest.row} - ${kTest.column})`);
}
}
const kTestsInChild = [
{ row: 0, column: 0, expected: "c2-1-1" },
{ row: 0, column: 1, expected: "c2-1-2" },
{ row: 0, column: 2, expected: null },
{ row: 1, column: 0, expected: "c2-2-1" },
{ row: 1, column: 1, expected: "c2-2-2" },
{ row: 2, column: 0, expected: null },
];
let innerTable = document.getElementById("inner-table");
for (const kTest of kTestsInChild) {
let cell = SpecialPowers.unwrap(getTableEditor().getCellAt(innerTable, kTest.row, kTest.column));
if (kTest.expected === null) {
is(cell, null,
`Specified the inner <table> element directly (${kTest.row} - ${kTest.column})`);
} else {
is(cell.getAttribute("id"), kTest.expected,
`Specified the inner <table> element directly (${kTest.row} - ${kTest.column})`);
}
if (cell && cell.firstChild && cell.firstChild.nodeType == Node.TEXT_NODE) {
selection.collapse(cell.firstChild, 0);
cell = getTableEditor().getCellAt(null, kTest.row, kTest.column);
is(cell.getAttribute("id"), kTest.expected,
`Selection is collapsed in a cell element in the inner <table> (${kTest.row} - ${kTest.column})`);
}
}
SimpleTest.finish();
});
function getTableEditor() {
var Ci = SpecialPowers.Ci;
var editingSession = SpecialPowers.wrap(window).docShell.editingSession;
return editingSession.getEditorForWindow(window).QueryInterface(Ci.nsITableEditor);
}
</script>
</body>
</html>

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

@ -0,0 +1,95 @@
<!DOCTYPE>
<html>
<head>
<title>Test for nsITableEditor.getTableSize()</title>
<script src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" href="/tests/SimpleTest/test.css">
</head>
<body>
<div id="display">
</div>
<div id="content" contenteditable></div>
<pre id="test">
</pre>
<script class="testbody" type="application/javascript">
SimpleTest.waitForExplicitFinish();
SimpleTest.waitForFocus(function() {
let editor = document.getElementById("content");
let selection = document.getSelection();
let rowCount = {}, columnCount = {};
try {
getTableEditor().getTableSize(undefined, rowCount, columnCount);
ok(false, "nsITableEditor.getTableSize(undefined) should cause throwing an exception");
} catch (e) {
ok(true, "nsITableEditor.getTableSize(undefined) should cause throwing an exception");
}
try {
getTableEditor().getTableSize(null, rowCount, columnCount);
ok(false, "nsITableEditor.getTableSize(null) should cause throwing an exception");
} catch (e) {
ok(true, "nsITableEditor.getTableSize(null) should cause throwing an exception");
}
try {
getTableEditor().getTableSize(editor, rowCount, columnCount);
ok(false, "nsITableEditor.getTableSize() should cause throwing an exception if given node is not in a <table>");
} catch (e) {
ok(true, "nsITableEditor.getTableSize() should cause throwing an exception if given node is not in a <table>");
}
// Set id to "test" for the argument for getTableSize().
// Set data-rows and data-cols to expected count of them.
kTests = [
'<table><tr><td id="test" data-rows="2" data-cols="3">cell1-1</td><td>cell1-2</td><td>cell1-3</td></tr><tr><td>cell2-1</td><td>cell2-2</td><td>cell2-3</td></tr></table>',
'<table><tr id="test" data-rows="2" data-cols="3"><td>cell1-1</td><td>cell1-2</td><td>cell1-3</td></tr><tr><td>cell2-1</td><td>cell2-2</td><td>cell2-3</td></tr></table>',
'<table id="test" data-rows="2" data-cols="3"><tr><td>cell1-1</td><td>cell1-2</td><td>cell1-3</td></tr><tr><td>cell2-1</td><td>cell2-2</td><td>cell2-3</td></tr></table>',
'<table><tr><td>cell1-1</td><td>cell1-2</td><td>cell1-3</td></tr><tr><td>cell2-1</td><td>cell2-2</td><td><p id="test" data-rows="2" data-cols="3">cell2-3</p></td></tr></table>',
'<table><caption id="test" data-rows="2" data-cols="3">caption</caption><tr><td>cell1-1</td><td>cell1-2</td><td>cell1-3</td></tr><tr><td>cell2-1</td><td>cell2-2</td><td>cell2-3</td></tr></table>',
'<table id="test" data-rows="0" data-cols="0"></table>',
'<table id="test" data-rows="0" data-cols="0"><caption>caption</caption></table>',
'<table id="test" data-rows="1" data-cols="1"><td>cell1-1</td></table>',
// rowspan does not affect, but colspan affects...
'<table id="test" data-rows="1" data-cols="12"><tr><td rowspan="8" colspan="12">cell1-1</td></tr></table>',
'<table id="test" data-rows="1" data-cols="1"><tr><td><table><tr><td>cell1-1</td><td>cell1-2</td></tr><tr><td>cell2-1</td><td>cell2-2</td></tr><tr><td>cell3-1</td><td>cell3-2</td></tr></table></td></tr></table>',
'<table><tr><td id="test" data-rows="1" data-cols="1"><table><tr><td>cell1-1</td><td>cell1-2</td></tr><tr><td>cell2-1</td><td>cell2-2</td></tr><tr><td>cell3-1</td><td>cell3-2</td></tr></table></td></tr></table>',
'<table><tr><td><table id="test" data-rows="3" data-cols="2"><tr><td>cell1-1</td><td>cell1-2</td></tr><tr><td>cell2-1</td><td>cell2-2</td></tr><tr><td>cell3-1</td><td>cell3-2</td></tr></table></td></tr></table>',
'<table><tr><td><table><tr><td id="test" data-rows="3" data-cols="2">cell1-1</td><td>cell1-2</td></tr><tr><td>cell2-1</td><td>cell2-2</td></tr><tr><td>cell3-1</td><td>cell3-2</td></tr></table></td></tr></table>',
'<table><tr><td><table><tr><td>cell1-1</td><td>cell1-2</td></tr><tr><td>cell2-1</td><td><p id="test" data-rows="3" data-cols="2">cell2-2</p></td></tr><tr><td>cell3-1</td><td>cell3-2</td></tr></table></td></tr></table>',
]
for (const kTest of kTests) {
editor.innerHTML = kTest;
editor.scrollTop; // compute layout now.
let element = document.getElementById("test");
getTableEditor().getTableSize(element, rowCount, columnCount);
is(rowCount.value.toString(10), element.getAttribute("data-rows"),
`Specified an element in a <table> directly, its parent table row count should be retrieved: ${kTest}`);
is(columnCount.value.toString(10), element.getAttribute("data-cols"),
`Specified an element in a <table> directly, its parent table column count should be retrieved: ${kTest}`);
if (element.firstChild && element.firstChild.nodeType == Node.TEXT_NODE) {
selection.collapse(element.firstChild, 0);
getTableEditor().getTableSize(null, rowCount, columnCount);
is(rowCount.value.toString(10), element.getAttribute("data-rows"),
`Selection is collapsed in a cell element, its parent table row count should be retrieved: ${kTest}`);
is(columnCount.value.toString(10), element.getAttribute("data-cols"),
`Selection is collapsed in a cell element, its parent table column count should be retrieved: ${kTest}`);
}
}
SimpleTest.finish();
});
function getTableEditor() {
var Ci = SpecialPowers.Ci;
var editingSession = SpecialPowers.wrap(window).docShell.editingSession;
return editingSession.getEditorForWindow(window).QueryInterface(Ci.nsITableEditor);
}
</script>
</body>
</html>

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

@ -158,30 +158,53 @@ interface nsITableEditor : nsISupports
void getCellIndexes(in Element aCellElement,
out long aRowIndex, out long aColumnIndex);
/** Get the number of rows and columns in a table from the layout's cellmap
* If aTable is null, it will try to find enclosing table of selection ancho
* Note that all rows in table will not have this many because of
* ROWSPAN effects or if table is not "rectangular" (has short rows)
/**
* getTableSize() computes number of rows and columns.
* Note that this depends on layout information. Therefore, all pending
* layout should've been flushed before calling this.
*
* @param aTableOrElementInTable If a <table> element, this computes number
* of rows and columns of it.
* If another element and in a <table>, this
* computes number of rows and columns of
* the nearest ancestor <table> element.
* If element is not in <table> element,
* throwing an exception.
* If null, this looks for nearest ancestor
* <table> element containing anchor of
* Selection. If found, computes the number
* of rows and columns of the <table>.
* Otherwise, throwing an exception.
* @param aRowCount Number of *actual* row count.
* I.e., rowspan does NOT increase this value.
* @param aColumnCount Number of column count.
* I.e., if colspan is specified with bigger
* number than actual, the value is used
* as this.
*/
void getTableSize(in Element aTable,
void getTableSize(in Element aTableOrElementInTable,
out long aRowCount, out long aColCount);
/** Get a cell element at cellmap grid coordinates
* A cell that spans across multiple cellmap locations will
* be returned multiple times, once for each location it occupies
/**
* getCellAt() returns a <td> or <th> element in a <table> if there is a
* cell at the indexes.
*
* @param aTable A table in the document
* @param aRowIndex, aColIndex The 0-based cellmap indexes
*
* (in C++ returns: NS_EDITOR_ELEMENT_NOT_FOUND if an element is not found
* passes NS_SUCCEEDED macro)
*
* You can scan for all cells in a row or column
* by iterating through the appropriate indexes
* until the returned aCell is null
* @param aTableElement If not null, must be a <table> element.
* If null, looks for the nearest ancestor <table>
* to look for a cell.
* @param aRowIndex Row index of the cell.
* @param aColumnIndex Column index of the cell.
* @return Returns a <td> or <th> element if there is.
* Otherwise, returns null without throwing
* exception.
* If aTableElement is not null and not a <table>
* element, throwing an exception.
* If aTableElement is null and anchor of Selection
* is not in any <table> element, throwing an
* exception.
*/
Element getCellAt(in Element aTable,
in long aRowIndex, in long aColIndex);
Element getCellAt(in Element aTableElement,
in long aRowIndex, in long aColumnIndex);
/** Get a cell at cellmap grid coordinates and associated data
* A cell that spans across multiple cellmap locations will

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

@ -1061,6 +1061,10 @@ CompositorOGL::GetShaderProgramFor(const ShaderConfigOGL &aConfig)
ProgramProfileOGL profile = ProgramProfileOGL::GetProfileFor(aConfig);
ShaderProgramOGL *shader = new ShaderProgramOGL(gl(), profile);
if (!shader->Initialize()) {
gfxCriticalError() << "Shader compilation failure, cfg:"
<< " features: " << gfx::hexa(aConfig.mFeatures)
<< " multiplier: " << aConfig.mMultiplier
<< " op: " << aConfig.mCompositionOp;
delete shader;
return nullptr;
}
@ -1314,6 +1318,10 @@ CompositorOGL::DrawGeometry(const Geometry& aGeometry,
ApplyPrimitiveConfig(config, aGeometry);
ShaderProgramOGL *program = GetShaderProgramFor(config);
MOZ_DIAGNOSTIC_ASSERT(program);
if (!program) {
return;
}
ActivateProgram(program);
program->SetProjectionMatrix(mProjMatrix);
program->SetLayerTransform(aTransform);

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

@ -18,6 +18,7 @@
#include <string.h>
#include "mozilla/Assertions.h"
#include "mozilla/TextUtils.h"
#include "nsString.h"
/*
@ -342,7 +343,7 @@ public:
} else if (strcmp(aString, "italic") == 0) {
return Italic();
} else {
if (isdigit(aString[0]) && strstr(aString, "deg")) {
if (mozilla::IsAsciiDigit(aString[0]) && strstr(aString, "deg")) {
float angle = strtof(aString, nullptr);
return Oblique(angle);
}

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

@ -1065,10 +1065,10 @@ BlockReflowInput::PushFloatPastBreak(nsIFrame *aFloat)
* Place below-current-line floats.
*/
void
BlockReflowInput::PlaceBelowCurrentLineFloats(nsFloatCacheFreeList& aList,
nsLineBox* aLine)
BlockReflowInput::PlaceBelowCurrentLineFloats(nsLineBox* aLine)
{
nsFloatCache* fc = aList.Head();
MOZ_ASSERT(mBelowCurrentLineFloats.NotEmpty());
nsFloatCache* fc = mBelowCurrentLineFloats.Head();
while (fc) {
#ifdef DEBUG
if (nsBlockFrame::gNoisyReflow) {
@ -1082,12 +1082,13 @@ BlockReflowInput::PlaceBelowCurrentLineFloats(nsFloatCacheFreeList& aList,
bool placed = FlowAndPlaceFloat(fc->mFloat);
nsFloatCache *next = fc->Next();
if (!placed) {
aList.Remove(fc);
mBelowCurrentLineFloats.Remove(fc);
delete fc;
aLine->SetHadFloatPushed();
}
fc = next;
}
aLine->AppendFloats(mBelowCurrentLineFloats);
}
nscoord

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

@ -154,8 +154,7 @@ public:
bool FlowAndPlaceFloat(nsIFrame* aFloat);
void PlaceBelowCurrentLineFloats(nsFloatCacheFreeList& aFloats,
nsLineBox* aLine);
void PlaceBelowCurrentLineFloats(nsLineBox* aLine);
// Returns the first coordinate >= aBCoord that clears the
// floats indicated by aBreakType and has enough inline size between floats

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

@ -0,0 +1,5 @@
<!doctype html>
<style>
pre::first-letter { float: left; }
</style>
<pre><span>//</span></pre>

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

@ -191,6 +191,7 @@ load 400244-1.html
load 400768-1.xhtml
load 400768-2.xhtml
load 401042-1.xhtml
load 401042-2.html
load 402380-1.html
load 402380-2.html
load 402872-1.html

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

@ -4806,8 +4806,7 @@ nsBlockFrame::PlaceLine(BlockReflowInput& aState,
if (aState.mBelowCurrentLineFloats.NotEmpty()) {
// Reflow the below-current-line floats, which places on the line's
// float list.
aState.PlaceBelowCurrentLineFloats(aState.mBelowCurrentLineFloats, aLine);
aLine->AppendFloats(aState.mBelowCurrentLineFloats);
aState.PlaceBelowCurrentLineFloats(aLine);
}
// When a line has floats, factor them into the combined-area

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

@ -200,9 +200,9 @@ dependencies {
testImplementation 'org.mockito:mockito-core:1.10.19'
androidTestImplementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
androidTestImplementation 'com.android.support.test:runner:0.5'
androidTestImplementation 'com.android.support.test:rules:0.5'
androidTestImplementation 'com.android.support.test.espresso:espresso-core:2.2.2'
androidTestImplementation 'com.android.support.test:runner:1.0.2'
androidTestImplementation 'com.android.support.test:rules:1.0.2'
androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
androidTestImplementation "com.android.support:support-annotations:$support_library_version"
}

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

@ -29,9 +29,6 @@ public class GeckoResultTest {
private static class MockException extends RuntimeException {
}
@Rule
public UiThreadTestRule mUiThreadTestRule = new UiThreadTestRule();
private boolean mDone;
private void waitUntilDone() {

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

@ -7,7 +7,6 @@ package org.mozilla.geckoview.test.rule;
import org.mozilla.gecko.gfx.GeckoDisplay;
import org.mozilla.geckoview.BuildConfig;
import org.mozilla.geckoview.GeckoResponse;
import org.mozilla.geckoview.GeckoResult;
import org.mozilla.geckoview.GeckoResult.OnExceptionListener;
import org.mozilla.geckoview.GeckoResult.OnValueListener;
@ -32,6 +31,7 @@ import org.hamcrest.Matcher;
import org.json.JSONObject;
import org.junit.rules.ErrorCollector;
import org.junit.rules.TestRule;
import org.junit.runner.Description;
import org.junit.runners.model.Statement;
@ -42,17 +42,12 @@ import android.net.LocalSocketAddress;
import android.os.Build;
import android.os.Bundle;
import android.os.Debug;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.os.MessageQueue;
import android.os.Process;
import android.os.SystemClock;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.test.InstrumentationRegistry;
import android.support.test.rule.UiThreadTestRule;
import android.util.Log;
import android.util.Pair;
import android.view.MotionEvent;
import android.view.Surface;
@ -77,6 +72,7 @@ import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.atomic.AtomicReference;
import java.util.regex.Pattern;
import kotlin.jvm.JvmClassMappingKt;
@ -88,7 +84,7 @@ import kotlin.reflect.KClass;
* for waiting on particular callbacks to be called, and methods for asserting that
* callbacks are called in the proper order.
*/
public class GeckoSessionTestRule extends UiThreadTestRule {
public class GeckoSessionTestRule implements TestRule {
private static final String LOGTAG = "GeckoSessionTestRule";
private static final long DEFAULT_TIMEOUT_MILLIS = 10000;
@ -1478,23 +1474,35 @@ public class GeckoSessionTestRule extends UiThreadTestRule {
@Override
public Statement apply(final Statement base, final Description description) {
return super.apply(new Statement() {
return new Statement() {
@Override
public void evaluate() throws Throwable {
final AtomicReference<Throwable> exceptionRef = new AtomicReference<>();
mInstrumentation.runOnMainSync(new Runnable() {
@Override
public void run() {
try {
prepareStatement(description);
base.evaluate();
performTestEndCheck();
} catch (Throwable t) {
exceptionRef.set(t);
} finally {
try {
cleanupStatement();
} catch (Throwable t) {
exceptionRef.set(t);
}
}
}, description);
}
});
@Override
protected boolean shouldRunOnUiThread(final Description description) {
return true;
Throwable throwable = exceptionRef.get();
if (throwable != null) {
throw throwable;
}
}
};
}
/**

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

@ -15,7 +15,6 @@ android {
applicationId "org.mozilla.geckoview_example"
versionCode 1
versionName "1.0"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}
buildTypes {
@ -30,16 +29,8 @@ android {
}
dependencies {
testImplementation 'junit:junit:4.12'
implementation "com.android.support:support-annotations:$support_library_version"
implementation "com.android.support:appcompat-v7:$support_library_version"
androidTestImplementation 'com.android.support.test.espresso:espresso-core:2.2.2'
androidTestImplementation 'com.android.support.test:runner:0.5'
// Not defining this library again results in test-app assuming 23.1.1, and the following errors:
// "Conflict with dependency 'com.android.support:support-annotations'. Resolved versions for app (23.4.0) and test app (23.1.1) differ."
androidTestImplementation "com.android.support:support-annotations:$support_library_version"
implementation project(path: ':geckoview')
}

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

@ -1,13 +0,0 @@
package org.mozilla.geckoview_example;
import android.app.Application;
import android.test.ApplicationTestCase;
/**
* <a href="http://d.android.com/tools/testing/testing_android.html">Testing Fundamentals</a>
*/
public class ApplicationTest extends ApplicationTestCase<Application> {
public ApplicationTest() {
super(Application.class);
}
}

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

@ -1,32 +0,0 @@
/* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*-
* 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/. */
package org.mozilla.geckoview_example;
import android.support.test.rule.ActivityTestRule;
import android.support.test.runner.AndroidJUnit4;
import org.junit.Assert;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import static android.support.test.espresso.Espresso.onView;
import static android.support.test.espresso.assertion.ViewAssertions.matches;
import static android.support.test.espresso.matcher.ViewMatchers.isDisplayed;
import static android.support.test.espresso.matcher.ViewMatchers.withId;
@RunWith(AndroidJUnit4.class)
public class GeckoViewActivityTest {
@Rule
public ActivityTestRule<GeckoViewActivity> mActivityRule = new ActivityTestRule<>(GeckoViewActivity.class);
@Test
public void testA() throws InterruptedException {
onView(withId(R.id.gecko_view))
.check(matches(isDisplayed()));
}
}

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

@ -1,15 +0,0 @@
package org.mozilla.geckoview_example;
import org.junit.Test;
import static org.junit.Assert.*;
/**
* To work on unit tests, switch the Test Artifact in the Build Variants view.
*/
public class ExampleUnitTest {
@Test
public void addition_isCorrect() throws Exception {
assertEquals(4, 2 + 2);
}
}

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

@ -1174,4 +1174,4 @@ static const TransportSecurityPreload kPublicKeyPinningPreloadList[] = {
static const int32_t kUnknownId = -1;
static const PRTime kPreloadPKPinsExpirationTime = INT64_C(1542881093590000);
static const PRTime kPreloadPKPinsExpirationTime = INT64_C(1543497165654000);

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

@ -8,7 +8,7 @@
/*****************************************************************************/
#include <stdint.h>
const PRTime gPreloadListExpirationTime = INT64_C(1545300209985000);
const PRTime gPreloadListExpirationTime = INT64_C(1545916292150000);
%%
0-1.party, 1
0.me.uk, 1

Различия файлов скрыты, потому что одна или несколько строк слишком длинны

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

@ -3,7 +3,7 @@ set -e -v
# This script is for building tup on Linux.
TUP_REVISION=f77dbd429d6157dac252014a26f6d275dce85d85
TUP_REVISION=e948a999a38fefa0ac0d92f6357f82aca2f9cb17
WORKSPACE=$HOME/workspace
UPLOAD_DIR=$HOME/artifacts

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

@ -735,7 +735,7 @@ def enable_code_coverage(config, tests):
"""Enable code coverage for the ccov and jsdcov build-platforms"""
for test in tests:
if 'ccov' in test['build-platform']:
# do not run tests on fuzzing or opt build
# Do not run tests on fuzzing or opt build
if 'opt' in test['build-platform'] or 'fuzzing' in test['build-platform']:
test['run-on-projects'] = []
continue
@ -786,7 +786,7 @@ def enable_code_coverage(config, tests):
test['max-run-time'] = 1800
if 'linux' in test['build-platform']:
test['docker-image'] = {"in-tree": "desktop1604-test"}
elif test['build-platform'] == 'linux64-jsdcov/opt':
elif 'jsdcov' in test['build-platform']:
# Ensure we always run on the projects defined by the build, unless the test
# is try only or shouldn't run at all.
if test['run-on-projects'] not in [[], ['try']]:

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

@ -550,6 +550,10 @@ class TryOptionSyntax(object):
return False
return set(['try', 'all']) & set(attr('run_on_projects', []))
# Don't schedule code coverage when try option syntax is used
if 'ccov' in attr('build_platform', []) or 'jsdcov' in attr('build_platform', []):
return False
def match_test(try_spec, attr_name):
run_by_default = True
if attr('build_type') not in self.build_types:

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

@ -1 +1 @@
lsan-allowed: [Alloc, MakeUnique, Malloc, NewPage, Realloc, mozilla::EMEDecryptor::EMEDecryptor, mozilla::SchedulerGroup::CreateEventTargetFor, mozilla::dom::MediaKeys::CreateCDMProxy, mozilla::dom::nsIContentChild::GetConstructedEventTarget]
lsan-allowed: [Alloc, MakeUnique, Malloc, NewPage, Realloc, mozilla::EMEDecryptor::EMEDecryptor, mozilla::SchedulerGroup::CreateEventTargetFor, CreateCDMProxy, mozilla::dom::MediaKeys::CreateCDMProxy, mozilla::dom::nsIContentChild::GetConstructedEventTarget]

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

@ -2415,10 +2415,8 @@ add_task(async function test_history() {
Assert.equal(lastKnownTitle, expectedFile.leafName);
let expectedFileURI = Services.io.newFileURI(expectedFile);
let destFileURI = PlacesUtils.annotations.getPageAnnotation(
Services.io.newURI(sourceUrl),
"downloads/destinationFileURI");
Assert.equal(destFileURI, expectedFileURI.spec,
let pageInfo = await PlacesUtils.history.fetch(sourceUrl, {includeAnnotations: true});
Assert.equal(pageInfo.annotations.get("downloads/destinationFileURI"), expectedFileURI.spec,
"Should have saved the correct download target annotation.");
// Restart and complete the download after clearing history.

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

@ -32,7 +32,7 @@ async function test_telemetry_background() {
async function contentScript() {
await browser.storage.local.set({a: "b"});
await browser.storage.local.get("a");
browser.runtime.sendMessage("contentDone");
browser.test.sendMessage("contentDone");
}
let baseManifest = {
@ -47,10 +47,6 @@ async function test_telemetry_background() {
let baseExtInfo = {
async background() {
browser.runtime.onMessage.addListener(msg => {
browser.test.sendMessage(msg);
});
await browser.storage.local.set({a: "b"});
await browser.storage.local.get("a");
browser.test.sendMessage("backgroundDone");
@ -122,10 +118,9 @@ async function test_telemetry_background() {
// Run a content script.
process = IS_OOP ? "content" : "parent";
let expectedCount = IS_OOP ? 1 : 3;
let contentScriptPromise = extension1.awaitMessage("contentDone");
let contentPage = await ExtensionTestUtils.loadContentPage(`${BASE_URL}/file_sample.html`);
await contentScriptPromise;
await contentPage.close();
await extension1.awaitMessage("contentDone");
for (let id of expectedNonEmptyHistograms) {
await promiseTelemetryRecorded(id, process, expectedCount);
@ -144,6 +139,8 @@ async function test_telemetry_background() {
for (let id of expectedEmptyHistograms) {
ok(!(id in snapshots), `No data recorded for histogram: ${id}.`);
}
await contentPage.close();
}
add_task(function test_telemetry_background_file_backend() {

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

@ -380,50 +380,6 @@ nsAnnotationService::SetAnnotationDoubleInternal(int64_t aItemId,
}
NS_IMETHODIMP
nsAnnotationService::GetPageAnnotation(nsIURI* aURI,
const nsACString& aName,
nsIVariant** _retval)
{
NS_ENSURE_ARG(aURI);
NS_ENSURE_ARG_POINTER(_retval);
nsCOMPtr<mozIStorageStatement> statement;
nsresult rv = StartGetAnnotation(aURI, 0, aName, statement);
if (NS_FAILED(rv))
return rv;
mozStorageStatementScoper scoper(statement);
nsCOMPtr<nsIWritableVariant> value = new nsVariant();
int32_t type = statement->AsInt32(kAnnoIndex_Type);
switch (type) {
case nsIAnnotationService::TYPE_INT32:
case nsIAnnotationService::TYPE_INT64:
case nsIAnnotationService::TYPE_DOUBLE: {
rv = value->SetAsDouble(statement->AsDouble(kAnnoIndex_Content));
break;
}
case nsIAnnotationService::TYPE_STRING: {
nsAutoString valueString;
rv = statement->GetString(kAnnoIndex_Content, valueString);
if (NS_SUCCEEDED(rv))
rv = value->SetAsAString(valueString);
break;
}
default: {
rv = NS_ERROR_UNEXPECTED;
break;
}
}
if (NS_SUCCEEDED(rv)) {
value.forget(_retval);
}
return rv;
}
nsresult
nsAnnotationService::GetValueFromStatement(nsCOMPtr<mozIStorageStatement>& aStatement,
nsIVariant** _retval)
@ -467,7 +423,7 @@ nsAnnotationService::GetItemAnnotation(int64_t aItemId,
NS_ENSURE_ARG_POINTER(_retval);
nsCOMPtr<mozIStorageStatement> statement;
nsresult rv = StartGetAnnotation(nullptr, aItemId, aName, statement);
nsresult rv = StartGetAnnotation(aItemId, aName, statement);
if (NS_FAILED(rv))
return rv;
@ -492,7 +448,7 @@ nsAnnotationService::GetItemAnnotationInfo(int64_t aItemId,
NS_ENSURE_ARG_POINTER(_storageType);
nsCOMPtr<mozIStorageStatement> statement;
nsresult rv = StartGetAnnotation(nullptr, aItemId, aName, statement);
nsresult rv = StartGetAnnotation(aItemId, aName, statement);
if (NS_FAILED(rv))
return rv;
@ -822,14 +778,10 @@ nsAnnotationService::ItemHasAnnotation(int64_t aItemId,
*/
nsresult
nsAnnotationService::StartGetAnnotation(nsIURI* aURI,
int64_t aItemId,
nsAnnotationService::StartGetAnnotation(int64_t aItemId,
const nsACString& aName,
nsCOMPtr<mozIStorageStatement>& aStatement)
{
bool isItemAnnotation = (aItemId > 0);
if (isItemAnnotation) {
aStatement = mDB->GetStatement(
"SELECT a.id, a.item_id, :anno_name, a.content, a.flags, "
"a.expiration, a.type "
@ -838,26 +790,11 @@ nsAnnotationService::StartGetAnnotation(nsIURI* aURI,
"WHERE a.item_id = :item_id "
"AND n.name = :anno_name"
);
}
else {
aStatement = mDB->GetStatement(
"SELECT a.id, a.place_id, :anno_name, a.content, a.flags, "
"a.expiration, a.type "
"FROM moz_anno_attributes n "
"JOIN moz_annos a ON n.id = a.anno_attribute_id "
"JOIN moz_places h ON h.id = a.place_id "
"WHERE h.url_hash = hash(:page_url) AND h.url = :page_url "
"AND n.name = :anno_name"
);
}
NS_ENSURE_STATE(aStatement);
mozStorageStatementScoper getAnnoScoper(aStatement);
nsresult rv;
if (isItemAnnotation)
rv = aStatement->BindInt64ByName(NS_LITERAL_CSTRING("item_id"), aItemId);
else
rv = URIBinder::Bind(aStatement, NS_LITERAL_CSTRING("page_url"), aURI);
NS_ENSURE_SUCCESS(rv, rv);
rv = aStatement->BindUTF8StringByName(NS_LITERAL_CSTRING("anno_name"), aName);

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

@ -97,8 +97,7 @@ protected:
static const int kAnnoIndex_DateAdded;
static const int kAnnoIndex_LastModified;
nsresult StartGetAnnotation(nsIURI* aURI,
int64_t aItemId,
nsresult StartGetAnnotation(int64_t aItemId,
const nsACString& aName,
nsCOMPtr<mozIStorageStatement>& aStatement);

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

@ -83,8 +83,6 @@ interface nsIAnnotationService : nsISupports
* The type-specific methods throw if the given annotation is set in
* a different type.
*/
nsIVariant getPageAnnotation(in nsIURI aURI,
in AUTF8String aName);
nsIVariant getItemAnnotation(in long long aItemId,
in AUTF8String aName);

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

@ -973,3 +973,23 @@ function getItemsWithAnnotation(name) {
return rows.map(row => row.getResultByName("guid"));
});
}
/**
* Checks there are no orphan page annotations in the database, and no
* orphan anno attribute names.
*/
async function assertNoOrphanPageAnnotations() {
let db = await PlacesUtils.promiseDBConnection();
let rows = await db.execute(`
SELECT place_id FROM moz_annos
WHERE place_id NOT IN (SELECT id FROM moz_places)
`);
Assert.equal(rows.length, 0, "Should not have any orphan page annotations");
rows = await db.execute(`
SELECT id FROM moz_anno_attributes
WHERE id NOT IN (SELECT anno_attribute_id FROM moz_annos) AND
id NOT IN (SELECT anno_attribute_id FROM moz_items_annos)`);
}

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

@ -185,6 +185,14 @@ add_task(async function test_change_description_and_preview_saved() {
Assert.equal(previewImageURL, previewImageURLInDB, "previewImageURL should not be updated");
});
/**
* Gets annotation information from the database for the specified URL and
* annotation name.
*
* @param {String} pageUrl The URL to search for.
* @param {String} annoName The name of the annotation to search for.
* @return {Array} An array of objects containing the annotations found.
*/
async function getAnnotationInfoFromDB(pageUrl, annoName) {
let db = await PlacesUtils.promiseDBConnection();

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

@ -2175,7 +2175,8 @@ tests.push({
Assert.equal(ts.getTagsForURI(this._uri1).length, 1);
Assert.equal((await PlacesUtils.keywords.fetch({ url: this._uri1.spec })).keyword, "testkeyword");
Assert.equal(as.getPageAnnotation(this._uri2, "anno"), "anno");
let pageInfo = await PlacesUtils.history.fetch(this._uri2, {includeAnnotations: true});
Assert.equal(pageInfo.annotations.get("anno"), "anno");
Assert.equal(as.getItemAnnotation(this._bookmarkId, "anno"), "anno");
await new Promise(resolve => {

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

@ -31,20 +31,18 @@ const TOTAL_SITES = 20;
add_task(async function test_execute() {
// add pages to global history
for (let i = 0; i < TOTAL_SITES; i++) {
let site = "http://www.test-" + i + ".com/";
let testURI = uri(site);
let uri = "http://www.test-" + i + ".com/";
let when = Date.now() * 1000 + (i * TOTAL_SITES);
await PlacesTestUtils.addVisits({ uri: testURI, visitDate: when });
await PlacesTestUtils.addVisits({ uri, visitDate: when });
}
for (let i = 0; i < TOTAL_SITES; i++) {
let site = "http://www.test.com/" + i + "/";
let testURI = uri(site);
let uri = "http://www.test.com/" + i + "/";
let when = Date.now() * 1000 + (i * TOTAL_SITES);
await PlacesTestUtils.addVisits({ uri: testURI, visitDate: when });
await PlacesTestUtils.addVisits({ uri, visitDate: when });
}
// set a page annotation on one of the urls that will be removed
var testAnnoDeletedURI = uri("http://www.test.com/1/");
var testAnnoDeletedURI = "http://www.test.com/1/";
var testAnnoDeletedName = "foo";
var testAnnoDeletedValue = "bar";
await PlacesUtils.history.update({
@ -53,7 +51,7 @@ add_task(async function test_execute() {
});
// set a page annotation on one of the urls that will NOT be removed
var testAnnoRetainedURI = uri("http://www.test-1.com/");
var testAnnoRetainedURI = "http://www.test-1.com/";
var testAnnoRetainedName = "foo";
var testAnnoRetainedValue = "bar";
await PlacesUtils.history.update({
@ -79,18 +77,11 @@ add_task(async function test_execute() {
}
// check that annotation on the removed item does not exists
try {
PlacesUtils.annotations.getPageAnnotation(testAnnoDeletedURI, testAnnoDeletedName);
do_throw("fetching page-annotation that doesn't exist, should've thrown");
} catch (ex) {}
await assertNoOrphanPageAnnotations();
// check that annotation on the NOT removed item still exists
try {
var annoVal = PlacesUtils.annotations.getPageAnnotation(testAnnoRetainedURI,
testAnnoRetainedName);
} catch (ex) {
do_throw("The annotation has been removed erroneously");
}
Assert.equal(annoVal, testAnnoRetainedValue);
let pageInfo = await PlacesUtils.history.fetch(testAnnoRetainedURI, {includeAnnotations: true});
Assert.equal(pageInfo.annotations.get(testAnnoRetainedName), testAnnoRetainedValue,
"Should have kept the annotation for the non-removed items");
});

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

@ -54,11 +54,6 @@ add_task(async function test_execute() {
do_throw("unable to get item annotation");
}
// get annotation that doesn't exist
try {
annosvc.getPageAnnotation(testURI, "blah");
do_throw("fetching page-annotation that doesn't exist, should've thrown");
} catch (ex) {}
try {
annosvc.getItemAnnotation(testURI, "blah");
do_throw("fetching item-annotation that doesn't exist, should've thrown");

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

@ -4,8 +4,8 @@
* 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/. */
const TEST_URI = NetUtil.newURI("http://mozilla.com/");
const TEST_SUBDOMAIN_URI = NetUtil.newURI("http://foobar.mozilla.com/");
const TEST_URI = "http://mozilla.com/";
const TEST_SUBDOMAIN_URI = "http://foobar.mozilla.com/";
async function checkEmptyHistory() {
let db = await PlacesUtils.promiseDBConnection();
@ -26,7 +26,7 @@ add_task(async function test_removePage() {
add_task(async function test_removePages() {
let pages = [];
for (let i = 0; i < 8; i++) {
pages.push(NetUtil.newURI(TEST_URI.spec + i));
pages.push(TEST_URI + i);
}
await PlacesTestUtils.addVisits(pages.map(uri => ({ uri })));
@ -55,14 +55,11 @@ add_task(async function test_removePages() {
// Check that the bookmark and its annotation still exist.
let folder = await PlacesUtils.getFolderContents(PlacesUtils.bookmarks.unfiledGuid);
Assert.equal(folder.root.childCount, 1);
Assert.equal(PlacesUtils.annotations.getPageAnnotation(pages[BOOKMARK_INDEX], ANNO_NAME),
ANNO_VALUE);
let pageInfo = await PlacesUtils.history.fetch(pages[BOOKMARK_INDEX], {includeAnnotations: true});
Assert.equal(pageInfo.annotations.get(ANNO_NAME), ANNO_VALUE);
// Check the annotation on the non-bookmarked page does not exist anymore.
try {
PlacesUtils.annotations.getPageAnnotation(pages[ANNO_INDEX], ANNO_NAME);
do_throw("did not expire expire_never anno on a not bookmarked item");
} catch (ex) {}
await assertNoOrphanPageAnnotations();
// Cleanup.
await PlacesUtils.bookmarks.eraseEverything();
@ -74,7 +71,7 @@ add_task(async function test_removePagesByTimeframe() {
let startDate = (Date.now() - 10000) * 1000;
for (let i = 0; i < 10; i++) {
visits.push({
uri: NetUtil.newURI(TEST_URI.spec + i),
uri: TEST_URI + i,
visitDate: startDate + i * 1000,
});
}
@ -89,8 +86,7 @@ add_task(async function test_removePagesByTimeframe() {
// Check that we have removed the correct pages.
for (let i = 0; i < 10; i++) {
Assert.equal(page_in_database(NetUtil.newURI(TEST_URI.spec + i)) == 0,
i > 0 && i < 9);
Assert.equal(page_in_database(TEST_URI + i) == 0, i > 0 && i < 9);
}
// Clear remaining items and check that all pages have been removed.