зеркало из https://github.com/mozilla/gecko-dev.git
Merge mozilla-central to mozilla-inbound on a CLOSED TREE
This commit is contained in:
Коммит
edf80a9c6c
|
@ -198,3 +198,7 @@ tps_result\.json
|
|||
|
||||
# Ignore the build directories of WebRender standalone builds.
|
||||
gfx/wr/target/
|
||||
|
||||
# Ignore this files in certviewer
|
||||
toolkit/components/certviewer/content/node_modules/
|
||||
toolkit/components/certviewer/content/package-lock.json
|
||||
|
|
|
@ -106,7 +106,7 @@ dependencies = [
|
|||
"mio-named-pipes 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"scoped-tls 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde 1.0.88 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde_derive 1.0.88 (git+https://github.com/servo/serde?branch=deserialize_from_enums10)",
|
||||
"serde_derive 1.0.88 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"tokio-core 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"tokio-io 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"tokio-uds 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
|
@ -315,7 +315,7 @@ dependencies = [
|
|||
"filetime_win 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"guid_win 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde 1.0.88 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde_derive 1.0.88 (git+https://github.com/servo/serde?branch=deserialize_from_enums10)",
|
||||
"serde_derive 1.0.88 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"winapi 0.3.6 (git+https://github.com/froydnj/winapi-rs?branch=aarch64)",
|
||||
]
|
||||
|
||||
|
@ -976,7 +976,7 @@ dependencies = [
|
|||
"lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.51 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde 1.0.88 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde_derive 1.0.88 (git+https://github.com/servo/serde?branch=deserialize_from_enums10)",
|
||||
"serde_derive 1.0.88 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"winapi 0.3.6 (git+https://github.com/froydnj/winapi-rs?branch=aarch64)",
|
||||
]
|
||||
|
||||
|
@ -1030,7 +1030,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
|
||||
[[package]]
|
||||
name = "euclid"
|
||||
version = "0.19.5"
|
||||
version = "0.19.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"euclid_macros 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
|
@ -1183,7 +1183,7 @@ dependencies = [
|
|||
"mozversion 0.2.0",
|
||||
"regex 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde 1.0.88 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde_derive 1.0.88 (git+https://github.com/servo/serde?branch=deserialize_from_enums10)",
|
||||
"serde_derive 1.0.88 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde_json 1.0.26 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"uuid 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"webdriver 0.39.0",
|
||||
|
@ -1715,7 +1715,7 @@ version = "0.0.1"
|
|||
dependencies = [
|
||||
"app_units 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"cssparser 0.25.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"euclid 0.19.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"euclid 0.19.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"hashglobe 0.1.0",
|
||||
"selectors 0.21.0",
|
||||
"servo_arc 0.1.1",
|
||||
|
@ -1911,7 +1911,7 @@ dependencies = [
|
|||
"proc-macro2 0.4.27 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"quote 0.6.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde 1.0.88 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde_derive 1.0.88 (git+https://github.com/servo/serde?branch=deserialize_from_enums10)",
|
||||
"serde_derive 1.0.88 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"syn 0.15.30 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"winapi 0.3.6 (git+https://github.com/froydnj/winapi-rs?branch=aarch64)",
|
||||
|
@ -2191,6 +2191,25 @@ dependencies = [
|
|||
"winapi 0.3.6 (git+https://github.com/froydnj/winapi-rs?branch=aarch64)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "peek-poke"
|
||||
version = "0.2.0"
|
||||
dependencies = [
|
||||
"euclid 0.19.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"peek-poke-derive 0.2.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "peek-poke-derive"
|
||||
version = "0.2.0"
|
||||
dependencies = [
|
||||
"proc-macro2 0.4.27 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"quote 0.6.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"syn 0.15.30 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"synstructure 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "peeking_take_while"
|
||||
version = "0.1.2"
|
||||
|
@ -2252,7 +2271,7 @@ version = "0.13.8"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"binary-space-partition 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"euclid 0.19.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"euclid 0.19.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"num-traits 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
@ -2573,7 +2592,7 @@ dependencies = [
|
|||
"lmdb-rkv 0.11.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"ordered-float 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde 1.0.88 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde_derive 1.0.88 (git+https://github.com/servo/serde?branch=deserialize_from_enums10)",
|
||||
"serde_derive 1.0.88 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"url 1.7.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"uuid 0.7.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
@ -2740,7 +2759,7 @@ name = "serde"
|
|||
version = "1.0.88"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"serde_derive 1.0.88 (git+https://github.com/servo/serde?branch=deserialize_from_enums10)",
|
||||
"serde_derive 1.0.88 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -2754,7 +2773,7 @@ dependencies = [
|
|||
[[package]]
|
||||
name = "serde_derive"
|
||||
version = "1.0.88"
|
||||
source = "git+https://github.com/servo/serde?branch=deserialize_from_enums10#84b2795d2a7b5312125a99b1ef11c67fd8d17c35"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"proc-macro2 0.4.27 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"quote 0.6.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
|
@ -2926,7 +2945,7 @@ dependencies = [
|
|||
"byteorder 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"cssparser 0.25.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"derive_more 0.13.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"euclid 0.19.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"euclid 0.19.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"fallible 0.0.1",
|
||||
"fxhash 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"hashglobe 0.1.0",
|
||||
|
@ -2987,7 +3006,7 @@ dependencies = [
|
|||
"app_units 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"cssparser 0.25.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"euclid 0.19.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"euclid 0.19.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"malloc_size_of 0.0.1",
|
||||
"malloc_size_of_derive 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
|
@ -3575,7 +3594,7 @@ dependencies = [
|
|||
"log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"regex 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde 1.0.88 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde_derive 1.0.88 (git+https://github.com/servo/serde?branch=deserialize_from_enums10)",
|
||||
"serde_derive 1.0.88 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde_json 1.0.26 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"time 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"tokio 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
|
@ -3598,7 +3617,7 @@ dependencies = [
|
|||
"core-text 13.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"cstr 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"dwrote 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"euclid 0.19.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"euclid 0.19.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"freetype 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"fxhash 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"gleam 0.6.17 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
|
@ -3629,17 +3648,17 @@ name = "webrender_api"
|
|||
version = "0.60.0"
|
||||
dependencies = [
|
||||
"app_units 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"bincode 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"byteorder 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"core-foundation 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"core-graphics 0.17.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"derive_more 0.13.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"euclid 0.19.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"euclid 0.19.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"malloc_size_of_derive 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"peek-poke 0.2.0",
|
||||
"serde 1.0.88 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde_bytes 0.10.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde_derive 1.0.88 (git+https://github.com/servo/serde?branch=deserialize_from_enums10)",
|
||||
"serde_derive 1.0.88 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"time 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"wr_malloc_size_of 0.0.1",
|
||||
]
|
||||
|
@ -3653,7 +3672,7 @@ dependencies = [
|
|||
"core-foundation 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"core-graphics 0.17.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"dwrote 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"euclid 0.19.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"euclid 0.19.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"foreign-types 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"fxhash 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"gleam 0.6.17 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
|
@ -3680,7 +3699,7 @@ version = "0.1.0"
|
|||
dependencies = [
|
||||
"log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde 1.0.88 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde_derive 1.0.88 (git+https://github.com/servo/serde?branch=deserialize_from_enums10)",
|
||||
"serde_derive 1.0.88 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde_json 1.0.26 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
|
@ -3750,7 +3769,7 @@ name = "wr_malloc_size_of"
|
|||
version = "0.0.1"
|
||||
dependencies = [
|
||||
"app_units 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"euclid 0.19.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"euclid 0.19.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -3948,7 +3967,7 @@ dependencies = [
|
|||
"checksum encoding_rs 0.8.17 (registry+https://github.com/rust-lang/crates.io-index)" = "4155785c79f2f6701f185eb2e6b4caf0555ec03477cb4c70db67b465311620ed"
|
||||
"checksum env_logger 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)" = "0561146661ae44c579e993456bc76d11ce1e0c7d745e57b2fa7146b6e49fa2ad"
|
||||
"checksum error-chain 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ff511d5dc435d703f4971bc399647c9bc38e20cb41452e3b9feb4765419ed3f3"
|
||||
"checksum euclid 0.19.5 (registry+https://github.com/rust-lang/crates.io-index)" = "d1a7698bdda3d7444a79d33bdc96e8b518d44ea3ff101d8492a6ca1207b886ea"
|
||||
"checksum euclid 0.19.9 (registry+https://github.com/rust-lang/crates.io-index)" = "596b99621b9477e7a5f94d2d8dd13a9c5c302ac358b822c67a42b6f1054450e1"
|
||||
"checksum euclid_macros 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fdcb84c18ea5037a1c5a23039b4ff29403abce2e0d6b1daa11cf0bde2b30be15"
|
||||
"checksum failure 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "6dd377bcc1b1b7ce911967e3ec24fa19c3224394ec05b54aa7b083d498341ac7"
|
||||
"checksum failure_derive 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "64c2d913fe8ed3b6c6518eedf4538255b989945c14c2a7d5cbff62a5e2120596"
|
||||
|
@ -4107,7 +4126,7 @@ dependencies = [
|
|||
"checksum semver-parser 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3"
|
||||
"checksum serde 1.0.88 (registry+https://github.com/rust-lang/crates.io-index)" = "9f301d728f2b94c9a7691c90f07b0b4e8a4517181d9461be94c04bddeb4bd850"
|
||||
"checksum serde_bytes 0.10.4 (registry+https://github.com/rust-lang/crates.io-index)" = "adb6e51a6b3696b301bc221d785f898b4457c619b51d7ce195a6d20baecb37b3"
|
||||
"checksum serde_derive 1.0.88 (git+https://github.com/servo/serde?branch=deserialize_from_enums10)" = "<none>"
|
||||
"checksum serde_derive 1.0.88 (registry+https://github.com/rust-lang/crates.io-index)" = "beed18e6f5175aef3ba670e57c60ef3b1b74d250d962a26604bff4c80e970dd4"
|
||||
"checksum serde_json 1.0.26 (registry+https://github.com/rust-lang/crates.io-index)" = "44dd2cfde475037451fa99b7e5df77aa3cfd1536575fa8e7a538ab36dcde49ae"
|
||||
"checksum serde_repr 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "29a734c298df0346c4cd5919595981c266dabbf12dc747c85e1a95e96077a52b"
|
||||
"checksum serde_urlencoded 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)" = "642dd69105886af2efd227f75a520ec9b44a820d65bc133a9131f7d229fd165a"
|
||||
|
|
|
@ -58,7 +58,6 @@ codegen-units = 1
|
|||
|
||||
[patch.crates-io]
|
||||
libudev-sys = { path = "dom/webauthn/libudev-sys" }
|
||||
serde_derive = { git = "https://github.com/servo/serde", branch = "deserialize_from_enums10" }
|
||||
winapi = { git = "https://github.com/froydnj/winapi-rs", branch = "aarch64" }
|
||||
packed_simd = { git = "https://github.com/hsivonen/packed_simd", branch = "rust_1_32" }
|
||||
|
||||
|
|
|
@ -1229,10 +1229,5 @@ class PluginChild extends ActorChild {
|
|||
messageString,
|
||||
pluginID,
|
||||
});
|
||||
|
||||
// Remove the notification when the page is reloaded.
|
||||
doc.defaultView.top.addEventListener("unload", event => {
|
||||
this.hideNotificationBar("plugin-crashed");
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8944,58 +8944,39 @@ var gPrivateBrowsingUI = {
|
|||
// temporary fix until bug 463607 is fixed
|
||||
document.getElementById("Tools:Sanitize").setAttribute("disabled", "true");
|
||||
|
||||
if (window.location.href == AppConstants.BROWSER_CHROME_URL) {
|
||||
// Adjust the window's title
|
||||
let docElement = document.documentElement;
|
||||
if (!PrivateBrowsingUtils.permanentPrivateBrowsing) {
|
||||
docElement.setAttribute(
|
||||
"title",
|
||||
docElement.getAttribute("title_privatebrowsing")
|
||||
);
|
||||
docElement.setAttribute(
|
||||
"titlemodifier",
|
||||
docElement.getAttribute("titlemodifier_privatebrowsing")
|
||||
);
|
||||
}
|
||||
if (window.location.href != AppConstants.BROWSER_CHROME_URL) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Adjust the window's title
|
||||
let docElement = document.documentElement;
|
||||
if (!PrivateBrowsingUtils.permanentPrivateBrowsing) {
|
||||
docElement.setAttribute(
|
||||
"privatebrowsingmode",
|
||||
PrivateBrowsingUtils.permanentPrivateBrowsing
|
||||
? "permanent"
|
||||
: "temporary"
|
||||
"title",
|
||||
docElement.getAttribute("title_privatebrowsing")
|
||||
);
|
||||
gBrowser.updateTitlebar();
|
||||
docElement.setAttribute(
|
||||
"titlemodifier",
|
||||
docElement.getAttribute("titlemodifier_privatebrowsing")
|
||||
);
|
||||
}
|
||||
docElement.setAttribute(
|
||||
"privatebrowsingmode",
|
||||
PrivateBrowsingUtils.permanentPrivateBrowsing ? "permanent" : "temporary"
|
||||
);
|
||||
gBrowser.updateTitlebar();
|
||||
|
||||
if (PrivateBrowsingUtils.permanentPrivateBrowsing) {
|
||||
// Adjust the New Window menu entries
|
||||
[
|
||||
{ normal: "menu_newNavigator", private: "menu_newPrivateWindow" },
|
||||
].forEach(function(menu) {
|
||||
let newWindow = document.getElementById(menu.normal);
|
||||
let newPrivateWindow = document.getElementById(menu.private);
|
||||
if (newWindow && newPrivateWindow) {
|
||||
newPrivateWindow.hidden = true;
|
||||
newWindow.label = newPrivateWindow.label;
|
||||
newWindow.accessKey = newPrivateWindow.accessKey;
|
||||
newWindow.command = newPrivateWindow.command;
|
||||
}
|
||||
});
|
||||
if (PrivateBrowsingUtils.permanentPrivateBrowsing) {
|
||||
// Adjust the New Window menu entries
|
||||
let newWindow = document.getElementById("menu_newNavigator");
|
||||
let newPrivateWindow = document.getElementById("menu_newPrivateWindow");
|
||||
if (newWindow && newPrivateWindow) {
|
||||
newPrivateWindow.hidden = true;
|
||||
newWindow.label = newPrivateWindow.label;
|
||||
newWindow.accessKey = newPrivateWindow.accessKey;
|
||||
newWindow.command = newPrivateWindow.command;
|
||||
}
|
||||
}
|
||||
|
||||
let urlBarSearchParam =
|
||||
gURLBar.getAttribute("autocompletesearchparam") || "";
|
||||
if (
|
||||
!PrivateBrowsingUtils.permanentPrivateBrowsing &&
|
||||
!urlBarSearchParam.includes("disable-private-actions")
|
||||
) {
|
||||
// Disable switch to tab autocompletion for private windows.
|
||||
// We leave it enabled for permanent private browsing mode though.
|
||||
urlBarSearchParam += " disable-private-actions";
|
||||
}
|
||||
if (!urlBarSearchParam.includes("private-window")) {
|
||||
urlBarSearchParam += " private-window";
|
||||
}
|
||||
gURLBar.setAttribute("autocompletesearchparam", urlBarSearchParam);
|
||||
},
|
||||
};
|
||||
|
||||
|
|
|
@ -20,6 +20,8 @@ const kESModuleList = new Set([
|
|||
/browser\/aboutlogins\/.*\.js$/,
|
||||
/browser\/protections.js$/,
|
||||
/browser\/lockwise-card.js$/,
|
||||
/toolkit\/content\/global\/certviewer\/components\/.*\.js$/,
|
||||
/toolkit\/content\/global\/certviewer\/.*\.js$/,
|
||||
]);
|
||||
|
||||
// Normally we would use reflect.jsm to get Reflect.parse. However, if
|
||||
|
|
|
@ -104,6 +104,7 @@ class UrlbarInput {
|
|||
this._textValueOnLastSearch = "";
|
||||
this._resultForCurrentValue = null;
|
||||
this._suppressStartQuery = false;
|
||||
this._suppressPrimaryAdjustment = false;
|
||||
this._untrimmedValue = "";
|
||||
|
||||
// This exists only for tests.
|
||||
|
@ -118,7 +119,6 @@ class UrlbarInput {
|
|||
"setAttribute",
|
||||
"removeAttribute",
|
||||
"toggleAttribute",
|
||||
"select",
|
||||
];
|
||||
const READ_ONLY_PROPERTIES = ["inputField", "editor"];
|
||||
const READ_WRITE_PROPERTIES = [
|
||||
|
@ -308,6 +308,14 @@ class UrlbarInput {
|
|||
this.inputField.blur();
|
||||
}
|
||||
|
||||
select() {
|
||||
// See _on_select(). HTMLInputElement.select() dispatches a "select"
|
||||
// event but does not set the primary selection.
|
||||
this._suppressPrimaryAdjustment = true;
|
||||
this.inputField.select();
|
||||
this._suppressPrimaryAdjustment = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts an internal URI (e.g. a URI with a username or password) into one
|
||||
* which we can expose to the user.
|
||||
|
@ -1551,7 +1559,22 @@ class UrlbarInput {
|
|||
}
|
||||
|
||||
_on_select(event) {
|
||||
// On certain user input, AutoCopyListener::OnSelectionChange() updates
|
||||
// the primary selection with user-selected text (when supported).
|
||||
// Selection::NotifySelectionListeners() then dispatches a "select" event
|
||||
// under similar conditions via TextInputListener::OnSelectionChange().
|
||||
// This event is received here in order to replace the primary selection
|
||||
// from the editor with text having the adjustments of
|
||||
// _getSelectedValueForClipboard(), such as adding the scheme for the url.
|
||||
//
|
||||
// Other "select" events are also received, however, and must be excluded.
|
||||
if (
|
||||
// _suppressPrimaryAdjustment is set during select(). Don't update
|
||||
// the primary selection because that is not the intent of user input,
|
||||
// which may be new tab or urlbar focus.
|
||||
this._suppressPrimaryAdjustment ||
|
||||
// The check on isHandlingUserInput filters out async "select" events
|
||||
// from setSelectionRange(), which occur when autofill text is selected.
|
||||
!this.window.windowUtils.isHandlingUserInput ||
|
||||
!Services.clipboard.supportsSelectionClipboard()
|
||||
) {
|
||||
|
|
|
@ -72,6 +72,7 @@ skip-if = (os == 'mac' && os_version == '10.14') # bug 1554807
|
|||
tags = clipboard
|
||||
[browser_percent_encoded.js]
|
||||
[browser_populateAfterPushState.js]
|
||||
[browser_primary_selection_safe_on_new_tab.js]
|
||||
[browser_privateBrowsingWindowChange.js]
|
||||
[browser_raceWithTabs.js]
|
||||
skip-if = os == "linux" # Bug 1533807
|
||||
|
|
|
@ -0,0 +1,74 @@
|
|||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
/**
|
||||
* Verify that the primary selection is unaffected by opening a new tab.
|
||||
*
|
||||
* The steps here follow STR for regression
|
||||
* https://bugzilla.mozilla.org/show_bug.cgi?id=1457355.
|
||||
*/
|
||||
|
||||
"use strict";
|
||||
|
||||
let tabs = [];
|
||||
let supportsPrimary = Services.clipboard.supportsSelectionClipboard();
|
||||
let ClipboardHelper = Cc["@mozilla.org/widget/clipboardhelper;1"].getService(
|
||||
Ci.nsIClipboardHelper
|
||||
);
|
||||
const NON_EMPTY_URL = "data:text/html,Hello";
|
||||
const TEXT_FOR_PRIMARY = "Text for PRIMARY selection";
|
||||
|
||||
add_task(async function() {
|
||||
tabs.push(
|
||||
await BrowserTestUtils.openNewForegroundTab(gBrowser, NON_EMPTY_URL)
|
||||
);
|
||||
|
||||
// Bug 1457355 reproduced only when the url had a non-empty selection.
|
||||
gURLBar.select();
|
||||
Assert.equal(gURLBar.inputField.selectionStart, 0);
|
||||
Assert.equal(
|
||||
gURLBar.inputField.selectionEnd,
|
||||
gURLBar.inputField.value.length
|
||||
);
|
||||
|
||||
if (supportsPrimary) {
|
||||
ClipboardHelper.copyStringToClipboard(
|
||||
TEXT_FOR_PRIMARY,
|
||||
Services.clipboard.kSelectionClipboard
|
||||
);
|
||||
}
|
||||
|
||||
tabs.push(
|
||||
await BrowserTestUtils.openNewForegroundTab({
|
||||
gBrowser,
|
||||
opening: () => {
|
||||
// Simulate tab open from user input such as keyboard shortcut or new
|
||||
// tab button.
|
||||
let userInput = window.windowUtils.setHandlingUserInput(true);
|
||||
try {
|
||||
BrowserOpenTab();
|
||||
} finally {
|
||||
userInput.destruct();
|
||||
}
|
||||
},
|
||||
waitForLoad: false,
|
||||
})
|
||||
);
|
||||
|
||||
if (!supportsPrimary) {
|
||||
info("Primary selection not supported. Skipping assertion.");
|
||||
return;
|
||||
}
|
||||
|
||||
let primaryAsText = SpecialPowers.getClipboardData(
|
||||
"text/unicode",
|
||||
SpecialPowers.Ci.nsIClipboard.kSelectionClipboard
|
||||
);
|
||||
Assert.equal(primaryAsText, TEXT_FOR_PRIMARY);
|
||||
});
|
||||
|
||||
registerCleanupFunction(() => {
|
||||
for (let tab of tabs) {
|
||||
BrowserTestUtils.removeTab(tab);
|
||||
}
|
||||
});
|
|
@ -11,7 +11,7 @@
|
|||
}
|
||||
|
||||
.deleteOptions {
|
||||
border: thin solid lightgray;
|
||||
border: 1px solid var(--in-content-box-border-color);
|
||||
padding: 1em;
|
||||
}
|
||||
|
||||
|
@ -20,7 +20,7 @@
|
|||
}
|
||||
|
||||
.deleteData {
|
||||
color: gray;
|
||||
color: var(--in-content-deemphasized-text);
|
||||
}
|
||||
|
||||
.disconnectThrobber {
|
||||
|
|
|
@ -2,11 +2,23 @@
|
|||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
/*
|
||||
* Global styles
|
||||
*/
|
||||
@import "resource://devtools/client/application/src/base.css";
|
||||
|
||||
/*
|
||||
* Components
|
||||
*/
|
||||
@import "resource://devtools/client/application/src/components/App.css";
|
||||
@import "resource://devtools/client/application/src/components/Worker.css";
|
||||
@import "resource://devtools/client/application/src/components/WorkerList.css";
|
||||
@import "resource://devtools/client/application/src/components/WorkerListEmpty.css";
|
||||
|
||||
|
||||
/*
|
||||
* Reset
|
||||
*/
|
||||
* {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,61 @@
|
|||
/* 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/. */
|
||||
|
||||
:root {
|
||||
/* Typography from Photon */
|
||||
/* See https://firefox-dev.tools/photon/visuals/typography.html */
|
||||
--body-10-font-size: 13px;
|
||||
--body-10-font-weight: 400;
|
||||
--body-20-font-size: 15px;
|
||||
--body-20-font-weight: 400;
|
||||
--body-20-font-weight-bold: 700;
|
||||
--title-20-font-size: 17px;
|
||||
--title-20-font-weight: 600;
|
||||
--title-30-font-size: 22px;
|
||||
--title-30-font-weight: 300;
|
||||
|
||||
/* Global styles */
|
||||
--base-font-size: var(--body-10-font-size);
|
||||
--base-font-weight: var(--body-10-font-weight);
|
||||
--base-line-height: 1.8;
|
||||
--list-line-height: 1.25;
|
||||
|
||||
/* Global colours */
|
||||
--bg-color: var(--grey-10);
|
||||
--text-color: var(--grey-90);
|
||||
|
||||
/* Global layout vars */
|
||||
--base-unit: 4px;
|
||||
}
|
||||
|
||||
/*
|
||||
* Reset some tags
|
||||
*/
|
||||
|
||||
body {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
line-height: var(--base-line-height);
|
||||
}
|
||||
|
||||
ul {
|
||||
line-height: var(--list-line-height);
|
||||
}
|
||||
|
||||
a {
|
||||
color: var(--theme-highlight-blue);
|
||||
text-decoration: none;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
h1,
|
||||
.application--title {
|
||||
font-size: var(--title-30-font-size);
|
||||
font-weight: var(--title-30-font-weight);
|
||||
line-height: var(--base-line-height);
|
||||
}
|
||||
|
||||
p {
|
||||
margin: 0;
|
||||
}
|
|
@ -6,26 +6,10 @@
|
|||
* General styles
|
||||
*/
|
||||
|
||||
h1 {
|
||||
font-size: 22px;
|
||||
font-weight: normal;
|
||||
}
|
||||
|
||||
a {
|
||||
margin: 0 10px;
|
||||
}
|
||||
|
||||
a,
|
||||
a:hover,
|
||||
a:visited {
|
||||
color: var(--theme-highlight-blue) !important;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
a.disabled-link,
|
||||
a.disabled-link:hover,
|
||||
a.disabled-link:visited {
|
||||
opacity: 0.5 !important;
|
||||
opacity: 0.5;
|
||||
cursor: not-allowed;
|
||||
}
|
||||
|
||||
|
|
|
@ -22,9 +22,8 @@
|
|||
width: 100%;
|
||||
grid-column-gap: 0;
|
||||
padding: 1rem 0;
|
||||
|
||||
line-height: 1.5;
|
||||
font-size: 1.2rem;
|
||||
font-size: var(--body-10-font-size);
|
||||
}
|
||||
|
||||
.worker:first-child {
|
||||
|
@ -73,3 +72,8 @@
|
|||
.worker__data__updated {
|
||||
color: var(--theme-text-color-alt);
|
||||
}
|
||||
|
||||
.worker__link-start,
|
||||
.worker__link-debug {
|
||||
margin: 0 calc(var(--base-unit) * 2);
|
||||
}
|
||||
|
|
|
@ -154,7 +154,7 @@ class Worker extends Component {
|
|||
},
|
||||
a({
|
||||
onClick: !shallDisableLink ? this.debug : null,
|
||||
className: `${linkClass} worker__debug-link js-debug-link`,
|
||||
className: `${linkClass} worker__link-debug js-link-debug`,
|
||||
})
|
||||
);
|
||||
return link;
|
||||
|
@ -174,7 +174,7 @@ class Worker extends Component {
|
|||
},
|
||||
a({
|
||||
onClick: this.start,
|
||||
className: `worker__start-link js-start-link ${linkClass}`,
|
||||
className: `worker__link-start js-link-start ${linkClass}`,
|
||||
})
|
||||
);
|
||||
return link;
|
||||
|
|
|
@ -42,7 +42,12 @@ class WorkerList extends Component {
|
|||
return [
|
||||
article(
|
||||
{ className: "workers-container" },
|
||||
Localized({ id: "serviceworker-list-header" }, h1({})),
|
||||
Localized(
|
||||
{ id: "serviceworker-list-header" },
|
||||
h1({
|
||||
className: "application--title",
|
||||
})
|
||||
),
|
||||
ul(
|
||||
{},
|
||||
workers.map(worker =>
|
||||
|
@ -56,7 +61,7 @@ class WorkerList extends Component {
|
|||
),
|
||||
Localized(
|
||||
{
|
||||
id: "serviceworker-list-aboutdebugging2",
|
||||
id: "serviceworker-list-aboutdebugging",
|
||||
a: a({
|
||||
className: "aboutdebugging-plug__link",
|
||||
onClick: () => openTrustedLink("about:debugging#workers"),
|
||||
|
|
|
@ -3,16 +3,20 @@
|
|||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
.worker-list-empty {
|
||||
max-width: 65rem;
|
||||
font-size: 1.2rem;
|
||||
line-height: 1.25;
|
||||
max-width: calc(var(--base-unit) * 179);
|
||||
font-size: var(--body-10-font-size);
|
||||
color: var(--theme-toolbar-color);
|
||||
}
|
||||
|
||||
.worker-list-empty__title {
|
||||
font-size: 1.4rem;
|
||||
font-size: var(--title-20-font-size);
|
||||
font-weight: var(--title-20-font-weight);
|
||||
}
|
||||
|
||||
.worker-list-empty__title .external-link {
|
||||
font-weight: var(--title-30-font-weight);
|
||||
}
|
||||
|
||||
.worker-list-empty__tips {
|
||||
margin-inline-start: 2rem;
|
||||
}
|
||||
|
@ -20,4 +24,4 @@
|
|||
.worker-list-empty__tips__item {
|
||||
margin-block-start: 0.5rem;
|
||||
margin-block-end: 0.5rem;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -13,7 +13,6 @@ const {
|
|||
const {
|
||||
a,
|
||||
article,
|
||||
h1,
|
||||
li,
|
||||
p,
|
||||
ul,
|
||||
|
@ -64,7 +63,7 @@ class WorkerListEmpty extends Component {
|
|||
onClick: () => this.openDocumentation(),
|
||||
}),
|
||||
},
|
||||
h1({ className: "worker-list-empty__title" })
|
||||
p({ className: "worker-list-empty__title" })
|
||||
),
|
||||
Localized({ id: "serviceworker-empty-suggestions" }, p({})),
|
||||
ul(
|
||||
|
|
|
@ -10,6 +10,7 @@ DIRS += [
|
|||
]
|
||||
|
||||
DevToolsModules(
|
||||
'base.css',
|
||||
'constants.js',
|
||||
'create-store.js',
|
||||
)
|
||||
|
|
|
@ -29,13 +29,13 @@ add_task(async function() {
|
|||
const container = getWorkerContainers(doc)[0];
|
||||
info("Wait until the debug link is displayed and enabled");
|
||||
await waitUntil(() =>
|
||||
container.querySelector(".js-debug-link:not(.worker__debug-link--disabled)")
|
||||
container.querySelector(".js-link-debug:not(.worker__debug-link--disabled)")
|
||||
);
|
||||
|
||||
info("Click on the debug link and wait for the new toolbox to be ready");
|
||||
const onToolboxReady = gDevTools.once("toolbox-ready");
|
||||
|
||||
const debugLink = container.querySelector(".js-debug-link");
|
||||
const debugLink = container.querySelector(".js-link-debug");
|
||||
debugLink.click();
|
||||
|
||||
const serviceWorkerToolbox = await onToolboxReady;
|
||||
|
|
|
@ -29,10 +29,10 @@ add_task(async function() {
|
|||
info("Wait until the start link is displayed and enabled");
|
||||
const container = getWorkerContainers(doc)[0];
|
||||
await waitUntil(() =>
|
||||
container.querySelector(".js-start-link:not(.disabled-link)")
|
||||
container.querySelector(".js-link-start:not(.disabled-link)")
|
||||
);
|
||||
info("Click the link and wait for the worker to start");
|
||||
const link = container.querySelector(".js-start-link");
|
||||
const link = container.querySelector(".js-link-start");
|
||||
link.click();
|
||||
await waitUntil(
|
||||
() => container.querySelector(".js-worker-status").textContent === "Running"
|
||||
|
@ -61,9 +61,9 @@ add_task(async function() {
|
|||
|
||||
info("Wait until the start link is displayed");
|
||||
const container = getWorkerContainers(doc)[0];
|
||||
await waitUntil(() => container.querySelector(".js-start-link"));
|
||||
await waitUntil(() => container.querySelector(".js-link-start"));
|
||||
ok(
|
||||
container.querySelector(".js-start-link.disabled-link"),
|
||||
container.querySelector(".js-link-start.disabled-link"),
|
||||
"Start link is disabled"
|
||||
);
|
||||
|
||||
|
|
|
@ -803,7 +803,6 @@ skip-if = os == "win"
|
|||
[browser_dbg-react-app.js]
|
||||
skip-if = os == "win"
|
||||
[browser_dbg-wasm-sourcemaps.js]
|
||||
skip-if = (os == "win") || os == ("linux") && debug # Bug 1561092
|
||||
[browser_dbg-windowless-workers.js]
|
||||
[browser_dbg-windowless-workers-early-breakpoint.js]
|
||||
[browser_dbg-worker-scopes.js]
|
||||
|
|
|
@ -83,22 +83,8 @@ class GridItem extends PureComponent {
|
|||
this.props.onSetGridOverlayColor(this.props.grid.nodeFront, color);
|
||||
}
|
||||
|
||||
onGridCheckboxClick(e) {
|
||||
// If the click was on the svg icon to select the node in the inspector, bail out.
|
||||
const originalTarget =
|
||||
e.nativeEvent && e.nativeEvent.explicitOriginalTarget;
|
||||
if (
|
||||
originalTarget &&
|
||||
originalTarget.namespaceURI === "http://www.w3.org/2000/svg"
|
||||
) {
|
||||
// We should be able to cancel the click event propagation after the following reps
|
||||
// issue is implemented : https://github.com/firefox-devtools/reps/issues/95 .
|
||||
e.preventDefault();
|
||||
return;
|
||||
}
|
||||
|
||||
onGridCheckboxClick() {
|
||||
const { grid, onToggleGridHighlighter } = this.props;
|
||||
|
||||
onToggleGridHighlighter(grid.nodeFront);
|
||||
}
|
||||
|
||||
|
@ -164,8 +150,11 @@ class GridItem extends PureComponent {
|
|||
onDOMNodeMouseOut: () => onHideBoxModelHighlighter(),
|
||||
onDOMNodeMouseOver: () =>
|
||||
onShowBoxModelHighlighterForNode(grid.nodeFront),
|
||||
onInspectIconClick: () =>
|
||||
this.onGridInspectIconClick(grid.nodeFront),
|
||||
onInspectIconClick: (_, e) => {
|
||||
// Stoping click propagation to avoid firing onGridCheckboxClick()
|
||||
e.stopPropagation();
|
||||
this.onGridInspectIconClick(grid.nodeFront);
|
||||
},
|
||||
})
|
||||
),
|
||||
dom.div({
|
||||
|
|
|
@ -645,9 +645,9 @@ netmonitor.ws.toolbar.frameType=Type
|
|||
# in the websocket frame table header, above the "size" column.
|
||||
netmonitor.ws.toolbar.size=Size
|
||||
|
||||
# LOCALIZATION NOTE (netmonitor.ws.toolbar.payload): This is the label displayed
|
||||
# in the websocket frame table header, above the "payload" column.
|
||||
netmonitor.ws.toolbar.payload=Payload
|
||||
# LOCALIZATION NOTE (netmonitor.ws.toolbar.data): This is the label displayed
|
||||
# in the websocket frame table header, above the "data" column.
|
||||
netmonitor.ws.toolbar.data=Data
|
||||
|
||||
# LOCALIZATION NOTE (netmonitor.ws.toolbar.opCode): This is the label displayed
|
||||
# in the websocket frame table header, above the "opCode" column.
|
||||
|
@ -665,13 +665,49 @@ netmonitor.ws.toolbar.finBit=FinBit
|
|||
# in the websocket frame table header, above the "time" column.
|
||||
netmonitor.ws.toolbar.time=Time
|
||||
|
||||
# LOCALIZATION NOTE (netmonitor.ws.toolbar.clear): This is the label displayed
|
||||
# in the websocket toolbar for the "Clear" button.
|
||||
netmonitor.ws.toolbar.clear=Clear
|
||||
|
||||
# LOCALIZATION NOTE (netmonitor.ws.toolbar.filterFreetext.label): This is the label
|
||||
# displayed in the websocket toolbar for the frames filtering textbox.
|
||||
netmonitor.ws.toolbar.filterFreetext.label=Filter Messages
|
||||
|
||||
# LOCALIZATION NOTE (netmonitor.ws.toolbar.filterFreetext.key): This is the
|
||||
# shortcut key to focus on the websocket toolbar frames filtering textbox
|
||||
netmonitor.ws.toolbar.filterFreetext.key=CmdOrCtrl+E
|
||||
|
||||
# LOCALIZATION NOTE (netmonitor.ws.context.all): This is the label displayed
|
||||
# on the context menu that shows "All" WebSocket frames.
|
||||
netmonitor.ws.context.all=All
|
||||
|
||||
# LOCALIZATION NOTE (netmonitor.ws.context.all.accesskey): This is the access key
|
||||
# for the "All" menu item displayed in the context menu in the websocket toolbar.
|
||||
netmonitor.ws.context.all.accesskey=A
|
||||
|
||||
# LOCALIZATION NOTE (netmonitor.ws.context.sent): This is the label displayed
|
||||
# on the context menu that shows "Sent" WebSocket frames.
|
||||
netmonitor.ws.context.sent=Sent
|
||||
|
||||
# LOCALIZATION NOTE (netmonitor.ws.context.sent.accesskey): This is the access key
|
||||
# for the "Sent" menu item displayed in the context menu in the websocket toolbar.
|
||||
netmonitor.ws.context.sent.accesskey=S
|
||||
|
||||
# LOCALIZATION NOTE (netmonitor.ws.context.received): This is the label displayed
|
||||
# on the context menu that shows "Received" WebSocket frames.
|
||||
netmonitor.ws.context.received=Received
|
||||
|
||||
# LOCALIZATION NOTE (netmonitor.ws.context.received.accesskey): This is the access key
|
||||
# for the "Received" menu item displayed in the context menu in the websocket toolbar.
|
||||
netmonitor.ws.context.received.accesskey=R
|
||||
|
||||
# LOCALIZATION NOTE (netmonitor.tab.headers): This is the label displayed
|
||||
# in the network details pane identifying the headers tab.
|
||||
netmonitor.tab.headers=Headers
|
||||
|
||||
# LOCALIZATION NOTE (netmonitor.tab.webSockets): This is the label displayed
|
||||
# in the network details pane identifying the webSockets tab.
|
||||
netmonitor.tab.webSockets=WebSockets
|
||||
# LOCALIZATION NOTE (netmonitor.tab.messages): This is the label displayed
|
||||
# in the network details pane identifying the messages tab.
|
||||
netmonitor.tab.messages=Messages
|
||||
|
||||
# LOCALIZATION NOTE (netmonitor.tab.cookies): This is the label displayed
|
||||
# in the network details pane identifying the cookies tab.
|
||||
|
|
|
@ -15,10 +15,11 @@ const PAGE_SIZE_ITEM_COUNT_RATIO = 5;
|
|||
/**
|
||||
* Select request with a given id.
|
||||
*/
|
||||
function selectRequest(id) {
|
||||
function selectRequest(id, httpChannelId) {
|
||||
return {
|
||||
type: SELECT_REQUEST,
|
||||
id,
|
||||
httpChannelId,
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -8,8 +8,14 @@ const {
|
|||
WS_ADD_FRAME,
|
||||
WS_SELECT_FRAME,
|
||||
WS_OPEN_FRAME_DETAILS,
|
||||
WS_CLEAR_FRAMES,
|
||||
WS_TOGGLE_FRAME_FILTER_TYPE,
|
||||
WS_SET_REQUEST_FILTER_TEXT,
|
||||
} = require("../constants");
|
||||
|
||||
/**
|
||||
* Add frame into state.
|
||||
*/
|
||||
function addFrame(httpChannelId, data) {
|
||||
return {
|
||||
type: WS_ADD_FRAME,
|
||||
|
@ -41,8 +47,43 @@ function openFrameDetails(open) {
|
|||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear all frames from the FrameListContent
|
||||
* component belonging to the current channelId
|
||||
*/
|
||||
function clearFrames() {
|
||||
return {
|
||||
type: WS_CLEAR_FRAMES,
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Show filtered frames from the FrameListContent
|
||||
* component belonging to the current channelId
|
||||
*/
|
||||
function toggleFrameFilterType(filter) {
|
||||
return {
|
||||
type: WS_TOGGLE_FRAME_FILTER_TYPE,
|
||||
filter,
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Set filter text in toolbar.
|
||||
*
|
||||
*/
|
||||
function setFrameFilterText(text) {
|
||||
return {
|
||||
type: WS_SET_REQUEST_FILTER_TEXT,
|
||||
text,
|
||||
};
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
addFrame,
|
||||
selectFrame,
|
||||
openFrameDetails,
|
||||
clearFrames,
|
||||
toggleFrameFilterType,
|
||||
setFrameFilterText,
|
||||
};
|
||||
|
|
|
@ -14,11 +14,6 @@
|
|||
min-height: var(--primary-toolbar-height);
|
||||
}
|
||||
|
||||
.requests-list-filter-buttons {
|
||||
white-space: nowrap;
|
||||
margin: 0 7px;
|
||||
}
|
||||
|
||||
.devtools-button.devtools-pause-icon::before,
|
||||
.devtools-button.devtools-play-icon::before {
|
||||
margin-bottom: 1px;
|
||||
|
|
|
@ -232,9 +232,9 @@ class RequestListContent extends Component {
|
|||
this.tooltip.hide();
|
||||
}
|
||||
|
||||
onMouseDown(evt, id) {
|
||||
onMouseDown(evt, id, channelId) {
|
||||
if (evt.button === LEFT_MOUSE_BUTTON) {
|
||||
this.props.selectRequest(id);
|
||||
this.props.selectRequest(id, channelId);
|
||||
} else if (evt.button === RIGHT_MOUSE_BUTTON) {
|
||||
this.props.onItemRightMouseButtonDown(id);
|
||||
}
|
||||
|
@ -383,7 +383,8 @@ class RequestListContent extends Component {
|
|||
onContextMenu: this.onContextMenu,
|
||||
onFocusedNodeChange: this.onFocusedNodeChange,
|
||||
onDoubleClick: () => this.onDoubleClick(item),
|
||||
onMouseDown: evt => this.onMouseDown(evt, item.id),
|
||||
onMouseDown: evt =>
|
||||
this.onMouseDown(evt, item.id, item.channelId),
|
||||
onCauseBadgeMouseDown: () => onCauseBadgeMouseDown(item.cause),
|
||||
onSecurityIconMouseDown: () =>
|
||||
onSecurityIconMouseDown(item.securityState),
|
||||
|
@ -435,7 +436,8 @@ module.exports = connect(
|
|||
dispatch(Actions.selectDetailsPanelTab("stack-trace"));
|
||||
}
|
||||
},
|
||||
selectRequest: id => dispatch(Actions.selectRequest(id)),
|
||||
selectRequest: (id, channelId) =>
|
||||
dispatch(Actions.selectRequest(id, channelId)),
|
||||
onItemRightMouseButtonDown: id => dispatch(Actions.rightClickRequest(id)),
|
||||
onItemMouseDown: id => dispatch(Actions.selectRequest(id)),
|
||||
/**
|
||||
|
|
|
@ -34,7 +34,7 @@ const COLLAPSE_DETAILS_PANE = L10N.getStr("collapseDetailsPane");
|
|||
const CACHE_TITLE = L10N.getStr("netmonitor.tab.cache");
|
||||
const COOKIES_TITLE = L10N.getStr("netmonitor.tab.cookies");
|
||||
const HEADERS_TITLE = L10N.getStr("netmonitor.tab.headers");
|
||||
const WEBSOCKETS_TITLE = L10N.getStr("netmonitor.tab.webSockets");
|
||||
const MESSAGES_TITLE = L10N.getStr("netmonitor.tab.messages");
|
||||
const PARAMS_TITLE = L10N.getStr("netmonitor.tab.params");
|
||||
const RESPONSE_TITLE = L10N.getStr("netmonitor.tab.response");
|
||||
const SECURITY_TITLE = L10N.getStr("netmonitor.tab.security");
|
||||
|
@ -96,7 +96,6 @@ class TabboxPanel extends Component {
|
|||
return null;
|
||||
}
|
||||
|
||||
const channelId = request.channelId;
|
||||
const showWebSocketsPanel =
|
||||
request.cause.type === "websocket" &&
|
||||
Services.prefs.getBoolPref("devtools.netmonitor.features.webSockets") &&
|
||||
|
@ -135,11 +134,10 @@ class TabboxPanel extends Component {
|
|||
showWebSocketsPanel &&
|
||||
TabPanel(
|
||||
{
|
||||
id: PANELS.WEBSOCKETS,
|
||||
title: WEBSOCKETS_TITLE,
|
||||
id: PANELS.MESSAGES,
|
||||
title: MESSAGES_TITLE,
|
||||
},
|
||||
WebSocketsPanel({
|
||||
channelId,
|
||||
connector,
|
||||
})
|
||||
),
|
||||
|
|
|
@ -0,0 +1,85 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
"use strict";
|
||||
const { PureComponent } = require("devtools/client/shared/vendor/react");
|
||||
const dom = require("devtools/client/shared/vendor/react-dom-factories");
|
||||
const PropTypes = require("devtools/client/shared/vendor/react-prop-types");
|
||||
|
||||
const { L10N } = require("devtools/client/netmonitor/src/utils/l10n.js");
|
||||
|
||||
// Menu
|
||||
loader.lazyRequireGetter(
|
||||
this,
|
||||
"showMenu",
|
||||
"devtools/client/shared/components/menu/utils",
|
||||
true
|
||||
);
|
||||
|
||||
class FrameFilterMenu extends PureComponent {
|
||||
static get propTypes() {
|
||||
return {
|
||||
frameFilterType: PropTypes.string.isRequired,
|
||||
toggleFrameFilterType: PropTypes.func.isRequired,
|
||||
};
|
||||
}
|
||||
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.onShowFilterMenu = this.onShowFilterMenu.bind(this);
|
||||
}
|
||||
|
||||
onShowFilterMenu(event) {
|
||||
const { frameFilterType, toggleFrameFilterType } = this.props;
|
||||
|
||||
const menuItems = [
|
||||
{
|
||||
id: "ws-frame-list-context-filter-all",
|
||||
label: L10N.getStr("netmonitor.ws.context.all"),
|
||||
accesskey: L10N.getStr("netmonitor.ws.context.all.accesskey"),
|
||||
checked: frameFilterType === "all",
|
||||
click: () => {
|
||||
toggleFrameFilterType("all");
|
||||
},
|
||||
},
|
||||
{
|
||||
id: "ws-frame-list-context-filter-sent",
|
||||
label: L10N.getStr("netmonitor.ws.context.sent"),
|
||||
accesskey: L10N.getStr("netmonitor.ws.context.sent.accesskey"),
|
||||
checked: frameFilterType === "sent",
|
||||
click: () => {
|
||||
toggleFrameFilterType("sent");
|
||||
},
|
||||
},
|
||||
{
|
||||
id: "ws-frame-list-context-filter-received",
|
||||
label: L10N.getStr("netmonitor.ws.context.received"),
|
||||
accesskey: L10N.getStr("netmonitor.ws.context.received.accesskey"),
|
||||
checked: frameFilterType === "received",
|
||||
click: () => {
|
||||
toggleFrameFilterType("received");
|
||||
},
|
||||
},
|
||||
];
|
||||
|
||||
showMenu(menuItems, { button: event.target });
|
||||
}
|
||||
|
||||
render() {
|
||||
const { frameFilterType } = this.props;
|
||||
const title = L10N.getStr(`netmonitor.ws.context.${frameFilterType}`);
|
||||
|
||||
return dom.button(
|
||||
{
|
||||
id: "frame-filter-menu",
|
||||
className: "devtools-button devtools-dropdown-button",
|
||||
title,
|
||||
onClick: this.onShowFilterMenu,
|
||||
},
|
||||
dom.span({ className: "title" }, title)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = FrameFilterMenu;
|
|
@ -10,9 +10,9 @@ const PropTypes = require("devtools/client/shared/vendor/react-prop-types");
|
|||
const { getFramePayload } = require("../../utils/request-utils");
|
||||
|
||||
/**
|
||||
* Renders the "Payload" column of a WebSocket frame.
|
||||
* Renders the "Data" column of a WebSocket frame.
|
||||
*/
|
||||
class FrameListColumnPayload extends Component {
|
||||
class FrameListColumnData extends Component {
|
||||
static get propTypes() {
|
||||
return {
|
||||
item: PropTypes.object.isRequired,
|
||||
|
@ -61,4 +61,4 @@ class FrameListColumnPayload extends Component {
|
|||
}
|
||||
}
|
||||
|
||||
module.exports = FrameListColumnPayload;
|
||||
module.exports = FrameListColumnData;
|
|
@ -29,6 +29,7 @@ class FrameListColumnTime extends Component {
|
|||
|
||||
// Convert microseconds (DOMHighResTimeStamp) to milliseconds
|
||||
const time = timeStamp / 1000;
|
||||
const microseconds = (timeStamp % 1000).toString().padStart(3, "0");
|
||||
|
||||
return dom.td(
|
||||
{
|
||||
|
@ -36,7 +37,9 @@ class FrameListColumnTime extends Component {
|
|||
className: "ws-frames-list-column ws-frames-list-time",
|
||||
title: timeStamp,
|
||||
},
|
||||
new Date(time).toLocaleTimeString()
|
||||
new Date(time).toLocaleTimeString(undefined, { hour12: false }) +
|
||||
"." +
|
||||
microseconds
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,7 +12,7 @@ const PropTypes = require("devtools/client/shared/vendor/react-prop-types");
|
|||
const {
|
||||
connect,
|
||||
} = require("devtools/client/shared/redux/visibility-handler-connect");
|
||||
const { getFramesByChannelId } = require("../../selectors/index");
|
||||
const { getDisplayedFrames } = require("../../selectors/index");
|
||||
|
||||
const dom = require("devtools/client/shared/vendor/react-dom-factories");
|
||||
const { table, tbody, div } = dom;
|
||||
|
@ -38,7 +38,6 @@ const LEFT_MOUSE_BUTTON = 0;
|
|||
class FrameListContent extends Component {
|
||||
static get propTypes() {
|
||||
return {
|
||||
channelId: PropTypes.number,
|
||||
connector: PropTypes.object.isRequired,
|
||||
frames: PropTypes.array,
|
||||
selectedFrame: PropTypes.object,
|
||||
|
@ -59,7 +58,7 @@ class FrameListContent extends Component {
|
|||
render() {
|
||||
const { frames, selectedFrame, connector } = this.props;
|
||||
|
||||
if (!frames) {
|
||||
if (frames.length === 0) {
|
||||
return div(
|
||||
{ className: "empty-notice ws-frame-list-empty-notice" },
|
||||
FRAMES_EMPTY_TEXT
|
||||
|
@ -89,9 +88,9 @@ class FrameListContent extends Component {
|
|||
}
|
||||
|
||||
module.exports = connect(
|
||||
(state, props) => ({
|
||||
state => ({
|
||||
selectedFrame: getSelectedFrame(state),
|
||||
frames: getFramesByChannelId(state, props.channelId),
|
||||
frames: getDisplayedFrames(state),
|
||||
}),
|
||||
dispatch => ({
|
||||
selectFrame: item => dispatch(Actions.selectFrame(item)),
|
||||
|
|
|
@ -18,8 +18,8 @@ loader.lazyGetter(this, "FrameListColumnType", function() {
|
|||
loader.lazyGetter(this, "FrameListColumnSize", function() {
|
||||
return createFactory(require("./FrameListColumnSize"));
|
||||
});
|
||||
loader.lazyGetter(this, "FrameListColumnPayload", function() {
|
||||
return createFactory(require("./FrameListColumnPayload"));
|
||||
loader.lazyGetter(this, "FrameListColumnData", function() {
|
||||
return createFactory(require("./FrameListColumnData"));
|
||||
});
|
||||
loader.lazyGetter(this, "FrameListColumnOpCode", function() {
|
||||
return createFactory(require("./FrameListColumnOpCode"));
|
||||
|
@ -37,7 +37,7 @@ loader.lazyGetter(this, "FrameListColumnTime", function() {
|
|||
const COLUMN_COMPONENTS = [
|
||||
{ column: "type", ColumnComponent: FrameListColumnType },
|
||||
{ column: "size", ColumnComponent: FrameListColumnSize },
|
||||
{ column: "payload", ColumnComponent: FrameListColumnPayload },
|
||||
{ column: "data", ColumnComponent: FrameListColumnData },
|
||||
{ column: "opCode", ColumnComponent: FrameListColumnOpCode },
|
||||
{ column: "maskBit", ColumnComponent: FrameListColumnMaskBit },
|
||||
{ column: "finBit", ColumnComponent: FrameListColumnFinBit },
|
||||
|
|
|
@ -0,0 +1,129 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
"use strict";
|
||||
|
||||
const {
|
||||
Component,
|
||||
createFactory,
|
||||
} = require("devtools/client/shared/vendor/react");
|
||||
const {
|
||||
connect,
|
||||
} = require("devtools/client/shared/redux/visibility-handler-connect");
|
||||
const PropTypes = require("devtools/client/shared/vendor/react-prop-types");
|
||||
const Actions = require("devtools/client/netmonitor/src/actions/index");
|
||||
const {
|
||||
FILTER_SEARCH_DELAY,
|
||||
} = require("devtools/client/netmonitor/src/constants");
|
||||
const dom = require("devtools/client/shared/vendor/react-dom-factories");
|
||||
const { L10N } = require("devtools/client/netmonitor/src/utils/l10n.js");
|
||||
const { button, span, div } = dom;
|
||||
|
||||
// Components
|
||||
const FrameFilterMenu = createFactory(require("./FrameFilterMenu"));
|
||||
const SearchBox = createFactory(
|
||||
require("devtools/client/shared/components/SearchBox")
|
||||
);
|
||||
|
||||
// Localization
|
||||
const WS_TOOLBAR_CLEAR = L10N.getStr("netmonitor.ws.toolbar.clear");
|
||||
const WS_SEARCH_KEY_SHORTCUT = L10N.getStr(
|
||||
"netmonitor.ws.toolbar.filterFreetext.key"
|
||||
);
|
||||
const WS_SEARCH_PLACE_HOLDER = L10N.getStr(
|
||||
"netmonitor.ws.toolbar.filterFreetext.label"
|
||||
);
|
||||
|
||||
/**
|
||||
* WebSocketsPanel toolbar component.
|
||||
*
|
||||
* Toolbar contains a set of useful tools that clear the list of
|
||||
* existing frames as well as filter content.
|
||||
*/
|
||||
class Toolbar extends Component {
|
||||
static get propTypes() {
|
||||
return {
|
||||
searchboxRef: PropTypes.object.isRequired,
|
||||
toggleFrameFilterType: PropTypes.func.isRequired,
|
||||
clearFrames: PropTypes.func.isRequired,
|
||||
setFrameFilterText: PropTypes.func.isRequired,
|
||||
frameFilterType: PropTypes.string.isRequired,
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Render a separator.
|
||||
*/
|
||||
renderSeparator() {
|
||||
return span({ className: "devtools-separator" });
|
||||
}
|
||||
|
||||
/**
|
||||
* Render a clear button.
|
||||
*/
|
||||
renderClearButton(clearFrames) {
|
||||
return button({
|
||||
className:
|
||||
"devtools-button devtools-clear-icon ws-frames-list-clear-button",
|
||||
title: WS_TOOLBAR_CLEAR,
|
||||
onClick: () => {
|
||||
clearFrames();
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Render the frame filter menu button.
|
||||
*/
|
||||
renderFrameFilterMenu() {
|
||||
const { frameFilterType, toggleFrameFilterType } = this.props;
|
||||
|
||||
return FrameFilterMenu({
|
||||
frameFilterType,
|
||||
toggleFrameFilterType,
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Render filter Searchbox.
|
||||
*/
|
||||
renderFilterBox(setFrameFilterText) {
|
||||
return SearchBox({
|
||||
delay: FILTER_SEARCH_DELAY,
|
||||
keyShortcut: WS_SEARCH_KEY_SHORTCUT,
|
||||
placeholder: WS_SEARCH_PLACE_HOLDER,
|
||||
type: "filter",
|
||||
ref: this.props.searchboxRef,
|
||||
onChange: setFrameFilterText,
|
||||
});
|
||||
}
|
||||
|
||||
render() {
|
||||
const { clearFrames, setFrameFilterText } = this.props;
|
||||
|
||||
return div(
|
||||
{
|
||||
id: "netmonitor-toolbar-container",
|
||||
className: "devtools-toolbar devtools-input-toolbar",
|
||||
},
|
||||
this.renderClearButton(clearFrames),
|
||||
this.renderSeparator(),
|
||||
this.renderFrameFilterMenu(),
|
||||
this.renderSeparator(),
|
||||
this.renderFilterBox(setFrameFilterText)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = connect(
|
||||
state => ({
|
||||
frameFilterType: state.webSockets.frameFilterType,
|
||||
}),
|
||||
dispatch => ({
|
||||
clearFrames: () => dispatch(Actions.clearFrames()),
|
||||
toggleFrameFilterType: filter =>
|
||||
dispatch(Actions.toggleFrameFilterType(filter)),
|
||||
setFrameFilterText: text => dispatch(Actions.setFrameFilterText(text)),
|
||||
})
|
||||
)(Toolbar);
|
|
@ -7,8 +7,11 @@
|
|||
const Services = require("Services");
|
||||
const {
|
||||
Component,
|
||||
createRef,
|
||||
createFactory,
|
||||
} = require("devtools/client/shared/vendor/react");
|
||||
const dom = require("devtools/client/shared/vendor/react-dom-factories");
|
||||
const { div } = dom;
|
||||
const PropTypes = require("devtools/client/shared/vendor/react-prop-types");
|
||||
const {
|
||||
connect,
|
||||
|
@ -25,6 +28,7 @@ const SplitBox = createFactory(
|
|||
require("devtools/client/shared/components/splitter/SplitBox")
|
||||
);
|
||||
const FrameListContent = createFactory(require("./FrameListContent"));
|
||||
const Toolbar = createFactory(require("./Toolbar"));
|
||||
|
||||
loader.lazyGetter(this, "FramePayload", function() {
|
||||
return createFactory(require("./FramePayload"));
|
||||
|
@ -37,33 +41,44 @@ loader.lazyGetter(this, "FramePayload", function() {
|
|||
class WebSocketsPanel extends Component {
|
||||
static get propTypes() {
|
||||
return {
|
||||
channelId: PropTypes.number,
|
||||
connector: PropTypes.object.isRequired,
|
||||
selectedFrame: PropTypes.object,
|
||||
frameDetailsOpen: PropTypes.bool.isRequired,
|
||||
openFrameDetailsTab: PropTypes.func.isRequired,
|
||||
selectedFrameVisible: PropTypes.bool.isRequired,
|
||||
channelId: PropTypes.number,
|
||||
};
|
||||
}
|
||||
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
||||
this.searchboxRef = createRef();
|
||||
this.clearFilterText = this.clearFilterText.bind(this);
|
||||
}
|
||||
|
||||
componentDidUpdate() {
|
||||
const { selectedFrameVisible, openFrameDetailsTab } = this.props;
|
||||
componentDidUpdate(nextProps) {
|
||||
const { selectedFrameVisible, openFrameDetailsTab, channelId } = this.props;
|
||||
|
||||
// If a new WebSocket connection is selected, clear the filter text
|
||||
if (channelId !== nextProps.channelId) {
|
||||
this.clearFilterText();
|
||||
}
|
||||
|
||||
if (!selectedFrameVisible) {
|
||||
openFrameDetailsTab(false);
|
||||
}
|
||||
}
|
||||
|
||||
// Reset the filter text
|
||||
clearFilterText() {
|
||||
if (this.searchboxRef) {
|
||||
this.searchboxRef.current.onClearButtonClick();
|
||||
}
|
||||
}
|
||||
|
||||
render() {
|
||||
const {
|
||||
frameDetailsOpen,
|
||||
channelId,
|
||||
connector,
|
||||
selectedFrame,
|
||||
} = this.props;
|
||||
const { frameDetailsOpen, connector, selectedFrame } = this.props;
|
||||
|
||||
const initialWidth = Services.prefs.getIntPref(
|
||||
"devtools.netmonitor.ws.payload-preview-width"
|
||||
|
@ -72,36 +87,39 @@ class WebSocketsPanel extends Component {
|
|||
"devtools.netmonitor.ws.payload-preview-height"
|
||||
);
|
||||
|
||||
return SplitBox({
|
||||
className: "devtools-responsive-container",
|
||||
initialWidth: initialWidth,
|
||||
initialHeight: initialHeight,
|
||||
minSize: "50px",
|
||||
maxSize: "50%",
|
||||
splitterSize: frameDetailsOpen ? 1 : 0,
|
||||
startPanel: FrameListContent({ channelId, connector }),
|
||||
endPanel:
|
||||
frameDetailsOpen &&
|
||||
FramePayload({
|
||||
connector,
|
||||
selectedFrame,
|
||||
}),
|
||||
endPanelCollapsed: !frameDetailsOpen,
|
||||
endPanelControl: true,
|
||||
vert: false,
|
||||
});
|
||||
return div(
|
||||
{ className: "monitor-panel" },
|
||||
Toolbar({
|
||||
searchboxRef: this.searchboxRef,
|
||||
}),
|
||||
SplitBox({
|
||||
className: "devtools-responsive-container",
|
||||
initialWidth: initialWidth,
|
||||
initialHeight: initialHeight,
|
||||
minSize: "50px",
|
||||
maxSize: "50%",
|
||||
splitterSize: frameDetailsOpen ? 1 : 0,
|
||||
startPanel: FrameListContent({ connector }),
|
||||
endPanel:
|
||||
frameDetailsOpen &&
|
||||
FramePayload({
|
||||
connector,
|
||||
selectedFrame,
|
||||
}),
|
||||
endPanelCollapsed: !frameDetailsOpen,
|
||||
endPanelControl: true,
|
||||
vert: false,
|
||||
})
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = connect(
|
||||
(state, props) => ({
|
||||
selectedFrame: getSelectedFrame(state),
|
||||
state => ({
|
||||
channelId: state.webSockets.currentChannelId,
|
||||
frameDetailsOpen: state.webSockets.frameDetailsOpen,
|
||||
selectedFrameVisible: isSelectedFrameVisible(
|
||||
state,
|
||||
props.channelId,
|
||||
getSelectedFrame(state)
|
||||
),
|
||||
selectedFrame: getSelectedFrame(state),
|
||||
selectedFrameVisible: isSelectedFrameVisible(state),
|
||||
}),
|
||||
dispatch => ({
|
||||
openFrameDetailsTab: open => dispatch(Actions.openFrameDetails(open)),
|
||||
|
|
|
@ -3,10 +3,11 @@
|
|||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
DevToolsModules(
|
||||
'FrameFilterMenu.js',
|
||||
'FrameListColumnData.js',
|
||||
'FrameListColumnFinBit.js',
|
||||
'FrameListColumnMaskBit.js',
|
||||
'FrameListColumnOpCode.js',
|
||||
'FrameListColumnPayload.js',
|
||||
'FrameListColumnSize.js',
|
||||
'FrameListColumnTime.js',
|
||||
'FrameListColumnType.js',
|
||||
|
@ -14,5 +15,6 @@ DevToolsModules(
|
|||
'FrameListHeader.js',
|
||||
'FrameListItem.js',
|
||||
'FramePayload.js',
|
||||
'Toolbar.js',
|
||||
'WebSocketsPanel.js',
|
||||
)
|
||||
|
|
|
@ -37,6 +37,9 @@ const actionTypes = {
|
|||
WS_ADD_FRAME: "WS_ADD_FRAME",
|
||||
WS_SELECT_FRAME: "WS_SELECT_FRAME",
|
||||
WS_OPEN_FRAME_DETAILS: "WS_OPEN_FRAME_DETAILS",
|
||||
WS_CLEAR_FRAMES: "WS_CLEAR_FRAMES",
|
||||
WS_TOGGLE_FRAME_FILTER_TYPE: "WS_TOGGLE_FRAME_FILTER_TYPE",
|
||||
WS_SET_REQUEST_FILTER_TEXT: "WS_SET_REQUEST_FILTER_TEXT",
|
||||
};
|
||||
|
||||
// Descriptions for what this frontend is currently doing.
|
||||
|
@ -163,7 +166,7 @@ const UPDATE_PROPS = [
|
|||
const PANELS = {
|
||||
COOKIES: "cookies",
|
||||
HEADERS: "headers",
|
||||
WEBSOCKETS: "webSockets",
|
||||
MESSAGES: "messages",
|
||||
PARAMS: "params",
|
||||
RESPONSE: "response",
|
||||
CACHE: "cache",
|
||||
|
@ -325,7 +328,7 @@ const WS_FRAMES_HEADERS = [
|
|||
name: "size",
|
||||
},
|
||||
{
|
||||
name: "payload",
|
||||
name: "data",
|
||||
},
|
||||
{
|
||||
name: "opCode",
|
||||
|
|
|
@ -5,9 +5,13 @@
|
|||
"use strict";
|
||||
|
||||
const {
|
||||
SELECT_REQUEST,
|
||||
WS_ADD_FRAME,
|
||||
WS_SELECT_FRAME,
|
||||
WS_OPEN_FRAME_DETAILS,
|
||||
WS_CLEAR_FRAMES,
|
||||
WS_TOGGLE_FRAME_FILTER_TYPE,
|
||||
WS_SET_REQUEST_FILTER_TEXT,
|
||||
} = require("../constants");
|
||||
|
||||
/**
|
||||
|
@ -18,26 +22,47 @@ function WebSockets() {
|
|||
return {
|
||||
// Map with all requests (key = channelId, value = array of frame objects)
|
||||
frames: new Map(),
|
||||
frameFilterText: "",
|
||||
// Default filter type is "all",
|
||||
frameFilterType: "all",
|
||||
selectedFrame: null,
|
||||
frameDetailsOpen: false,
|
||||
currentChannelId: null,
|
||||
};
|
||||
}
|
||||
|
||||
// Appending new frame into the map.
|
||||
/**
|
||||
* When a network request is selected,
|
||||
* set the current channelId affiliated with the WebSocket connection.
|
||||
*/
|
||||
function setChannelId(state, action) {
|
||||
return {
|
||||
...state,
|
||||
currentChannelId: action.httpChannelId,
|
||||
// Default filter text is empty string for a new WebSocket connection
|
||||
frameFilterText: "",
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Appending new frame into the map.
|
||||
*/
|
||||
function addFrame(state, action) {
|
||||
const { httpChannelId } = action;
|
||||
const nextState = { ...state };
|
||||
|
||||
const newFrame = {
|
||||
httpChannelId: action.httpChannelId,
|
||||
httpChannelId,
|
||||
...action.data,
|
||||
};
|
||||
|
||||
nextState.frames = mapSet(state.frames, newFrame.httpChannelId, newFrame);
|
||||
|
||||
nextState.frames = mapSet(nextState.frames, newFrame.httpChannelId, newFrame);
|
||||
return nextState;
|
||||
}
|
||||
|
||||
// Select specific frame.
|
||||
/**
|
||||
* Select specific frame.
|
||||
*/
|
||||
function selectFrame(state, action) {
|
||||
return {
|
||||
...state,
|
||||
|
@ -46,6 +71,9 @@ function selectFrame(state, action) {
|
|||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Shows/Hides the FramePayload component.
|
||||
*/
|
||||
function openFrameDetails(state, action) {
|
||||
return {
|
||||
...state,
|
||||
|
@ -53,6 +81,45 @@ function openFrameDetails(state, action) {
|
|||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear WS frames of the request from the state.
|
||||
*/
|
||||
function clearFrames(state) {
|
||||
const nextState = { ...state };
|
||||
nextState.frames = new Map(nextState.frames);
|
||||
nextState.frames.delete(nextState.currentChannelId);
|
||||
|
||||
return {
|
||||
...WebSockets(),
|
||||
// Preserving the Map objects as they might contain state for other channelIds
|
||||
frames: nextState.frames,
|
||||
// Preserving the currentChannelId as there would not be another reset of channelId
|
||||
currentChannelId: nextState.currentChannelId,
|
||||
frameFilterType: nextState.frameFilterType,
|
||||
frameFilterText: nextState.frameFilterText,
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Toggle the frame filter type of the WebSocket connection.
|
||||
*/
|
||||
function toggleFrameFilterType(state, action) {
|
||||
return {
|
||||
...state,
|
||||
frameFilterType: action.filter,
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the filter text of the current channelId.
|
||||
*/
|
||||
function setFrameFilterText(state, action) {
|
||||
return {
|
||||
...state,
|
||||
frameFilterText: action.text,
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Append new item into existing map and return new map.
|
||||
*/
|
||||
|
@ -73,12 +140,20 @@ function mapSet(map, key, value) {
|
|||
*/
|
||||
function webSockets(state = WebSockets(), action) {
|
||||
switch (action.type) {
|
||||
case SELECT_REQUEST:
|
||||
return setChannelId(state, action);
|
||||
case WS_ADD_FRAME:
|
||||
return addFrame(state, action);
|
||||
case WS_SELECT_FRAME:
|
||||
return selectFrame(state, action);
|
||||
case WS_OPEN_FRAME_DETAILS:
|
||||
return openFrameDetails(state, action);
|
||||
case WS_CLEAR_FRAMES:
|
||||
return clearFrames(state);
|
||||
case WS_TOGGLE_FRAME_FILTER_TYPE:
|
||||
return toggleFrameFilterType(state, action);
|
||||
case WS_SET_REQUEST_FILTER_TEXT:
|
||||
return setFrameFilterText(state, action);
|
||||
default:
|
||||
return state;
|
||||
}
|
||||
|
|
|
@ -6,30 +6,52 @@
|
|||
|
||||
const { createSelector } = require("devtools/client/shared/vendor/reselect");
|
||||
|
||||
function getFramesByChannelId(state, channelId) {
|
||||
return state.webSockets.frames.get(channelId);
|
||||
}
|
||||
/**
|
||||
* Returns list of frames that are visible to the user.
|
||||
* Filtered frames by types and text are factored in.
|
||||
*/
|
||||
const getDisplayedFrames = createSelector(
|
||||
state => state.webSockets,
|
||||
({ frames, frameFilterType, frameFilterText, currentChannelId }) => {
|
||||
if (!currentChannelId || !frames.get(currentChannelId)) {
|
||||
return [];
|
||||
}
|
||||
|
||||
const framesArray = frames.get(currentChannelId);
|
||||
if (frameFilterType === "all" && frameFilterText.length === 0) {
|
||||
return framesArray;
|
||||
}
|
||||
|
||||
return framesArray.filter(
|
||||
frame =>
|
||||
frame.payload.includes(frameFilterText) &&
|
||||
(frameFilterType === "all" || frameFilterType === frame.type)
|
||||
);
|
||||
}
|
||||
);
|
||||
|
||||
/**
|
||||
* Checks if the selected frame is visible.
|
||||
* If the selected frame is not visible, the SplitBox component
|
||||
* should not show the FramePayload component.
|
||||
*/
|
||||
function isSelectedFrameVisible(state, channelId, targetFrame) {
|
||||
const displayedFrames = getFramesByChannelId(state, channelId);
|
||||
if (displayedFrames && targetFrame) {
|
||||
return displayedFrames.some(frame => frame === targetFrame);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
const isSelectedFrameVisible = createSelector(
|
||||
state => state.webSockets,
|
||||
getDisplayedFrames,
|
||||
({ selectedFrame }, displayedFrames) =>
|
||||
displayedFrames.some(frame => frame === selectedFrame)
|
||||
);
|
||||
|
||||
/**
|
||||
* Returns the current selected frame.
|
||||
*/
|
||||
const getSelectedFrame = createSelector(
|
||||
state => state.webSockets,
|
||||
({ selectedFrame }) => (selectedFrame ? selectedFrame : undefined)
|
||||
);
|
||||
|
||||
module.exports = {
|
||||
getFramesByChannelId,
|
||||
getSelectedFrame,
|
||||
isSelectedFrameVisible,
|
||||
getDisplayedFrames,
|
||||
};
|
||||
|
|
|
@ -1287,7 +1287,13 @@ class MOZ_STACK_CLASS HeapSnapshotHandler {
|
|||
if (!first) return true;
|
||||
|
||||
CoreDumpWriter::EdgePolicy policy;
|
||||
if (!ShouldIncludeEdge(compartments, origin, edge, &policy)) return true;
|
||||
if (!ShouldIncludeEdge(compartments, origin, edge, &policy)) {
|
||||
// Because ShouldIncludeEdge considers the |origin| node as well, we don't
|
||||
// want to consider this node 'visited' until we write it to the core
|
||||
// dump.
|
||||
traversal.doNotMarkReferentAsVisited();
|
||||
return true;
|
||||
}
|
||||
|
||||
nodeCount++;
|
||||
|
||||
|
|
|
@ -9153,7 +9153,7 @@ nsresult nsDocShell::MaybeHandleSameDocumentNavigation(
|
|||
} else {
|
||||
newURITriggeringPrincipal = aLoadState->TriggeringPrincipal();
|
||||
newURIPrincipalToInherit = doc->NodePrincipal();
|
||||
newURIStoragePrincipalToInherit = doc->EffectiveStoragePrincipal();
|
||||
newURIStoragePrincipalToInherit = doc->IntrinsicStoragePrincipal();
|
||||
newCsp = doc->GetCsp();
|
||||
}
|
||||
// Pass true for aCloneSHChildren, since we're not
|
||||
|
@ -9717,7 +9717,7 @@ nsIPrincipal* nsDocShell::GetInheritedPrincipal(
|
|||
//-- Get the document's principal
|
||||
if (document) {
|
||||
nsIPrincipal* docPrincipal = aConsiderStoragePrincipal
|
||||
? document->EffectiveStoragePrincipal()
|
||||
? document->IntrinsicStoragePrincipal()
|
||||
: document->NodePrincipal();
|
||||
|
||||
// Don't allow loads in typeContent docShells to inherit the system
|
||||
|
|
|
@ -559,6 +559,14 @@ class Document : public nsINode,
|
|||
return EffectiveStoragePrincipal();
|
||||
}
|
||||
|
||||
// You should probably not be using this function, since it performs no
|
||||
// checks to ensure that the intrinsic storage principal should really be
|
||||
// used here. It is only designed to be used in very specific circumstances,
|
||||
// such as when inheriting the document/storage principal.
|
||||
nsIPrincipal* IntrinsicStoragePrincipal() const {
|
||||
return mIntrinsicStoragePrincipal;
|
||||
}
|
||||
|
||||
// EventTarget
|
||||
void GetEventTargetParent(EventChainPreVisitor& aVisitor) override;
|
||||
EventListenerManager* GetOrCreateListenerManager() override;
|
||||
|
|
|
@ -12,7 +12,7 @@ typedef CustomEventInit TestDictionaryTypedef;
|
|||
interface TestExternalInterface;
|
||||
|
||||
// We need a pref name that's in StaticPrefList.h here.
|
||||
[Pref="abc.def"]
|
||||
[Pref="dom.webidl.test1"]
|
||||
interface TestRenamedInterface {
|
||||
};
|
||||
|
||||
|
@ -899,63 +899,63 @@ interface TestInterface {
|
|||
void passVariadicThirdArg(DOMString arg1, long arg2, TestInterface... arg3);
|
||||
|
||||
// Conditionally exposed methods/attributes
|
||||
[Pref="abc.def"]
|
||||
[Pref="dom.webidl.test1"]
|
||||
readonly attribute boolean prefable1;
|
||||
[Pref="abc.def"]
|
||||
[Pref="dom.webidl.test1"]
|
||||
readonly attribute boolean prefable2;
|
||||
[Pref="ghi.jkl"]
|
||||
[Pref="dom.webidl.test2"]
|
||||
readonly attribute boolean prefable3;
|
||||
[Pref="ghi.jkl"]
|
||||
[Pref="dom.webidl.test2"]
|
||||
readonly attribute boolean prefable4;
|
||||
[Pref="abc.def"]
|
||||
[Pref="dom.webidl.test1"]
|
||||
readonly attribute boolean prefable5;
|
||||
[Pref="abc.def", Func="nsGenericHTMLElement::LegacyTouchAPIEnabled"]
|
||||
[Pref="dom.webidl.test1", Func="nsGenericHTMLElement::LegacyTouchAPIEnabled"]
|
||||
readonly attribute boolean prefable6;
|
||||
[Pref="abc.def", Func="nsGenericHTMLElement::LegacyTouchAPIEnabled"]
|
||||
[Pref="dom.webidl.test1", Func="nsGenericHTMLElement::LegacyTouchAPIEnabled"]
|
||||
readonly attribute boolean prefable7;
|
||||
[Pref="ghi.jkl", Func="nsGenericHTMLElement::LegacyTouchAPIEnabled"]
|
||||
[Pref="dom.webidl.test2", Func="nsGenericHTMLElement::LegacyTouchAPIEnabled"]
|
||||
readonly attribute boolean prefable8;
|
||||
[Pref="abc.def", Func="nsGenericHTMLElement::LegacyTouchAPIEnabled"]
|
||||
[Pref="dom.webidl.test1", Func="nsGenericHTMLElement::LegacyTouchAPIEnabled"]
|
||||
readonly attribute boolean prefable9;
|
||||
[Pref="abc.def"]
|
||||
[Pref="dom.webidl.test1"]
|
||||
void prefable10();
|
||||
[Pref="abc.def", Func="nsGenericHTMLElement::LegacyTouchAPIEnabled"]
|
||||
[Pref="dom.webidl.test1", Func="nsGenericHTMLElement::LegacyTouchAPIEnabled"]
|
||||
void prefable11();
|
||||
[Pref="abc.def", Func="TestFuncControlledMember"]
|
||||
[Pref="dom.webidl.test1", Func="TestFuncControlledMember"]
|
||||
readonly attribute boolean prefable12;
|
||||
[Pref="abc.def", Func="nsGenericHTMLElement::LegacyTouchAPIEnabled"]
|
||||
[Pref="dom.webidl.test1", Func="nsGenericHTMLElement::LegacyTouchAPIEnabled"]
|
||||
void prefable13();
|
||||
[Pref="abc.def", Func="TestFuncControlledMember"]
|
||||
[Pref="dom.webidl.test1", Func="TestFuncControlledMember"]
|
||||
readonly attribute boolean prefable14;
|
||||
[Func="TestFuncControlledMember"]
|
||||
readonly attribute boolean prefable15;
|
||||
[Func="TestFuncControlledMember"]
|
||||
readonly attribute boolean prefable16;
|
||||
[Pref="abc.def", Func="TestFuncControlledMember"]
|
||||
[Pref="dom.webidl.test1", Func="TestFuncControlledMember"]
|
||||
void prefable17();
|
||||
[Func="TestFuncControlledMember"]
|
||||
void prefable18();
|
||||
[Func="TestFuncControlledMember"]
|
||||
void prefable19();
|
||||
[Pref="abc.def", Func="TestFuncControlledMember", ChromeOnly]
|
||||
[Pref="dom.webidl.test1", Func="TestFuncControlledMember", ChromeOnly]
|
||||
void prefable20();
|
||||
|
||||
// Conditionally exposed methods/attributes involving [SecureContext]
|
||||
[SecureContext]
|
||||
readonly attribute boolean conditionalOnSecureContext1;
|
||||
[SecureContext, Pref="abc.def"]
|
||||
[SecureContext, Pref="dom.webidl.test1"]
|
||||
readonly attribute boolean conditionalOnSecureContext2;
|
||||
[SecureContext, Pref="abc.def", Func="nsGenericHTMLElement::LegacyTouchAPIEnabled"]
|
||||
[SecureContext, Pref="dom.webidl.test1", Func="nsGenericHTMLElement::LegacyTouchAPIEnabled"]
|
||||
readonly attribute boolean conditionalOnSecureContext3;
|
||||
[SecureContext, Pref="abc.def", Func="TestFuncControlledMember"]
|
||||
[SecureContext, Pref="dom.webidl.test1", Func="TestFuncControlledMember"]
|
||||
readonly attribute boolean conditionalOnSecureContext4;
|
||||
[SecureContext]
|
||||
void conditionalOnSecureContext5();
|
||||
[SecureContext, Pref="abc.def"]
|
||||
[SecureContext, Pref="dom.webidl.test1"]
|
||||
void conditionalOnSecureContext6();
|
||||
[SecureContext, Pref="abc.def", Func="nsGenericHTMLElement::LegacyTouchAPIEnabled"]
|
||||
[SecureContext, Pref="dom.webidl.test1", Func="nsGenericHTMLElement::LegacyTouchAPIEnabled"]
|
||||
void conditionalOnSecureContext7();
|
||||
[SecureContext, Pref="abc.def", Func="TestFuncControlledMember"]
|
||||
[SecureContext, Pref="dom.webidl.test1", Func="TestFuncControlledMember"]
|
||||
void conditionalOnSecureContext8();
|
||||
|
||||
// Miscellania
|
||||
|
@ -1221,9 +1221,9 @@ dictionary DictWithConditionalMembers {
|
|||
[ChromeOnly, Func="nsGenericHTMLElement::LegacyTouchAPIEnabled"]
|
||||
long chromeOnlyFuncControlledMember;
|
||||
// We need a pref name that's in StaticPrefList.h here.
|
||||
[Pref="abc.def"]
|
||||
[Pref="dom.webidl.test1"]
|
||||
long prefControlledMember;
|
||||
[Pref="abc.def", ChromeOnly, Func="TestFuncControlledMember"]
|
||||
[Pref="dom.webidl.test1", ChromeOnly, Func="TestFuncControlledMember"]
|
||||
long chromeOnlyFuncAndPrefControlledMember;
|
||||
};
|
||||
|
||||
|
|
|
@ -705,39 +705,39 @@ interface TestExampleInterface {
|
|||
void passVariadicThirdArg(DOMString arg1, long arg2, TestInterface... arg3);
|
||||
|
||||
// Conditionally exposed methods/attributes
|
||||
[Pref="abc.def"]
|
||||
[Pref="dom.webidl.test1"]
|
||||
readonly attribute boolean prefable1;
|
||||
[Pref="abc.def"]
|
||||
[Pref="dom.webidl.test1"]
|
||||
readonly attribute boolean prefable2;
|
||||
[Pref="ghi.jkl"]
|
||||
[Pref="dom.webidl.test2"]
|
||||
readonly attribute boolean prefable3;
|
||||
[Pref="ghi.jkl"]
|
||||
[Pref="dom.webidl.test2"]
|
||||
readonly attribute boolean prefable4;
|
||||
[Pref="abc.def"]
|
||||
[Pref="dom.webidl.test1"]
|
||||
readonly attribute boolean prefable5;
|
||||
[Pref="abc.def", Func="nsGenericHTMLElement::LegacyTouchAPIEnabled"]
|
||||
[Pref="dom.webidl.test1", Func="nsGenericHTMLElement::LegacyTouchAPIEnabled"]
|
||||
readonly attribute boolean prefable6;
|
||||
[Pref="abc.def", Func="nsGenericHTMLElement::LegacyTouchAPIEnabled"]
|
||||
[Pref="dom.webidl.test1", Func="nsGenericHTMLElement::LegacyTouchAPIEnabled"]
|
||||
readonly attribute boolean prefable7;
|
||||
[Pref="ghi.jkl", Func="nsGenericHTMLElement::LegacyTouchAPIEnabled"]
|
||||
[Pref="dom.webidl.test2", Func="nsGenericHTMLElement::LegacyTouchAPIEnabled"]
|
||||
readonly attribute boolean prefable8;
|
||||
[Pref="abc.def", Func="nsGenericHTMLElement::LegacyTouchAPIEnabled"]
|
||||
[Pref="dom.webidl.test1", Func="nsGenericHTMLElement::LegacyTouchAPIEnabled"]
|
||||
readonly attribute boolean prefable9;
|
||||
[Pref="abc.def"]
|
||||
[Pref="dom.webidl.test1"]
|
||||
void prefable10();
|
||||
[Pref="abc.def", Func="nsGenericHTMLElement::LegacyTouchAPIEnabled"]
|
||||
[Pref="dom.webidl.test1", Func="nsGenericHTMLElement::LegacyTouchAPIEnabled"]
|
||||
void prefable11();
|
||||
[Pref="abc.def", Func="TestFuncControlledMember"]
|
||||
[Pref="dom.webidl.test1", Func="TestFuncControlledMember"]
|
||||
readonly attribute boolean prefable12;
|
||||
[Pref="abc.def", Func="nsGenericHTMLElement::LegacyTouchAPIEnabled"]
|
||||
[Pref="dom.webidl.test1", Func="nsGenericHTMLElement::LegacyTouchAPIEnabled"]
|
||||
void prefable13();
|
||||
[Pref="abc.def", Func="TestFuncControlledMember"]
|
||||
[Pref="dom.webidl.test1", Func="TestFuncControlledMember"]
|
||||
readonly attribute boolean prefable14;
|
||||
[Func="TestFuncControlledMember"]
|
||||
readonly attribute boolean prefable15;
|
||||
[Func="TestFuncControlledMember"]
|
||||
readonly attribute boolean prefable16;
|
||||
[Pref="abc.def", Func="TestFuncControlledMember"]
|
||||
[Pref="dom.webidl.test1", Func="TestFuncControlledMember"]
|
||||
void prefable17();
|
||||
[Func="TestFuncControlledMember"]
|
||||
void prefable18();
|
||||
|
@ -747,19 +747,19 @@ interface TestExampleInterface {
|
|||
// Conditionally exposed methods/attributes involving [SecureContext]
|
||||
[SecureContext]
|
||||
readonly attribute boolean conditionalOnSecureContext1;
|
||||
[SecureContext, Pref="abc.def"]
|
||||
[SecureContext, Pref="dom.webidl.test1"]
|
||||
readonly attribute boolean conditionalOnSecureContext2;
|
||||
[SecureContext, Pref="abc.def", Func="nsGenericHTMLElement::LegacyTouchAPIEnabled"]
|
||||
[SecureContext, Pref="dom.webidl.test1", Func="nsGenericHTMLElement::LegacyTouchAPIEnabled"]
|
||||
readonly attribute boolean conditionalOnSecureContext3;
|
||||
[SecureContext, Pref="abc.def", Func="TestFuncControlledMember"]
|
||||
[SecureContext, Pref="dom.webidl.test1", Func="TestFuncControlledMember"]
|
||||
readonly attribute boolean conditionalOnSecureContext4;
|
||||
[SecureContext]
|
||||
void conditionalOnSecureContext5();
|
||||
[SecureContext, Pref="abc.def"]
|
||||
[SecureContext, Pref="dom.webidl.test1"]
|
||||
void conditionalOnSecureContext6();
|
||||
[SecureContext, Pref="abc.def", Func="nsGenericHTMLElement::LegacyTouchAPIEnabled"]
|
||||
[SecureContext, Pref="dom.webidl.test1", Func="nsGenericHTMLElement::LegacyTouchAPIEnabled"]
|
||||
void conditionalOnSecureContext7();
|
||||
[SecureContext, Pref="abc.def", Func="TestFuncControlledMember"]
|
||||
[SecureContext, Pref="dom.webidl.test1", Func="TestFuncControlledMember"]
|
||||
void conditionalOnSecureContext8();
|
||||
|
||||
// Miscellania
|
||||
|
|
|
@ -723,63 +723,63 @@ interface TestJSImplInterface {
|
|||
void passVariadicThirdArg(DOMString arg1, long arg2, TestJSImplInterface... arg3);
|
||||
|
||||
// Conditionally exposed methods/attributes
|
||||
[Pref="abc.def"]
|
||||
[Pref="dom.webidl.test1"]
|
||||
readonly attribute boolean prefable1;
|
||||
[Pref="abc.def"]
|
||||
[Pref="dom.webidl.test1"]
|
||||
readonly attribute boolean prefable2;
|
||||
[Pref="ghi.jkl"]
|
||||
[Pref="dom.webidl.test2"]
|
||||
readonly attribute boolean prefable3;
|
||||
[Pref="ghi.jkl"]
|
||||
[Pref="dom.webidl.test2"]
|
||||
readonly attribute boolean prefable4;
|
||||
[Pref="abc.def"]
|
||||
[Pref="dom.webidl.test1"]
|
||||
readonly attribute boolean prefable5;
|
||||
[Pref="abc.def", Func="nsGenericHTMLElement::LegacyTouchAPIEnabled"]
|
||||
[Pref="dom.webidl.test1", Func="nsGenericHTMLElement::LegacyTouchAPIEnabled"]
|
||||
readonly attribute boolean prefable6;
|
||||
[Pref="abc.def", Func="nsGenericHTMLElement::LegacyTouchAPIEnabled"]
|
||||
[Pref="dom.webidl.test1", Func="nsGenericHTMLElement::LegacyTouchAPIEnabled"]
|
||||
readonly attribute boolean prefable7;
|
||||
[Pref="ghi.jkl", Func="nsGenericHTMLElement::LegacyTouchAPIEnabled"]
|
||||
[Pref="dom.webidl.test2", Func="nsGenericHTMLElement::LegacyTouchAPIEnabled"]
|
||||
readonly attribute boolean prefable8;
|
||||
[Pref="abc.def", Func="nsGenericHTMLElement::LegacyTouchAPIEnabled"]
|
||||
[Pref="dom.webidl.test1", Func="nsGenericHTMLElement::LegacyTouchAPIEnabled"]
|
||||
readonly attribute boolean prefable9;
|
||||
[Pref="abc.def"]
|
||||
[Pref="dom.webidl.test1"]
|
||||
void prefable10();
|
||||
[Pref="abc.def", Func="nsGenericHTMLElement::LegacyTouchAPIEnabled"]
|
||||
[Pref="dom.webidl.test1", Func="nsGenericHTMLElement::LegacyTouchAPIEnabled"]
|
||||
void prefable11();
|
||||
[Pref="abc.def", Func="TestFuncControlledMember"]
|
||||
[Pref="dom.webidl.test1", Func="TestFuncControlledMember"]
|
||||
readonly attribute boolean prefable12;
|
||||
[Pref="abc.def", Func="nsGenericHTMLElement::LegacyTouchAPIEnabled"]
|
||||
[Pref="dom.webidl.test1", Func="nsGenericHTMLElement::LegacyTouchAPIEnabled"]
|
||||
void prefable13();
|
||||
[Pref="abc.def", Func="TestFuncControlledMember"]
|
||||
[Pref="dom.webidl.test1", Func="TestFuncControlledMember"]
|
||||
readonly attribute boolean prefable14;
|
||||
[Func="TestFuncControlledMember"]
|
||||
readonly attribute boolean prefable15;
|
||||
[Func="TestFuncControlledMember"]
|
||||
readonly attribute boolean prefable16;
|
||||
[Pref="abc.def", Func="TestFuncControlledMember"]
|
||||
[Pref="dom.webidl.test1", Func="TestFuncControlledMember"]
|
||||
void prefable17();
|
||||
[Func="TestFuncControlledMember"]
|
||||
void prefable18();
|
||||
[Func="TestFuncControlledMember"]
|
||||
void prefable19();
|
||||
[Pref="abc.def", Func="TestFuncControlledMember", ChromeOnly]
|
||||
[Pref="dom.webidl.test1", Func="TestFuncControlledMember", ChromeOnly]
|
||||
void prefable20();
|
||||
|
||||
// Conditionally exposed methods/attributes involving [SecureContext]
|
||||
[SecureContext]
|
||||
readonly attribute boolean conditionalOnSecureContext1;
|
||||
[SecureContext, Pref="abc.def"]
|
||||
[SecureContext, Pref="dom.webidl.test1"]
|
||||
readonly attribute boolean conditionalOnSecureContext2;
|
||||
[SecureContext, Pref="abc.def", Func="nsGenericHTMLElement::LegacyTouchAPIEnabled"]
|
||||
[SecureContext, Pref="dom.webidl.test1", Func="nsGenericHTMLElement::LegacyTouchAPIEnabled"]
|
||||
readonly attribute boolean conditionalOnSecureContext3;
|
||||
[SecureContext, Pref="abc.def", Func="TestFuncControlledMember"]
|
||||
[SecureContext, Pref="dom.webidl.test1", Func="TestFuncControlledMember"]
|
||||
readonly attribute boolean conditionalOnSecureContext4;
|
||||
[SecureContext]
|
||||
void conditionalOnSecureContext5();
|
||||
[SecureContext, Pref="abc.def"]
|
||||
[SecureContext, Pref="dom.webidl.test1"]
|
||||
void conditionalOnSecureContext6();
|
||||
[SecureContext, Pref="abc.def", Func="nsGenericHTMLElement::LegacyTouchAPIEnabled"]
|
||||
[SecureContext, Pref="dom.webidl.test1", Func="nsGenericHTMLElement::LegacyTouchAPIEnabled"]
|
||||
void conditionalOnSecureContext7();
|
||||
[SecureContext, Pref="abc.def", Func="TestFuncControlledMember"]
|
||||
[SecureContext, Pref="dom.webidl.test1", Func="TestFuncControlledMember"]
|
||||
void conditionalOnSecureContext8();
|
||||
|
||||
// Miscellania
|
||||
|
|
|
@ -6,45 +6,45 @@
|
|||
|
||||
#include "mozilla/dom/cache/ActorChild.h"
|
||||
|
||||
#include "mozilla/dom/cache/CacheWorkerHolder.h"
|
||||
#include "mozilla/dom/cache/CacheWorkerRef.h"
|
||||
#include "nsThreadUtils.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
namespace cache {
|
||||
|
||||
void ActorChild::SetWorkerHolder(CacheWorkerHolder* aWorkerHolder) {
|
||||
void ActorChild::SetWorkerRef(CacheWorkerRef* aWorkerRef) {
|
||||
// Some of the Cache actors can have multiple DOM objects associated with
|
||||
// them. In this case the workerHolder will be added multiple times. This is
|
||||
// permitted, but the workerHolder should be the same each time.
|
||||
if (mWorkerHolder) {
|
||||
MOZ_DIAGNOSTIC_ASSERT(mWorkerHolder == aWorkerHolder);
|
||||
// them. In this case the workerRef will be added multiple times. This is
|
||||
// permitted, but the workerRef should be the same each time.
|
||||
if (mWorkerRef) {
|
||||
MOZ_DIAGNOSTIC_ASSERT(mWorkerRef == aWorkerRef);
|
||||
return;
|
||||
}
|
||||
|
||||
mWorkerHolder = aWorkerHolder;
|
||||
if (mWorkerHolder) {
|
||||
mWorkerHolder->AddActor(this);
|
||||
mWorkerRef = aWorkerRef;
|
||||
if (mWorkerRef) {
|
||||
mWorkerRef->AddActor(this);
|
||||
}
|
||||
}
|
||||
|
||||
void ActorChild::RemoveWorkerHolder() {
|
||||
MOZ_ASSERT_IF(!NS_IsMainThread(), mWorkerHolder);
|
||||
if (mWorkerHolder) {
|
||||
mWorkerHolder->RemoveActor(this);
|
||||
mWorkerHolder = nullptr;
|
||||
void ActorChild::RemoveWorkerRef() {
|
||||
MOZ_ASSERT_IF(!NS_IsMainThread(), mWorkerRef);
|
||||
if (mWorkerRef) {
|
||||
mWorkerRef->RemoveActor(this);
|
||||
mWorkerRef = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
CacheWorkerHolder* ActorChild::GetWorkerHolder() const { return mWorkerHolder; }
|
||||
CacheWorkerRef* ActorChild::GetWorkerRef() const { return mWorkerRef; }
|
||||
|
||||
bool ActorChild::WorkerHolderNotified() const {
|
||||
return mWorkerHolder && mWorkerHolder->Notified();
|
||||
bool ActorChild::WorkerRefNotified() const {
|
||||
return mWorkerRef && mWorkerRef->Notified();
|
||||
}
|
||||
|
||||
ActorChild::ActorChild() {}
|
||||
|
||||
ActorChild::~ActorChild() { MOZ_DIAGNOSTIC_ASSERT(!mWorkerHolder); }
|
||||
ActorChild::~ActorChild() { MOZ_DIAGNOSTIC_ASSERT(!mWorkerRef); }
|
||||
|
||||
} // namespace cache
|
||||
} // namespace dom
|
||||
|
|
|
@ -13,26 +13,26 @@ namespace mozilla {
|
|||
namespace dom {
|
||||
namespace cache {
|
||||
|
||||
class CacheWorkerHolder;
|
||||
class CacheWorkerRef;
|
||||
|
||||
class ActorChild {
|
||||
public:
|
||||
virtual void StartDestroy() = 0;
|
||||
|
||||
void SetWorkerHolder(CacheWorkerHolder* aWorkerHolder);
|
||||
void SetWorkerRef(CacheWorkerRef* aWorkerRef);
|
||||
|
||||
void RemoveWorkerHolder();
|
||||
void RemoveWorkerRef();
|
||||
|
||||
CacheWorkerHolder* GetWorkerHolder() const;
|
||||
CacheWorkerRef* GetWorkerRef() const;
|
||||
|
||||
bool WorkerHolderNotified() const;
|
||||
bool WorkerRefNotified() const;
|
||||
|
||||
protected:
|
||||
ActorChild();
|
||||
~ActorChild();
|
||||
|
||||
private:
|
||||
RefPtr<CacheWorkerHolder> mWorkerHolder;
|
||||
RefPtr<CacheWorkerRef> mWorkerRef;
|
||||
};
|
||||
|
||||
} // namespace cache
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
#include "mozilla/dom/CacheBinding.h"
|
||||
#include "mozilla/dom/cache/AutoUtils.h"
|
||||
#include "mozilla/dom/cache/CacheChild.h"
|
||||
#include "mozilla/dom/cache/CacheWorkerHolder.h"
|
||||
#include "mozilla/dom/cache/CacheWorkerRef.h"
|
||||
#include "mozilla/dom/cache/ReadStream.h"
|
||||
#include "mozilla/ErrorResult.h"
|
||||
#include "mozilla/Preferences.h"
|
||||
|
@ -96,19 +96,19 @@ static bool IsValidPutResponseStatus(Response& aResponse,
|
|||
} // namespace
|
||||
|
||||
// Helper class to wait for Add()/AddAll() fetch requests to complete and
|
||||
// then perform a PutAll() with the responses. This class holds a WorkerHolder
|
||||
// then perform a PutAll() with the responses. This class holds a WorkerRef
|
||||
// to keep the Worker thread alive. This is mainly to ensure that Add/AddAll
|
||||
// act the same as other Cache operations that directly create a CacheOpChild
|
||||
// actor.
|
||||
class Cache::FetchHandler final : public PromiseNativeHandler {
|
||||
public:
|
||||
FetchHandler(CacheWorkerHolder* aWorkerHolder, Cache* aCache,
|
||||
FetchHandler(CacheWorkerRef* aWorkerRef, Cache* aCache,
|
||||
nsTArray<RefPtr<Request>>&& aRequestList, Promise* aPromise)
|
||||
: mWorkerHolder(aWorkerHolder),
|
||||
: mWorkerRef(aWorkerRef),
|
||||
mCache(aCache),
|
||||
mRequestList(std::move(aRequestList)),
|
||||
mPromise(aPromise) {
|
||||
MOZ_ASSERT_IF(!NS_IsMainThread(), mWorkerHolder);
|
||||
MOZ_ASSERT_IF(!NS_IsMainThread(), mWorkerRef);
|
||||
MOZ_DIAGNOSTIC_ASSERT(mCache);
|
||||
MOZ_DIAGNOSTIC_ASSERT(mPromise);
|
||||
}
|
||||
|
@ -118,8 +118,8 @@ class Cache::FetchHandler final : public PromiseNativeHandler {
|
|||
NS_ASSERT_OWNINGTHREAD(FetchHandler);
|
||||
|
||||
// Stop holding the worker alive when we leave this method.
|
||||
RefPtr<CacheWorkerHolder> workerHolder;
|
||||
workerHolder.swap(mWorkerHolder);
|
||||
RefPtr<CacheWorkerRef> workerRef;
|
||||
workerRef.swap(mWorkerRef);
|
||||
|
||||
// Promise::All() passed an array of fetch() Promises should give us
|
||||
// an Array of Response objects. The following code unwraps these
|
||||
|
@ -220,7 +220,7 @@ class Cache::FetchHandler final : public PromiseNativeHandler {
|
|||
mPromise->MaybeReject(rv);
|
||||
}
|
||||
|
||||
RefPtr<CacheWorkerHolder> mWorkerHolder;
|
||||
RefPtr<CacheWorkerRef> mWorkerRef;
|
||||
RefPtr<Cache> mCache;
|
||||
nsTArray<RefPtr<Request>> mRequestList;
|
||||
RefPtr<Promise> mPromise;
|
||||
|
@ -576,7 +576,7 @@ already_AddRefed<Promise> Cache::AddAll(
|
|||
}
|
||||
|
||||
RefPtr<FetchHandler> handler = new FetchHandler(
|
||||
mActor->GetWorkerHolder(), this, std::move(aRequestList), promise);
|
||||
mActor->GetWorkerRef(), this, std::move(aRequestList), promise);
|
||||
|
||||
RefPtr<Promise> fetchPromise =
|
||||
Promise::All(aGlobal.Context(), fetchList, aRv);
|
||||
|
|
|
@ -54,7 +54,7 @@ void CacheChild::ExecuteOp(nsIGlobalObject* aGlobal, Promise* aPromise,
|
|||
nsISupports* aParent, const CacheOpArgs& aArgs) {
|
||||
mNumChildActors += 1;
|
||||
MOZ_ALWAYS_TRUE(SendPCacheOpConstructor(
|
||||
new CacheOpChild(GetWorkerHolder(), aGlobal, aParent, aPromise), aArgs));
|
||||
new CacheOpChild(GetWorkerRef(), aGlobal, aParent, aPromise), aArgs));
|
||||
}
|
||||
|
||||
void CacheChild::StartDestroyFromListener() {
|
||||
|
@ -83,7 +83,7 @@ void CacheChild::StartDestroy() {
|
|||
|
||||
RefPtr<Cache> listener = mListener;
|
||||
|
||||
// StartDestroy() can get called from either Cache or the WorkerHolder.
|
||||
// StartDestroy() can get called from either Cache or the WorkerRef.
|
||||
// Theoretically we can get double called if the right race happens. Handle
|
||||
// that by just ignoring the second StartDestroy() call.
|
||||
if (!listener) {
|
||||
|
@ -108,7 +108,7 @@ void CacheChild::ActorDestroy(ActorDestroyReason aReason) {
|
|||
MOZ_DIAGNOSTIC_ASSERT(!mListener);
|
||||
}
|
||||
|
||||
RemoveWorkerHolder();
|
||||
RemoveWorkerRef();
|
||||
}
|
||||
|
||||
PCacheOpChild* CacheChild::AllocPCacheOpChild(const CacheOpArgs& aOpArgs) {
|
||||
|
|
|
@ -58,7 +58,7 @@ class CacheChild final : public PCacheChild, public ActorChild {
|
|||
private:
|
||||
// ActorChild methods
|
||||
|
||||
// WorkerHolder is trying to destroy due to worker shutdown.
|
||||
// WorkerRef is trying to destroy due to worker shutdown.
|
||||
virtual void StartDestroy() override;
|
||||
|
||||
// PCacheChild methods
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
#include "mozilla/dom/cache/Cache.h"
|
||||
#include "mozilla/dom/cache/CacheChild.h"
|
||||
#include "mozilla/dom/cache/CacheStreamControlChild.h"
|
||||
#include "mozilla/dom/cache/CacheWorkerHolder.h"
|
||||
#include "mozilla/dom/cache/CacheWorkerRef.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
|
@ -22,54 +22,53 @@ using mozilla::ipc::PBackgroundChild;
|
|||
|
||||
namespace {
|
||||
|
||||
void AddWorkerHolderToStreamChild(const CacheReadStream& aReadStream,
|
||||
CacheWorkerHolder* aWorkerHolder) {
|
||||
MOZ_ASSERT_IF(!NS_IsMainThread(), aWorkerHolder);
|
||||
void AddWorkerRefToStreamChild(const CacheReadStream& aReadStream,
|
||||
CacheWorkerRef* aWorkerRef) {
|
||||
MOZ_ASSERT_IF(!NS_IsMainThread(), aWorkerRef);
|
||||
CacheStreamControlChild* cacheControl =
|
||||
static_cast<CacheStreamControlChild*>(aReadStream.controlChild());
|
||||
if (cacheControl) {
|
||||
cacheControl->SetWorkerHolder(aWorkerHolder);
|
||||
cacheControl->SetWorkerRef(aWorkerRef);
|
||||
}
|
||||
}
|
||||
|
||||
void AddWorkerHolderToStreamChild(const CacheResponse& aResponse,
|
||||
CacheWorkerHolder* aWorkerHolder) {
|
||||
MOZ_ASSERT_IF(!NS_IsMainThread(), aWorkerHolder);
|
||||
void AddWorkerRefToStreamChild(const CacheResponse& aResponse,
|
||||
CacheWorkerRef* aWorkerRef) {
|
||||
MOZ_ASSERT_IF(!NS_IsMainThread(), aWorkerRef);
|
||||
|
||||
if (aResponse.body().isNothing()) {
|
||||
return;
|
||||
}
|
||||
|
||||
AddWorkerHolderToStreamChild(aResponse.body().ref(), aWorkerHolder);
|
||||
AddWorkerRefToStreamChild(aResponse.body().ref(), aWorkerRef);
|
||||
}
|
||||
|
||||
void AddWorkerHolderToStreamChild(const CacheRequest& aRequest,
|
||||
CacheWorkerHolder* aWorkerHolder) {
|
||||
MOZ_ASSERT_IF(!NS_IsMainThread(), aWorkerHolder);
|
||||
void AddWorkerRefToStreamChild(const CacheRequest& aRequest,
|
||||
CacheWorkerRef* aWorkerRef) {
|
||||
MOZ_ASSERT_IF(!NS_IsMainThread(), aWorkerRef);
|
||||
|
||||
if (aRequest.body().isNothing()) {
|
||||
return;
|
||||
}
|
||||
|
||||
AddWorkerHolderToStreamChild(aRequest.body().ref(), aWorkerHolder);
|
||||
AddWorkerRefToStreamChild(aRequest.body().ref(), aWorkerRef);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
CacheOpChild::CacheOpChild(CacheWorkerHolder* aWorkerHolder,
|
||||
nsIGlobalObject* aGlobal, nsISupports* aParent,
|
||||
Promise* aPromise)
|
||||
CacheOpChild::CacheOpChild(CacheWorkerRef* aWorkerRef, nsIGlobalObject* aGlobal,
|
||||
nsISupports* aParent, Promise* aPromise)
|
||||
: mGlobal(aGlobal), mParent(aParent), mPromise(aPromise) {
|
||||
MOZ_DIAGNOSTIC_ASSERT(mGlobal);
|
||||
MOZ_DIAGNOSTIC_ASSERT(mParent);
|
||||
MOZ_DIAGNOSTIC_ASSERT(mPromise);
|
||||
|
||||
MOZ_ASSERT_IF(!NS_IsMainThread(), aWorkerHolder);
|
||||
MOZ_ASSERT_IF(!NS_IsMainThread(), aWorkerRef);
|
||||
|
||||
RefPtr<CacheWorkerHolder> workerHolder = CacheWorkerHolder::PreferBehavior(
|
||||
aWorkerHolder, CacheWorkerHolder::PreventIdleShutdownStart);
|
||||
RefPtr<CacheWorkerRef> workerRef = CacheWorkerRef::PreferBehavior(
|
||||
aWorkerRef, CacheWorkerRef::eStrongWorkerRef);
|
||||
|
||||
SetWorkerHolder(workerHolder);
|
||||
SetWorkerRef(workerRef);
|
||||
}
|
||||
|
||||
CacheOpChild::~CacheOpChild() {
|
||||
|
@ -87,7 +86,7 @@ void CacheOpChild::ActorDestroy(ActorDestroyReason aReason) {
|
|||
mPromise = nullptr;
|
||||
}
|
||||
|
||||
RemoveWorkerHolder();
|
||||
RemoveWorkerRef();
|
||||
}
|
||||
|
||||
mozilla::ipc::IPCResult CacheOpChild::Recv__delete__(
|
||||
|
@ -147,11 +146,10 @@ mozilla::ipc::IPCResult CacheOpChild::Recv__delete__(
|
|||
break;
|
||||
}
|
||||
|
||||
RefPtr<CacheWorkerHolder> workerHolder =
|
||||
CacheWorkerHolder::PreferBehavior(
|
||||
GetWorkerHolder(), CacheWorkerHolder::AllowIdleShutdownStart);
|
||||
RefPtr<CacheWorkerRef> workerRef = CacheWorkerRef::PreferBehavior(
|
||||
GetWorkerRef(), CacheWorkerRef::eIPCWorkerRef);
|
||||
|
||||
actor->SetWorkerHolder(workerHolder);
|
||||
actor->SetWorkerRef(workerRef);
|
||||
RefPtr<Cache> cache = new Cache(mGlobal, actor, result.ns());
|
||||
mPromise->MaybeResolve(cache);
|
||||
break;
|
||||
|
@ -176,7 +174,7 @@ mozilla::ipc::IPCResult CacheOpChild::Recv__delete__(
|
|||
void CacheOpChild::StartDestroy() {
|
||||
NS_ASSERT_OWNINGTHREAD(CacheOpChild);
|
||||
|
||||
// Do not cancel on-going operations when WorkerHolder calls this. Instead,
|
||||
// Do not cancel on-going operations when WorkerRef calls this. Instead,
|
||||
// keep the Worker alive until we are done.
|
||||
}
|
||||
|
||||
|
@ -200,7 +198,7 @@ void CacheOpChild::HandleResponse(const Maybe<CacheResponse>& aMaybeResponse) {
|
|||
|
||||
const CacheResponse& cacheResponse = aMaybeResponse.ref();
|
||||
|
||||
AddWorkerHolderToStreamChild(cacheResponse, GetWorkerHolder());
|
||||
AddWorkerRefToStreamChild(cacheResponse, GetWorkerRef());
|
||||
RefPtr<Response> response = ToResponse(cacheResponse);
|
||||
|
||||
mPromise->MaybeResolve(response);
|
||||
|
@ -212,7 +210,7 @@ void CacheOpChild::HandleResponseList(
|
|||
responses.SetCapacity(aResponseList.Length());
|
||||
|
||||
for (uint32_t i = 0; i < aResponseList.Length(); ++i) {
|
||||
AddWorkerHolderToStreamChild(aResponseList[i], GetWorkerHolder());
|
||||
AddWorkerRefToStreamChild(aResponseList[i], GetWorkerRef());
|
||||
responses.AppendElement(ToResponse(aResponseList[i]));
|
||||
}
|
||||
|
||||
|
@ -225,7 +223,7 @@ void CacheOpChild::HandleRequestList(
|
|||
requests.SetCapacity(aRequestList.Length());
|
||||
|
||||
for (uint32_t i = 0; i < aRequestList.Length(); ++i) {
|
||||
AddWorkerHolderToStreamChild(aRequestList[i], GetWorkerHolder());
|
||||
AddWorkerRefToStreamChild(aRequestList[i], GetWorkerRef());
|
||||
requests.AppendElement(ToRequest(aRequestList[i]));
|
||||
}
|
||||
|
||||
|
|
|
@ -31,7 +31,7 @@ class CacheOpChild final : public PCacheOpChild,
|
|||
private:
|
||||
// This class must be constructed by CacheChild or CacheStorageChild using
|
||||
// their ExecuteOp() factory method.
|
||||
CacheOpChild(CacheWorkerHolder* aWorkerHolder, nsIGlobalObject* aGlobal,
|
||||
CacheOpChild(CacheWorkerRef* aWorkerRef, nsIGlobalObject* aGlobal,
|
||||
nsISupports* aParent, Promise* aPromise);
|
||||
~CacheOpChild();
|
||||
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
#include "mozilla/dom/cache/Cache.h"
|
||||
#include "mozilla/dom/cache/CacheChild.h"
|
||||
#include "mozilla/dom/cache/CacheStorageChild.h"
|
||||
#include "mozilla/dom/cache/CacheWorkerHolder.h"
|
||||
#include "mozilla/dom/cache/CacheWorkerRef.h"
|
||||
#include "mozilla/dom/cache/PCacheChild.h"
|
||||
#include "mozilla/dom/cache/ReadStream.h"
|
||||
#include "mozilla/dom/cache/TypeUtils.h"
|
||||
|
@ -189,9 +189,9 @@ already_AddRefed<CacheStorage> CacheStorage::CreateOnWorker(
|
|||
return ref.forget();
|
||||
}
|
||||
|
||||
RefPtr<CacheWorkerHolder> workerHolder = CacheWorkerHolder::Create(
|
||||
aWorkerPrivate, CacheWorkerHolder::AllowIdleShutdownStart);
|
||||
if (!workerHolder) {
|
||||
RefPtr<CacheWorkerRef> workerRef =
|
||||
CacheWorkerRef::Create(aWorkerPrivate, CacheWorkerRef::eIPCWorkerRef);
|
||||
if (!workerRef) {
|
||||
NS_WARNING("Worker thread is shutting down.");
|
||||
aRv.Throw(NS_ERROR_FAILURE);
|
||||
return nullptr;
|
||||
|
@ -230,7 +230,7 @@ already_AddRefed<CacheStorage> CacheStorage::CreateOnWorker(
|
|||
}
|
||||
|
||||
RefPtr<CacheStorage> ref =
|
||||
new CacheStorage(aNamespace, aGlobal, principalInfo, workerHolder);
|
||||
new CacheStorage(aNamespace, aGlobal, principalInfo, workerRef);
|
||||
return ref.forget();
|
||||
}
|
||||
|
||||
|
@ -268,7 +268,7 @@ bool CacheStorage::DefineCaches(JSContext* aCx, JS::Handle<JSObject*> aGlobal) {
|
|||
|
||||
CacheStorage::CacheStorage(Namespace aNamespace, nsIGlobalObject* aGlobal,
|
||||
const PrincipalInfo& aPrincipalInfo,
|
||||
CacheWorkerHolder* aWorkerHolder)
|
||||
CacheWorkerRef* aWorkerRef)
|
||||
: mNamespace(aNamespace),
|
||||
mGlobal(aGlobal),
|
||||
mPrincipalInfo(MakeUnique<PrincipalInfo>(aPrincipalInfo)),
|
||||
|
@ -284,10 +284,10 @@ CacheStorage::CacheStorage(Namespace aNamespace, nsIGlobalObject* aGlobal,
|
|||
return;
|
||||
}
|
||||
|
||||
// WorkerHolder ownership is passed to the CacheStorageChild actor and any
|
||||
// actors it may create. The WorkerHolder will keep the worker thread alive
|
||||
// WorkerRef ownership is passed to the CacheStorageChild actor and any
|
||||
// actors it may create. The WorkerRef will keep the worker thread alive
|
||||
// until the actors can gracefully shutdown.
|
||||
CacheStorageChild* newActor = new CacheStorageChild(this, aWorkerHolder);
|
||||
CacheStorageChild* newActor = new CacheStorageChild(this, aWorkerRef);
|
||||
PCacheStorageChild* constructedActor = actor->SendPCacheStorageConstructor(
|
||||
newActor, mNamespace, *mPrincipalInfo);
|
||||
|
||||
|
|
|
@ -34,7 +34,7 @@ class WorkerPrivate;
|
|||
namespace cache {
|
||||
|
||||
class CacheStorageChild;
|
||||
class CacheWorkerHolder;
|
||||
class CacheWorkerRef;
|
||||
|
||||
class CacheStorage final : public nsISupports,
|
||||
public nsWrapperCache,
|
||||
|
@ -86,7 +86,7 @@ class CacheStorage final : public nsISupports,
|
|||
private:
|
||||
CacheStorage(Namespace aNamespace, nsIGlobalObject* aGlobal,
|
||||
const mozilla::ipc::PrincipalInfo& aPrincipalInfo,
|
||||
CacheWorkerHolder* aWorkerHolder);
|
||||
CacheWorkerRef* aWorkerRef);
|
||||
explicit CacheStorage(nsresult aFailureResult);
|
||||
~CacheStorage();
|
||||
|
||||
|
|
|
@ -19,12 +19,12 @@ namespace cache {
|
|||
void DeallocPCacheStorageChild(PCacheStorageChild* aActor) { delete aActor; }
|
||||
|
||||
CacheStorageChild::CacheStorageChild(CacheStorage* aListener,
|
||||
CacheWorkerHolder* aWorkerHolder)
|
||||
CacheWorkerRef* aWorkerRef)
|
||||
: mListener(aListener), mNumChildActors(0), mDelayedDestroy(false) {
|
||||
MOZ_COUNT_CTOR(cache::CacheStorageChild);
|
||||
MOZ_DIAGNOSTIC_ASSERT(mListener);
|
||||
|
||||
SetWorkerHolder(aWorkerHolder);
|
||||
SetWorkerRef(aWorkerRef);
|
||||
}
|
||||
|
||||
CacheStorageChild::~CacheStorageChild() {
|
||||
|
@ -44,7 +44,7 @@ void CacheStorageChild::ExecuteOp(nsIGlobalObject* aGlobal, Promise* aPromise,
|
|||
const CacheOpArgs& aArgs) {
|
||||
mNumChildActors += 1;
|
||||
Unused << SendPCacheOpConstructor(
|
||||
new CacheOpChild(GetWorkerHolder(), aGlobal, aParent, aPromise), aArgs);
|
||||
new CacheOpChild(GetWorkerRef(), aGlobal, aParent, aPromise), aArgs);
|
||||
}
|
||||
|
||||
void CacheStorageChild::StartDestroyFromListener() {
|
||||
|
@ -73,7 +73,7 @@ void CacheStorageChild::StartDestroy() {
|
|||
RefPtr<CacheStorage> listener = mListener;
|
||||
|
||||
// StartDestroy() can get called from either CacheStorage or the
|
||||
// CacheWorkerHolder.
|
||||
// CacheWorkerRef.
|
||||
// Theoretically we can get double called if the right race happens. Handle
|
||||
// that by just ignoring the second StartDestroy() call.
|
||||
if (!listener) {
|
||||
|
@ -98,7 +98,7 @@ void CacheStorageChild::ActorDestroy(ActorDestroyReason aReason) {
|
|||
MOZ_DIAGNOSTIC_ASSERT(!mListener);
|
||||
}
|
||||
|
||||
RemoveWorkerHolder();
|
||||
RemoveWorkerRef();
|
||||
}
|
||||
|
||||
PCacheOpChild* CacheStorageChild::AllocPCacheOpChild(
|
||||
|
|
|
@ -22,14 +22,14 @@ namespace cache {
|
|||
|
||||
class CacheOpArgs;
|
||||
class CacheStorage;
|
||||
class CacheWorkerHolder;
|
||||
class CacheWorkerRef;
|
||||
class PCacheChild;
|
||||
|
||||
class CacheStorageChild final : public PCacheStorageChild, public ActorChild {
|
||||
friend class PCacheStorageChild;
|
||||
|
||||
public:
|
||||
CacheStorageChild(CacheStorage* aListener, CacheWorkerHolder* aWorkerHolder);
|
||||
CacheStorageChild(CacheStorage* aListener, CacheWorkerRef* aWorkerRef);
|
||||
~CacheStorageChild();
|
||||
|
||||
// Must be called by the associated CacheStorage listener in its
|
||||
|
@ -47,7 +47,7 @@ class CacheStorageChild final : public PCacheStorageChild, public ActorChild {
|
|||
private:
|
||||
// ActorChild methods
|
||||
|
||||
// CacheWorkerHolder is trying to destroy due to worker shutdown.
|
||||
// CacheWorkerRef is trying to destroy due to worker shutdown.
|
||||
virtual void StartDestroy() override;
|
||||
|
||||
// PCacheStorageChild methods
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
#include "mozilla/Unused.h"
|
||||
#include "mozilla/dom/cache/ActorUtils.h"
|
||||
#include "mozilla/dom/cache/CacheTypes.h"
|
||||
#include "mozilla/dom/cache/CacheWorkerHolder.h"
|
||||
#include "mozilla/dom/cache/CacheWorkerRef.h"
|
||||
#include "mozilla/dom/cache/ReadStream.h"
|
||||
#include "mozilla/ipc/FileDescriptorSetChild.h"
|
||||
#include "mozilla/ipc/IPCStreamUtils.h"
|
||||
|
@ -50,7 +50,7 @@ CacheStreamControlChild::~CacheStreamControlChild() {
|
|||
void CacheStreamControlChild::StartDestroy() {
|
||||
NS_ASSERT_OWNINGTHREAD(CacheStreamControlChild);
|
||||
// This can get called twice under some circumstances. For example, if the
|
||||
// actor is added to a CacheWorkerHolder that has already been notified and
|
||||
// actor is added to a CacheWorkerRef that has already been notified and
|
||||
// the Cache actor has no mListener.
|
||||
if (mDestroyStarted) {
|
||||
return;
|
||||
|
@ -110,7 +110,7 @@ void CacheStreamControlChild::OpenStream(const nsID& aId,
|
|||
// rejection here in many cases, we must handle the case where the
|
||||
// MozPromise resolve runnable is already in the event queue when the
|
||||
// worker wants to shut down.
|
||||
RefPtr<CacheWorkerHolder> holder = GetWorkerHolder();
|
||||
RefPtr<CacheWorkerRef> holder = GetWorkerRef();
|
||||
|
||||
SendOpenStream(aId)->Then(
|
||||
GetCurrentThreadSerialEventTarget(), __func__,
|
||||
|
@ -145,7 +145,7 @@ void CacheStreamControlChild::AssertOwningThread() {
|
|||
void CacheStreamControlChild::ActorDestroy(ActorDestroyReason aReason) {
|
||||
NS_ASSERT_OWNINGTHREAD(CacheStreamControlChild);
|
||||
CloseAllReadStreamsWithoutReporting();
|
||||
RemoveWorkerHolder();
|
||||
RemoveWorkerRef();
|
||||
}
|
||||
|
||||
mozilla::ipc::IPCResult CacheStreamControlChild::RecvClose(const nsID& aId) {
|
||||
|
|
|
@ -1,111 +0,0 @@
|
|||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
||||
/* 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/. */
|
||||
|
||||
#include "mozilla/dom/cache/CacheWorkerHolder.h"
|
||||
|
||||
#include "mozilla/dom/cache/ActorChild.h"
|
||||
#include "mozilla/dom/WorkerPrivate.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
namespace cache {
|
||||
|
||||
// static
|
||||
already_AddRefed<CacheWorkerHolder> CacheWorkerHolder::Create(
|
||||
WorkerPrivate* aWorkerPrivate, Behavior aBehavior) {
|
||||
MOZ_DIAGNOSTIC_ASSERT(aWorkerPrivate);
|
||||
|
||||
RefPtr<CacheWorkerHolder> workerHolder = new CacheWorkerHolder(aBehavior);
|
||||
if (NS_WARN_IF(!workerHolder->HoldWorker(aWorkerPrivate, Canceling))) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return workerHolder.forget();
|
||||
}
|
||||
|
||||
// static
|
||||
already_AddRefed<CacheWorkerHolder> CacheWorkerHolder::PreferBehavior(
|
||||
CacheWorkerHolder* aCurrentHolder, Behavior aBehavior) {
|
||||
if (!aCurrentHolder) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
RefPtr<CacheWorkerHolder> orig = aCurrentHolder;
|
||||
if (orig->GetBehavior() == aBehavior) {
|
||||
return orig.forget();
|
||||
}
|
||||
|
||||
RefPtr<CacheWorkerHolder> replace = Create(orig->mWorkerPrivate, aBehavior);
|
||||
if (!replace) {
|
||||
return orig.forget();
|
||||
}
|
||||
|
||||
return replace.forget();
|
||||
}
|
||||
|
||||
void CacheWorkerHolder::AddActor(ActorChild* aActor) {
|
||||
NS_ASSERT_OWNINGTHREAD(CacheWorkerHolder);
|
||||
MOZ_DIAGNOSTIC_ASSERT(aActor);
|
||||
MOZ_ASSERT(!mActorList.Contains(aActor));
|
||||
|
||||
mActorList.AppendElement(aActor);
|
||||
|
||||
// Allow an actor to be added after we've entered the Notifying case. We
|
||||
// can't stop the actor creation from racing with out destruction of the
|
||||
// other actors and we need to wait for this extra one to close as well.
|
||||
// Signal it should destroy itself right away.
|
||||
if (mNotified) {
|
||||
aActor->StartDestroy();
|
||||
}
|
||||
}
|
||||
|
||||
void CacheWorkerHolder::RemoveActor(ActorChild* aActor) {
|
||||
NS_ASSERT_OWNINGTHREAD(CacheWorkerHolder);
|
||||
MOZ_DIAGNOSTIC_ASSERT(aActor);
|
||||
|
||||
#if defined(RELEASE_OR_BETA)
|
||||
mActorList.RemoveElement(aActor);
|
||||
#else
|
||||
MOZ_DIAGNOSTIC_ASSERT(mActorList.RemoveElement(aActor));
|
||||
#endif
|
||||
|
||||
MOZ_ASSERT(!mActorList.Contains(aActor));
|
||||
}
|
||||
|
||||
bool CacheWorkerHolder::Notified() const { return mNotified; }
|
||||
|
||||
bool CacheWorkerHolder::Notify(WorkerStatus aStatus) {
|
||||
NS_ASSERT_OWNINGTHREAD(CacheWorkerHolder);
|
||||
|
||||
// When the service worker thread is stopped we will get Canceling,
|
||||
// but nothing higher than that. We must shut things down at Canceling.
|
||||
if (aStatus < Canceling || mNotified) {
|
||||
return true;
|
||||
}
|
||||
|
||||
mNotified = true;
|
||||
|
||||
// Start the asynchronous destruction of our actors. These will call back
|
||||
// into RemoveActor() once the actor is destroyed.
|
||||
for (uint32_t i = 0; i < mActorList.Length(); ++i) {
|
||||
MOZ_DIAGNOSTIC_ASSERT(mActorList[i]);
|
||||
mActorList[i]->StartDestroy();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
CacheWorkerHolder::CacheWorkerHolder(Behavior aBehavior)
|
||||
: WorkerHolder("CacheWorkerHolder", aBehavior), mNotified(false) {}
|
||||
|
||||
CacheWorkerHolder::~CacheWorkerHolder() {
|
||||
NS_ASSERT_OWNINGTHREAD(CacheWorkerHolder);
|
||||
MOZ_DIAGNOSTIC_ASSERT(mActorList.IsEmpty());
|
||||
}
|
||||
|
||||
} // namespace cache
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
|
@ -1,54 +0,0 @@
|
|||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
||||
/* 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/. */
|
||||
|
||||
#ifndef mozilla_dom_cache_CacheWorkerHolder_h
|
||||
#define mozilla_dom_cache_CacheWorkerHolder_h
|
||||
|
||||
#include "nsISupportsImpl.h"
|
||||
#include "nsTArray.h"
|
||||
#include "mozilla/dom/WorkerHolder.h"
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
class WorkerPrivate;
|
||||
|
||||
namespace dom {
|
||||
namespace cache {
|
||||
|
||||
class ActorChild;
|
||||
|
||||
class CacheWorkerHolder final : public WorkerHolder {
|
||||
public:
|
||||
static already_AddRefed<CacheWorkerHolder> Create(
|
||||
WorkerPrivate* aWorkerPrivate, Behavior aBehavior);
|
||||
|
||||
static already_AddRefed<CacheWorkerHolder> PreferBehavior(
|
||||
CacheWorkerHolder* aCurrentHolder, Behavior aBehavior);
|
||||
|
||||
void AddActor(ActorChild* aActor);
|
||||
void RemoveActor(ActorChild* aActor);
|
||||
|
||||
bool Notified() const;
|
||||
|
||||
// WorkerHolder methods
|
||||
virtual bool Notify(WorkerStatus aStatus) override;
|
||||
|
||||
private:
|
||||
explicit CacheWorkerHolder(Behavior aBehavior);
|
||||
~CacheWorkerHolder();
|
||||
|
||||
nsTArray<ActorChild*> mActorList;
|
||||
bool mNotified;
|
||||
|
||||
public:
|
||||
NS_INLINE_DECL_REFCOUNTING(mozilla::dom::cache::CacheWorkerHolder)
|
||||
};
|
||||
|
||||
} // namespace cache
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
||||
|
||||
#endif // mozilla_dom_cache_CacheWorkerHolder_h
|
|
@ -0,0 +1,130 @@
|
|||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
||||
/* 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/. */
|
||||
|
||||
#include "mozilla/dom/cache/CacheWorkerRef.h"
|
||||
|
||||
#include "mozilla/dom/cache/ActorChild.h"
|
||||
#include "mozilla/dom/WorkerPrivate.h"
|
||||
#include "mozilla/dom/WorkerRef.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
namespace cache {
|
||||
|
||||
// static
|
||||
already_AddRefed<CacheWorkerRef> CacheWorkerRef::Create(
|
||||
WorkerPrivate* aWorkerPrivate, Behavior aBehavior) {
|
||||
MOZ_DIAGNOSTIC_ASSERT(aWorkerPrivate);
|
||||
|
||||
RefPtr<CacheWorkerRef> workerRef = new CacheWorkerRef(aBehavior);
|
||||
if (aBehavior == eStrongWorkerRef) {
|
||||
workerRef->mStrongWorkerRef =
|
||||
StrongWorkerRef::Create(aWorkerPrivate, "CacheWorkerRef-Strong",
|
||||
[workerRef] { workerRef->Notify(); });
|
||||
} else {
|
||||
MOZ_ASSERT(aBehavior == eIPCWorkerRef);
|
||||
workerRef->mIPCWorkerRef =
|
||||
IPCWorkerRef::Create(aWorkerPrivate, "CacheWorkerRef-IPC",
|
||||
[workerRef] { workerRef->Notify(); });
|
||||
}
|
||||
|
||||
if (NS_WARN_IF(!workerRef->mIPCWorkerRef && !workerRef->mStrongWorkerRef)) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return workerRef.forget();
|
||||
}
|
||||
|
||||
// static
|
||||
already_AddRefed<CacheWorkerRef> CacheWorkerRef::PreferBehavior(
|
||||
CacheWorkerRef* aCurrentRef, Behavior aBehavior) {
|
||||
if (!aCurrentRef) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
RefPtr<CacheWorkerRef> orig = aCurrentRef;
|
||||
if (orig->mBehavior == aBehavior) {
|
||||
return orig.forget();
|
||||
}
|
||||
|
||||
WorkerPrivate* workerPrivate = nullptr;
|
||||
if (orig->mBehavior == eStrongWorkerRef) {
|
||||
workerPrivate = orig->mStrongWorkerRef->Private();
|
||||
} else {
|
||||
MOZ_ASSERT(orig->mBehavior == eIPCWorkerRef);
|
||||
workerPrivate = orig->mIPCWorkerRef->Private();
|
||||
}
|
||||
|
||||
MOZ_ASSERT(workerPrivate);
|
||||
|
||||
RefPtr<CacheWorkerRef> replace = Create(workerPrivate, aBehavior);
|
||||
if (!replace) {
|
||||
return orig.forget();
|
||||
}
|
||||
|
||||
return replace.forget();
|
||||
}
|
||||
|
||||
void CacheWorkerRef::AddActor(ActorChild* aActor) {
|
||||
NS_ASSERT_OWNINGTHREAD(CacheWorkerRef);
|
||||
MOZ_DIAGNOSTIC_ASSERT(aActor);
|
||||
MOZ_ASSERT(!mActorList.Contains(aActor));
|
||||
|
||||
mActorList.AppendElement(aActor);
|
||||
|
||||
// Allow an actor to be added after we've entered the Notifying case. We
|
||||
// can't stop the actor creation from racing with out destruction of the
|
||||
// other actors and we need to wait for this extra one to close as well.
|
||||
// Signal it should destroy itself right away.
|
||||
if (mNotified) {
|
||||
aActor->StartDestroy();
|
||||
}
|
||||
}
|
||||
|
||||
void CacheWorkerRef::RemoveActor(ActorChild* aActor) {
|
||||
NS_ASSERT_OWNINGTHREAD(CacheWorkerRef);
|
||||
MOZ_DIAGNOSTIC_ASSERT(aActor);
|
||||
|
||||
#if defined(RELEASE_OR_BETA)
|
||||
mActorList.RemoveElement(aActor);
|
||||
#else
|
||||
MOZ_DIAGNOSTIC_ASSERT(mActorList.RemoveElement(aActor));
|
||||
#endif
|
||||
|
||||
MOZ_ASSERT(!mActorList.Contains(aActor));
|
||||
|
||||
if (mActorList.IsEmpty()) {
|
||||
mStrongWorkerRef = nullptr;
|
||||
mIPCWorkerRef = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
bool CacheWorkerRef::Notified() const { return mNotified; }
|
||||
|
||||
void CacheWorkerRef::Notify() {
|
||||
NS_ASSERT_OWNINGTHREAD(CacheWorkerRef);
|
||||
|
||||
mNotified = true;
|
||||
|
||||
// Start the asynchronous destruction of our actors. These will call back
|
||||
// into RemoveActor() once the actor is destroyed.
|
||||
for (uint32_t i = 0; i < mActorList.Length(); ++i) {
|
||||
MOZ_DIAGNOSTIC_ASSERT(mActorList[i]);
|
||||
mActorList[i]->StartDestroy();
|
||||
}
|
||||
}
|
||||
|
||||
CacheWorkerRef::CacheWorkerRef(Behavior aBehavior)
|
||||
: mBehavior(aBehavior), mNotified(false) {}
|
||||
|
||||
CacheWorkerRef::~CacheWorkerRef() {
|
||||
NS_ASSERT_OWNINGTHREAD(CacheWorkerRef);
|
||||
MOZ_DIAGNOSTIC_ASSERT(mActorList.IsEmpty());
|
||||
}
|
||||
|
||||
} // namespace cache
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
|
@ -0,0 +1,64 @@
|
|||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
||||
/* 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/. */
|
||||
|
||||
#ifndef mozilla_dom_cache_CacheWorkerRef_h
|
||||
#define mozilla_dom_cache_CacheWorkerRef_h
|
||||
|
||||
#include "nsISupportsImpl.h"
|
||||
#include "nsTArray.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
|
||||
class IPCWorkerRef;
|
||||
class StrongWorkerRef;
|
||||
class WorkerPrivate;
|
||||
|
||||
namespace cache {
|
||||
|
||||
class ActorChild;
|
||||
|
||||
class CacheWorkerRef final {
|
||||
public:
|
||||
enum Behavior {
|
||||
eStrongWorkerRef,
|
||||
eIPCWorkerRef,
|
||||
};
|
||||
|
||||
static already_AddRefed<CacheWorkerRef> Create(WorkerPrivate* aWorkerPrivate,
|
||||
Behavior aBehavior);
|
||||
|
||||
static already_AddRefed<CacheWorkerRef> PreferBehavior(
|
||||
CacheWorkerRef* aCurrentRef, Behavior aBehavior);
|
||||
|
||||
void AddActor(ActorChild* aActor);
|
||||
void RemoveActor(ActorChild* aActor);
|
||||
|
||||
bool Notified() const;
|
||||
|
||||
private:
|
||||
explicit CacheWorkerRef(Behavior aBehavior);
|
||||
~CacheWorkerRef();
|
||||
|
||||
void Notify();
|
||||
|
||||
nsTArray<ActorChild*> mActorList;
|
||||
|
||||
Behavior mBehavior;
|
||||
bool mNotified;
|
||||
|
||||
RefPtr<StrongWorkerRef> mStrongWorkerRef;
|
||||
RefPtr<IPCWorkerRef> mIPCWorkerRef;
|
||||
|
||||
public:
|
||||
NS_INLINE_DECL_REFCOUNTING(mozilla::dom::cache::CacheWorkerRef)
|
||||
};
|
||||
|
||||
} // namespace cache
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
||||
|
||||
#endif // mozilla_dom_cache_CacheWorkerRef_h
|
|
@ -23,7 +23,7 @@ EXPORTS.mozilla.dom.cache += [
|
|||
'CacheStorageParent.h',
|
||||
'CacheStreamControlChild.h',
|
||||
'CacheStreamControlParent.h',
|
||||
'CacheWorkerHolder.h',
|
||||
'CacheWorkerRef.h',
|
||||
'Connection.h',
|
||||
'Context.h',
|
||||
'DBAction.h',
|
||||
|
@ -56,7 +56,7 @@ UNIFIED_SOURCES += [
|
|||
'CacheStorageParent.cpp',
|
||||
'CacheStreamControlChild.cpp',
|
||||
'CacheStreamControlParent.cpp',
|
||||
'CacheWorkerHolder.cpp',
|
||||
'CacheWorkerRef.cpp',
|
||||
'Connection.cpp',
|
||||
'Context.cpp',
|
||||
'DBAction.cpp',
|
||||
|
|
|
@ -42,7 +42,8 @@ struct ImageCacheEntryData {
|
|||
: mImage(aOther.mImage),
|
||||
mCanvas(aOther.mCanvas),
|
||||
mSourceSurface(aOther.mSourceSurface),
|
||||
mSize(aOther.mSize) {}
|
||||
mSize(aOther.mSize),
|
||||
mIntrinsicSize(aOther.mIntrinsicSize) {}
|
||||
explicit ImageCacheEntryData(const ImageCacheKey& aKey)
|
||||
: mImage(aKey.mImage), mCanvas(aKey.mCanvas) {}
|
||||
|
||||
|
@ -55,6 +56,7 @@ struct ImageCacheEntryData {
|
|||
// Value
|
||||
RefPtr<SourceSurface> mSourceSurface;
|
||||
IntSize mSize;
|
||||
IntSize mIntrinsicSize;
|
||||
nsExpirationState mState;
|
||||
};
|
||||
|
||||
|
@ -257,7 +259,8 @@ static already_AddRefed<imgIContainer> GetImageContainer(dom::Element* aImage) {
|
|||
void CanvasImageCache::NotifyDrawImage(Element* aImage,
|
||||
HTMLCanvasElement* aCanvas,
|
||||
SourceSurface* aSource,
|
||||
const IntSize& aSize) {
|
||||
const IntSize& aSize,
|
||||
const IntSize& aIntrinsicSize) {
|
||||
if (!gImageCache) {
|
||||
gImageCache = new ImageCache();
|
||||
nsContentUtils::RegisterShutdownObserver(
|
||||
|
@ -284,6 +287,7 @@ void CanvasImageCache::NotifyDrawImage(Element* aImage,
|
|||
gImageCache->AddObject(entry->mData);
|
||||
entry->mData->mSourceSurface = aSource;
|
||||
entry->mData->mSize = aSize;
|
||||
entry->mData->mIntrinsicSize = aIntrinsicSize;
|
||||
gImageCache->mTotal += entry->mData->SizeInBytes();
|
||||
|
||||
AllCanvasImageCacheEntry* allEntry =
|
||||
|
@ -321,7 +325,8 @@ SourceSurface* CanvasImageCache::LookupAllCanvas(Element* aImage) {
|
|||
|
||||
SourceSurface* CanvasImageCache::LookupCanvas(Element* aImage,
|
||||
HTMLCanvasElement* aCanvas,
|
||||
IntSize* aSizeOut) {
|
||||
IntSize* aSizeOut,
|
||||
IntSize* aIntrinsicSizeOut) {
|
||||
if (!gImageCache) {
|
||||
return nullptr;
|
||||
}
|
||||
|
@ -341,6 +346,7 @@ SourceSurface* CanvasImageCache::LookupCanvas(Element* aImage,
|
|||
|
||||
gImageCache->MarkUsed(entry->mData);
|
||||
*aSizeOut = entry->mData->mSize;
|
||||
*aIntrinsicSizeOut = entry->mData->mIntrinsicSize;
|
||||
return entry->mData->mSourceSurface;
|
||||
}
|
||||
|
||||
|
|
|
@ -29,12 +29,13 @@ class CanvasImageCache {
|
|||
/**
|
||||
* Notify that image element aImage was drawn to aCanvas element
|
||||
* using the first frame of aRequest's image. The data for the surface is
|
||||
* in aSurface, and the image size is in aSize.
|
||||
* in aSurface, and the image size is in aSize. aIntrinsicSize is the size
|
||||
* the surface is intended to be rendered at.
|
||||
*/
|
||||
static void NotifyDrawImage(dom::Element* aImage,
|
||||
dom::HTMLCanvasElement* aCanvas,
|
||||
SourceSurface* aSource,
|
||||
const gfx::IntSize& aSize);
|
||||
SourceSurface* aSource, const gfx::IntSize& aSize,
|
||||
const gfx::IntSize& aIntrinsicSize);
|
||||
|
||||
/**
|
||||
* Check whether aImage has recently been drawn any canvas. If we return
|
||||
|
@ -48,7 +49,8 @@ class CanvasImageCache {
|
|||
*/
|
||||
static SourceSurface* LookupCanvas(dom::Element* aImage,
|
||||
dom::HTMLCanvasElement* aCanvas,
|
||||
gfx::IntSize* aSizeOut);
|
||||
gfx::IntSize* aSizeOut,
|
||||
gfx::IntSize* aIntrinsicSizeOut);
|
||||
};
|
||||
|
||||
} // namespace mozilla
|
||||
|
|
|
@ -4288,7 +4288,7 @@ CanvasRenderingContext2D::CachedSurfaceFromElement(Element* aElement) {
|
|||
res.mCORSUsed = corsmode != imgIRequest::CORS_NONE;
|
||||
}
|
||||
|
||||
res.mSize = res.mSourceSurface->GetSize();
|
||||
res.mSize = res.mIntrinsicSize = res.mSourceSurface->GetSize();
|
||||
res.mPrincipal = principal.forget();
|
||||
res.mImageRequest = imgRequest.forget();
|
||||
res.mIsWriteOnly = CheckWriteOnlySecurity(res.mCORSUsed, res.mPrincipal,
|
||||
|
@ -4331,6 +4331,7 @@ void CanvasRenderingContext2D::DrawImage(const CanvasImageSource& aImage,
|
|||
|
||||
RefPtr<SourceSurface> srcSurf;
|
||||
gfx::IntSize imgSize;
|
||||
gfx::IntSize intrinsicImgSize;
|
||||
|
||||
Element* element = nullptr;
|
||||
|
||||
|
@ -4363,7 +4364,8 @@ void CanvasRenderingContext2D::DrawImage(const CanvasImageSource& aImage,
|
|||
SetWriteOnly();
|
||||
}
|
||||
|
||||
imgSize = gfx::IntSize(imageBitmap.Width(), imageBitmap.Height());
|
||||
imgSize = intrinsicImgSize =
|
||||
gfx::IntSize(imageBitmap.Width(), imageBitmap.Height());
|
||||
} else {
|
||||
if (aImage.IsHTMLImageElement()) {
|
||||
HTMLImageElement* img = &aImage.GetAsHTMLImageElement();
|
||||
|
@ -4378,7 +4380,8 @@ void CanvasRenderingContext2D::DrawImage(const CanvasImageSource& aImage,
|
|||
element = video;
|
||||
}
|
||||
|
||||
srcSurf = CanvasImageCache::LookupCanvas(element, mCanvasElement, &imgSize);
|
||||
srcSurf = CanvasImageCache::LookupCanvas(element, mCanvasElement, &imgSize,
|
||||
&intrinsicImgSize);
|
||||
}
|
||||
|
||||
nsLayoutUtils::DirectDrawInfo drawInfo;
|
||||
|
@ -4408,18 +4411,7 @@ void CanvasRenderingContext2D::DrawImage(const CanvasImageSource& aImage,
|
|||
}
|
||||
|
||||
imgSize = res.mSize;
|
||||
|
||||
// Scale sw/sh based on aspect ratio
|
||||
if (aImage.IsHTMLVideoElement()) {
|
||||
HTMLVideoElement* video = &aImage.GetAsHTMLVideoElement();
|
||||
int32_t displayWidth = video->VideoWidth();
|
||||
int32_t displayHeight = video->VideoHeight();
|
||||
if (displayWidth == 0 || displayHeight == 0) {
|
||||
return;
|
||||
}
|
||||
aSw *= (double)imgSize.width / (double)displayWidth;
|
||||
aSh *= (double)imgSize.height / (double)displayHeight;
|
||||
}
|
||||
intrinsicImgSize = res.mIntrinsicSize;
|
||||
|
||||
if (mCanvasElement) {
|
||||
CanvasUtils::DoDrawImageSecurityCheck(mCanvasElement, res.mPrincipal,
|
||||
|
@ -4429,7 +4421,8 @@ void CanvasRenderingContext2D::DrawImage(const CanvasImageSource& aImage,
|
|||
if (res.mSourceSurface) {
|
||||
if (res.mImageRequest) {
|
||||
CanvasImageCache::NotifyDrawImage(element, mCanvasElement,
|
||||
res.mSourceSurface, imgSize);
|
||||
res.mSourceSurface, imgSize,
|
||||
intrinsicImgSize);
|
||||
}
|
||||
srcSurf = res.mSourceSurface;
|
||||
} else {
|
||||
|
@ -4439,8 +4432,10 @@ void CanvasRenderingContext2D::DrawImage(const CanvasImageSource& aImage,
|
|||
|
||||
if (aOptional_argc == 0) {
|
||||
aSx = aSy = 0.0;
|
||||
aDw = aSw = (double)imgSize.width;
|
||||
aDh = aSh = (double)imgSize.height;
|
||||
aSw = (double)imgSize.width;
|
||||
aSh = (double)imgSize.height;
|
||||
aDw = (double)intrinsicImgSize.width;
|
||||
aDh = (double)intrinsicImgSize.height;
|
||||
} else if (aOptional_argc == 2) {
|
||||
aSx = aSy = 0.0;
|
||||
aSw = (double)imgSize.width;
|
||||
|
|
|
@ -455,7 +455,7 @@ bool WebGLContext::CreateAndInitGL(
|
|||
}
|
||||
|
||||
// WebGL2 is separately blocked:
|
||||
if (IsWebGL2()) {
|
||||
if (IsWebGL2() && !forceEnabled) {
|
||||
const nsCOMPtr<nsIGfxInfo> gfxInfo = services::GetGfxInfo();
|
||||
const auto feature = nsIGfxInfo::FEATURE_WEBGL2;
|
||||
|
||||
|
|
|
@ -9,7 +9,6 @@
|
|||
#include "mozilla/dom/ClientIPCTypes.h"
|
||||
#include "mozilla/dom/ClientOpPromise.h"
|
||||
#include "mozilla/dom/DOMMozPromiseRequestHolder.h"
|
||||
#include "mozilla/dom/WorkerHolderToken.h"
|
||||
#include "mozilla/dom/WorkerPrivate.h"
|
||||
|
||||
class nsIGlobalObject;
|
||||
|
|
|
@ -11,7 +11,6 @@
|
|||
#include "ClientManagerOpChild.h"
|
||||
#include "ClientPrefs.h"
|
||||
#include "ClientSource.h"
|
||||
#include "mozilla/dom/WorkerHolderToken.h"
|
||||
#include "mozilla/dom/WorkerPrivate.h"
|
||||
#include "mozilla/ipc/BackgroundChild.h"
|
||||
#include "mozilla/ipc/PBackgroundChild.h"
|
||||
|
@ -54,27 +53,12 @@ ClientManager::ClientManager() {
|
|||
return;
|
||||
}
|
||||
|
||||
RefPtr<WorkerHolderToken> workerHolderToken;
|
||||
if (!NS_IsMainThread()) {
|
||||
WorkerPrivate* workerPrivate = GetCurrentThreadWorkerPrivate();
|
||||
MOZ_DIAGNOSTIC_ASSERT(workerPrivate);
|
||||
|
||||
// Note, it would be nice to replace this with a WorkerRef, but
|
||||
// currently there is no WorkerRef option that matches what we
|
||||
// need here. We need something like a StrongWorkerRef that will
|
||||
// let us keep the worker alive until our actor is destroyed, but
|
||||
// we also need to use AllowIdleShutdownStart like WeakWorkerRef.
|
||||
// We need AllowIdleShutdownStart since every worker thread will
|
||||
// have a ClientManager to support creating its ClientSource.
|
||||
workerHolderToken = WorkerHolderToken::Create(
|
||||
workerPrivate, Canceling, WorkerHolderToken::AllowIdleShutdownStart);
|
||||
if (NS_WARN_IF(!workerHolderToken)) {
|
||||
Shutdown();
|
||||
return;
|
||||
}
|
||||
ClientManagerChild* actor = ClientManagerChild::Create();
|
||||
if (NS_WARN_IF(!actor)) {
|
||||
Shutdown();
|
||||
return;
|
||||
}
|
||||
|
||||
ClientManagerChild* actor = new ClientManagerChild(workerHolderToken);
|
||||
PClientManagerChild* sentActor =
|
||||
parentActor->SendPClientManagerConstructor(actor);
|
||||
if (NS_WARN_IF(!sentActor)) {
|
||||
|
|
|
@ -11,14 +11,13 @@
|
|||
#include "ClientNavigateOpChild.h"
|
||||
#include "ClientSourceChild.h"
|
||||
|
||||
#include "mozilla/dom/WorkerRef.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
|
||||
void ClientManagerChild::ActorDestroy(ActorDestroyReason aReason) {
|
||||
if (mWorkerHolderToken) {
|
||||
mWorkerHolderToken->RemoveListener(this);
|
||||
mWorkerHolderToken = nullptr;
|
||||
}
|
||||
mIPCWorkerRef = nullptr;
|
||||
|
||||
if (mManager) {
|
||||
mManager->RevokeActor(this);
|
||||
|
@ -81,19 +80,33 @@ bool ClientManagerChild::DeallocPClientSourceChild(PClientSourceChild* aActor) {
|
|||
return true;
|
||||
}
|
||||
|
||||
void ClientManagerChild::WorkerShuttingDown() { MaybeStartTeardown(); }
|
||||
// static
|
||||
ClientManagerChild* ClientManagerChild::Create() {
|
||||
ClientManagerChild* actor = new ClientManagerChild();
|
||||
|
||||
ClientManagerChild::ClientManagerChild(WorkerHolderToken* aWorkerHolderToken)
|
||||
: mManager(nullptr),
|
||||
mWorkerHolderToken(aWorkerHolderToken),
|
||||
mTeardownStarted(false) {
|
||||
MOZ_ASSERT_IF(!NS_IsMainThread(), mWorkerHolderToken);
|
||||
if (!NS_IsMainThread()) {
|
||||
WorkerPrivate* workerPrivate = GetCurrentThreadWorkerPrivate();
|
||||
MOZ_DIAGNOSTIC_ASSERT(workerPrivate);
|
||||
|
||||
if (mWorkerHolderToken) {
|
||||
mWorkerHolderToken->AddListener(this);
|
||||
RefPtr<IPCWorkerRefHelper<ClientManagerChild>> helper =
|
||||
new IPCWorkerRefHelper<ClientManagerChild>(actor);
|
||||
|
||||
actor->mIPCWorkerRef = IPCWorkerRef::Create(
|
||||
workerPrivate, "ClientManagerChild",
|
||||
[helper] { helper->Actor()->MaybeStartTeardown(); });
|
||||
|
||||
if (NS_WARN_IF(!actor->mIPCWorkerRef)) {
|
||||
delete actor;
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
return actor;
|
||||
}
|
||||
|
||||
ClientManagerChild::ClientManagerChild()
|
||||
: mManager(nullptr), mTeardownStarted(false) {}
|
||||
|
||||
void ClientManagerChild::SetOwner(ClientThing<ClientManagerChild>* aThing) {
|
||||
MOZ_DIAGNOSTIC_ASSERT(aThing);
|
||||
MOZ_DIAGNOSTIC_ASSERT(!mManager);
|
||||
|
@ -115,10 +128,10 @@ void ClientManagerChild::MaybeStartTeardown() {
|
|||
}
|
||||
|
||||
WorkerPrivate* ClientManagerChild::GetWorkerPrivate() const {
|
||||
if (!mWorkerHolderToken) {
|
||||
if (!mIPCWorkerRef) {
|
||||
return nullptr;
|
||||
}
|
||||
return mWorkerHolderToken->GetWorkerPrivate();
|
||||
return mIPCWorkerRef->Private();
|
||||
}
|
||||
|
||||
} // namespace dom
|
||||
|
|
|
@ -8,20 +8,21 @@
|
|||
|
||||
#include "ClientThing.h"
|
||||
#include "mozilla/dom/PClientManagerChild.h"
|
||||
#include "mozilla/dom/WorkerHolderToken.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
|
||||
class IPCWorkerRef;
|
||||
class WorkerPrivate;
|
||||
|
||||
class ClientManagerChild final : public PClientManagerChild,
|
||||
public WorkerHolderToken::Listener {
|
||||
class ClientManagerChild final : public PClientManagerChild {
|
||||
ClientThing<ClientManagerChild>* mManager;
|
||||
|
||||
RefPtr<WorkerHolderToken> mWorkerHolderToken;
|
||||
RefPtr<IPCWorkerRef> mIPCWorkerRef;
|
||||
bool mTeardownStarted;
|
||||
|
||||
ClientManagerChild();
|
||||
|
||||
// PClientManagerChild interface
|
||||
void ActorDestroy(ActorDestroyReason aReason) override;
|
||||
|
||||
|
@ -49,11 +50,8 @@ class ClientManagerChild final : public PClientManagerChild,
|
|||
|
||||
bool DeallocPClientSourceChild(PClientSourceChild* aActor) override;
|
||||
|
||||
// WorkerHolderToken::Listener interface
|
||||
void WorkerShuttingDown() override;
|
||||
|
||||
public:
|
||||
explicit ClientManagerChild(WorkerHolderToken* aWorkerHolderToken);
|
||||
static ClientManagerChild* Create();
|
||||
|
||||
void SetOwner(ClientThing<ClientManagerChild>* aThing);
|
||||
|
||||
|
|
|
@ -46,9 +46,6 @@ class IDBTransaction final : public DOMEventTargetHelper, public nsIRunnable {
|
|||
friend class indexedDB::BackgroundCursorChild;
|
||||
friend class indexedDB::BackgroundRequestChild;
|
||||
|
||||
class WorkerHolder;
|
||||
friend class WorkerHolder;
|
||||
|
||||
public:
|
||||
enum Mode {
|
||||
READ_ONLY = 0,
|
||||
|
|
|
@ -1132,6 +1132,17 @@ void AudioCallbackDriver::CompleteAudioContextOperations(
|
|||
}
|
||||
}
|
||||
|
||||
TimeDuration AudioCallbackDriver::AudioOutputLatency() {
|
||||
uint32_t latency_frames;
|
||||
int rv = cubeb_stream_get_latency(mAudioStream, &latency_frames);
|
||||
if (rv || mSampleRate == 0) {
|
||||
return TimeDuration::FromSeconds(0.0);
|
||||
}
|
||||
|
||||
return TimeDuration::FromSeconds(static_cast<double>(latency_frames) /
|
||||
mSampleRate);
|
||||
}
|
||||
|
||||
void AudioCallbackDriver::FallbackToSystemClockDriver() {
|
||||
MOZ_ASSERT(!ThreadRunning());
|
||||
GraphImpl()->GetMonitor().AssertCurrentThreadOwns();
|
||||
|
|
|
@ -433,6 +433,9 @@ class AudioCallbackDriver : public GraphDriver,
|
|||
|
||||
void CompleteAudioContextOperations(AsyncCubebOperation aOperation);
|
||||
|
||||
// Returns the output latency for the current audio output stream.
|
||||
TimeDuration AudioOutputLatency();
|
||||
|
||||
private:
|
||||
/* Remove Mixer callbacks when switching */
|
||||
void RemoveMixerCallback();
|
||||
|
|
|
@ -2289,10 +2289,17 @@ static void ReduceConstraint(
|
|||
}
|
||||
|
||||
// Keep mediaSource, ignore all other constraints.
|
||||
auto& c = aConstraint.GetAsMediaTrackConstraints();
|
||||
MOZ_DIAGNOSTIC_ASSERT(c.mMediaSource.WasPassed());
|
||||
nsString mediaSource = c.mMediaSource.Value();
|
||||
aConstraint.SetAsMediaTrackConstraints().mMediaSource.Construct(mediaSource);
|
||||
Maybe<nsString> mediaSource;
|
||||
if (aConstraint.GetAsMediaTrackConstraints().mMediaSource.WasPassed()) {
|
||||
mediaSource =
|
||||
Some(aConstraint.GetAsMediaTrackConstraints().mMediaSource.Value());
|
||||
}
|
||||
if (mediaSource) {
|
||||
aConstraint.SetAsMediaTrackConstraints().mMediaSource.Value() =
|
||||
*mediaSource;
|
||||
} else {
|
||||
aConstraint.SetAsMediaTrackConstraints();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -957,6 +957,10 @@ void MediaStreamGraphImpl::DeviceChanged() {
|
|||
MediaStreamGraphImpl* mGraphImpl;
|
||||
};
|
||||
|
||||
// Reset the latency, it will get fetched again next time it's queried.
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
mAudioOutputLatency = 0.0;
|
||||
|
||||
AppendMessage(MakeUnique<Message>(this));
|
||||
}
|
||||
|
||||
|
@ -3192,7 +3196,8 @@ MediaStreamGraphImpl::MediaStreamGraphImpl(GraphDriverType aDriverRequested,
|
|||
mCanRunMessagesSynchronously(false)
|
||||
#endif
|
||||
,
|
||||
mMainThreadGraphTime(0, "MediaStreamGraphImpl::mMainThreadGraphTime") {
|
||||
mMainThreadGraphTime(0, "MediaStreamGraphImpl::mMainThreadGraphTime"),
|
||||
mAudioOutputLatency(0.0) {
|
||||
if (mRealtime) {
|
||||
if (aDriverRequested == AUDIO_THREAD_DRIVER) {
|
||||
// Always start with zero input channels, and no particular preferences
|
||||
|
@ -3796,6 +3801,29 @@ void MediaStreamGraph::ApplyAudioContextOperation(
|
|||
aDestinationStream, aStreams, aOperation, aPromise, aFlags));
|
||||
}
|
||||
|
||||
double MediaStreamGraph::AudioOutputLatency() {
|
||||
return static_cast<MediaStreamGraphImpl*>(this)->AudioOutputLatency();
|
||||
}
|
||||
|
||||
double MediaStreamGraphImpl::AudioOutputLatency() {
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
if (mAudioOutputLatency != 0.0) {
|
||||
return mAudioOutputLatency;
|
||||
}
|
||||
MonitorAutoLock lock(mMonitor);
|
||||
if (CurrentDriver()->AsAudioCallbackDriver()) {
|
||||
mAudioOutputLatency = CurrentDriver()
|
||||
->AsAudioCallbackDriver()
|
||||
->AudioOutputLatency()
|
||||
.ToSeconds();
|
||||
} else {
|
||||
// Failure mode: return 0.0 if running on a normal thread.
|
||||
mAudioOutputLatency = 0.0;
|
||||
}
|
||||
|
||||
return mAudioOutputLatency;
|
||||
}
|
||||
|
||||
bool MediaStreamGraph::IsNonRealtime() const {
|
||||
return !static_cast<const MediaStreamGraphImpl*>(this)->mRealtime;
|
||||
}
|
||||
|
|
|
@ -1272,6 +1272,8 @@ class MediaStreamGraph {
|
|||
*/
|
||||
TrackRate GraphRate() const { return mSampleRate; }
|
||||
|
||||
double AudioOutputLatency();
|
||||
|
||||
void RegisterCaptureStreamForWindow(uint64_t aWindowId,
|
||||
ProcessedMediaStream* aCaptureStream);
|
||||
void UnregisterCaptureStreamForWindow(uint64_t aWindowId);
|
||||
|
|
|
@ -453,6 +453,8 @@ class MediaStreamGraphImpl : public MediaStreamGraph,
|
|||
|
||||
uint32_t AudioOutputChannelCount() const { return mOutputChannels; }
|
||||
|
||||
double AudioOutputLatency();
|
||||
|
||||
/**
|
||||
* The audio input channel count for a MediaStreamGraph is the max of all the
|
||||
* channel counts requested by the listeners. The max channel count is
|
||||
|
@ -950,6 +952,12 @@ class MediaStreamGraphImpl : public MediaStreamGraph,
|
|||
* Read by stable state runnable on main thread. Protected by mMonitor.
|
||||
*/
|
||||
GraphTime mNextMainThreadGraphTime = 0;
|
||||
|
||||
/**
|
||||
* Cached audio output latency, in seconds. Main thread only. This is reset
|
||||
* whenever the audio device running this MediaStreamGraph changes.
|
||||
*/
|
||||
double mAudioOutputLatency;
|
||||
};
|
||||
|
||||
} // namespace mozilla
|
||||
|
|
|
@ -36,6 +36,7 @@
|
|||
#include "mozilla/dom/OscillatorNodeBinding.h"
|
||||
#include "mozilla/dom/PannerNodeBinding.h"
|
||||
#include "mozilla/dom/PeriodicWaveBinding.h"
|
||||
#include "mozilla/dom/Performance.h"
|
||||
#include "mozilla/dom/Promise.h"
|
||||
#include "mozilla/dom/StereoPannerNodeBinding.h"
|
||||
#include "mozilla/dom/WaveShaperNodeBinding.h"
|
||||
|
@ -523,6 +524,48 @@ AudioListener* AudioContext::Listener() {
|
|||
return mListener;
|
||||
}
|
||||
|
||||
double AudioContext::OutputLatency() {
|
||||
// When reduceFingerprinting is enabled, return a latency figure that is
|
||||
// fixed, but plausible for the platform.
|
||||
double latency_s = 0.0;
|
||||
if (nsRFPService::IsResistFingerprintingEnabled()) {
|
||||
#ifdef XP_MACOSX
|
||||
latency_s = 512. / mSampleRate;
|
||||
#elif MOZ_WIDGET_ANDROID
|
||||
latency_s = 0.020;
|
||||
#elif XP_WIN
|
||||
latency_s = 0.04;
|
||||
#else // Catchall for other OSes, including Linux.
|
||||
latency_s = 0.025;
|
||||
#endif
|
||||
} else {
|
||||
return Graph()->AudioOutputLatency();
|
||||
}
|
||||
return latency_s;
|
||||
}
|
||||
|
||||
void AudioContext::GetOutputTimestamp(AudioTimestamp& aTimeStamp) {
|
||||
if (!Destination()) {
|
||||
aTimeStamp.mContextTime.Construct(0.0);
|
||||
aTimeStamp.mPerformanceTime.Construct(0.0);
|
||||
return;
|
||||
}
|
||||
|
||||
// The currentTime currently being output is the currentTime minus the audio
|
||||
// output latency. The resolution of CurrentTime() is already reduced.
|
||||
aTimeStamp.mContextTime.Construct(
|
||||
std::max(0.0, CurrentTime() - OutputLatency()));
|
||||
nsPIDOMWindowInner* parent = GetParentObject();
|
||||
Performance* perf = parent ? parent->GetPerformance() : nullptr;
|
||||
if (perf) {
|
||||
// perf->Now() already has reduced resolution here, no need to do it again.
|
||||
aTimeStamp.mPerformanceTime.Construct(
|
||||
std::max(0., perf->Now() - (OutputLatency() * 1000.)));
|
||||
} else {
|
||||
aTimeStamp.mPerformanceTime.Construct(0.0);
|
||||
}
|
||||
}
|
||||
|
||||
Worklet* AudioContext::GetAudioWorklet(ErrorResult& aRv) {
|
||||
if (!mWorklet) {
|
||||
mWorklet = AudioWorkletImpl::CreateWorklet(this, aRv);
|
||||
|
@ -530,7 +573,6 @@ Worklet* AudioContext::GetAudioWorklet(ErrorResult& aRv) {
|
|||
|
||||
return mWorklet;
|
||||
}
|
||||
|
||||
bool AudioContext::IsRunning() const {
|
||||
return mAudioContextState == AudioContextState::Running;
|
||||
}
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
|
||||
#include "AudioParamDescriptorMap.h"
|
||||
#include "mozilla/dom/OfflineAudioContextBinding.h"
|
||||
#include "mozilla/dom/AudioContextBinding.h"
|
||||
#include "MediaBufferDecoder.h"
|
||||
#include "mozilla/Attributes.h"
|
||||
#include "mozilla/DOMEventTargetHelper.h"
|
||||
|
@ -192,6 +193,16 @@ class AudioContext final : public DOMEventTargetHelper,
|
|||
|
||||
AudioContextState State() const { return mAudioContextState; }
|
||||
|
||||
double BaseLatency() const {
|
||||
// Gecko does not do any buffering between rendering the audio and sending
|
||||
// it to the audio subsystem.
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
double OutputLatency();
|
||||
|
||||
void GetOutputTimestamp(AudioTimestamp& aTimeStamp);
|
||||
|
||||
Worklet* GetAudioWorklet(ErrorResult& aRv);
|
||||
|
||||
bool IsRunning() const;
|
||||
|
|
|
@ -13,8 +13,31 @@
|
|||
namespace mozilla {
|
||||
namespace dom {
|
||||
|
||||
MediaElementAudioSourceNode::MediaElementAudioSourceNode(AudioContext* aContext)
|
||||
: MediaStreamAudioSourceNode(aContext, TrackChangeBehavior::FollowChanges) {
|
||||
NS_IMPL_CYCLE_COLLECTION_CLASS(MediaElementAudioSourceNode)
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(MediaElementAudioSourceNode)
|
||||
tmp->Destroy();
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK(mElement)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_END_INHERITED(AudioNode)
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(MediaElementAudioSourceNode,
|
||||
MediaStreamAudioSourceNode)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mElement)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
|
||||
|
||||
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(MediaElementAudioSourceNode)
|
||||
NS_INTERFACE_MAP_END_INHERITING(MediaStreamAudioSourceNode)
|
||||
|
||||
NS_IMPL_ADDREF_INHERITED(MediaElementAudioSourceNode,
|
||||
MediaStreamAudioSourceNode)
|
||||
NS_IMPL_RELEASE_INHERITED(MediaElementAudioSourceNode,
|
||||
MediaStreamAudioSourceNode)
|
||||
|
||||
MediaElementAudioSourceNode::MediaElementAudioSourceNode(
|
||||
AudioContext* aContext, HTMLMediaElement* aElement)
|
||||
: MediaStreamAudioSourceNode(aContext, TrackChangeBehavior::FollowChanges),
|
||||
mElement(aElement) {
|
||||
MOZ_ASSERT(aElement);
|
||||
}
|
||||
|
||||
/* static */
|
||||
|
@ -28,7 +51,7 @@ MediaElementAudioSourceNode::Create(
|
|||
}
|
||||
|
||||
RefPtr<MediaElementAudioSourceNode> node =
|
||||
new MediaElementAudioSourceNode(&aAudioContext);
|
||||
new MediaElementAudioSourceNode(&aAudioContext, aOptions.mMediaElement);
|
||||
|
||||
RefPtr<DOMMediaStream> stream = aOptions.mMediaElement->CaptureAudio(
|
||||
aRv, aAudioContext.Destination()->Stream()->Graph());
|
||||
|
@ -71,5 +94,9 @@ void MediaElementAudioSourceNode::Destroy() {
|
|||
MediaStreamAudioSourceNode::Destroy();
|
||||
}
|
||||
|
||||
HTMLMediaElement* MediaElementAudioSourceNode::MediaElement() {
|
||||
return mElement;
|
||||
}
|
||||
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
||||
|
|
|
@ -17,6 +17,9 @@ struct MediaElementAudioSourceOptions;
|
|||
|
||||
class MediaElementAudioSourceNode final : public MediaStreamAudioSourceNode {
|
||||
public:
|
||||
NS_DECL_ISUPPORTS_INHERITED
|
||||
NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(MediaElementAudioSourceNode,
|
||||
MediaStreamAudioSourceNode)
|
||||
static already_AddRefed<MediaElementAudioSourceNode> Create(
|
||||
AudioContext& aAudioContext,
|
||||
const MediaElementAudioSourceOptions& aOptions, ErrorResult& aRv);
|
||||
|
@ -42,8 +45,12 @@ class MediaElementAudioSourceNode final : public MediaStreamAudioSourceNode {
|
|||
return aMallocSizeOf(this) + SizeOfExcludingThis(aMallocSizeOf);
|
||||
}
|
||||
|
||||
HTMLMediaElement* MediaElement();
|
||||
|
||||
private:
|
||||
explicit MediaElementAudioSourceNode(AudioContext* aContext);
|
||||
explicit MediaElementAudioSourceNode(AudioContext* aContext,
|
||||
HTMLMediaElement* aElement);
|
||||
~MediaElementAudioSourceNode() = default;
|
||||
|
||||
void Destroy() override;
|
||||
|
||||
|
@ -52,6 +59,8 @@ class MediaElementAudioSourceNode final : public MediaStreamAudioSourceNode {
|
|||
void ListenForAllowedToPlay(const MediaElementAudioSourceOptions& aOptions);
|
||||
|
||||
MozPromiseRequestHolder<GenericNonExclusivePromise> mAllowedToPlayRequest;
|
||||
|
||||
RefPtr<HTMLMediaElement> mElement;
|
||||
};
|
||||
|
||||
} // namespace dom
|
||||
|
|
|
@ -65,6 +65,8 @@ class MediaStreamAudioSourceNode
|
|||
|
||||
uint16_t NumberOfInputs() const override { return 0; }
|
||||
|
||||
DOMMediaStream* GetMediaStream() { return mInputStream; }
|
||||
|
||||
const char* NodeType() const override { return "MediaStreamAudioSourceNode"; }
|
||||
|
||||
virtual const char* CrossOriginErrorString() const {
|
||||
|
|
|
@ -997,7 +997,7 @@ Notification::~Notification() {
|
|||
mData.setUndefined();
|
||||
mozilla::DropJSObjects(this);
|
||||
AssertIsOnTargetThread();
|
||||
MOZ_ASSERT(!mWorkerHolder);
|
||||
MOZ_ASSERT(!mWorkerRef);
|
||||
MOZ_ASSERT(!mTempRef);
|
||||
}
|
||||
|
||||
|
@ -2054,10 +2054,10 @@ void Notification::InitFromBase64(const nsAString& aData, ErrorResult& aRv) {
|
|||
|
||||
bool Notification::AddRefObject() {
|
||||
AssertIsOnTargetThread();
|
||||
MOZ_ASSERT_IF(mWorkerPrivate && !mWorkerHolder, mTaskCount == 0);
|
||||
MOZ_ASSERT_IF(mWorkerPrivate && mWorkerHolder, mTaskCount > 0);
|
||||
if (mWorkerPrivate && !mWorkerHolder) {
|
||||
if (!RegisterWorkerHolder()) {
|
||||
MOZ_ASSERT_IF(mWorkerPrivate && !mWorkerRef, mTaskCount == 0);
|
||||
MOZ_ASSERT_IF(mWorkerPrivate && mWorkerRef, mTaskCount > 0);
|
||||
if (mWorkerPrivate && !mWorkerRef) {
|
||||
if (!CreateWorkerRef()) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -2069,21 +2069,16 @@ bool Notification::AddRefObject() {
|
|||
void Notification::ReleaseObject() {
|
||||
AssertIsOnTargetThread();
|
||||
MOZ_ASSERT(mTaskCount > 0);
|
||||
MOZ_ASSERT_IF(mWorkerPrivate, mWorkerHolder);
|
||||
MOZ_ASSERT_IF(mWorkerPrivate, mWorkerRef);
|
||||
|
||||
--mTaskCount;
|
||||
if (mWorkerPrivate && mTaskCount == 0) {
|
||||
UnregisterWorkerHolder();
|
||||
MOZ_ASSERT(mWorkerRef);
|
||||
mWorkerRef = nullptr;
|
||||
}
|
||||
Release();
|
||||
}
|
||||
|
||||
NotificationWorkerHolder::NotificationWorkerHolder(Notification* aNotification)
|
||||
: WorkerHolder("NotificationWorkerHolder"), mNotification(aNotification) {
|
||||
MOZ_ASSERT(mNotification->mWorkerPrivate);
|
||||
mNotification->mWorkerPrivate->AssertIsOnWorkerThread();
|
||||
}
|
||||
|
||||
/*
|
||||
* Called from the worker, runs on main thread, blocks worker.
|
||||
*
|
||||
|
@ -2116,66 +2111,57 @@ class CloseNotificationRunnable final : public WorkerMainThreadRunnable {
|
|||
bool HadObserver() { return mHadObserver; }
|
||||
};
|
||||
|
||||
bool NotificationWorkerHolder::Notify(WorkerStatus aStatus) {
|
||||
if (aStatus >= Canceling) {
|
||||
// CloseNotificationRunnable blocks the worker by pushing a sync event loop
|
||||
// on the stack. Meanwhile, WorkerControlRunnables dispatched to the worker
|
||||
// can still continue running. One of these is
|
||||
// ReleaseNotificationControlRunnable that releases the notification,
|
||||
// invalidating the notification and this feature. We hold this reference to
|
||||
// keep the notification valid until we are done with it.
|
||||
//
|
||||
// An example of when the control runnable could get dispatched to the
|
||||
// worker is if a Notification is created and the worker is immediately
|
||||
// closed, but there is no permission to show it so that the main thread
|
||||
// immediately drops the NotificationRef. In this case, this function blocks
|
||||
// on the main thread, but the main thread dispatches the control runnable,
|
||||
// invalidating mNotification.
|
||||
RefPtr<Notification> kungFuDeathGrip = mNotification;
|
||||
|
||||
// Dispatched to main thread, blocks on closing the Notification.
|
||||
RefPtr<CloseNotificationRunnable> r =
|
||||
new CloseNotificationRunnable(kungFuDeathGrip);
|
||||
ErrorResult rv;
|
||||
r->Dispatch(Killing, rv);
|
||||
// XXXbz I'm told throwing and returning false from here is pointless (and
|
||||
// also that doing sync stuff from here is really weird), so I guess we just
|
||||
// suppress the exception on rv, if any.
|
||||
rv.SuppressException();
|
||||
|
||||
// Only call ReleaseObject() to match the observer's NotificationRef
|
||||
// ownership (since CloseNotificationRunnable asked the observer to drop the
|
||||
// reference to the notification).
|
||||
if (r->HadObserver()) {
|
||||
kungFuDeathGrip->ReleaseObject();
|
||||
}
|
||||
|
||||
// From this point we cannot touch properties of this feature because
|
||||
// ReleaseObject() may have led to the notification going away and the
|
||||
// notification owns this feature!
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Notification::RegisterWorkerHolder() {
|
||||
bool Notification::CreateWorkerRef() {
|
||||
MOZ_ASSERT(mWorkerPrivate);
|
||||
mWorkerPrivate->AssertIsOnWorkerThread();
|
||||
MOZ_ASSERT(!mWorkerHolder);
|
||||
mWorkerHolder = MakeUnique<NotificationWorkerHolder>(this);
|
||||
if (NS_WARN_IF(!mWorkerHolder->HoldWorker(mWorkerPrivate, Canceling))) {
|
||||
MOZ_ASSERT(!mWorkerRef);
|
||||
|
||||
RefPtr<Notification> self = this;
|
||||
mWorkerRef =
|
||||
StrongWorkerRef::Create(mWorkerPrivate, "Notification", [self]() {
|
||||
// CloseNotificationRunnable blocks the worker by pushing a sync event
|
||||
// loop on the stack. Meanwhile, WorkerControlRunnables dispatched to
|
||||
// the worker can still continue running. One of these is
|
||||
// ReleaseNotificationControlRunnable that releases the notification,
|
||||
// invalidating the notification and this feature. We hold this
|
||||
// reference to keep the notification valid until we are done with it.
|
||||
//
|
||||
// An example of when the control runnable could get dispatched to the
|
||||
// worker is if a Notification is created and the worker is immediately
|
||||
// closed, but there is no permission to show it so that the main thread
|
||||
// immediately drops the NotificationRef. In this case, this function
|
||||
// blocks on the main thread, but the main thread dispatches the control
|
||||
// runnable, invalidating mNotification.
|
||||
|
||||
// Dispatched to main thread, blocks on closing the Notification.
|
||||
RefPtr<CloseNotificationRunnable> r =
|
||||
new CloseNotificationRunnable(self);
|
||||
ErrorResult rv;
|
||||
r->Dispatch(Killing, rv);
|
||||
// XXXbz I'm told throwing and returning false from here is pointless
|
||||
// (and also that doing sync stuff from here is really weird), so I
|
||||
// guess we just suppress the exception on rv, if any.
|
||||
rv.SuppressException();
|
||||
|
||||
// Only call ReleaseObject() to match the observer's NotificationRef
|
||||
// ownership (since CloseNotificationRunnable asked the observer to drop
|
||||
// the reference to the notification).
|
||||
if (r->HadObserver()) {
|
||||
self->ReleaseObject();
|
||||
}
|
||||
|
||||
// From this point we cannot touch properties of this feature because
|
||||
// ReleaseObject() may have led to the notification going away and the
|
||||
// notification owns this feature!
|
||||
});
|
||||
|
||||
if (NS_WARN_IF(!mWorkerRef)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void Notification::UnregisterWorkerHolder() {
|
||||
MOZ_ASSERT(mWorkerPrivate);
|
||||
mWorkerPrivate->AssertIsOnWorkerThread();
|
||||
MOZ_ASSERT(mWorkerHolder);
|
||||
mWorkerHolder = nullptr;
|
||||
}
|
||||
|
||||
/*
|
||||
* Checks:
|
||||
* 1) Is aWorker allowed to show a notification for scope?
|
||||
|
|
|
@ -10,7 +10,6 @@
|
|||
#include "mozilla/DOMEventTargetHelper.h"
|
||||
#include "mozilla/UniquePtr.h"
|
||||
#include "mozilla/dom/NotificationBinding.h"
|
||||
#include "mozilla/dom/WorkerHolder.h"
|
||||
|
||||
#include "nsIObserver.h"
|
||||
#include "nsISupports.h"
|
||||
|
@ -32,20 +31,9 @@ namespace dom {
|
|||
class NotificationRef;
|
||||
class WorkerNotificationObserver;
|
||||
class Promise;
|
||||
class StrongWorkerRef;
|
||||
class WorkerPrivate;
|
||||
|
||||
class Notification;
|
||||
class NotificationWorkerHolder final : public WorkerHolder {
|
||||
// Since the feature is strongly held by a Notification, it is ok to hold
|
||||
// a raw pointer here.
|
||||
Notification* mNotification;
|
||||
|
||||
public:
|
||||
explicit NotificationWorkerHolder(Notification* aNotification);
|
||||
|
||||
bool Notify(WorkerStatus aStatus) override;
|
||||
};
|
||||
|
||||
// Records telemetry probes at application startup, when a notification is
|
||||
// shown, and when the notification permission is revoked for a site.
|
||||
class NotificationTelemetryService final : public nsIObserver {
|
||||
|
@ -385,13 +373,12 @@ class Notification : public DOMEventTargetHelper,
|
|||
|
||||
bool IsTargetThread() const { return NS_IsMainThread() == !mWorkerPrivate; }
|
||||
|
||||
bool RegisterWorkerHolder();
|
||||
void UnregisterWorkerHolder();
|
||||
bool CreateWorkerRef();
|
||||
|
||||
nsresult ResolveIconAndSoundURL(nsString&, nsString&);
|
||||
|
||||
// Only used for Notifications on Workers, worker thread only.
|
||||
UniquePtr<NotificationWorkerHolder> mWorkerHolder;
|
||||
RefPtr<StrongWorkerRef> mWorkerRef;
|
||||
// Target thread only.
|
||||
uint32_t mTaskCount;
|
||||
};
|
||||
|
|
|
@ -59,26 +59,6 @@ class PerformanceEntryAdder final : public WorkerControlRunnable {
|
|||
UniquePtr<PerformanceProxyData> mData;
|
||||
};
|
||||
|
||||
class PerformanceStorageWorkerHolder final : public WorkerHolder {
|
||||
RefPtr<PerformanceStorageWorker> mStorage;
|
||||
|
||||
public:
|
||||
explicit PerformanceStorageWorkerHolder(PerformanceStorageWorker* aStorage)
|
||||
: WorkerHolder("PerformanceStorageWorkerHolder",
|
||||
WorkerHolder::AllowIdleShutdownStart),
|
||||
mStorage(aStorage) {}
|
||||
|
||||
bool Notify(WorkerStatus aStatus) override {
|
||||
if (mStorage) {
|
||||
RefPtr<PerformanceStorageWorker> storage;
|
||||
storage.swap(mStorage);
|
||||
storage->ShutdownOnWorker();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
/* static */
|
||||
|
|
|
@ -199,22 +199,12 @@ RemoteServiceWorkerContainerImpl::RemoteServiceWorkerContainerImpl()
|
|||
return;
|
||||
}
|
||||
|
||||
RefPtr<WorkerHolderToken> workerHolderToken;
|
||||
if (!NS_IsMainThread()) {
|
||||
WorkerPrivate* workerPrivate = GetCurrentThreadWorkerPrivate();
|
||||
MOZ_DIAGNOSTIC_ASSERT(workerPrivate);
|
||||
|
||||
workerHolderToken = WorkerHolderToken::Create(
|
||||
workerPrivate, Canceling, WorkerHolderToken::AllowIdleShutdownStart);
|
||||
|
||||
if (NS_WARN_IF(!workerHolderToken)) {
|
||||
Shutdown();
|
||||
return;
|
||||
}
|
||||
ServiceWorkerContainerChild* actor = ServiceWorkerContainerChild::Create();
|
||||
if (NS_WARN_IF(!actor)) {
|
||||
Shutdown();
|
||||
return;
|
||||
}
|
||||
|
||||
ServiceWorkerContainerChild* actor =
|
||||
new ServiceWorkerContainerChild(workerHolderToken);
|
||||
PServiceWorkerContainerChild* sentActor =
|
||||
parentActor->SendPServiceWorkerContainerConstructor(actor);
|
||||
if (NS_WARN_IF(!sentActor)) {
|
||||
|
|
|
@ -85,21 +85,12 @@ RemoteServiceWorkerImpl::RemoteServiceWorkerImpl(
|
|||
return;
|
||||
}
|
||||
|
||||
RefPtr<WorkerHolderToken> workerHolderToken;
|
||||
if (!NS_IsMainThread()) {
|
||||
WorkerPrivate* workerPrivate = GetCurrentThreadWorkerPrivate();
|
||||
MOZ_DIAGNOSTIC_ASSERT(workerPrivate);
|
||||
|
||||
workerHolderToken = WorkerHolderToken::Create(
|
||||
workerPrivate, Canceling, WorkerHolderToken::AllowIdleShutdownStart);
|
||||
|
||||
if (NS_WARN_IF(!workerHolderToken)) {
|
||||
Shutdown();
|
||||
return;
|
||||
}
|
||||
ServiceWorkerChild* actor = ServiceWorkerChild::Create();
|
||||
if (NS_WARN_IF(!actor)) {
|
||||
Shutdown();
|
||||
return;
|
||||
}
|
||||
|
||||
ServiceWorkerChild* actor = new ServiceWorkerChild(workerHolderToken);
|
||||
PServiceWorkerChild* sentActor =
|
||||
parentActor->SendPServiceWorkerConstructor(actor, aDescriptor.ToIPC());
|
||||
if (NS_WARN_IF(!sentActor)) {
|
||||
|
|
|
@ -114,22 +114,13 @@ RemoteServiceWorkerRegistrationImpl::RemoteServiceWorkerRegistrationImpl(
|
|||
return;
|
||||
}
|
||||
|
||||
RefPtr<WorkerHolderToken> workerHolderToken;
|
||||
if (!NS_IsMainThread()) {
|
||||
WorkerPrivate* workerPrivate = GetCurrentThreadWorkerPrivate();
|
||||
MOZ_DIAGNOSTIC_ASSERT(workerPrivate);
|
||||
|
||||
workerHolderToken = WorkerHolderToken::Create(
|
||||
workerPrivate, Canceling, WorkerHolderToken::AllowIdleShutdownStart);
|
||||
|
||||
if (NS_WARN_IF(!workerHolderToken)) {
|
||||
Shutdown();
|
||||
return;
|
||||
}
|
||||
ServiceWorkerRegistrationChild* actor =
|
||||
ServiceWorkerRegistrationChild::Create();
|
||||
if (NS_WARN_IF(!actor)) {
|
||||
Shutdown();
|
||||
return;
|
||||
}
|
||||
|
||||
ServiceWorkerRegistrationChild* actor =
|
||||
new ServiceWorkerRegistrationChild(workerHolderToken);
|
||||
PServiceWorkerRegistrationChild* sentActor =
|
||||
parentActor->SendPServiceWorkerRegistrationConstructor(
|
||||
actor, aDescriptor.ToIPC());
|
||||
|
|
|
@ -5,15 +5,13 @@
|
|||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "ServiceWorkerChild.h"
|
||||
#include "mozilla/dom/WorkerRef.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
|
||||
void ServiceWorkerChild::ActorDestroy(ActorDestroyReason aReason) {
|
||||
if (mWorkerHolderToken) {
|
||||
mWorkerHolderToken->RemoveListener(this);
|
||||
mWorkerHolderToken = nullptr;
|
||||
}
|
||||
mIPCWorkerRef = nullptr;
|
||||
|
||||
if (mOwner) {
|
||||
mOwner->RevokeActor(this);
|
||||
|
@ -21,17 +19,33 @@ void ServiceWorkerChild::ActorDestroy(ActorDestroyReason aReason) {
|
|||
}
|
||||
}
|
||||
|
||||
void ServiceWorkerChild::WorkerShuttingDown() { MaybeStartTeardown(); }
|
||||
// static
|
||||
ServiceWorkerChild* ServiceWorkerChild::Create() {
|
||||
ServiceWorkerChild* actor = new ServiceWorkerChild();
|
||||
|
||||
ServiceWorkerChild::ServiceWorkerChild(WorkerHolderToken* aWorkerHolderToken)
|
||||
: mWorkerHolderToken(aWorkerHolderToken),
|
||||
mOwner(nullptr),
|
||||
mTeardownStarted(false) {
|
||||
if (mWorkerHolderToken) {
|
||||
mWorkerHolderToken->AddListener(this);
|
||||
if (!NS_IsMainThread()) {
|
||||
WorkerPrivate* workerPrivate = GetCurrentThreadWorkerPrivate();
|
||||
MOZ_DIAGNOSTIC_ASSERT(workerPrivate);
|
||||
|
||||
RefPtr<IPCWorkerRefHelper<ServiceWorkerChild>> helper =
|
||||
new IPCWorkerRefHelper<ServiceWorkerChild>(actor);
|
||||
|
||||
actor->mIPCWorkerRef = IPCWorkerRef::Create(
|
||||
workerPrivate, "ServiceWorkerChild",
|
||||
[helper] { helper->Actor()->MaybeStartTeardown(); });
|
||||
|
||||
if (NS_WARN_IF(!actor->mIPCWorkerRef)) {
|
||||
delete actor;
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
return actor;
|
||||
}
|
||||
|
||||
ServiceWorkerChild::ServiceWorkerChild()
|
||||
: mOwner(nullptr), mTeardownStarted(false) {}
|
||||
|
||||
void ServiceWorkerChild::SetOwner(RemoteServiceWorkerImpl* aOwner) {
|
||||
MOZ_DIAGNOSTIC_ASSERT(!mOwner);
|
||||
MOZ_DIAGNOSTIC_ASSERT(aOwner);
|
||||
|
|
|
@ -8,27 +8,26 @@
|
|||
#define mozilla_dom_serviceworkerchild_h__
|
||||
|
||||
#include "mozilla/dom/PServiceWorkerChild.h"
|
||||
#include "mozilla/dom/WorkerHolderToken.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
|
||||
class IPCWorkerRef;
|
||||
class RemoteServiceWorkerImpl;
|
||||
|
||||
class ServiceWorkerChild final : public PServiceWorkerChild,
|
||||
public WorkerHolderToken::Listener {
|
||||
RefPtr<WorkerHolderToken> mWorkerHolderToken;
|
||||
class ServiceWorkerChild final : public PServiceWorkerChild {
|
||||
RefPtr<IPCWorkerRef> mIPCWorkerRef;
|
||||
RemoteServiceWorkerImpl* mOwner;
|
||||
bool mTeardownStarted;
|
||||
|
||||
ServiceWorkerChild();
|
||||
|
||||
// PServiceWorkerChild
|
||||
void ActorDestroy(ActorDestroyReason aReason) override;
|
||||
|
||||
// WorkerHolderToken::Listener
|
||||
void WorkerShuttingDown() override;
|
||||
|
||||
public:
|
||||
explicit ServiceWorkerChild(WorkerHolderToken* aWorkerHolderToken);
|
||||
static ServiceWorkerChild* Create();
|
||||
|
||||
~ServiceWorkerChild() = default;
|
||||
|
||||
void SetOwner(RemoteServiceWorkerImpl* aOwner);
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "mozilla/dom/PServiceWorkerContainerChild.h"
|
||||
#include "mozilla/dom/WorkerRef.h"
|
||||
|
||||
#include "RemoteServiceWorkerContainerImpl.h"
|
||||
|
||||
|
@ -12,10 +13,7 @@ namespace mozilla {
|
|||
namespace dom {
|
||||
|
||||
void ServiceWorkerContainerChild::ActorDestroy(ActorDestroyReason aReason) {
|
||||
if (mWorkerHolderToken) {
|
||||
mWorkerHolderToken->RemoveListener(this);
|
||||
mWorkerHolderToken = nullptr;
|
||||
}
|
||||
mIPCWorkerRef = nullptr;
|
||||
|
||||
if (mOwner) {
|
||||
mOwner->RevokeActor(this);
|
||||
|
@ -23,18 +21,32 @@ void ServiceWorkerContainerChild::ActorDestroy(ActorDestroyReason aReason) {
|
|||
}
|
||||
}
|
||||
|
||||
void ServiceWorkerContainerChild::WorkerShuttingDown() { MaybeStartTeardown(); }
|
||||
// static
|
||||
ServiceWorkerContainerChild* ServiceWorkerContainerChild::Create() {
|
||||
ServiceWorkerContainerChild* actor = new ServiceWorkerContainerChild();
|
||||
|
||||
ServiceWorkerContainerChild::ServiceWorkerContainerChild(
|
||||
WorkerHolderToken* aWorkerHolderToken)
|
||||
: mWorkerHolderToken(aWorkerHolderToken),
|
||||
mOwner(nullptr),
|
||||
mTeardownStarted(false) {
|
||||
if (mWorkerHolderToken) {
|
||||
mWorkerHolderToken->AddListener(this);
|
||||
if (!NS_IsMainThread()) {
|
||||
WorkerPrivate* workerPrivate = GetCurrentThreadWorkerPrivate();
|
||||
MOZ_DIAGNOSTIC_ASSERT(workerPrivate);
|
||||
|
||||
RefPtr<IPCWorkerRefHelper<ServiceWorkerContainerChild>> helper =
|
||||
new IPCWorkerRefHelper<ServiceWorkerContainerChild>(actor);
|
||||
|
||||
actor->mIPCWorkerRef = IPCWorkerRef::Create(
|
||||
workerPrivate, "ServiceWorkerContainerChild",
|
||||
[helper] { helper->Actor()->MaybeStartTeardown(); });
|
||||
if (NS_WARN_IF(!actor->mIPCWorkerRef)) {
|
||||
delete actor;
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
return actor;
|
||||
}
|
||||
|
||||
ServiceWorkerContainerChild::ServiceWorkerContainerChild()
|
||||
: mOwner(nullptr), mTeardownStarted(false) {}
|
||||
|
||||
void ServiceWorkerContainerChild::SetOwner(
|
||||
RemoteServiceWorkerContainerImpl* aOwner) {
|
||||
MOZ_DIAGNOSTIC_ASSERT(!mOwner);
|
||||
|
|
|
@ -8,25 +8,25 @@
|
|||
#define mozilla_dom_serviceworkercontainerchild_h__
|
||||
|
||||
#include "mozilla/dom/PServiceWorkerContainerChild.h"
|
||||
#include "mozilla/dom/WorkerHolderToken.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
|
||||
class ServiceWorkerContainerChild final : public PServiceWorkerContainerChild,
|
||||
public WorkerHolderToken::Listener {
|
||||
RefPtr<WorkerHolderToken> mWorkerHolderToken;
|
||||
class IPCWorkerRef;
|
||||
|
||||
class ServiceWorkerContainerChild final : public PServiceWorkerContainerChild {
|
||||
RefPtr<IPCWorkerRef> mIPCWorkerRef;
|
||||
RemoteServiceWorkerContainerImpl* mOwner;
|
||||
bool mTeardownStarted;
|
||||
|
||||
ServiceWorkerContainerChild();
|
||||
|
||||
// PServiceWorkerContainerChild
|
||||
void ActorDestroy(ActorDestroyReason aReason) override;
|
||||
|
||||
// WorkerHolderToken::Listener
|
||||
void WorkerShuttingDown() override;
|
||||
|
||||
public:
|
||||
explicit ServiceWorkerContainerChild(WorkerHolderToken* aWorkerHolderToken);
|
||||
static ServiceWorkerContainerChild* Create();
|
||||
|
||||
~ServiceWorkerContainerChild() = default;
|
||||
|
||||
void SetOwner(RemoteServiceWorkerContainerImpl* aOwner);
|
||||
|
|
|
@ -14,10 +14,7 @@ namespace dom {
|
|||
using mozilla::ipc::IPCResult;
|
||||
|
||||
void ServiceWorkerRegistrationChild::ActorDestroy(ActorDestroyReason aReason) {
|
||||
if (mWorkerHolderToken) {
|
||||
mWorkerHolderToken->RemoveListener(this);
|
||||
mWorkerHolderToken = nullptr;
|
||||
}
|
||||
mIPCWorkerRef = nullptr;
|
||||
|
||||
if (mOwner) {
|
||||
mOwner->RevokeActor(this);
|
||||
|
@ -40,19 +37,32 @@ IPCResult ServiceWorkerRegistrationChild::RecvFireUpdateFound() {
|
|||
return IPC_OK();
|
||||
}
|
||||
|
||||
void ServiceWorkerRegistrationChild::WorkerShuttingDown() {
|
||||
MaybeStartTeardown();
|
||||
// static
|
||||
ServiceWorkerRegistrationChild* ServiceWorkerRegistrationChild::Create() {
|
||||
ServiceWorkerRegistrationChild* actor = new ServiceWorkerRegistrationChild();
|
||||
|
||||
if (!NS_IsMainThread()) {
|
||||
WorkerPrivate* workerPrivate = GetCurrentThreadWorkerPrivate();
|
||||
MOZ_DIAGNOSTIC_ASSERT(workerPrivate);
|
||||
|
||||
RefPtr<IPCWorkerRefHelper<ServiceWorkerRegistrationChild>> helper =
|
||||
new IPCWorkerRefHelper<ServiceWorkerRegistrationChild>(actor);
|
||||
|
||||
actor->mIPCWorkerRef = IPCWorkerRef::Create(
|
||||
workerPrivate, "ServiceWorkerRegistrationChild",
|
||||
[helper] { helper->Actor()->MaybeStartTeardown(); });
|
||||
|
||||
if (NS_WARN_IF(!actor->mIPCWorkerRef)) {
|
||||
delete actor;
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
return actor;
|
||||
}
|
||||
|
||||
ServiceWorkerRegistrationChild::ServiceWorkerRegistrationChild(
|
||||
WorkerHolderToken* aWorkerHolderToken)
|
||||
: mWorkerHolderToken(aWorkerHolderToken),
|
||||
mOwner(nullptr),
|
||||
mTeardownStarted(false) {
|
||||
if (mWorkerHolderToken) {
|
||||
mWorkerHolderToken->AddListener(this);
|
||||
}
|
||||
}
|
||||
ServiceWorkerRegistrationChild::ServiceWorkerRegistrationChild()
|
||||
: mOwner(nullptr), mTeardownStarted(false) {}
|
||||
|
||||
void ServiceWorkerRegistrationChild::SetOwner(
|
||||
RemoteServiceWorkerRegistrationImpl* aOwner) {
|
||||
|
|
|
@ -8,20 +8,21 @@
|
|||
#define mozilla_dom_serviceworkerregistrationchild_h__
|
||||
|
||||
#include "mozilla/dom/PServiceWorkerRegistrationChild.h"
|
||||
#include "mozilla/dom/WorkerHolderToken.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
|
||||
class IPCWorkerRef;
|
||||
class RemoteServiceWorkerRegistrationImpl;
|
||||
|
||||
class ServiceWorkerRegistrationChild final
|
||||
: public PServiceWorkerRegistrationChild,
|
||||
public WorkerHolderToken::Listener {
|
||||
RefPtr<WorkerHolderToken> mWorkerHolderToken;
|
||||
: public PServiceWorkerRegistrationChild {
|
||||
RefPtr<IPCWorkerRef> mIPCWorkerRef;
|
||||
RemoteServiceWorkerRegistrationImpl* mOwner;
|
||||
bool mTeardownStarted;
|
||||
|
||||
ServiceWorkerRegistrationChild();
|
||||
|
||||
// PServiceWorkerRegistrationChild
|
||||
void ActorDestroy(ActorDestroyReason aReason) override;
|
||||
|
||||
|
@ -30,12 +31,9 @@ class ServiceWorkerRegistrationChild final
|
|||
|
||||
mozilla::ipc::IPCResult RecvFireUpdateFound() override;
|
||||
|
||||
// WorkerHolderToken::Listener
|
||||
void WorkerShuttingDown() override;
|
||||
|
||||
public:
|
||||
explicit ServiceWorkerRegistrationChild(
|
||||
WorkerHolderToken* aWorkerHolderToken);
|
||||
static ServiceWorkerRegistrationChild* Create();
|
||||
|
||||
~ServiceWorkerRegistrationChild() = default;
|
||||
|
||||
void SetOwner(RemoteServiceWorkerRegistrationImpl* aOwner);
|
||||
|
|
|
@ -14,12 +14,18 @@ dictionary AudioContextOptions {
|
|||
float sampleRate = 0;
|
||||
};
|
||||
|
||||
dictionary AudioTimestamp {
|
||||
double contextTime;
|
||||
DOMHighResTimeStamp performanceTime;
|
||||
};
|
||||
|
||||
[Pref="dom.webaudio.enabled",
|
||||
Constructor(optional AudioContextOptions contextOptions = {})]
|
||||
interface AudioContext : BaseAudioContext {
|
||||
|
||||
// Bug 1324545: readonly attribute double outputLatency;
|
||||
// Bug 1324545: AudioTimestamp getOutputTimestamp ();
|
||||
readonly attribute double baseLatency;
|
||||
readonly attribute double outputLatency;
|
||||
AudioTimestamp getOutputTimestamp();
|
||||
|
||||
[Throws]
|
||||
Promise<void> suspend();
|
||||
|
|
|
@ -27,7 +27,6 @@ interface BaseAudioContext : EventTarget {
|
|||
readonly attribute AudioContextState state;
|
||||
[Throws, SameObject, SecureContext, Pref="dom.audioworklet.enabled"]
|
||||
readonly attribute AudioWorklet audioWorklet;
|
||||
// Bug 1324552: readonly attribute double baseLatency;
|
||||
|
||||
[Throws]
|
||||
Promise<void> resume();
|
||||
|
|
|
@ -17,7 +17,7 @@ dictionary MediaElementAudioSourceOptions {
|
|||
[Pref="dom.webaudio.enabled",
|
||||
Constructor(AudioContext context, MediaElementAudioSourceOptions options)]
|
||||
interface MediaElementAudioSourceNode : AudioNode {
|
||||
|
||||
readonly attribute HTMLMediaElement mediaElement;
|
||||
};
|
||||
|
||||
// Mozilla extensions
|
||||
|
|
|
@ -17,7 +17,8 @@ dictionary MediaStreamAudioSourceOptions {
|
|||
[Pref="dom.webaudio.enabled",
|
||||
Constructor(AudioContext context, MediaStreamAudioSourceOptions options)]
|
||||
interface MediaStreamAudioSourceNode : AudioNode {
|
||||
|
||||
[BinaryName="GetMediaStream"]
|
||||
readonly attribute MediaStream mediaStream;
|
||||
};
|
||||
|
||||
// Mozilla extensions
|
||||
|
|
|
@ -73,7 +73,6 @@
|
|||
#include "mozilla/dom/ServiceWorkerManager.h"
|
||||
#include "mozilla/UniquePtr.h"
|
||||
#include "Principal.h"
|
||||
#include "WorkerHolder.h"
|
||||
#include "WorkerPrivate.h"
|
||||
#include "WorkerRunnable.h"
|
||||
#include "WorkerScope.h"
|
||||
|
|
Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше
Загрузка…
Ссылка в новой задаче