Merge autoland to mozilla-central. a=merge
|
@ -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 result = await this._search(query, options);
|
||||
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));
|
||||
});
|
||||
|
|
|
@ -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)
|
||||
*/
|
||||
void getTableSize(in Element aTable,
|
||||
/**
|
||||
* 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 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
|
||||
*
|
||||
* @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
|
||||
*/
|
||||
Element getCellAt(in Element aTable,
|
||||
in long aRowIndex, in long aColIndex);
|
||||
/**
|
||||
* getCellAt() returns a <td> or <th> element in a <table> if there is a
|
||||
* cell at the indexes.
|
||||
*
|
||||
* @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 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
|
||||
|
|
|
@ -4802,8 +4802,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 {
|
||||
try {
|
||||
prepareStatement(description);
|
||||
base.evaluate();
|
||||
performTestEndCheck();
|
||||
} finally {
|
||||
cleanupStatement();
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
Throwable throwable = exceptionRef.get();
|
||||
if (throwable != null) {
|
||||
throw throwable;
|
||||
}
|
||||
}
|
||||
}, description);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean shouldRunOnUiThread(final Description description) {
|
||||
return true;
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -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:
|
||||
|
@ -593,8 +597,8 @@ class TryOptionSyntax(object):
|
|||
return check_run_on_projects()
|
||||
elif attr('kind') == 'test':
|
||||
return match_test(self.unittests, 'unittest_try_name') \
|
||||
or match_test(self.talos, 'talos_try_name') \
|
||||
or match_test(self.raptor, 'raptor_try_name')
|
||||
or match_test(self.talos, 'talos_try_name') \
|
||||
or match_test(self.raptor, 'raptor_try_name')
|
||||
elif attr('kind') in BUILD_KINDS:
|
||||
if attr('build_type') not in self.build_types:
|
||||
return False
|
||||
|
|
|
@ -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,42 +778,23 @@ 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 "
|
||||
"FROM moz_anno_attributes n "
|
||||
"JOIN moz_items_annos a ON a.anno_attribute_id = n.id "
|
||||
"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"
|
||||
);
|
||||
}
|
||||
aStatement = mDB->GetStatement(
|
||||
"SELECT a.id, a.item_id, :anno_name, a.content, a.flags, "
|
||||
"a.expiration, a.type "
|
||||
"FROM moz_anno_attributes n "
|
||||
"JOIN moz_items_annos a ON a.anno_attribute_id = n.id "
|
||||
"WHERE a.item_id = :item_id "
|
||||
"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);
|
||||
rv = aStatement->BindInt64ByName(NS_LITERAL_CSTRING("item_id"), aItemId);
|
||||
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.
|
||||
|
|