From ed0947bbf51de86fedfacad041334284c839e1ec Mon Sep 17 00:00:00 2001 From: Matt Brubeck Date: Tue, 21 Feb 2017 10:53:38 -0800 Subject: [PATCH 01/48] servo: Merge #15676 - Update thread_local, serde_json, syn, offscreen_gl_context, quote (from mbrubeck:always-be-updating); r=SimonSapin This adds one new crate the the dependency graph, `synom`, which is part of the `syn` repo and is dual-licensed MIT/Apache-2.0. Source-Repo: https://github.com/servo/servo Source-Revision: ec5ed8edfdfac1cf0692af813217ee7e21620139 --HG-- extra : subtree_source : https%3A//hg.mozilla.org/projects/converted-servo-linear extra : subtree_revision : e475742fd3e8ca6c88eb1dba2de6beb579956fd2 --- servo/Cargo.lock | 94 ++++++++++++++++++++++++++---------------------- 1 file changed, 52 insertions(+), 42 deletions(-) diff --git a/servo/Cargo.lock b/servo/Cargo.lock index c1e574396acf..9ee6cb8a9890 100644 --- a/servo/Cargo.lock +++ b/servo/Cargo.lock @@ -154,7 +154,7 @@ dependencies = [ "cexpr 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "cfg-if 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "clang-sys 0.14.0 (registry+https://github.com/rust-lang/crates.io-index)", - "clap 2.20.4 (registry+https://github.com/rust-lang/crates.io-index)", + "clap 2.20.5 (registry+https://github.com/rust-lang/crates.io-index)", "env_logger 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", @@ -281,7 +281,7 @@ dependencies = [ "ipc-channel 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", "num-traits 0.1.36 (registry+https://github.com/rust-lang/crates.io-index)", - "offscreen_gl_context 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", + "offscreen_gl_context 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", "servo_config 0.0.1", "webrender_traits 0.16.0 (git+https://github.com/servo/webrender)", ] @@ -345,14 +345,14 @@ dependencies = [ [[package]] name = "clap" -version = "2.20.4" +version = "2.20.5" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "ansi_term 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", "bitflags 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.20 (registry+https://github.com/rust-lang/crates.io-index)", "strsim 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", - "term_size 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", + "term_size 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", "unicode-segmentation 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "unicode-width 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", "vec_map 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -442,7 +442,7 @@ dependencies = [ "log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", "msg 0.0.1", "net_traits 0.0.1", - "offscreen_gl_context 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", + "offscreen_gl_context 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", "profile_traits 0.0.1", "script_traits 0.0.1", "serde 0.9.7 (registry+https://github.com/rust-lang/crates.io-index)", @@ -462,7 +462,7 @@ version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "regex 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 0.9.6 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 0.9.7 (registry+https://github.com/rust-lang/crates.io-index)", "url 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -521,7 +521,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "heapsize 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", "matches 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", - "quote 0.3.12 (registry+https://github.com/rust-lang/crates.io-index)", + "quote 0.3.13 (registry+https://github.com/rust-lang/crates.io-index)", "serde 0.9.7 (registry+https://github.com/rust-lang/crates.io-index)", "syn 0.10.8 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -608,7 +608,7 @@ dependencies = [ "msg 0.0.1", "serde 0.9.7 (registry+https://github.com/rust-lang/crates.io-index)", "serde_derive 0.9.7 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 0.9.6 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 0.9.7 (registry+https://github.com/rust-lang/crates.io-index)", "time 0.1.36 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -633,7 +633,7 @@ dependencies = [ name = "domobject_derive" version = "0.0.1" dependencies = [ - "quote 0.3.12 (registry+https://github.com/rust-lang/crates.io-index)", + "quote 0.3.13 (registry+https://github.com/rust-lang/crates.io-index)", "syn 0.10.8 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1075,7 +1075,7 @@ name = "heapsize_derive" version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "quote 0.3.12 (registry+https://github.com/rust-lang/crates.io-index)", + "quote 0.3.13 (registry+https://github.com/rust-lang/crates.io-index)", "syn 0.10.8 (registry+https://github.com/rust-lang/crates.io-index)", "synstructure 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1119,7 +1119,7 @@ dependencies = [ "mac 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "phf 0.7.21 (registry+https://github.com/rust-lang/crates.io-index)", "phf_codegen 0.7.21 (registry+https://github.com/rust-lang/crates.io-index)", - "quote 0.3.12 (registry+https://github.com/rust-lang/crates.io-index)", + "quote 0.3.13 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-serialize 0.3.22 (registry+https://github.com/rust-lang/crates.io-index)", "syn 0.10.8 (registry+https://github.com/rust-lang/crates.io-index)", "tendril 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1275,7 +1275,7 @@ dependencies = [ name = "jstraceable_derive" version = "0.0.1" dependencies = [ - "quote 0.3.12 (registry+https://github.com/rust-lang/crates.io-index)", + "quote 0.3.13 (registry+https://github.com/rust-lang/crates.io-index)", "syn 0.10.8 (registry+https://github.com/rust-lang/crates.io-index)", "synstructure 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1329,7 +1329,7 @@ dependencies = [ "selectors 0.18.0", "serde 0.9.7 (registry+https://github.com/rust-lang/crates.io-index)", "serde_derive 0.9.7 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 0.9.6 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 0.9.7 (registry+https://github.com/rust-lang/crates.io-index)", "servo_config 0.0.1", "servo_geometry 0.0.1", "servo_url 0.0.1", @@ -1373,7 +1373,7 @@ dependencies = [ "script_traits 0.0.1", "selectors 0.18.0", "serde_derive 0.9.7 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 0.9.6 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 0.9.7 (registry+https://github.com/rust-lang/crates.io-index)", "servo_config 0.0.1", "servo_geometry 0.0.1", "servo_url 0.0.1", @@ -1801,7 +1801,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "offscreen_gl_context" -version = "0.6.0" +version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "cgl 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2020,7 +2020,7 @@ dependencies = [ "regex 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "serde 0.9.7 (registry+https://github.com/rust-lang/crates.io-index)", "serde_derive 0.9.7 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 0.9.6 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 0.9.7 (registry+https://github.com/rust-lang/crates.io-index)", "servo_config 0.0.1", "task_info 0.0.1", "time 0.1.36 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2072,7 +2072,7 @@ dependencies = [ [[package]] name = "quote" -version = "0.3.12" +version = "0.3.13" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -2128,7 +2128,7 @@ dependencies = [ "aho-corasick 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", "memchr 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", "regex-syntax 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "thread_local 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", + "thread_local 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", "utf8-ranges 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -2221,7 +2221,7 @@ dependencies = [ "msg 0.0.1", "net_traits 0.0.1", "num-traits 0.1.36 (registry+https://github.com/rust-lang/crates.io-index)", - "offscreen_gl_context 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", + "offscreen_gl_context 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", "open 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", "phf 0.7.21 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2238,7 +2238,7 @@ dependencies = [ "script_traits 0.0.1", "selectors 0.18.0", "serde 0.9.7 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 0.9.6 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 0.9.7 (registry+https://github.com/rust-lang/crates.io-index)", "servo_atoms 0.0.1", "servo_config 0.0.1", "servo_geometry 0.0.1", @@ -2317,7 +2317,7 @@ dependencies = [ "libc 0.2.20 (registry+https://github.com/rust-lang/crates.io-index)", "msg 0.0.1", "net_traits 0.0.1", - "offscreen_gl_context 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", + "offscreen_gl_context 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", "profile_traits 0.0.1", "rustc-serialize 0.3.22 (registry+https://github.com/rust-lang/crates.io-index)", "serde 0.9.7 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2354,7 +2354,7 @@ name = "serde_codegen" version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "quote 0.3.12 (registry+https://github.com/rust-lang/crates.io-index)", + "quote 0.3.13 (registry+https://github.com/rust-lang/crates.io-index)", "serde_codegen_internals 0.11.3 (registry+https://github.com/rust-lang/crates.io-index)", "syn 0.10.8 (registry+https://github.com/rust-lang/crates.io-index)", "syntex 0.54.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2374,7 +2374,7 @@ name = "serde_codegen_internals" version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "syn 0.11.4 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 0.11.6 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -2382,14 +2382,14 @@ name = "serde_derive" version = "0.9.7" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "quote 0.3.12 (registry+https://github.com/rust-lang/crates.io-index)", + "quote 0.3.13 (registry+https://github.com/rust-lang/crates.io-index)", "serde_codegen_internals 0.13.0 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 0.11.4 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 0.11.6 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "serde_json" -version = "0.9.6" +version = "0.9.7" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "dtoa 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2798,16 +2798,25 @@ name = "syn" version = "0.10.8" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "quote 0.3.12 (registry+https://github.com/rust-lang/crates.io-index)", + "quote 0.3.13 (registry+https://github.com/rust-lang/crates.io-index)", "unicode-xid 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "syn" -version = "0.11.4" +version = "0.11.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "quote 0.3.13 (registry+https://github.com/rust-lang/crates.io-index)", + "synom 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", + "unicode-xid 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "synom" +version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "quote 0.3.12 (registry+https://github.com/rust-lang/crates.io-index)", "unicode-xid 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -2816,7 +2825,7 @@ name = "synstructure" version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "quote 0.3.12 (registry+https://github.com/rust-lang/crates.io-index)", + "quote 0.3.13 (registry+https://github.com/rust-lang/crates.io-index)", "syn 0.10.8 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -2872,7 +2881,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "phf 0.7.21 (registry+https://github.com/rust-lang/crates.io-index)", "phf_codegen 0.7.21 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 0.9.6 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 0.9.7 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -2912,7 +2921,7 @@ dependencies = [ [[package]] name = "term_size" -version = "0.2.2" +version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2931,7 +2940,7 @@ dependencies = [ [[package]] name = "thread_local" -version = "0.3.2" +version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "thread-id 3.0.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -3169,7 +3178,7 @@ dependencies = [ "lazy_static 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", "num-traits 0.1.36 (registry+https://github.com/rust-lang/crates.io-index)", - "offscreen_gl_context 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", + "offscreen_gl_context 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", "servo-dwrote 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "thread_profiler 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "threadpool 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)", @@ -3189,7 +3198,7 @@ dependencies = [ "gleam 0.2.32 (registry+https://github.com/rust-lang/crates.io-index)", "heapsize 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", "ipc-channel 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", - "offscreen_gl_context 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", + "offscreen_gl_context 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", "serde 0.9.7 (registry+https://github.com/rust-lang/crates.io-index)", "serde_derive 0.9.7 (registry+https://github.com/rust-lang/crates.io-index)", "servo-dwrote 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -3345,7 +3354,7 @@ dependencies = [ "checksum cfg-if 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "de1e760d7b6535af4241fca8bd8adf68e2e7edacc6b29f5d399050c5e48cf88c" "checksum cgl 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "8bdd78cca65a739cb5475dbf6b6bbb49373e327f4a6f2b499c0f98632df38c10" "checksum clang-sys 0.14.0 (registry+https://github.com/rust-lang/crates.io-index)" = "4f98f0715ff67f27ca6a2f8f0ffc2a56f8edbc7acd57489c29eadc3a15c4eafe" -"checksum clap 2.20.4 (registry+https://github.com/rust-lang/crates.io-index)" = "a60af5cb867dd4ee2378398acde80c73b466b58a963f598061ce7e394800998d" +"checksum clap 2.20.5 (registry+https://github.com/rust-lang/crates.io-index)" = "7db281b0520e97fbd15cd615dcd8f8bcad0c26f5f7d5effe705f090f39e9a758" "checksum cmake 0.1.20 (registry+https://github.com/rust-lang/crates.io-index)" = "a3a6805df695087e7c1bcd9a82e03ad6fb864c8e67ac41b1348229ce5b7f0407" "checksum cocoa 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d55b620aff4da7d4b9d85f2974cc62a097146623b75e3f36734fe68d8cef493e" "checksum color_quant 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a475fc4af42d83d28adf72968d9bcfaf035a1a9381642d8e85d8a04957767b0d" @@ -3453,7 +3462,7 @@ dependencies = [ "checksum num_cpus 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a225d1e2717567599c24f88e49f00856c6e825a12125181ee42c4257e3688d39" "checksum objc 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "877f30f37acef6749b1841cceab289707f211aecfc756553cd63976190e6cc2e" "checksum odds 0.2.25 (registry+https://github.com/rust-lang/crates.io-index)" = "c3df9b730298cea3a1c3faa90b7e2f9df3a9c400d0936d6015e6165734eefcba" -"checksum offscreen_gl_context 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b33309fc17d50be59b466fe26a337023f297e8c9e9032ca0ccfdcdf3c0c627d0" +"checksum offscreen_gl_context 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)" = "4ac875ea951d7d695a1cc8c370777d6a0e2b7355ca49506034683df09b24b1bc" "checksum ogg 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "426d8dc59cdd206be1925461087350385c0a02f291d87625829c6d08e72b457b" "checksum ogg_metadata 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e755cc735fa6faa709cb23048433d9201d6caa85fa96215386ccdd5e9b40ad01" "checksum open 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3478ed1686bd1300c8a981a940abc92b06fac9cbef747f4c668d4e032ff7b842" @@ -3477,7 +3486,7 @@ dependencies = [ "checksum png 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "3cb773e9a557edb568ce9935cf783e3cdcabe06a9449d41b3e5506d88e582c82" "checksum quasi 0.29.0 (registry+https://github.com/rust-lang/crates.io-index)" = "dcbf815446dc6a0afbc72d88f9a8aa71b608d10b168e09437c80c0fd6fd410c9" "checksum quasi_codegen 0.29.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b06172e92ab0099427609854ffb1512c377be5fc4beaf572ae5d5a01b8359596" -"checksum quote 0.3.12 (registry+https://github.com/rust-lang/crates.io-index)" = "e7b44fd83db28b83c1c58187159934906e5e955c812e211df413b76b03c909a5" +"checksum quote 0.3.13 (registry+https://github.com/rust-lang/crates.io-index)" = "08de3f12e670f83f61e450443cbae34496a35b665691fd8e99b24ec662f75865" "checksum rand 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)" = "022e0636ec2519ddae48154b028864bdce4eaf7d35226ab8e65c611be97b189d" "checksum rayon 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "50c575b58c2b109e2fbc181820cbe177474f35610ff9e357dc75f6bac854ffbf" "checksum redox_syscall 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)" = "8dd35cc9a8bdec562c757e3d43c1526b5c6d2653e23e2315065bc25556550753" @@ -3497,7 +3506,7 @@ dependencies = [ "checksum serde_codegen_internals 0.11.3 (registry+https://github.com/rust-lang/crates.io-index)" = "afad7924a009f859f380e4a2e3a509a845c2ac66435fcead74a4d983b21ae806" "checksum serde_codegen_internals 0.13.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c3172bf2940b975c0e4f6ab42a511c0a4407d4f46ccef87a9d3615db5c26fa96" "checksum serde_derive 0.9.7 (registry+https://github.com/rust-lang/crates.io-index)" = "6af30425c5161deb200aac4803c62b903eb3be7e889c5823d0e16c4ce0ce989c" -"checksum serde_json 0.9.6 (registry+https://github.com/rust-lang/crates.io-index)" = "e095e4e94e7382b76f48e93bd845ffddda62df8dfd4c163b1bfa93d40e22e13a" +"checksum serde_json 0.9.7 (registry+https://github.com/rust-lang/crates.io-index)" = "2eb96d30e4e6f9fc52e08f51176d078b6f79b981dc3ed4134f7b850be9f446a8" "checksum servo-dwrote 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "9f013da79c3fb2a9653534b064cd2ca62e10f8b6d19ed8fdc885cb2873412789" "checksum servo-egl 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "21069a884c33fe6ee596975e1f3849ed88c4ec857fbaf11d33672d8ebe051217" "checksum servo-fontconfig 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "93f799b649b4a2bf362398910eca35240704c7e765e780349b2bb1070d892262" @@ -3520,7 +3529,8 @@ dependencies = [ "checksum string_cache_shared 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b1884d1bc09741d466d9b14e6d37ac89d6909cbcac41dd9ae982d4d063bbedfc" "checksum strsim 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b4d15c810519a91cf877e7e36e63fe068815c678181439f2f29e2562147c3694" "checksum syn 0.10.8 (registry+https://github.com/rust-lang/crates.io-index)" = "58fd09df59565db3399efbba34ba8a2fec1307511ebd245d0061ff9d42691673" -"checksum syn 0.11.4 (registry+https://github.com/rust-lang/crates.io-index)" = "f4f94368aae82bb29656c98443a7026ca931a659e8d19dcdc41d6e273054e820" +"checksum syn 0.11.6 (registry+https://github.com/rust-lang/crates.io-index)" = "0e28da8d02d75d1e58b89258e0741128f0b0d8a8309fb5c627be0fbd37a76c67" +"checksum synom 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8fece1853fb872b0acdc3ff88f37c474018e125ef81cd4cb8c0ca515746b62ed" "checksum synstructure 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a811f8e51453cada27c033be6b5fdac6e4e63981983702eb85b4c897a25ecc6c" "checksum syntex 0.54.0 (registry+https://github.com/rust-lang/crates.io-index)" = "bb3f52553a966675982404dc34028291b347e0c9a9c0b0b34f2da6be8a0443f8" "checksum syntex_errors 0.54.0 (registry+https://github.com/rust-lang/crates.io-index)" = "dee2f6e49c075f71332bb775219d5982bee6732d26227fa1ae1b53cdb12f5cc5" @@ -3530,9 +3540,9 @@ dependencies = [ "checksum tempdir 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "87974a6f5c1dfb344d733055601650059a3363de2a6104819293baff662132d6" "checksum tendril 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "cebf864c2d90394a1b66d6fe45963f9a177f2af81a0edea5060f77627f9c4587" "checksum term 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)" = "d168af3930b369cfe245132550579d47dfd873d69470755a19c2c6568dbbd989" -"checksum term_size 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "71662702fe5cd2cf95edd4ad655eea42f24a87a0e44059cbaa4e55260b7bc331" +"checksum term_size 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "07b6c1ac5b3fffd75073276bca1ceed01f67a28537097a2a9539e116e50fb21a" "checksum thread-id 3.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "4437c97558c70d129e40629a5b385b3fb1ffac301e63941335e4d354081ec14a" -"checksum thread_local 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7793b722f0f77ce716e7f1acf416359ca32ff24d04ffbac4269f44a4a83be05d" +"checksum thread_local 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "c85048c6260d17cf486ceae3282d9fb6b90be220bf5b28c400f5485ffc29f0c7" "checksum thread_profiler 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "cf947d192a9be60ef5131cc7a4648886ba89d712f16700ebbf80c8a69d05d48f" "checksum threadpool 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "59f6d3eff89920113dac9db44dde461d71d01e88a5b57b258a0466c32b5d7fe1" "checksum time 0.1.36 (registry+https://github.com/rust-lang/crates.io-index)" = "211b63c112206356ef1ff9b19355f43740fc3f85960c598a93d3a3d3ba7beade" From 722280270f1372e285eb96cae96cc4727d1e2481 Mon Sep 17 00:00:00 2001 From: Hiroyuki Ikezoe Date: Sat, 18 Feb 2017 10:43:24 +0900 Subject: [PATCH 02/48] Bug 1340344 - Calmp hue value in finite float range. r=dholbert MozReview-Commit-ID: ItxwcKjpHyO --HG-- extra : rebase_source : 8ffa77db0272d1ac836b395736d2d8e4ddb233e3 --- layout/style/crashtests/1340344.html | 15 +++++++++++++++ layout/style/crashtests/crashtests.list | 1 + layout/style/nsCSSParser.cpp | 5 +++++ 3 files changed, 21 insertions(+) create mode 100644 layout/style/crashtests/1340344.html diff --git a/layout/style/crashtests/1340344.html b/layout/style/crashtests/1340344.html new file mode 100644 index 000000000000..5d0a3c85fdba --- /dev/null +++ b/layout/style/crashtests/1340344.html @@ -0,0 +1,15 @@ + + + + + + + diff --git a/layout/style/crashtests/crashtests.list b/layout/style/crashtests/crashtests.list index c209431e1654..011adb6fab85 100644 --- a/layout/style/crashtests/crashtests.list +++ b/layout/style/crashtests/crashtests.list @@ -169,3 +169,4 @@ load 1321357-1.html load 1328535-1.html load 1331272.html HTTP load 1333001-1.html +pref(dom.animations-api.core.enabled,true) load 1340344.html diff --git a/layout/style/nsCSSParser.cpp b/layout/style/nsCSSParser.cpp index f4f1abf8af96..efbd0146bf7f 100644 --- a/layout/style/nsCSSParser.cpp +++ b/layout/style/nsCSSParser.cpp @@ -6936,7 +6936,12 @@ CSSParserImpl::ParseHue(float& aAngle) // The '0' value is handled by parsing, so use VARIANT_ANGLE flag // instead of VARIANT_ANGLE_OR_ZERO. if (ParseSingleTokenVariant(angleValue, VARIANT_ANGLE, nullptr)) { + // Convert double value of GetAngleValueInDegrees() to float. aAngle = angleValue.GetAngleValueInDegrees(); + // And then clamp it as finite values in float. + aAngle = mozilla::clamped(aAngle, + -std::numeric_limits::max(), + std::numeric_limits::max()); return true; } From 81a2b977ddb6eadf03057454edf46ce063a1a6e1 Mon Sep 17 00:00:00 2001 From: Shane Caraveo Date: Tue, 21 Feb 2017 13:51:14 -0800 Subject: [PATCH 03/48] Bug 1340750 fix remote handling of sidebar browser, r=kmag MozReview-Commit-ID: 3hamdXtxKjh --HG-- extra : rebase_source : 0945671bad701fef2986d2bc51a6b9af75ec1a03 --- browser/base/content/webext-panels.js | 66 +++++++++++++++++++------- browser/base/content/webext-panels.xul | 5 -- 2 files changed, 49 insertions(+), 22 deletions(-) diff --git a/browser/base/content/webext-panels.js b/browser/base/content/webext-panels.js index 74586ead0621..6ea706faed46 100644 --- a/browser/base/content/webext-panels.js +++ b/browser/base/content/webext-panels.js @@ -5,28 +5,60 @@ XPCOMUtils.defineLazyModuleGetter(this, "ExtensionParent", "resource://gre/modules/ExtensionParent.jsm"); +Cu.import("resource://gre/modules/ExtensionUtils.jsm"); + +var { + promiseEvent, +} = ExtensionUtils; + +const XUL_NS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"; + +function getBrowser(sidebar) { + let browser = document.getElementById("webext-panels-browser"); + if (browser) { + return Promise.resolve(browser); + } + + browser = document.createElementNS(XUL_NS, "browser"); + browser.setAttribute("id", "webext-panels-browser"); + browser.setAttribute("type", "content"); + browser.setAttribute("flex", "1"); + browser.setAttribute("disableglobalhistory", "true"); + browser.setAttribute("webextension-view-type", "sidebar"); + browser.setAttribute("context", "contentAreaContextMenu"); + browser.setAttribute("tooltip", "aHTMLTooltip"); + browser.setAttribute("onclick", "window.parent.contentAreaClick(event, true);"); + + let readyPromise; + if (sidebar.remote) { + browser.setAttribute("remote", "true"); + browser.setAttribute("remoteType", + E10SUtils.getRemoteTypeForURI(sidebar.uri, true, + E10SUtils.EXTENSION_REMOTE_TYPE)); + readyPromise = promiseEvent(browser, "XULFrameLoaderCreated"); + } else { + readyPromise = Promise.resolve(); + } + document.documentElement.appendChild(browser); + + return readyPromise.then(() => { + browser.messageManager.loadFrameScript("chrome://browser/content/content.js", false); + ExtensionParent.apiManager.emit("extension-browser-inserted", browser); + return browser; + }); +} function loadWebPanel() { let sidebarURI = new URL(location); - let uri = sidebarURI.searchParams.get("panel"); - let remote = sidebarURI.searchParams.get("remote"); - let browser = document.getElementById("webext-panels-browser"); - if (remote) { - let remoteType = E10SUtils.getRemoteTypeForURI(uri, true, - E10SUtils.EXTENSION_REMOTE_TYPE); - browser.setAttribute("remote", "true"); - browser.setAttribute("remoteType", remoteType); - } else { - browser.removeAttribute("remote"); - browser.removeAttribute("remoteType"); - } - browser.loadURI(uri); + let sidebar = { + uri: sidebarURI.searchParams.get("panel"), + remote: sidebarURI.searchParams.get("remote"), + }; + getBrowser(sidebar).then(browser => { + browser.loadURI(sidebar.uri); + }); } function load() { - let browser = document.getElementById("webext-panels-browser"); - browser.messageManager.loadFrameScript("chrome://browser/content/content.js", true); - ExtensionParent.apiManager.emit("extension-browser-inserted", browser); - this.loadWebPanel(); } diff --git a/browser/base/content/webext-panels.xul b/browser/base/content/webext-panels.xul index 35e8eb0f2619..57be52ffa549 100644 --- a/browser/base/content/webext-panels.xul +++ b/browser/base/content/webext-panels.xul @@ -65,9 +65,4 @@ - From 3a2a54e7d2c9eac8a39f64893f60d09e7bf923b2 Mon Sep 17 00:00:00 2001 From: Mike Hommey Date: Tue, 21 Feb 2017 15:53:27 +0900 Subject: [PATCH 04/48] Bug 1339240 - Detect git worktrees in MachCommandConditions.is_git. r=chmanchester --HG-- extra : rebase_source : 1763953383ead9f9985fdadc0e862ace23cb2b21 --- python/mozbuild/mozbuild/base.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/python/mozbuild/mozbuild/base.py b/python/mozbuild/mozbuild/base.py index 30535ebc07f3..d1ebd9fd4d9a 100644 --- a/python/mozbuild/mozbuild/base.py +++ b/python/mozbuild/mozbuild/base.py @@ -785,7 +785,7 @@ class MachCommandConditions(object): """Must have a git source checkout.""" if hasattr(cls, 'substs'): top_srcdir = cls.substs.get('top_srcdir') - return top_srcdir and os.path.isdir(os.path.join(top_srcdir, '.git')) + return top_srcdir and os.path.exists(os.path.join(top_srcdir, '.git')) return False From 4f2c73ffd9ff6cb35f1cf66c187532fed07e0ba0 Mon Sep 17 00:00:00 2001 From: Mike Hommey Date: Tue, 21 Feb 2017 16:04:08 +0900 Subject: [PATCH 05/48] Bug 1341207 - Use MachCommandConditions.is_{git,hg} for `mach clobber python`. r=chmanchester --HG-- extra : rebase_source : 4b78d3857cca67455343847ab27902c5877e0a6e --- python/mozbuild/mozbuild/base.py | 14 ++++++++++---- python/mozbuild/mozbuild/mach_commands.py | 4 ++-- 2 files changed, 12 insertions(+), 6 deletions(-) diff --git a/python/mozbuild/mozbuild/base.py b/python/mozbuild/mozbuild/base.py index d1ebd9fd4d9a..c33ddeddaf2a 100644 --- a/python/mozbuild/mozbuild/base.py +++ b/python/mozbuild/mozbuild/base.py @@ -777,16 +777,22 @@ class MachCommandConditions(object): """Must have a mercurial source checkout.""" if hasattr(cls, 'substs'): top_srcdir = cls.substs.get('top_srcdir') - return top_srcdir and os.path.isdir(os.path.join(top_srcdir, '.hg')) - return False + elif hasattr(cls, 'topsrcdir'): + top_srcdir = cls.topsrcdir + else: + return False + return top_srcdir and os.path.isdir(os.path.join(top_srcdir, '.hg')) @staticmethod def is_git(cls): """Must have a git source checkout.""" if hasattr(cls, 'substs'): top_srcdir = cls.substs.get('top_srcdir') - return top_srcdir and os.path.exists(os.path.join(top_srcdir, '.git')) - return False + elif hasattr(cls, 'topsrcdir'): + top_srcdir = cls.topsrcdir + else: + return False + return top_srcdir and os.path.exists(os.path.join(top_srcdir, '.git')) class PathArgument(object): diff --git a/python/mozbuild/mozbuild/mach_commands.py b/python/mozbuild/mozbuild/mach_commands.py index da8eee35f5c1..08711bfd1fa0 100644 --- a/python/mozbuild/mozbuild/mach_commands.py +++ b/python/mozbuild/mozbuild/mach_commands.py @@ -695,9 +695,9 @@ class Clobber(MachCommandBase): raise if 'python' in what: - if os.path.isdir(mozpath.join(self.topsrcdir, '.hg')): + if conditions.is_hg(self): cmd = ['hg', 'purge', '--all', '-I', 'glob:**.py[co]'] - elif os.path.isdir(mozpath.join(self.topsrcdir, '.git')): + elif conditions.is_git(self): cmd = ['git', 'clean', '-f', '-x', '*.py[co]'] else: cmd = ['find', '.', '-type', 'f', '-name', '*.py[co]', '-delete'] From e43e63e3a7a0844aad6678608ce62e88f619111d Mon Sep 17 00:00:00 2001 From: Xidorn Quan Date: Tue, 21 Feb 2017 22:27:58 +1100 Subject: [PATCH 06/48] Bug 1331102 - Move #include around to avoid triggering this issue. r=heycam MozReview-Commit-ID: Fx2DbUwuf0v --HG-- extra : rebase_source : 01625a1fb08bd5fe06a7095314cc093c37f89a17 --- layout/style/moz.build | 10 ++-------- layout/style/nsStyleCoord.cpp | 6 +++++- 2 files changed, 7 insertions(+), 9 deletions(-) diff --git a/layout/style/moz.build b/layout/style/moz.build index f5cd92302332..02241b46286d 100644 --- a/layout/style/moz.build +++ b/layout/style/moz.build @@ -148,6 +148,7 @@ EXPORTS.mozilla.css += [ UNIFIED_SOURCES += [ 'AnimationCollection.cpp', 'AnimationCommon.cpp', + 'BindingStyleRule.cpp', 'CounterStyleManager.cpp', 'CSS.cpp', 'CSSLexer.cpp', @@ -208,6 +209,7 @@ UNIFIED_SOURCES += [ 'ServoCSSRuleList.cpp', 'ServoDeclarationBlock.cpp', 'ServoElementSnapshot.cpp', + 'ServoSpecifiedValues.cpp', 'ServoStyleRule.cpp', 'ServoStyleSet.cpp', 'ServoStyleSheet.cpp', @@ -217,21 +219,13 @@ UNIFIED_SOURCES += [ 'SVGAttrAnimationRuleProcessor.cpp', ] -# - BindingStyleRule.cpp doesn't _really_ needs to be built separately, -# except insofar as it shifts unified build boundaries, causing -# Unified_cpp_layout_style4.cpp to include nsStyleCoord.cpp, which -# includes, via nsStyleCoord.h, , which ends up including -# , which fails in much the way described in -# . # - nsCSSRuleProcessor.cpp needs to be built separately because it uses # plarena.h. # - nsLayoutStylesheetCache.cpp needs to be built separately because it uses # nsExceptionHandler.h, which includes windows.h. SOURCES += [ - 'BindingStyleRule.cpp', 'nsCSSRuleProcessor.cpp', 'nsLayoutStylesheetCache.cpp', - 'ServoSpecifiedValues.cpp', ] include('/ipc/chromium/chromium-config.mozbuild') diff --git a/layout/style/nsStyleCoord.cpp b/layout/style/nsStyleCoord.cpp index 2eaf09104985..8d155e9ad496 100644 --- a/layout/style/nsStyleCoord.cpp +++ b/layout/style/nsStyleCoord.cpp @@ -5,10 +5,14 @@ /* representation of length values in computed style data */ -#include "nsStyleCoord.h" #include "mozilla/HashFunctions.h" #include "mozilla/PodOperations.h" +// nsStyleCoord.h must not be the first header in a unified source file, +// otherwise it may not build with MSVC due to a bug in our STL wrapper. +// See bug 1331102. +#include "nsStyleCoord.h" + using namespace mozilla; nsStyleCoord::nsStyleCoord(nsStyleUnit aUnit) From 74b626654727f11421d15522513138ece8979afe Mon Sep 17 00:00:00 2001 From: Bob Silverberg Date: Wed, 15 Feb 2017 17:32:24 -0500 Subject: [PATCH 07/48] Bug 1312802 - Implement chrome.privacy API, r=aswan MozReview-Commit-ID: 5DoGnYb945Z --HG-- extra : rebase_source : 4dec751bb420beb262e74e812ebd6ff98cba5aca extra : source : 73764944f1f914ca5c0c45b0a38be26cd5b38143 --- .../en-US/chrome/browser/browser.properties | 1 + toolkit/components/extensions/Schemas.jsm | 2 +- toolkit/components/extensions/ext-privacy.js | 164 +++++++++ .../extensions/extensions-toolkit.manifest | 3 + toolkit/components/extensions/jar.mn | 1 + toolkit/components/extensions/schemas/jar.mn | 2 + .../extensions/schemas/privacy.json | 73 ++++ .../components/extensions/schemas/types.json | 163 +++++++++ .../test/mochitest/test_ext_all_apis.js | 2 + .../test/xpcshell/test_ext_privacy.js | 326 ++++++++++++++++++ .../extensions/test/xpcshell/xpcshell.ini | 1 + 11 files changed, 737 insertions(+), 1 deletion(-) create mode 100644 toolkit/components/extensions/ext-privacy.js create mode 100644 toolkit/components/extensions/schemas/privacy.json create mode 100644 toolkit/components/extensions/schemas/types.json create mode 100644 toolkit/components/extensions/test/xpcshell/test_ext_privacy.js diff --git a/browser/locales/en-US/chrome/browser/browser.properties b/browser/locales/en-US/chrome/browser/browser.properties index 134969d62429..a8e3da7a8eb4 100644 --- a/browser/locales/en-US/chrome/browser/browser.properties +++ b/browser/locales/en-US/chrome/browser/browser.properties @@ -91,6 +91,7 @@ webextPerms.description.history=Access browsing history # %S will be replaced with the name of the application webextPerms.description.nativeMessaging=Exchange messages with programs other than %S webextPerms.description.notifications=Display notifications to you +webextPerms.description.privacy=Read and modify privacy settings webextPerms.description.sessions=Access recently closed tabs webextPerms.description.tabs=Access browser tabs webextPerms.description.topSites=Access browsing history diff --git a/toolkit/components/extensions/Schemas.jsm b/toolkit/components/extensions/Schemas.jsm index 8013da72f541..80c50f16967a 100644 --- a/toolkit/components/extensions/Schemas.jsm +++ b/toolkit/components/extensions/Schemas.jsm @@ -1617,7 +1617,7 @@ class SubModuleProperty extends Entry { `is not a sub-module`); } } - let subpath = [path, this.name]; + let subpath = [...path, this.name]; let namespace = subpath.join("."); let functions = type.functions; diff --git a/toolkit/components/extensions/ext-privacy.js b/toolkit/components/extensions/ext-privacy.js new file mode 100644 index 000000000000..020bbf656b23 --- /dev/null +++ b/toolkit/components/extensions/ext-privacy.js @@ -0,0 +1,164 @@ +/* -*- Mode: indent-tabs-mode: nil; js-indent-level: 2 -*- */ +/* vim: set sts=2 sw=2 et tw=80: */ +"use strict"; + +const {classes: Cc, interfaces: Ci, utils: Cu} = Components; + +XPCOMUtils.defineLazyModuleGetter(this, "Preferences", + "resource://gre/modules/Preferences.jsm"); + +Cu.import("resource://gre/modules/ExtensionPreferencesManager.jsm"); +Cu.import("resource://gre/modules/ExtensionUtils.jsm"); +const { + ExtensionError, +} = ExtensionUtils; + +function checkScope(scope) { + if (scope && scope !== "regular") { + throw new ExtensionError( + `Firefox does not support the ${scope} settings scope.`); + } +} + +function getAPI(extension, context, name, callback) { + let anythingSet = false; + return { + async get(details) { + return { + levelOfControl: details.incognito ? + "not_controllable" : + await ExtensionPreferencesManager.getLevelOfControl( + extension, name), + value: await callback(), + }; + }, + async set(details) { + checkScope(details.scope); + if (!anythingSet) { + anythingSet = true; + context.callOnClose({ + close: async () => { + if (["ADDON_DISABLE", "ADDON_UNINSTALL"].includes(extension.shutdownReason)) { + await ExtensionPreferencesManager.unsetAll(extension); + anythingSet = false; + } + }, + }); + } + return await ExtensionPreferencesManager.setSetting( + extension, name, details.value); + }, + async clear(details) { + checkScope(details.scope); + return await ExtensionPreferencesManager.unsetSetting( + extension, name); + }, + }; +} + +// Add settings objects for supported APIs to the preferences manager. +ExtensionPreferencesManager.addSetting("network.networkPredictionEnabled", { + prefNames: [ + "network.predictor.enabled", + "network.prefetch-next", + "network.http.speculative-parallel-limit", + "network.dns.disablePrefetch", + ], + + setCallback(value) { + return { + "network.http.speculative-parallel-limit": value ? undefined : 0, + "network.dns.disablePrefetch": !value, + "network.predictor.enabled": value, + "network.prefetch-next": value, + }; + }, +}); + +ExtensionPreferencesManager.addSetting("network.webRTCIPHandlingPolicy", { + prefNames: [ + "media.peerconnection.ice.default_address_only", + "media.peerconnection.ice.no_host", + "media.peerconnection.ice.proxy_only", + ], + + setCallback(value) { + let prefs = {}; + // Start with all prefs being reset. + for (let pref of this.prefNames) { + prefs[pref] = undefined; + } + switch (value) { + case "default": + // All prefs are already set to be reset. + break; + + case "default_public_and_private_interfaces": + prefs["media.peerconnection.ice.default_address_only"] = true; + break; + + case "default_public_interface_only": + prefs["media.peerconnection.ice.default_address_only"] = true; + prefs["media.peerconnection.ice.no_host"] = true; + break; + + case "disable_non_proxied_udp": + prefs["media.peerconnection.ice.proxy_only"] = true; + break; + } + return prefs; + }, +}); + +ExtensionPreferencesManager.addSetting("websites.hyperlinkAuditingEnabled", { + prefNames: [ + "browser.send_pings", + ], + + setCallback(value) { + return {[this.prefNames[0]]: value}; + }, +}); + +extensions.registerSchemaAPI("privacy.network", "addon_parent", context => { + let {extension} = context; + return { + privacy: { + network: { + networkPredictionEnabled: getAPI(extension, context, + "network.networkPredictionEnabled", + () => { + return Preferences.get("network.predictor.enabled") && + Preferences.get("network.prefetch-next") && + Preferences.get("network.http.speculative-parallel-limit") > 0 && + !Preferences.get("network.dns.disablePrefetch"); + }), + webRTCIPHandlingPolicy: getAPI(extension, context, + "network.webRTCIPHandlingPolicy", + () => { + if (Preferences.get("media.peerconnection.ice.proxy_only")) { + return "disable_non_proxied_udp"; + } + + let default_address_only = + Preferences.get("media.peerconnection.ice.default_address_only"); + if (default_address_only) { + if (Preferences.get("media.peerconnection.ice.no_host")) { + return "default_public_interface_only"; + } + return "default_public_and_private_interfaces"; + } + + return "default"; + }), + }, + websites: { + hyperlinkAuditingEnabled: getAPI(extension, context, + "websites.hyperlinkAuditingEnabled", + () => { + return Preferences.get("browser.send_pings"); + }), + }, + }, + }; +}); diff --git a/toolkit/components/extensions/extensions-toolkit.manifest b/toolkit/components/extensions/extensions-toolkit.manifest index 54db978a7729..3aa8f6ad29ee 100644 --- a/toolkit/components/extensions/extensions-toolkit.manifest +++ b/toolkit/components/extensions/extensions-toolkit.manifest @@ -15,6 +15,7 @@ category webextension-scripts runtime chrome://extensions/content/ext-runtime.js category webextension-scripts extension chrome://extensions/content/ext-extension.js category webextension-scripts storage chrome://extensions/content/ext-storage.js category webextension-scripts topSites chrome://extensions/content/ext-topSites.js +category webextension-scripts privacy chrome://extensions/content/ext-privacy.js # scripts specific for content process. category webextension-scripts-content extension chrome://extensions/content/ext-c-extension.js @@ -57,9 +58,11 @@ category webextension-schemas idle chrome://extensions/content/schemas/idle.json category webextension-schemas management chrome://extensions/content/schemas/management.json category webextension-schemas native_host_manifest chrome://extensions/content/schemas/native_host_manifest.json category webextension-schemas notifications chrome://extensions/content/schemas/notifications.json +category webextension-schemas privacy chrome://extensions/content/schemas/privacy.json category webextension-schemas runtime chrome://extensions/content/schemas/runtime.json category webextension-schemas storage chrome://extensions/content/schemas/storage.json category webextension-schemas test chrome://extensions/content/schemas/test.json category webextension-schemas top_sites chrome://extensions/content/schemas/top_sites.json +category webextension-schemas types chrome://extensions/content/schemas/types.json category webextension-schemas web_navigation chrome://extensions/content/schemas/web_navigation.json category webextension-schemas web_request chrome://extensions/content/schemas/web_request.json diff --git a/toolkit/components/extensions/jar.mn b/toolkit/components/extensions/jar.mn index c30fd9c61957..e877ea645731 100644 --- a/toolkit/components/extensions/jar.mn +++ b/toolkit/components/extensions/jar.mn @@ -21,6 +21,7 @@ toolkit.jar: content/extensions/ext-extension.js content/extensions/ext-storage.js content/extensions/ext-topSites.js + content/extensions/ext-privacy.js content/extensions/ext-c-backgroundPage.js content/extensions/ext-c-extension.js #ifndef ANDROID diff --git a/toolkit/components/extensions/schemas/jar.mn b/toolkit/components/extensions/schemas/jar.mn index d8669e082531..3a91c97e53cf 100644 --- a/toolkit/components/extensions/schemas/jar.mn +++ b/toolkit/components/extensions/schemas/jar.mn @@ -21,9 +21,11 @@ toolkit.jar: content/extensions/schemas/manifest.json content/extensions/schemas/native_host_manifest.json content/extensions/schemas/notifications.json + content/extensions/schemas/privacy.json content/extensions/schemas/runtime.json content/extensions/schemas/storage.json content/extensions/schemas/test.json content/extensions/schemas/top_sites.json + content/extensions/schemas/types.json content/extensions/schemas/web_navigation.json content/extensions/schemas/web_request.json diff --git a/toolkit/components/extensions/schemas/privacy.json b/toolkit/components/extensions/schemas/privacy.json new file mode 100644 index 000000000000..24fa7ad444c4 --- /dev/null +++ b/toolkit/components/extensions/schemas/privacy.json @@ -0,0 +1,73 @@ +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +[ + { + "namespace": "manifest", + "types": [ + { + "$extend": "Permission", + "choices": [{ + "type": "string", + "enum": [ + "privacy" + ] + }] + } + ] + }, + { + "namespace": "privacy", + "permissions": ["privacy"] + }, + { + "namespace": "privacy.network", + "description": "Use the browser.privacy API to control usage of the features in the browser that can affect a user's privacy.", + "permissions": ["privacy"], + "types": [ + { + "id": "IPHandlingPolicy", + "type": "string", + "enum": ["default", "default_public_and_private_interfaces", "default_public_interface_only", "disable_non_proxied_udp"], + "description": "The IP handling policy of WebRTC." + } + ], + "properties": { + "networkPredictionEnabled": { + "$ref": "types.Setting", + "description": "If enabled, the browser attempts to speed up your web browsing experience by pre-resolving DNS entries, prerendering sites (<link rel='prefetch' ...>), and preemptively opening TCP and SSL connections to servers. This preference's value is a boolean, defaulting to true." + }, + "webRTCIPHandlingPolicy": { + "$ref": "types.Setting", + "description": "Allow users to specify the media performance/privacy tradeoffs which impacts how WebRTC traffic will be routed and how much local address information is exposed. This preference's value is of type IPHandlingPolicy, defaulting to default." + } + } + }, + { + "namespace": "privacy.websites", + "description": "Use the browser.privacy API to control usage of the features in the browser that can affect a user's privacy.", + "permissions": ["privacy"], + "properties": { + "thirdPartyCookiesAllowed": { + "$ref": "types.Setting", + "description": "If disabled, the browser blocks third-party sites from setting cookies. The value of this preference is of type boolean, and the default value is true.", + "unsupported": true + }, + "hyperlinkAuditingEnabled": { + "$ref": "types.Setting", + "description": "If enabled, the browser sends auditing pings when requested by a website (<a ping>). The value of this preference is of type boolean, and the default value is true." + }, + "referrersEnabled": { + "$ref": "types.Setting", + "description": "If enabled, the browser sends referer headers with your requests. Yes, the name of this preference doesn't match the misspelled header. No, we're not going to change it. The value of this preference is of type boolean, and the default value is true.", + "unsupported": true + }, + "protectedContentEnabled": { + "$ref": "types.Setting", + "description": "Available on Windows and ChromeOS only: If enabled, the browser provides a unique ID to plugins in order to run protected content. The value of this preference is of type boolean, and the default value is true.", + "unsupported": true + } + } + } +] diff --git a/toolkit/components/extensions/schemas/types.json b/toolkit/components/extensions/schemas/types.json new file mode 100644 index 000000000000..7bc745a0ca24 --- /dev/null +++ b/toolkit/components/extensions/schemas/types.json @@ -0,0 +1,163 @@ +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +[ + { + "namespace": "types", + "description": "Contains types used by other schemas.", + "types": [ + { + "id": "SettingScope", + "type": "string", + "enum": ["regular", "regular_only", "incognito_persistent", "incognito_session_only"], + "description": "The scope of the Setting. One of
  • regular: setting for the regular profile (which is inherited by the incognito profile if not overridden elsewhere),
  • regular_only: setting for the regular profile only (not inherited by the incognito profile),
  • incognito_persistent: setting for the incognito profile that survives browser restarts (overrides regular preferences),
  • incognito_session_only: setting for the incognito profile that can only be set during an incognito session and is deleted when the incognito session ends (overrides regular and incognito_persistent preferences).
Only regular is supported by Firefox at this time." + }, + { + "id": "LevelOfControl", + "type": "string", + "enum": ["not_controllable", "controlled_by_other_extensions", "controllable_by_this_extension", "controlled_by_this_extension"], + "description": "One of
  • not_controllable: cannot be controlled by any extension
  • controlled_by_other_extensions: controlled by extensions with higher precedence
  • controllable_by_this_extension: can be controlled by this extension
  • controlled_by_this_extension: controlled by this extension
" + }, + { + "id": "Setting", + "type": "object", + "functions": [ + { + "name": "get", + "type": "function", + "description": "Gets the value of a setting.", + "async": "callback", + "parameters": [ + { + "name": "details", + "type": "object", + "description": "Which setting to consider.", + "properties": { + "incognito": { + "type": "boolean", + "optional": true, + "description": "Whether to return the value that applies to the incognito session (default false)." + } + } + }, + { + "name": "callback", + "type": "function", + "parameters": [ + { + "name": "details", + "type": "object", + "description": "Details of the currently effective value.", + "properties": { + "value": { + "description": "The value of the setting.", + "type": "any" + }, + "levelOfControl": { + "$ref": "LevelOfControl", + "description": "The level of control of the setting." + }, + "incognitoSpecific": { + "description": "Whether the effective value is specific to the incognito session.
This property will only be present if the incognito property in the details parameter of get() was true.", + "type": "boolean", + "optional": true + } + } + } + ] + } + ] + }, + { + "name": "set", + "type": "function", + "description": "Sets the value of a setting.", + "async": "callback", + "parameters": [ + { + "name": "details", + "type": "object", + "description": "Which setting to change.", + "properties": { + "value": { + "description": "The value of the setting.
Note that every setting has a specific value type, which is described together with the setting. An extension should not set a value of a different type.", + "type": "any" + }, + "scope": { + "$ref": "SettingScope", + "optional": true, + "description": "Where to set the setting (default: regular)." + } + } + }, + { + "name": "callback", + "type": "function", + "description": "Called at the completion of the set operation.", + "optional": true, + "parameters": [] + } + ] + }, + { + "name": "clear", + "type": "function", + "description": "Clears the setting, restoring any default value.", + "async": "callback", + "parameters": [ + { + "name": "details", + "type": "object", + "description": "Which setting to clear.", + "properties": { + "scope": { + "$ref": "SettingScope", + "optional": true, + "description": "Where to clear the setting (default: regular)." + } + } + }, + { + "name": "callback", + "type": "function", + "description": "Called at the completion of the clear operation.", + "optional": true, + "parameters": [] + } + ] + } + ], + "events": [ + { + "name": "onChange", + "type": "function", + "description": "Fired after the setting changes.", + "unsupported": true, + "parameters": [ + { + "type": "object", + "name": "details", + "properties": { + "value": { + "description": "The value of the setting after the change.", + "type": "any" + }, + "levelOfControl": { + "$ref": "LevelOfControl", + "description": "The level of control of the setting." + }, + "incognitoSpecific": { + "description": "Whether the value that has changed is specific to the incognito session.
This property will only be present if the user has enabled the extension in incognito mode.", + "type": "boolean", + "optional": true + } + } + } + ] + } + ] + } + ] + } +] diff --git a/toolkit/components/extensions/test/mochitest/test_ext_all_apis.js b/toolkit/components/extensions/test/mochitest/test_ext_all_apis.js index ae43da8a5ea8..48ec9cedc91c 100644 --- a/toolkit/components/extensions/test/mochitest/test_ext_all_apis.js +++ b/toolkit/components/extensions/test/mochitest/test_ext_all_apis.js @@ -82,6 +82,8 @@ let expectedBackgroundApis = [ "runtime.openOptionsPage", "runtime.reload", "runtime.setUninstallURL", + "types.LevelOfControl", + "types.SettingScope", ]; function sendAllApis() { diff --git a/toolkit/components/extensions/test/xpcshell/test_ext_privacy.js b/toolkit/components/extensions/test/xpcshell/test_ext_privacy.js new file mode 100644 index 000000000000..5562e391bab4 --- /dev/null +++ b/toolkit/components/extensions/test/xpcshell/test_ext_privacy.js @@ -0,0 +1,326 @@ +/* -*- Mode: indent-tabs-mode: nil; js-indent-level: 2 -*- */ +/* vim: set sts=2 sw=2 et tw=80: */ +"use strict"; + +XPCOMUtils.defineLazyModuleGetter(this, "AddonManager", + "resource://gre/modules/AddonManager.jsm"); +XPCOMUtils.defineLazyModuleGetter(this, "ExtensionPreferencesManager", + "resource://gre/modules/ExtensionPreferencesManager.jsm"); +XPCOMUtils.defineLazyModuleGetter(this, "Preferences", + "resource://gre/modules/Preferences.jsm"); + +const { + createAppInfo, + promiseShutdownManager, + promiseStartupManager, +} = AddonTestUtils; + +AddonTestUtils.init(this); + +createAppInfo("xpcshell@tests.mozilla.org", "XPCShell", "1", "42"); + +add_task(async function test_privacy() { + // Create a object to hold the values to which we will initialize the prefs. + const SETTINGS = { + "network.networkPredictionEnabled": { + "network.predictor.enabled": true, + "network.prefetch-next": true, + "network.http.speculative-parallel-limit": 10, + "network.dns.disablePrefetch": false, + }, + "websites.hyperlinkAuditingEnabled": { + "browser.send_pings": true, + }, + }; + + async function background() { + browser.test.onMessage.addListener(async (msg, ...args) => { + let data = args[0]; + // The second argument is the end of the api name, + // e.g., "network.networkPredictionEnabled". + let apiObj = args[1].split(".").reduce((o, i) => o[i], browser.privacy); + let settingData; + switch (msg) { + case "get": + settingData = await apiObj.get(data); + browser.test.sendMessage("gotData", settingData); + break; + + case "set": + await apiObj.set(data); + settingData = await apiObj.get({}); + browser.test.sendMessage("afterSet", settingData); + break; + + case "clear": + await apiObj.clear(data); + settingData = await apiObj.get({}); + browser.test.sendMessage("afterClear", settingData); + break; + } + }); + } + + // Set prefs to our initial values. + for (let setting in SETTINGS) { + for (let pref in SETTINGS[setting]) { + Preferences.set(pref, SETTINGS[setting][pref]); + } + } + + do_register_cleanup(() => { + // Reset the prefs. + for (let setting in SETTINGS) { + for (let pref in SETTINGS[setting]) { + Preferences.reset(pref); + } + } + }); + + // Create an array of extensions to install. + let testExtensions = [ + ExtensionTestUtils.loadExtension({ + background, + manifest: { + permissions: ["privacy"], + }, + useAddonManager: "temporary", + }), + + ExtensionTestUtils.loadExtension({ + background, + manifest: { + permissions: ["privacy"], + }, + useAddonManager: "temporary", + }), + ]; + + await promiseStartupManager(); + + for (let extension of testExtensions) { + await extension.startup(); + } + + for (let setting in SETTINGS) { + testExtensions[0].sendMessage("get", {}, setting); + let data = await testExtensions[0].awaitMessage("gotData"); + ok(data.value, "get returns expected value."); + equal(data.levelOfControl, "controllable_by_this_extension", + "get returns expected levelOfControl."); + + testExtensions[0].sendMessage("get", {incognito: true}, setting); + data = await testExtensions[0].awaitMessage("gotData"); + ok(data.value, "get returns expected value with incognito."); + equal(data.levelOfControl, "not_controllable", + "get returns expected levelOfControl with incognito."); + + // Change the value to false. + testExtensions[0].sendMessage("set", {value: false}, setting); + data = await testExtensions[0].awaitMessage("afterSet"); + ok(!data.value, "get returns expected value after setting."); + equal(data.levelOfControl, "controlled_by_this_extension", + "get returns expected levelOfControl after setting."); + + // Verify the prefs have been set to match the "false" setting. + for (let pref in SETTINGS[setting]) { + let msg = `${pref} set correctly for ${setting}`; + if (pref === "network.http.speculative-parallel-limit") { + equal(Preferences.get(pref), 0, msg); + } else { + equal(Preferences.get(pref), !SETTINGS[setting][pref], msg); + } + } + + // Change the value with a newer extension. + testExtensions[1].sendMessage("set", {value: true}, setting); + data = await testExtensions[1].awaitMessage("afterSet"); + ok(data.value, "get returns expected value after setting via newer extension."); + equal(data.levelOfControl, "controlled_by_this_extension", + "get returns expected levelOfControl after setting."); + + // Verify the prefs have been set to match the "true" setting. + for (let pref in SETTINGS[setting]) { + let msg = `${pref} set correctly for ${setting}`; + if (pref === "network.http.speculative-parallel-limit") { + equal(Preferences.get(pref), ExtensionPreferencesManager.getDefaultValue(pref), msg); + } else { + equal(Preferences.get(pref), SETTINGS[setting][pref], msg); + } + } + + // Change the value with an older extension. + testExtensions[0].sendMessage("set", {value: false}, setting); + data = await testExtensions[0].awaitMessage("afterSet"); + ok(data.value, "Newer extension remains in control."); + equal(data.levelOfControl, "controlled_by_other_extensions", + "get returns expected levelOfControl when controlled by other."); + + // Clear the value of the newer extension. + testExtensions[1].sendMessage("clear", {}, setting); + data = await testExtensions[1].awaitMessage("afterClear"); + ok(!data.value, "Older extension gains control."); + equal(data.levelOfControl, "controllable_by_this_extension", + "Expected levelOfControl returned after clearing."); + + testExtensions[0].sendMessage("get", {}, setting); + data = await testExtensions[0].awaitMessage("gotData"); + ok(!data.value, "Current, older extension has control."); + equal(data.levelOfControl, "controlled_by_this_extension", + "Expected levelOfControl returned after clearing."); + + // Set the value again with the newer extension. + testExtensions[1].sendMessage("set", {value: true}, setting); + data = await testExtensions[1].awaitMessage("afterSet"); + ok(data.value, "get returns expected value after setting via newer extension."); + equal(data.levelOfControl, "controlled_by_this_extension", + "get returns expected levelOfControl after setting."); + + // Unload the newer extension. Expect the older extension to regain control. + await testExtensions[1].unload(); + testExtensions[0].sendMessage("get", {}, setting); + data = await testExtensions[0].awaitMessage("gotData"); + ok(!data.value, "Older extension regained control."); + equal(data.levelOfControl, "controlled_by_this_extension", + "Expected levelOfControl returned after unloading."); + + // Reload the extension for the next iteration of the loop. + testExtensions[1] = ExtensionTestUtils.loadExtension({ + background, + manifest: { + permissions: ["privacy"], + }, + useAddonManager: "temporary", + }); + await testExtensions[1].startup(); + + // Clear the value of the older extension. + testExtensions[0].sendMessage("clear", {}, setting); + data = await testExtensions[0].awaitMessage("afterClear"); + ok(data.value, "Setting returns to original value when all are cleared."); + equal(data.levelOfControl, "controllable_by_this_extension", + "Expected levelOfControl returned after clearing."); + + // Verify that our initial values were restored. + for (let pref in SETTINGS[setting]) { + equal(Preferences.get(pref), SETTINGS[setting][pref], `${pref} was reset to its initial value.`); + } + } + + for (let extension of testExtensions) { + await extension.unload(); + } + + await promiseShutdownManager(); +}); + +add_task(async function test_privacy_webRTCIPHandlingPolicy() { + // Create a object to hold the default values of all the prefs. + const PREF_DEFAULTS = { + "media.peerconnection.ice.default_address_only": null, + "media.peerconnection.ice.no_host": null, + "media.peerconnection.ice.proxy_only": null, + }; + + // Store the default values of each pref. + for (let pref in PREF_DEFAULTS) { + PREF_DEFAULTS[pref] = ExtensionPreferencesManager.getDefaultValue(pref); + } + + do_register_cleanup(() => { + // Reset the prefs. + for (let pref in PREF_DEFAULTS) { + Preferences.reset(pref); + } + }); + + async function background() { + browser.test.onMessage.addListener(async (msg, value) => { + let rtcData; + switch (msg) { + case "set": + await browser.privacy.network.webRTCIPHandlingPolicy.set({value}); + rtcData = await browser.privacy.network.webRTCIPHandlingPolicy.get({}); + browser.test.sendMessage("rtcData", rtcData); + break; + + case "clear": + await browser.privacy.network.webRTCIPHandlingPolicy.clear({}); + rtcData = await browser.privacy.network.webRTCIPHandlingPolicy.get({}); + browser.test.sendMessage("rtcData", rtcData); + break; + + } + }); + } + + let extension = ExtensionTestUtils.loadExtension({ + background, + manifest: { + permissions: ["privacy"], + }, + useAddonManager: "temporary", + }); + + await promiseStartupManager(); + await extension.startup(); + + async function testSetting(value, truePrefs) { + extension.sendMessage("set", value); + let data = await extension.awaitMessage("rtcData"); + equal(data.value, value); + for (let pref in PREF_DEFAULTS) { + let prefValue = Preferences.get(pref); + if (truePrefs.includes(pref)) { + ok(prefValue, `${pref} set correctly for ${value}`); + } else { + equal(prefValue, PREF_DEFAULTS[pref], `${pref} contains default value for ${value}`); + } + } + } + + await testSetting( + "default_public_and_private_interfaces", + ["media.peerconnection.ice.default_address_only"]); + + await testSetting( + "default_public_interface_only", + ["media.peerconnection.ice.default_address_only", "media.peerconnection.ice.no_host"]); + + await testSetting( + "disable_non_proxied_udp", + ["media.peerconnection.ice.proxy_only"]); + + await testSetting("default", []); + + await extension.unload(); + + await promiseShutdownManager(); +}); + +add_task(async function test_exceptions() { + async function background() { + await browser.test.assertRejects( + browser.privacy.network.networkPredictionEnabled.set({value: true, scope: "regular_only"}), + "Firefox does not support the regular_only settings scope.", + "Expected rejection calling set with invalid scope."); + + await browser.test.assertRejects( + browser.privacy.network.networkPredictionEnabled.clear({scope: "incognito_persistent"}), + "Firefox does not support the incognito_persistent settings scope.", + "Expected rejection calling clear with invalid scope."); + + browser.test.notifyPass("exceptionTests"); + } + + let extension = ExtensionTestUtils.loadExtension({ + background, + manifest: { + permissions: ["privacy"], + }, + }); + + await extension.startup(); + await extension.awaitFinish("exceptionTests"); + await extension.unload(); +}); diff --git a/toolkit/components/extensions/test/xpcshell/xpcshell.ini b/toolkit/components/extensions/test/xpcshell/xpcshell.ini index 5f3048026aeb..225d8f41b8dd 100644 --- a/toolkit/components/extensions/test/xpcshell/xpcshell.ini +++ b/toolkit/components/extensions/test/xpcshell/xpcshell.ini @@ -48,6 +48,7 @@ skip-if = release_or_beta [test_ext_manifest_minimum_chrome_version.js] [test_ext_onmessage_removelistener.js] skip-if = true # This test no longer tests what it is meant to test. +[test_ext_privacy.js] [test_ext_runtime_connect_no_receiver.js] [test_ext_runtime_getBrowserInfo.js] [test_ext_runtime_getPlatformInfo.js] From 931d61c07cf7fd843504ae5565081ce037c97b58 Mon Sep 17 00:00:00 2001 From: Xidorn Quan Date: Mon, 20 Feb 2017 12:35:15 +1100 Subject: [PATCH 08/48] Bug 1340926 part 1 - Make nsDocument::IsAboutPage usable in const function. r=Ehsan MozReview-Commit-ID: 6MYH6VAQ911 --HG-- extra : rebase_source : 1a03566da675cb585fab50efde35e7487f00ff9b --- dom/base/nsDocument.cpp | 4 ++-- dom/base/nsDocument.h | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/dom/base/nsDocument.cpp b/dom/base/nsDocument.cpp index 657e9415eec5..a556957e89c1 100644 --- a/dom/base/nsDocument.cpp +++ b/dom/base/nsDocument.cpp @@ -1474,9 +1474,9 @@ nsIDocument::~nsIDocument() } bool -nsDocument::IsAboutPage() +nsDocument::IsAboutPage() const { - nsCOMPtr principal = GetPrincipal(); + nsCOMPtr principal = NodePrincipal(); nsCOMPtr uri; principal->GetURI(getter_AddRefs(uri)); bool isAboutScheme = true; diff --git a/dom/base/nsDocument.h b/dom/base/nsDocument.h index 41c4b37c3ea3..814d7c144ac5 100644 --- a/dom/base/nsDocument.h +++ b/dom/base/nsDocument.h @@ -1535,7 +1535,7 @@ private: void ClearAllBoxObjects(); // Returns true if the scheme for the url for this document is "about" - bool IsAboutPage(); + bool IsAboutPage() const; // These are not implemented and not supported. nsDocument(const nsDocument& aOther); From c0c5866f646cfba752c1e7308e3a78cd59eea285 Mon Sep 17 00:00:00 2001 From: Xidorn Quan Date: Mon, 20 Feb 2017 12:35:56 +1100 Subject: [PATCH 09/48] Bug 1340926 part 2 - Avoid record deprecated operation inside about: pages. r=Ehsan MozReview-Commit-ID: GksnEDiHboq --HG-- extra : rebase_source : ba7e075630e1fbeb3ce752eef9f002d32065de59 --- dom/base/nsDocument.cpp | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/dom/base/nsDocument.cpp b/dom/base/nsDocument.cpp index a556957e89c1..8a48240183f5 100644 --- a/dom/base/nsDocument.cpp +++ b/dom/base/nsDocument.cpp @@ -10193,7 +10193,13 @@ nsIDocument::WarnOnceAbout(DeprecatedOperations aOperation, return; } mDeprecationWarnedAbout[aOperation] = true; - const_cast(this)->SetDocumentAndPageUseCounter(OperationToUseCounter(aOperation)); + // Don't count deprecated operations for about pages since those pages + // are almost in our control, and we always need to remove uses there + // before we remove the operation itself anyway. + if (!static_cast(this)->IsAboutPage()) { + const_cast(this)-> + SetDocumentAndPageUseCounter(OperationToUseCounter(aOperation)); + } uint32_t flags = asError ? nsIScriptError::errorFlag : nsIScriptError::warningFlag; nsContentUtils::ReportToConsole(flags, From fc22390de5437ace140f4223fa6f59f6837c4d45 Mon Sep 17 00:00:00 2001 From: Xidorn Quan Date: Mon, 20 Feb 2017 12:41:11 +1100 Subject: [PATCH 10/48] Bug 1340926 part 3 - Deprecate usage of xml:base. r=Ehsan,francois MozReview-Commit-ID: EpuKLrCj0qc --HG-- extra : rebase_source : 051f300371d27d4dcdbcb8e70b54c3196155780e --- dom/base/FragmentOrElement.cpp | 31 +++++++++++---------- dom/base/nsDeprecatedOperationList.h | 1 + dom/locales/en-US/chrome/dom/dom.properties | 2 ++ 3 files changed, 20 insertions(+), 14 deletions(-) diff --git a/dom/base/FragmentOrElement.cpp b/dom/base/FragmentOrElement.cpp index 042f5b7287d0..3e79f93d5d9f 100644 --- a/dom/base/FragmentOrElement.cpp +++ b/dom/base/FragmentOrElement.cpp @@ -388,20 +388,23 @@ nsIContent::GetBaseURI(bool aTryUseXHRDocBaseURI) const elem = elem->GetParent(); } while(elem); - // Now resolve against all xml:base attrs - for (uint32_t i = baseAttrs.Length() - 1; i != uint32_t(-1); --i) { - nsCOMPtr newBase; - nsresult rv = NS_NewURI(getter_AddRefs(newBase), baseAttrs[i], - doc->GetDocumentCharacterSet().get(), base); - // Do a security check, almost the same as nsDocument::SetBaseURL() - // Only need to do this on the final uri - if (NS_SUCCEEDED(rv) && i == 0) { - rv = nsContentUtils::GetSecurityManager()-> - CheckLoadURIWithPrincipal(NodePrincipal(), newBase, - nsIScriptSecurityManager::STANDARD); - } - if (NS_SUCCEEDED(rv)) { - base.swap(newBase); + if (!baseAttrs.IsEmpty()) { + doc->WarnOnceAbout(nsIDocument::eXMLBaseAttribute); + // Now resolve against all xml:base attrs + for (uint32_t i = baseAttrs.Length() - 1; i != uint32_t(-1); --i) { + nsCOMPtr newBase; + nsresult rv = NS_NewURI(getter_AddRefs(newBase), baseAttrs[i], + doc->GetDocumentCharacterSet().get(), base); + // Do a security check, almost the same as nsDocument::SetBaseURL() + // Only need to do this on the final uri + if (NS_SUCCEEDED(rv) && i == 0) { + rv = nsContentUtils::GetSecurityManager()-> + CheckLoadURIWithPrincipal(NodePrincipal(), newBase, + nsIScriptSecurityManager::STANDARD); + } + if (NS_SUCCEEDED(rv)) { + base.swap(newBase); + } } } diff --git a/dom/base/nsDeprecatedOperationList.h b/dom/base/nsDeprecatedOperationList.h index b326403e77e3..ae2530f41e6e 100644 --- a/dom/base/nsDeprecatedOperationList.h +++ b/dom/base/nsDeprecatedOperationList.h @@ -51,3 +51,4 @@ DEPRECATED_OPERATION(LenientSetter) DEPRECATED_OPERATION(FileLastModifiedDate) DEPRECATED_OPERATION(ImageBitmapRenderingContext_TransferImageBitmap) DEPRECATED_OPERATION(URLCreateObjectURL_MediaStream) +DEPRECATED_OPERATION(XMLBaseAttribute) diff --git a/dom/locales/en-US/chrome/dom/dom.properties b/dom/locales/en-US/chrome/dom/dom.properties index f71c20ec0608..218fcb5da0ab 100644 --- a/dom/locales/en-US/chrome/dom/dom.properties +++ b/dom/locales/en-US/chrome/dom/dom.properties @@ -323,3 +323,5 @@ GeolocationInsecureRequestIsForbidden=A Geolocation request can only be fulfille LargeAllocationNonWin32=This page would be loaded in a new process due to a Large-Allocation header, however Large-Allocation process creation is disabled on non-Win32 platforms. # LOCALIZATION NOTE: Do not translate URL.createObjectURL(MediaStream). URLCreateObjectURL_MediaStream=URL.createObjectURL(MediaStream) is deprecated and will be removed soon. +# LOCALIZATION NOTE: Do not translate xml:base. +XMLBaseAttributeWarning=Use of xml:base attribute is deprecated and will be removed soon. Please remove any use of it. From fefb089d1f9825c7e70644bec7b114c22a5596fc Mon Sep 17 00:00:00 2001 From: Chris Pearce Date: Wed, 22 Feb 2017 13:04:17 +1300 Subject: [PATCH 11/48] Bug 1341475 - Ensure clearkey doesn't think it can decode AAC on Windows. r=gerald Because it can't now. MozReview-Commit-ID: JCO4zUGaryY --HG-- extra : rebase_source : b3c1ec5cd2b246a85ca3d44f5436252803b76e32 --- dom/media/eme/MediaKeySystemAccess.cpp | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/dom/media/eme/MediaKeySystemAccess.cpp b/dom/media/eme/MediaKeySystemAccess.cpp index 32e4d4163281..6b43f3f6ae3e 100644 --- a/dom/media/eme/MediaKeySystemAccess.cpp +++ b/dom/media/eme/MediaKeySystemAccess.cpp @@ -272,21 +272,16 @@ GetSupportedKeySystems() clearkey.mSessionTypes.AppendElement(MediaKeySessionType::Persistent_license); } #if defined(XP_WIN) - // Clearkey CDM uses WMF decoders on Windows. - if (WMFDecoderModule::HasAAC()) { - clearkey.mMP4.SetCanDecryptAndDecode(EME_CODEC_AAC); - } else { - clearkey.mMP4.SetCanDecrypt(EME_CODEC_AAC); - } + // Clearkey CDM uses WMF's H.264 decoder on Windows. if (WMFDecoderModule::HasH264()) { clearkey.mMP4.SetCanDecryptAndDecode(EME_CODEC_H264); } else { clearkey.mMP4.SetCanDecrypt(EME_CODEC_H264); } #else - clearkey.mMP4.SetCanDecrypt(EME_CODEC_AAC); clearkey.mMP4.SetCanDecrypt(EME_CODEC_H264); #endif + clearkey.mMP4.SetCanDecrypt(EME_CODEC_AAC); if (Preferences::GetBool("media.eme.vp9-in-mp4.enabled", false)) { clearkey.mMP4.SetCanDecrypt(EME_CODEC_VP9); } From 3da56e266dc0355d6fd6e5e71b521f5c559e4db0 Mon Sep 17 00:00:00 2001 From: Shane Caraveo Date: Tue, 21 Feb 2017 16:16:21 -0800 Subject: [PATCH 12/48] Bug 1340739 sidebar window is not the browser window, r=kmag MozReview-Commit-ID: 9HBwIaAefO1 --HG-- extra : rebase_source : 00bd8aaee20d4c9b3c5988a260416d4e515144d6 --- .../test/browser/browser_ext_sidebarAction.js | 43 +++++++++++++++++++ .../components/extensions/ExtensionParent.jsm | 5 ++- 2 files changed, 47 insertions(+), 1 deletion(-) diff --git a/browser/components/extensions/test/browser/browser_ext_sidebarAction.js b/browser/components/extensions/test/browser/browser_ext_sidebarAction.js index e6fb985f3e29..1e27fb082b38 100644 --- a/browser/components/extensions/test/browser/browser_ext_sidebarAction.js +++ b/browser/components/extensions/test/browser/browser_ext_sidebarAction.js @@ -126,6 +126,49 @@ add_task(function* sidebar_empty_panel() { yield extension.unload(); }); +add_task(function* sidebar_tab_query_bug_1340739() { + let data = { + manifest: { + "permissions": [ + "tabs", + ], + "sidebar_action": { + "default_panel": "sidebar.html", + }, + }, + useAddonManager: "temporary", + files: { + "sidebar.html": ` + + + + + + + A Test Sidebar + + `, + "sidebar.js": function() { + Promise.all([ + browser.tabs.query({}).then((tabs) => { + browser.test.assertEq(1, tabs.length, "got tab without currentWindow"); + }), + browser.tabs.query({currentWindow: true}).then((tabs) => { + browser.test.assertEq(1, tabs.length, "got tab with currentWindow"); + }), + ]).then(() => { + browser.test.sendMessage("sidebar"); + }); + }, + }, + }; + + let extension = ExtensionTestUtils.loadExtension(data); + yield extension.startup(); + yield extension.awaitMessage("sidebar"); + yield extension.unload(); +}); + add_task(function* cleanup() { // This is set on initial sidebar install. Services.prefs.clearUserPref("extensions.sidebar-button.shown"); diff --git a/toolkit/components/extensions/ExtensionParent.jsm b/toolkit/components/extensions/ExtensionParent.jsm index cb353d8a42ab..a4a7a8b443ab 100644 --- a/toolkit/components/extensions/ExtensionParent.jsm +++ b/toolkit/components/extensions/ExtensionParent.jsm @@ -366,7 +366,10 @@ class ExtensionPageContextParent extends ProxyContextParent { // The window that contains this context. This may change due to moving tabs. get xulWindow() { - return this.xulBrowser.ownerGlobal; + let win = this.xulBrowser.ownerGlobal; + return win.QueryInterface(Ci.nsIInterfaceRequestor).getInterface(Ci.nsIDocShell) + .QueryInterface(Ci.nsIDocShellTreeItem).rootTreeItem + .QueryInterface(Ci.nsIInterfaceRequestor).getInterface(Ci.nsIDOMWindow); } get currentWindow() { From 970ca57ee78debbcc3ab69c515af93dbfde0b307 Mon Sep 17 00:00:00 2001 From: Kris Maglione Date: Sat, 11 Feb 2017 14:26:05 -0800 Subject: [PATCH 13/48] Bug 1322273: Return DeadObjectProxy when wrapping for nuked compartment. r=bholley MozReview-Commit-ID: V07P0eZvKO --HG-- extra : rebase_source : 52a20f4a6ee9b9a85c4eb9191a4c86076455f19e --- js/xpconnect/tests/unit/test_nuke_sandbox.js | 37 +++++++++++++++---- js/xpconnect/wrappers/WrapperFactory.cpp | 38 ++++++++++++-------- 2 files changed, 54 insertions(+), 21 deletions(-) diff --git a/js/xpconnect/tests/unit/test_nuke_sandbox.js b/js/xpconnect/tests/unit/test_nuke_sandbox.js index a4dd25498af1..9659902610d8 100644 --- a/js/xpconnect/tests/unit/test_nuke_sandbox.js +++ b/js/xpconnect/tests/unit/test_nuke_sandbox.js @@ -4,20 +4,46 @@ /* See https://bugzilla.mozilla.org/show_bug.cgi?id=769273 */ +const {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components; + +const global = this; + function run_test() { - var sb = Components.utils.Sandbox("http://www.blah.com"); + var ifacePointer = Cc["@mozilla.org/supports-interface-pointer;1"] + .createInstance(Ci.nsISupportsInterfacePointer); + + var sb = Cu.Sandbox(global); sb.prop = "prop" - var refToObjFromSb = Components.utils.evalInSandbox("var a = {prop2:'prop2'}; a", sb); - Components.utils.nukeSandbox(sb); - do_check_true(Components.utils.isDeadWrapper(sb), "sb should be dead"); + sb.ifacePointer = ifacePointer + + var refToObjFromSb = Cu.evalInSandbox(` + Components.utils.import("resource://gre/modules/XPCOMUtils.jsm"); + + ifacePointer.data = { + QueryInterface: XPCOMUtils.generateQI([]), + wrappedJSObject: {foo: "bar"}, + }; + + var a = {prop2:'prop2'}; + a + `, sb); + + equal(ifacePointer.data.wrappedJSObject.foo, "bar", + "Got expected wrapper into sandbox") + + Cu.nukeSandbox(sb); + ok(Cu.isDeadWrapper(sb), "sb should be dead"); + ok(Cu.isDeadWrapper(ifacePointer.data.wrappedJSObject), + "Wrapper retrieved via XPConnect should be dead"); + try{ sb.prop; do_check_true(false); } catch (e) { do_check_true(e.toString().indexOf("can't access dead object") > -1); } - + Components.utils.isDeadWrapper(refToObjFromSb, "ref to object from sb should be dead"); try{ refToObjFromSb.prop2; @@ -25,5 +51,4 @@ function run_test() } catch (e) { do_check_true(e.toString().indexOf("can't access dead object") > -1); } - } diff --git a/js/xpconnect/wrappers/WrapperFactory.cpp b/js/xpconnect/wrappers/WrapperFactory.cpp index bdb727841f08..c9ae96b7ff92 100644 --- a/js/xpconnect/wrappers/WrapperFactory.cpp +++ b/js/xpconnect/wrappers/WrapperFactory.cpp @@ -181,6 +181,24 @@ WrapperFactory::PrepareForWrapping(JSContext* cx, HandleObject scope, ExposeObjectToActiveJS(obj); } + // If we've somehow gotten to this point after either the source or target + // compartment has been nuked, return a DeadObjectProxy to prevent further + // access. + JSCompartment* origin = js::GetObjectCompartment(obj); + JSCompartment* target = js::GetObjectCompartment(scope); + if (CompartmentPrivate::Get(origin)->wasNuked || + CompartmentPrivate::Get(target)->wasNuked) { + NS_WARNING("Trying to create a wrapper into or out of a nuked compartment"); + + RootedObject ccw(cx, Wrapper::New(cx, obj, &CrossCompartmentWrapper::singleton)); + + NukeCrossCompartmentWrapper(cx, ccw); + + retObj.set(ccw); + return; + } + + // If we've got a WindowProxy, there's nothing special that needs to be // done here, and we can move on to the next phase of wrapping. We handle // this case first to allow us to assert against wrappers below. @@ -332,8 +350,10 @@ DEBUG_CheckUnwrapSafety(HandleObject obj, const js::Wrapper* handler, JSCompartment* origin, JSCompartment* target) { if (CompartmentPrivate::Get(origin)->wasNuked || CompartmentPrivate::Get(target)->wasNuked) { - // If either compartment has already been nuked, we should have an opaque wrapper. - MOZ_ASSERT(handler->hasSecurityPolicy()); + // If either compartment has already been nuked, we should have returned + // a dead wrapper from our prewrap callback, and this function should + // not be called. + MOZ_ASSERT_UNREACHABLE("CheckUnwrapSafety called for a dead wrapper"); } else if (AccessCheck::isChrome(target) || xpc::IsUniversalXPConnectEnabled(target)) { // If the caller is chrome (or effectively so), unwrap should always be allowed. MOZ_ASSERT(!handler->hasSecurityPolicy()); @@ -457,21 +477,9 @@ WrapperFactory::Rewrap(JSContext* cx, HandleObject existing, HandleObject obj) // First, handle the special cases. // - // If we've somehow gotten to this point after either the source or target - // compartment has been nuked, return an opaque wrapper to prevent further - // access. - // Ideally, we should return a DeadProxyObject instead of a wrapper in this - // case (bug 1322273). - if (CompartmentPrivate::Get(origin)->wasNuked || - CompartmentPrivate::Get(target)->wasNuked) { - NS_WARNING("Trying to create a wrapper into or out of a nuked compartment"); - - wrapper = &FilteringWrapper::singleton; - } - // If UniversalXPConnect is enabled, this is just some dumb mochitest. Use // a vanilla CCW. - else if (xpc::IsUniversalXPConnectEnabled(target)) { + if (xpc::IsUniversalXPConnectEnabled(target)) { CrashIfNotInAutomation(); wrapper = &CrossCompartmentWrapper::singleton; } From a226f9e31018e9cd7222adc4b34a9cf118da6205 Mon Sep 17 00:00:00 2001 From: Shane Caraveo Date: Tue, 21 Feb 2017 10:00:06 -0800 Subject: [PATCH 14/48] Bug 1313459 support CUI areas for browserAction, r=aswan MozReview-Commit-ID: IoPOCv6M0qy --HG-- extra : rebase_source : 501d3bd94c7f2859c8c5b3b05667cdb35a679b62 --- .../extensions/ext-browserAction.js | 12 ++- .../extensions/schemas/browser_action.json | 6 ++ .../test/browser/browser-common.ini | 1 + .../browser/browser_ext_browserAction_area.js | 73 +++++++++++++++++++ 4 files changed, 90 insertions(+), 2 deletions(-) create mode 100644 browser/components/extensions/test/browser/browser_ext_browserAction_area.js diff --git a/browser/components/extensions/ext-browserAction.js b/browser/components/extensions/ext-browserAction.js index 6dbd2663698a..f7562579ccaa 100644 --- a/browser/components/extensions/ext-browserAction.js +++ b/browser/components/extensions/ext-browserAction.js @@ -38,7 +38,14 @@ function isAncestorOrSelf(target, node) { } // WeakMap[Extension -> BrowserAction] -var browserActionMap = new WeakMap(); +const browserActionMap = new WeakMap(); + +const browserAreas = { + "navbar": CustomizableUI.AREA_NAVBAR, + "menupanel": CustomizableUI.AREA_PANEL, + "tabstrip": CustomizableUI.AREA_TABSTRIP, + "personaltoolbar": CustomizableUI.AREA_BOOKMARKS, +}; // Responsible for the browser_action section of the manifest as well // as the associated popup. @@ -62,6 +69,7 @@ function BrowserAction(options, extension) { badgeBackgroundColor: null, icon: IconDetails.normalize({path: options.default_icon}, extension), popup: options.default_popup || "", + area: browserAreas[options.default_area || "navbar"], }; this.browserStyle = options.browser_style || false; @@ -85,7 +93,7 @@ BrowserAction.prototype = { removable: true, label: this.defaults.title || this.extension.name, tooltiptext: this.defaults.title || "", - defaultArea: CustomizableUI.AREA_NAVBAR, + defaultArea: this.defaults.area, onBeforeCreated: document => { let view = document.createElementNS(XUL_NS, "panelview"); diff --git a/browser/components/extensions/schemas/browser_action.json b/browser/components/extensions/schemas/browser_action.json index 1a7da956a13b..575731e68679 100644 --- a/browser/components/extensions/schemas/browser_action.json +++ b/browser/components/extensions/schemas/browser_action.json @@ -31,6 +31,12 @@ "browser_style": { "type": "boolean", "optional": true + }, + "default_area": { + "description": "Defines the location the browserAction will appear by default. The default location is navbar.", + "type": "string", + "enum": ["navbar", "menupanel", "tabstrip", "personaltoolbar"], + "optional": true } }, "optional": true diff --git a/browser/components/extensions/test/browser/browser-common.ini b/browser/components/extensions/test/browser/browser-common.ini index f908835ea766..a4676d81bd49 100644 --- a/browser/components/extensions/test/browser/browser-common.ini +++ b/browser/components/extensions/test/browser/browser-common.ini @@ -24,6 +24,7 @@ support-files = searchSuggestionEngine.sjs ../../../../../toolkit/components/extensions/test/mochitest/head_webrequest.js +[browser_ext_browserAction_area.js] [browser_ext_browserAction_context.js] [browser_ext_browserAction_disabled.js] [browser_ext_browserAction_pageAction_icon.js] diff --git a/browser/components/extensions/test/browser/browser_ext_browserAction_area.js b/browser/components/extensions/test/browser/browser_ext_browserAction_area.js new file mode 100644 index 000000000000..d05eeca3cd7a --- /dev/null +++ b/browser/components/extensions/test/browser/browser_ext_browserAction_area.js @@ -0,0 +1,73 @@ +/* -*- Mode: indent-tabs-mode: nil; js-indent-level: 2 -*- */ +/* vim: set sts=2 sw=2 et tw=80: */ +"use strict"; + +var browserAreas = { + "navbar": CustomizableUI.AREA_NAVBAR, + "menupanel": CustomizableUI.AREA_PANEL, + "tabstrip": CustomizableUI.AREA_TABSTRIP, + "personaltoolbar": CustomizableUI.AREA_BOOKMARKS, +}; + +function* testInArea(area) { + let manifest = { + "browser_action": { + "default_popup": "popup.html", + "browser_style": true, + }, + }; + if (area) { + manifest.browser_action.default_area = area; + } + let extension = ExtensionTestUtils.loadExtension({ + manifest, + files: { + "popup.html": ` + + + + + + + `, + + "popup.js": function() { + window.onload = () => { + browser.test.sendMessage("from-popup"); + }; + }, + }, + }); + yield extension.startup(); + let widget = getBrowserActionWidget(extension); + let placement = CustomizableUI.getPlacementOfWidget(widget.id); + is(placement && placement.area, browserAreas[area || "navbar"], `widget located in correct area`); + + clickBrowserAction(extension); + + yield extension.awaitMessage("from-popup"); + + yield extension.unload(); +} + +add_task(function* testBrowserActionDefaultArea() { + yield testInArea(); +}); + +add_task(function* testBrowserActionInToolbar() { + yield testInArea("navbar"); +}); + +add_task(function* testBrowserActionInMenuPanel() { + yield testInArea("menupanel"); +}); + +add_task(function* testBrowserActionInTabStrip() { + yield testInArea("tabstrip"); +}); + +add_task(function* testBrowserActionInPersonalToolbar() { + CustomizableUI.setToolbarVisibility("PersonalToolbar", true); + yield testInArea("personaltoolbar"); + CustomizableUI.setToolbarVisibility("PersonalToolbar", false); +}); From 0982410db210caa38f3836a006f23806f2e8bffb Mon Sep 17 00:00:00 2001 From: Mike Hommey Date: Thu, 16 Feb 2017 17:33:35 +0900 Subject: [PATCH 15/48] Bug 1341213 - Make the index path for toolchain jobs independent of the source path. r=dustin When I refactored hash_paths to add caching, I mixed things up such that for each file, we end up hashing: (u'$sha256sum', u'$topsrcdir/$relpath') $relpath when the intent was to hash: $sha256sum $relpath This change fixes it, such that now the index paths are independent of the source path, as originally intended. --HG-- extra : rebase_source : 8ff7b49927d2365ed87fa06d8e6fca157faddc7d --- taskcluster/taskgraph/util/hash.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/taskcluster/taskgraph/util/hash.py b/taskcluster/taskgraph/util/hash.py index 4cf2f75c9557..23f87b09b501 100644 --- a/taskcluster/taskgraph/util/hash.py +++ b/taskcluster/taskgraph/util/hash.py @@ -12,8 +12,7 @@ import hashlib @memoize def _hash_path(path): with open(path) as fh: - return (hashlib.sha256(fh.read()).hexdigest(), - mozpath.normsep(path)) + return hashlib.sha256(fh.read()).hexdigest() def hash_paths(base_path, patterns): From f99718e2722a3f6c1c32468a8bff30d01f6faab9 Mon Sep 17 00:00:00 2001 From: Mike Hommey Date: Fri, 17 Feb 2017 11:56:12 +0900 Subject: [PATCH 16/48] Bug 1341214 - Define GECKO in a single location. r=dustin Instead of every file trying to get the top source directory having an ad-hoc definition that gets wrong if the files gets moved around for some reason, define it in a more central location. --HG-- extra : rebase_source : 06fa06d47732223e19b0201f8791fdbffdc9ee03 --- taskcluster/taskgraph/__init__.py | 7 +++++++ taskcluster/taskgraph/cron/__init__.py | 2 +- taskcluster/taskgraph/decision.py | 2 +- taskcluster/taskgraph/docker.py | 2 +- taskcluster/taskgraph/filter_tasks.py | 3 --- taskcluster/taskgraph/task/docker_image.py | 2 +- taskcluster/taskgraph/taskgraph.py | 3 --- taskcluster/taskgraph/transforms/job/toolchain.py | 4 +--- taskcluster/taskgraph/util/docker.py | 2 +- 9 files changed, 13 insertions(+), 14 deletions(-) diff --git a/taskcluster/taskgraph/__init__.py b/taskcluster/taskgraph/__init__.py index e69de29bb2d1..84b524c81a37 100644 --- a/taskcluster/taskgraph/__init__.py +++ b/taskcluster/taskgraph/__init__.py @@ -0,0 +1,7 @@ +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. + +import os + +GECKO = os.path.realpath(os.path.join(__file__, '..', '..', '..')) diff --git a/taskcluster/taskgraph/cron/__init__.py b/taskcluster/taskgraph/cron/__init__.py index 9745cea38acc..8c372892a1d1 100644 --- a/taskcluster/taskgraph/cron/__init__.py +++ b/taskcluster/taskgraph/cron/__init__.py @@ -21,6 +21,7 @@ from .util import ( calculate_head_rev ) from ..create import create_task +from .. import GECKO from taskgraph.util.attributes import match_run_on_projects from taskgraph.util.schema import resolve_keyed_by @@ -32,7 +33,6 @@ JOB_TYPES = { 'decision-task': decision.run_decision_task, } -GECKO = os.path.realpath(os.path.join(__file__, '..', '..', '..', '..')) logger = logging.getLogger(__name__) _session = None diff --git a/taskcluster/taskgraph/decision.py b/taskcluster/taskgraph/decision.py index b33dcaec7a58..1521dfcee949 100644 --- a/taskcluster/taskgraph/decision.py +++ b/taskcluster/taskgraph/decision.py @@ -18,6 +18,7 @@ from .create import create_tasks from .parameters import Parameters from .taskgraph import TaskGraph from actions import render_actions_json +from . import GECKO from taskgraph.util.templates import Templates from taskgraph.util.time import ( @@ -28,7 +29,6 @@ from taskgraph.util.time import ( logger = logging.getLogger(__name__) ARTIFACTS_DIR = 'artifacts' -GECKO = os.path.realpath(os.path.join(__file__, '..', '..', '..')) # For each project, this gives a set of parameters specific to the project. # See `taskcluster/docs/parameters.rst` for information on parameters. diff --git a/taskcluster/taskgraph/docker.py b/taskcluster/taskgraph/docker.py index f053378df83f..1b30a09c2f3e 100644 --- a/taskcluster/taskgraph/docker.py +++ b/taskcluster/taskgraph/docker.py @@ -18,8 +18,8 @@ from subprocess import Popen, PIPE from io import BytesIO from taskgraph.util import docker +from . import GECKO -GECKO = os.path.realpath(os.path.join(__file__, '..', '..', '..')) INDEX_URL = 'https://index.taskcluster.net/v1/task/' + docker.INDEX_PREFIX + '.{}.{}.hash.{}' ARTIFACT_URL = 'https://queue.taskcluster.net/v1/task/{}/artifacts/{}' diff --git a/taskcluster/taskgraph/filter_tasks.py b/taskcluster/taskgraph/filter_tasks.py index e24c30d1e33a..db28eb570dd1 100644 --- a/taskcluster/taskgraph/filter_tasks.py +++ b/taskcluster/taskgraph/filter_tasks.py @@ -5,7 +5,6 @@ from __future__ import absolute_import, unicode_literals import logging -import os from . import ( target_tasks, @@ -13,8 +12,6 @@ from . import ( logger = logging.getLogger(__name__) -GECKO = os.path.realpath(os.path.join(os.path.dirname(__file__), '..', '..')) - filter_task_functions = {} diff --git a/taskcluster/taskgraph/task/docker_image.py b/taskcluster/taskgraph/task/docker_image.py index 9a72420fa9d8..33e5618b6908 100644 --- a/taskcluster/taskgraph/task/docker_image.py +++ b/taskcluster/taskgraph/task/docker_image.py @@ -9,6 +9,7 @@ import os import urllib2 from . import base +from .. import GECKO from taskgraph.util.docker import ( docker_image, generate_context_hash, @@ -17,7 +18,6 @@ from taskgraph.util.docker import ( from taskgraph.util.templates import Templates logger = logging.getLogger(__name__) -GECKO = os.path.realpath(os.path.join(__file__, '..', '..', '..', '..')) # if running in a task, prefer to use the taskcluster proxy (http://taskcluster/), # otherwise hit the services directly diff --git a/taskcluster/taskgraph/taskgraph.py b/taskcluster/taskgraph/taskgraph.py index 606ea209868a..82167cff708c 100644 --- a/taskcluster/taskgraph/taskgraph.py +++ b/taskcluster/taskgraph/taskgraph.py @@ -4,13 +4,10 @@ from __future__ import absolute_import, print_function, unicode_literals -import os - from .graph import Graph from .util.python_path import find_object TASKCLUSTER_QUEUE_URL = "https://queue.taskcluster.net/v1/task/" -GECKO = os.path.realpath(os.path.join(__file__, '..', '..', '..')) class TaskGraph(object): diff --git a/taskcluster/taskgraph/transforms/job/toolchain.py b/taskcluster/taskgraph/transforms/job/toolchain.py index e6581401fc44..c8bb8fad007b 100644 --- a/taskcluster/taskgraph/transforms/job/toolchain.py +++ b/taskcluster/taskgraph/transforms/job/toolchain.py @@ -7,8 +7,6 @@ Support for running toolchain-building jobs via dedicated scripts from __future__ import absolute_import, print_function, unicode_literals -import os - from voluptuous import Schema, Optional, Required, Any from taskgraph.transforms.job import run_job_using @@ -18,9 +16,9 @@ from taskgraph.transforms.job.common import ( docker_worker_support_vcs_checkout, ) from taskgraph.util.hash import hash_paths +from taskgraph import GECKO -GECKO = os.path.realpath(os.path.join(__file__, '..', '..', '..', '..', '..')) TOOLCHAIN_INDEX = 'gecko.cache.level-{level}.toolchains.v1.{name}.{digest}' toolchain_run_schema = Schema({ diff --git a/taskcluster/taskgraph/util/docker.py b/taskcluster/taskgraph/util/docker.py index 09289b6447f5..46077bdc9d5c 100644 --- a/taskcluster/taskgraph/util/docker.py +++ b/taskcluster/taskgraph/util/docker.py @@ -14,9 +14,9 @@ import tempfile from mozpack.archive import ( create_tar_gz_from_files, ) +from .. import GECKO -GECKO = os.path.realpath(os.path.join(__file__, '..', '..', '..', '..')) IMAGE_DIR = os.path.join(GECKO, 'taskcluster', 'docker') INDEX_PREFIX = 'docker.images.v2' ARTIFACT_URL = 'https://queue.taskcluster.net/v1/task/{}/artifacts/{}' From 3e79befa4b6556dad3fcc2970a5dab8a30c29f31 Mon Sep 17 00:00:00 2001 From: Mike Hommey Date: Fri, 17 Feb 2017 12:04:48 +0900 Subject: [PATCH 17/48] Bug 1341214 - Add a small API to handle taskcluster queue and index requests. r=dustin Various modules under taskcluster are doing ad-hoc url formatting or requests to taskcluster services. While we could use the taskcluster client python module, it's kind of overkill for the simple requests done here. So instead of vendoring that module, create a smaller one with a limited set of functions we need. This changes the behavior of the get_artifact function to return a file-like object when the file is neither a json nor a yaml, but that branch was never used (and was actually returning an unassigned variable, so it was broken anyways). At the same time, make the function that does HTTP requests more error-resistant, using urllib3's Retry with a backoff factor. Also add a function that retrieves the list of artifacts, that while currently unused, will be used by `mach artifact` shortly. --HG-- extra : rebase_source : 06777dea62e884f546a5b951baad80fd8aec1f1e --- taskcluster/mach_commands.py | 2 - taskcluster/taskgraph/action.py | 14 +--- taskcluster/taskgraph/docker.py | 17 +++-- taskcluster/taskgraph/parameters.py | 6 +- taskcluster/taskgraph/task/base.py | 20 ++--- taskcluster/taskgraph/task/docker_image.py | 10 +-- taskcluster/taskgraph/taskgraph.py | 2 - .../transforms/job/mozharness_test.py | 29 ++++--- taskcluster/taskgraph/transforms/signing.py | 3 - taskcluster/taskgraph/util/docker.py | 1 - taskcluster/taskgraph/util/taskcluster.py | 76 +++++++++++++++++++ 11 files changed, 110 insertions(+), 70 deletions(-) create mode 100644 taskcluster/taskgraph/util/taskcluster.py diff --git a/taskcluster/mach_commands.py b/taskcluster/mach_commands.py index 176fda2c83ee..749b684c4dbc 100644 --- a/taskcluster/mach_commands.py +++ b/taskcluster/mach_commands.py @@ -22,8 +22,6 @@ from mach.decorators import ( from mozbuild.base import MachCommandBase -ARTIFACT_URL = 'https://queue.taskcluster.net/v1/task/{}/artifacts/{}' - class ShowTaskGraphSubCommand(SubCommand): """A SubCommand with TaskGraph-specific arguments""" diff --git a/taskcluster/taskgraph/action.py b/taskcluster/taskgraph/action.py index 2f7a0ed46f93..601435d6a3dd 100644 --- a/taskcluster/taskgraph/action.py +++ b/taskcluster/taskgraph/action.py @@ -6,18 +6,17 @@ from __future__ import absolute_import, print_function, unicode_literals -import json import logging import requests -import yaml from .create import create_tasks from .decision import write_artifact from .optimize import optimize_task_graph from .taskgraph import TaskGraph +from .util.taskcluster import get_artifact + logger = logging.getLogger(__name__) -TASKCLUSTER_QUEUE_URL = "https://queue.taskcluster.net/v1/task" TREEHERDER_URL = "https://treeherder.mozilla.org/api" # We set this to 5 for now because this is what SETA sets the @@ -63,15 +62,6 @@ def add_tasks(decision_task_id, task_labels, prefix=''): create_tasks(optimized_graph, label_to_taskid, decision_params) -def get_artifact(task_id, path): - resp = requests.get(url="{}/{}/artifacts/{}".format(TASKCLUSTER_QUEUE_URL, task_id, path)) - if path.endswith('.json'): - artifact = json.loads(resp.text) - elif path.endswith('.yml'): - artifact = yaml.load(resp.text) - return artifact - - def backfill(project, job_id): """ Run the backfill task. This function implements `mach taskgraph backfill-task`, diff --git a/taskcluster/taskgraph/docker.py b/taskcluster/taskgraph/docker.py index 1b30a09c2f3e..76e333ec6296 100644 --- a/taskcluster/taskgraph/docker.py +++ b/taskcluster/taskgraph/docker.py @@ -12,31 +12,32 @@ import sys import subprocess import tarfile import tempfile -import urllib2 import which from subprocess import Popen, PIPE from io import BytesIO from taskgraph.util import docker +from taskgraph.util.taskcluster import ( + find_task_id, + get_artifact_url, +) from . import GECKO -INDEX_URL = 'https://index.taskcluster.net/v1/task/' + docker.INDEX_PREFIX + '.{}.{}.hash.{}' -ARTIFACT_URL = 'https://queue.taskcluster.net/v1/task/{}/artifacts/{}' +DOCKER_INDEX = docker.INDEX_PREFIX + '.{}.{}.hash.{}' def load_image_by_name(image_name, tag=None): context_path = os.path.join(GECKO, 'taskcluster', 'docker', image_name) context_hash = docker.generate_context_hash(GECKO, context_path, image_name) - image_index_url = INDEX_URL.format('level-3', image_name, context_hash) - print("Fetching", image_index_url) - task = json.load(urllib2.urlopen(image_index_url)) + index_path = DOCKER_INDEX.format('level-3', image_name, context_hash) + task_id = find_task_id(index_path) - return load_image_by_task_id(task['taskId'], tag) + return load_image_by_task_id(task_id, tag) def load_image_by_task_id(task_id, tag=None): - artifact_url = ARTIFACT_URL.format(task_id, 'public/image.tar.zst') + artifact_url = get_artifact_url(task_id, 'public/image.tar.zst') result = load_image(artifact_url, tag) print("Found docker image: {}:{}".format(result['image'], result['tag'])) if tag: diff --git a/taskcluster/taskgraph/parameters.py b/taskcluster/taskgraph/parameters.py index f7ee8fab9342..925dc39d3981 100644 --- a/taskcluster/taskgraph/parameters.py +++ b/taskcluster/taskgraph/parameters.py @@ -62,9 +62,7 @@ def load_parameters_file(options): Load parameters from the --parameters option """ import urllib - - url_prefix = "https://queue.taskcluster.net/v1/task/" - url_postfix = "/artifacts/public/parameters.yml" + from taskgraph.util.taskcluster import get_artifact_url filename = options['parameters'] @@ -78,7 +76,7 @@ def load_parameters_file(options): # fetching parameters.yml using task task-id or supplied url if filename.startswith("task-id="): task_id = filename.split("=")[1] - filename = url_prefix + task_id + url_postfix + filename = get_artifact_url(task_id, 'public/parameters.yml') f = urllib.urlopen(filename) if filename.endswith('.yml'): diff --git a/taskcluster/taskgraph/task/base.py b/taskcluster/taskgraph/task/base.py index 084f90ae1fc2..01c28df7c16f 100644 --- a/taskcluster/taskgraph/task/base.py +++ b/taskcluster/taskgraph/task/base.py @@ -5,17 +5,8 @@ from __future__ import absolute_import, print_function, unicode_literals import abc -import json -import os -import urllib2 - - -# if running in a task, prefer to use the taskcluster proxy (http://taskcluster/), -# otherwise hit the services directly -if os.environ.get('TASK_ID'): - INDEX_URL = 'http://taskcluster/index/v1/task/{}' -else: - INDEX_URL = 'https://index.taskcluster.net/v1/task/{}' +import requests +from taskgraph.util.taskcluster import find_task_id class Task(object): @@ -109,11 +100,10 @@ class Task(object): """ for index_path in self.index_paths: try: - url = INDEX_URL.format(index_path) - existing_task = json.load(urllib2.urlopen(url)) + task_id = find_task_id(index_path) - return True, existing_task['taskId'] - except urllib2.HTTPError: + return True, task_id + except requests.exceptions.HTTPError: pass return False, None diff --git a/taskcluster/taskgraph/task/docker_image.py b/taskcluster/taskgraph/task/docker_image.py index 33e5618b6908..ce2b622def22 100644 --- a/taskcluster/taskgraph/task/docker_image.py +++ b/taskcluster/taskgraph/task/docker_image.py @@ -15,17 +15,11 @@ from taskgraph.util.docker import ( generate_context_hash, INDEX_PREFIX, ) +from taskgraph.util.taskcluster import get_artifact_url from taskgraph.util.templates import Templates logger = logging.getLogger(__name__) -# if running in a task, prefer to use the taskcluster proxy (http://taskcluster/), -# otherwise hit the services directly -if os.environ.get('TASK_ID'): - ARTIFACT_URL = 'http://taskcluster/queue/v1/task/{}/artifacts/{}' -else: - ARTIFACT_URL = 'https://queue.taskcluster.net/v1/task/{}/artifacts/{}' - class DockerImageTask(base.Task): @@ -94,7 +88,7 @@ class DockerImageTask(base.Task): # Only return the task ID if the artifact exists for the indexed # task. request = urllib2.Request( - ARTIFACT_URL.format(taskId, 'public/image.tar.zst')) + get_artifact_url(taskId, 'public/image.tar.zst')) request.get_method = lambda: 'HEAD' urllib2.urlopen(request) diff --git a/taskcluster/taskgraph/taskgraph.py b/taskcluster/taskgraph/taskgraph.py index 82167cff708c..4722002a3678 100644 --- a/taskcluster/taskgraph/taskgraph.py +++ b/taskcluster/taskgraph/taskgraph.py @@ -7,8 +7,6 @@ from __future__ import absolute_import, print_function, unicode_literals from .graph import Graph from .util.python_path import find_object -TASKCLUSTER_QUEUE_URL = "https://queue.taskcluster.net/v1/task/" - class TaskGraph(object): """ diff --git a/taskcluster/taskgraph/transforms/job/mozharness_test.py b/taskcluster/taskgraph/transforms/job/mozharness_test.py index ac84242264bc..2fd8f89de32f 100644 --- a/taskcluster/taskgraph/transforms/job/mozharness_test.py +++ b/taskcluster/taskgraph/transforms/job/mozharness_test.py @@ -3,6 +3,7 @@ # file, You can obtain one at http://mozilla.org/MPL/2.0/. from voluptuous import Schema, Required +from taskgraph.util.taskcluster import get_artifact_url from taskgraph.transforms.job import run_job_using from taskgraph.transforms.tests import ( test_description_schema, @@ -15,8 +16,6 @@ from taskgraph.transforms.job.common import ( import os import re -ARTIFACT_URL = 'https://queue.taskcluster.net/v1/task/{}/artifacts/{}' - ARTIFACTS = [ # (artifact name prefix, in-image path) ("public/logs/", "build/upload/logs/"), @@ -59,11 +58,11 @@ def mozharness_test_on_docker(config, job, taskdesc): ("public/test_info/", "/home/worker/workspace/build/blobber_upload_dir/"), ] - installer_url = ARTIFACT_URL.format('', mozharness['build-artifact-name']) - test_packages_url = ARTIFACT_URL.format('', - 'public/build/target.test_packages.json') - mozharness_url = ARTIFACT_URL.format('', - 'public/build/mozharness.zip') + installer_url = get_artifact_url('', mozharness['build-artifact-name']) + test_packages_url = get_artifact_url('', + 'public/build/target.test_packages.json') + mozharness_url = get_artifact_url('', + 'public/build/mozharness.zip') worker['artifacts'] = [{ 'name': prefix, @@ -206,11 +205,11 @@ def mozharness_test_on_windows(config, job, taskdesc): target = 'firefox-{}.en-US.{}'.format(get_firefox_version(), build_platform) - installer_url = ARTIFACT_URL.format( + installer_url = get_artifact_url( '', 'public/build/{}.zip'.format(target)) - test_packages_url = ARTIFACT_URL.format( + test_packages_url = get_artifact_url( '', 'public/build/{}.test_packages.json'.format(target)) - mozharness_url = ARTIFACT_URL.format( + mozharness_url = get_artifact_url( '', 'public/build/mozharness.zip') taskdesc['scopes'].extend( @@ -270,11 +269,11 @@ def mozharness_test_on_mac_osx(config, job, taskdesc): mozharness = test['mozharness'] worker = taskdesc['worker'] - installer_url = ARTIFACT_URL.format('', mozharness['build-artifact-name']) - test_packages_url = ARTIFACT_URL.format('', - 'public/build/target.test_packages.json') - mozharness_url = ARTIFACT_URL.format('', - 'public/build/mozharness.zip') + installer_url = get_artifact_url('', mozharness['build-artifact-name']) + test_packages_url = get_artifact_url('', + 'public/build/target.test_packages.json') + mozharness_url = get_artifact_url('', + 'public/build/mozharness.zip') worker['artifacts'] = [{ 'name': prefix.rstrip('/'), diff --git a/taskcluster/taskgraph/transforms/signing.py b/taskcluster/taskgraph/transforms/signing.py index efcce4259b70..c5fc10f2d047 100644 --- a/taskcluster/taskgraph/transforms/signing.py +++ b/taskcluster/taskgraph/transforms/signing.py @@ -13,9 +13,6 @@ from taskgraph.transforms.task import task_description_schema from voluptuous import Schema, Any, Required, Optional -ARTIFACT_URL = 'https://queue.taskcluster.net/v1/task/<{}>/artifacts/{}' - - # Voluptuous uses marker objects as dictionary *keys*, but they are not # comparable, so we cast all of the keys back to regular strings task_description_schema = {str(k): v for k, v in task_description_schema.schema.iteritems()} diff --git a/taskcluster/taskgraph/util/docker.py b/taskcluster/taskgraph/util/docker.py index 46077bdc9d5c..d7c38002f26f 100644 --- a/taskcluster/taskgraph/util/docker.py +++ b/taskcluster/taskgraph/util/docker.py @@ -19,7 +19,6 @@ from .. import GECKO IMAGE_DIR = os.path.join(GECKO, 'taskcluster', 'docker') INDEX_PREFIX = 'docker.images.v2' -ARTIFACT_URL = 'https://queue.taskcluster.net/v1/task/{}/artifacts/{}' def docker_image(name, by_tag=False): diff --git a/taskcluster/taskgraph/util/taskcluster.py b/taskcluster/taskgraph/util/taskcluster.py new file mode 100644 index 000000000000..0dbd35c45968 --- /dev/null +++ b/taskcluster/taskgraph/util/taskcluster.py @@ -0,0 +1,76 @@ +# -*- coding: utf-8 -*- + +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. + +from __future__ import absolute_import, print_function, unicode_literals + +import functools +import os +import yaml +import requests +from mozbuild.util import memoize +from requests.packages.urllib3.util.retry import Retry +from requests.adapters import HTTPAdapter + + +# if running in a task, prefer to use the taskcluster proxy +# (http://taskcluster/), otherwise hit the services directly +if os.environ.get('TASK_ID'): + INDEX_URL = 'http://taskcluster/index/v1/task/{}' + ARTIFACT_URL = 'http://taskcluster/queue/v1/task/{}/artifacts/{}' +else: + INDEX_URL = 'https://index.taskcluster.net/v1/task/{}' + ARTIFACT_URL = 'https://queue.taskcluster.net/v1/task/{}/artifacts/{}' + + +@memoize +def _get_session(): + session = requests.Session() + retry = Retry(total=5, backoff_factor=0.1, + status_forcelist=[500, 502, 503, 504]) + session.mount('http://', HTTPAdapter(max_retries=retry)) + session.mount('https://', HTTPAdapter(max_retries=retry)) + return session + + +def _do_request(url): + session = _get_session() + return session.get(url, stream=True) + + +def get_artifact_url(task_id, path): + return ARTIFACT_URL.format(task_id, path) + + +def get_artifact(task_id, path): + """ + Returns the artifact with the given path for the given task id. + + If the path ends with ".json" or ".yml", the content is deserialized as, + respectively, json or yaml, and the corresponding python data (usually + dict) is returned. + For other types of content, a file-like object is returned. + """ + response = _do_request(get_artifact_url(task_id, path)) + response.raise_for_status() + if path.endswith('.json'): + return response.json() + if path.endswith('.yml'): + return yaml.load(response.text) + response.raw.read = functools.partial(response.raw.read, + decode_content=True) + return response.raw + + +def list_artifacts(task_id): + response = _do_request(get_artifact_url(task_id, '').rstrip('/')) + response.raise_for_status() + return response.json()['artifacts'] + + +def find_task_id(index_path): + response = _do_request(INDEX_URL.format(index_path)) + response.raise_for_status() + return response.json()['taskId'] From bf7f47db2be7ad026423fa11ed20fdfe9986acc9 Mon Sep 17 00:00:00 2001 From: Ethan Glasser-Camp Date: Tue, 17 Jan 2017 13:25:02 -0500 Subject: [PATCH 18/48] Bug 1328974: Record metrics for chrome.storage.sync usage, r=bsmedberg,kmag MozReview-Commit-ID: 7c2CHLuXxS6 --HG-- extra : rebase_source : f56bf58bfdf2f3ecb7fb5dbe8ee22d3a3569ae34 extra : source : c48083c4b41537af44a38722e64d8e10987ba199 --- services/common/kinto-storage-adapter.js | 16 ++++++ .../extensions/ExtensionStorageSync.jsm | 31 ++++++++++- .../test/xpcshell/test_ext_storage_sync.js | 24 ++++++++- toolkit/components/telemetry/Histograms.json | 31 +++++++++++ toolkit/components/telemetry/Scalars.yaml | 52 +++++++++++++++++++ 5 files changed, 151 insertions(+), 3 deletions(-) diff --git a/services/common/kinto-storage-adapter.js b/services/common/kinto-storage-adapter.js index bcfcc0b9e82e..6448620a2c6b 100644 --- a/services/common/kinto-storage-adapter.js +++ b/services/common/kinto-storage-adapter.js @@ -173,6 +173,11 @@ const statements = { "scanAllRecords": `SELECT * FROM collection_data;`, "clearCollectionMetadata": `DELETE FROM collection_metadata;`, + + "calculateStorage": ` + SELECT collection_name, SUM(LENGTH(record)) as size, COUNT(record) as num_records + FROM collection_data + GROUP BY collection_name;`, }; const createStatements = [ @@ -380,6 +385,17 @@ class FirefoxAdapter extends Kinto.adapters.BaseAdapter { }); } + calculateStorage() { + return this._executeStatement(statements.calculateStorage, {}) + .then(result => { + return Array.from(result, row => ({ + collectionName: row.getResultByName("collection_name"), + size: row.getResultByName("size"), + numRecords: row.getResultByName("num_records"), + })); + }); + } + /** * Reset the sync status of every record and collection we have * access to. diff --git a/toolkit/components/extensions/ExtensionStorageSync.jsm b/toolkit/components/extensions/ExtensionStorageSync.jsm index 47bed3283339..c8637b68c49f 100644 --- a/toolkit/components/extensions/ExtensionStorageSync.jsm +++ b/toolkit/components/extensions/ExtensionStorageSync.jsm @@ -30,6 +30,12 @@ const STORAGE_SYNC_CRYPTO_SALT_LENGTH_BYTES = 32; const FXA_OAUTH_OPTIONS = { scope: STORAGE_SYNC_SCOPE, }; +const HISTOGRAM_GET_OPS_SIZE = "STORAGE_SYNC_GET_OPS_SIZE"; +const HISTOGRAM_SET_OPS_SIZE = "STORAGE_SYNC_SET_OPS_SIZE"; +const HISTOGRAM_REMOVE_OPS = "STORAGE_SYNC_REMOVE_OPS"; +const SCALAR_EXTENSIONS_USING = "storage.sync.api.usage.extensions_using"; +const SCALAR_ITEMS_STORED = "storage.sync.api.usage.items_stored"; +const SCALAR_STORAGE_CONSUMED = "storage.sync.api.usage.storage_consumed"; // Default is 5sec, which seems a bit aggressive on the open internet const KINTO_REQUEST_TIMEOUT = 30000; @@ -61,6 +67,8 @@ XPCOMUtils.defineLazyModuleGetter(this, "Log", "resource://gre/modules/Log.jsm"); XPCOMUtils.defineLazyModuleGetter(this, "Observers", "resource://services-common/observers.js"); +XPCOMUtils.defineLazyModuleGetter(this, "Services", + "resource://gre/modules/Services.jsm"); XPCOMUtils.defineLazyModuleGetter(this, "Sqlite", "resource://gre/modules/Sqlite.jsm"); XPCOMUtils.defineLazyModuleGetter(this, "Svc", @@ -718,9 +726,12 @@ class ExtensionStorageSync { /** * @param {FXAccounts} fxaService (Optional) If not * present, trying to sync will fail. + * @param {nsITelemetry} telemetry Telemetry service to use to + * report sync usage. */ - constructor(fxaService) { + constructor(fxaService, telemetry) { this._fxaService = fxaService; + this._telemetry = telemetry; this.cryptoCollection = new CryptoCollection(fxaService); this.listeners = new WeakMap(); } @@ -741,6 +752,15 @@ class ExtensionStorageSync { }); }); await Promise.all(promises); + + // This needs access to an adapter, but any adapter will do + const collection = await this.cryptoCollection.getCollection(); + const storage = await collection.db.calculateStorage(); + this._telemetry.scalarSet(SCALAR_EXTENSIONS_USING, storage.length); + for (let {collectionName, size, numRecords} of storage) { + this._telemetry.keyedScalarSet(SCALAR_ITEMS_STORED, collectionName, numRecords); + this._telemetry.keyedScalarSet(SCALAR_STORAGE_CONSUMED, collectionName, size); + } } async sync(extension, collection) { @@ -1077,11 +1097,13 @@ class ExtensionStorageSync { const coll = await this.getCollection(extension, context); const keys = Object.keys(items); const ids = keys.map(keyToId); + const histogramSize = this._telemetry.getKeyedHistogramById(HISTOGRAM_SET_OPS_SIZE); const changes = await coll.execute(txn => { let changes = {}; for (let [i, key] of keys.entries()) { const id = ids[i]; let item = items[key]; + histogramSize.add(extension.id, JSON.stringify(item).length); let {oldRecord} = txn.upsert({ id, key, @@ -1121,6 +1143,8 @@ class ExtensionStorageSync { if (Object.keys(changes).length > 0) { this.notifyListeners(extension, changes); } + const histogram = this._telemetry.getKeyedHistogramById(HISTOGRAM_REMOVE_OPS); + histogram.add(extension.id, keys.length); } async clear(extension, context) { @@ -1136,11 +1160,13 @@ class ExtensionStorageSync { async get(extension, spec, context) { const coll = await this.getCollection(extension, context); + const histogramSize = this._telemetry.getKeyedHistogramById(HISTOGRAM_GET_OPS_SIZE); let keys, records; if (spec === null) { records = {}; const res = await coll.list(); for (let record of res.data) { + histogramSize.add(extension.id, JSON.stringify(record.data).length); records[record.key] = record.data; } return records; @@ -1159,6 +1185,7 @@ class ExtensionStorageSync { for (let key of keys) { const res = await coll.getAny(keyToId(key)); if (res.data && res.data._status != "deleted") { + histogramSize.add(extension.id, JSON.stringify(res.data.data).length); records[res.data.key] = res.data.data; } } @@ -1194,4 +1221,4 @@ class ExtensionStorageSync { } } this.ExtensionStorageSync = ExtensionStorageSync; -this.extensionStorageSync = new ExtensionStorageSync(_fxaService); +this.extensionStorageSync = new ExtensionStorageSync(_fxaService, Services.telemetry); diff --git a/toolkit/components/extensions/test/xpcshell/test_ext_storage_sync.js b/toolkit/components/extensions/test/xpcshell/test_ext_storage_sync.js index 7aa4505f7ee2..fe6d24bb5f5b 100644 --- a/toolkit/components/extensions/test/xpcshell/test_ext_storage_sync.js +++ b/toolkit/components/extensions/test/xpcshell/test_ext_storage_sync.js @@ -391,7 +391,29 @@ function* withSignedInUser(user, f) { return Promise.resolve(true); }, }; - let extensionStorageSync = new ExtensionStorageSync(fxaServiceMock); + + let telemetryMock = { + _calls: [], + _histograms: {}, + scalarSet(name, value) { + this._calls.push({method: "scalarSet", name, value}); + }, + keyedScalarSet(name, key, value) { + this._calls.push({method: "keyedScalarSet", name, key, value}); + }, + getKeyedHistogramById(name) { + let self = this; + return { + add(key, value) { + if (!self._histograms[name]) { + self._histograms[name] = []; + } + self._histograms[name].push(value); + }, + }; + }, + }; + let extensionStorageSync = new ExtensionStorageSync(fxaServiceMock, telemetryMock); yield* f(extensionStorageSync, fxaServiceMock); } diff --git a/toolkit/components/telemetry/Histograms.json b/toolkit/components/telemetry/Histograms.json index 26238639b615..a1282079fbd6 100644 --- a/toolkit/components/telemetry/Histograms.json +++ b/toolkit/components/telemetry/Histograms.json @@ -10700,6 +10700,37 @@ "kind": "count", "description": "Tracking the total number of opened Containers." }, + "STORAGE_SYNC_GET_OPS_SIZE": { + "alert_emails": ["eglassercamp@mozilla.com"], + "expires_in_version": "58", + "bug_numbers": [1328974], + "kind": "exponential", + "high": 100000, + "n_buckets": 30, + "keyed": true, + "description": "Track the size of results of get() operations performed this subsession. The key is the addon ID.", + "releaseChannelCollection": "opt-out" + }, + "STORAGE_SYNC_SET_OPS_SIZE": { + "alert_emails": ["eglassercamp@mozilla.com"], + "expires_in_version": "58", + "bug_numbers": [1328974], + "kind": "exponential", + "high": 100000, + "n_buckets": 30, + "keyed": true, + "description": "Track the size of set() operations performed by addons this subsession. The key is the addon ID.", + "releaseChannelCollection": "opt-out" + }, + "STORAGE_SYNC_REMOVE_OPS": { + "alert_emails": ["eglassercamp@mozilla.com"], + "expires_in_version": "58", + "bug_numbers": [1328974], + "kind": "count", + "keyed": true, + "description": "Track the number of remove() operations addons perform this subsession. The key is the addon ID.", + "releaseChannelCollection": "opt-out" + }, "FENNEC_SESSIONSTORE_DAMAGED_SESSION_FILE": { "alert_emails": ["jh+bugzilla@buttercookie.de"], "expires_in_version": "56", diff --git a/toolkit/components/telemetry/Scalars.yaml b/toolkit/components/telemetry/Scalars.yaml index 94fdd8e8b5aa..3550dec3e92d 100644 --- a/toolkit/components/telemetry/Scalars.yaml +++ b/toolkit/components/telemetry/Scalars.yaml @@ -201,6 +201,58 @@ browser.engagement.navigation: record_in_processes: - 'main' +# This section is for probes used to measure use of the Webextensions storage.sync API. +storage.sync.api.usage: + extensions_using: + bug_numbers: + - 1328974 + description: > + The count of webextensions that have data stored in the chrome.storage.sync API. + This includes extensions that have not used the storage.sync API this session. + This includes items that were not stored this session. + This scalar is collected after every sync. + expires: "58" + kind: uint + keyed: false + notification_emails: + - eglassercamp@mozilla.com + release_channel_collection: opt-out + record_in_processes: + - main + items_stored: + bug_numbers: + - 1328974 + description: > + The count of items in storage.sync storage, broken down by extension ID. + This includes extensions that have not used the storage.sync API this session. + This includes items that were not stored this session. + This scalar is collected after every sync. + expires: "58" + kind: uint + keyed: true + notification_emails: + - eglassercamp@mozilla.com + release_channel_collection: opt-out + record_in_processes: + - main + storage_consumed: + bug_numbers: + - 1328974 + description: > + The count of bytes used in storage.sync, broken down by extension ID. + This includes extensions that have not used the storage.sync API this session. + This includes items that were not stored this session. + This scalar is collected after every sync. + expires: "58" + kind: uint + keyed: true + notification_emails: + - eglassercamp@mozilla.com + release_channel_collection: opt-out + record_in_processes: + - main + + # The following section is for probes testing the Telemetry system. They will not be # submitted in pings and are only used for testing. telemetry.test: From 9fd32c86221840b0f867a0501ec19a81a67995bc Mon Sep 17 00:00:00 2001 From: cnevinc Date: Tue, 21 Feb 2017 21:47:43 +0800 Subject: [PATCH 19/48] Bug 1341276 - Correctly exit full screen. r=jchen MozReview-Commit-ID: ErPilSXPWFr --HG-- extra : rebase_source : 383d2a476d462fea34e06fb445de7b6bad428454 --- mobile/android/chrome/content/browser.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mobile/android/chrome/content/browser.js b/mobile/android/chrome/content/browser.js index c16d20ac4631..7531c616117c 100644 --- a/mobile/android/chrome/content/browser.js +++ b/mobile/android/chrome/content/browser.js @@ -1218,7 +1218,7 @@ var BrowserApp = { if (fullscreenState) { this.fullscreenTransitionTab = newTab; - doc.exitFullscreen(); + this.selectedBrowser.contentDocument.exitFullscreen(); } if (typeof aParams.tabIndex == "number") { From 9de058213ed2494577d69e92cc1c50b683a5b0eb Mon Sep 17 00:00:00 2001 From: Shih-Chiang Chien Date: Fri, 10 Feb 2017 10:45:28 +0800 Subject: [PATCH 20/48] Bug 1337721 - Part 1, preserve the channel priority after redirect. r=mayhemer MozReview-Commit-ID: 14rIrhOcXXK --HG-- extra : rebase_source : ec26484daa2684313990f54e4d579fe6b08daaa3 --- netwerk/protocol/http/HttpBaseChannel.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/netwerk/protocol/http/HttpBaseChannel.cpp b/netwerk/protocol/http/HttpBaseChannel.cpp index 8fb12e67155a..a48191ff7f40 100644 --- a/netwerk/protocol/http/HttpBaseChannel.cpp +++ b/netwerk/protocol/http/HttpBaseChannel.cpp @@ -3248,6 +3248,12 @@ HttpBaseChannel::SetupReplacementChannel(nsIURI *newURI, // share the request context - see bug 1236650 httpChannel->SetRequestContextID(mRequestContextID); + // Preserve the loading order + nsCOMPtr p = do_QueryInterface(newChannel); + if (p) { + p->SetPriority(mPriority); + } + if (httpInternal) { // Convey third party cookie, conservative, and spdy flags. httpInternal->SetThirdPartyFlags(mThirdPartyFlags); From 9c648e86fc256392bc831862b689e2f8ae391d09 Mon Sep 17 00:00:00 2001 From: Shih-Chiang Chien Date: Fri, 10 Feb 2017 16:56:04 +0800 Subject: [PATCH 21/48] Bug 1337721 - Part 2, add xpcshell test for channel priority. r=mayhemer MozReview-Commit-ID: JbbRg63ufW9 --HG-- extra : rebase_source : 4a32499e62a9c3f9292311a3974d5759bf5a579e --- netwerk/test/unit/test_channel_priority.js | 91 +++++++++++++++++++ netwerk/test/unit/xpcshell.ini | 1 + .../unit_ipc/test_channel_priority_wrap.js | 50 ++++++++++ netwerk/test/unit_ipc/xpcshell.ini | 2 + 4 files changed, 144 insertions(+) create mode 100644 netwerk/test/unit/test_channel_priority.js create mode 100644 netwerk/test/unit_ipc/test_channel_priority_wrap.js diff --git a/netwerk/test/unit/test_channel_priority.js b/netwerk/test/unit/test_channel_priority.js new file mode 100644 index 000000000000..490ad69b5d45 --- /dev/null +++ b/netwerk/test/unit/test_channel_priority.js @@ -0,0 +1,91 @@ +/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */ +/* Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/publicdomain/zero/1.0/ */ +/* jshint esnext:true, globalstrict:true, moz:true, undef:true, unused:true */ +/* globals Cu, Ci, Assert, run_next_test, add_test, do_register_cleanup */ +/* globals runningInParent, do_send_remote_message */ +/* globals ChannelListener */ + +'use strict'; + +/* globals NetUtil*/ +Cu.import('resource://gre/modules/NetUtil.jsm'); +/* globals HttpServer */ +Cu.import('resource://testing-common/httpd.js'); + +let httpserver; +let port; + +function startHttpServer() { + httpserver = new HttpServer(); + + httpserver.registerPathHandler('/resource', (metadata, response) => { + response.setStatusLine(metadata.httpVersion, 200, 'OK'); + response.setHeader('Content-Type', 'text/plain', false); + response.setHeader('Cache-Control', 'no-cache', false); + response.bodyOutputStream.write("data", 4); + }); + + httpserver.registerPathHandler('/redirect', (metadata, response) => { + response.setStatusLine(metadata.httpVersion, 302, 'Redirect'); + response.setHeader('Location', '/resource', false); + response.setHeader('Cache-Control', 'no-cache', false); + }); + + httpserver.start(-1); + port = httpserver.identity.primaryPort; +} + +function stopHttpServer() { + httpserver.stop(()=>{}); +} + +function makeRequest(uri) { + let requestChannel = NetUtil.newChannel({uri, loadUsingSystemPrincipal: true}); + requestChannel.QueryInterface(Ci.nsISupportsPriority); + requestChannel.priority = Ci.nsISupportsPriority.PRIORITY_HIGHEST; + requestChannel.asyncOpen2(new ChannelListener(checkResponse, requestChannel)); +} + +function checkResponse(request, buffer, requestChannel) { + requestChannel.QueryInterface(Ci.nsISupportsPriority); + Assert.equal(requestChannel.priority, Ci.nsISupportsPriority.PRIORITY_HIGHEST); + + // the response channel can be different (if it was redirected) + let responseChannel = request.QueryInterface(Ci.nsISupportsPriority); + Assert.equal(responseChannel.priority, Ci.nsISupportsPriority.PRIORITY_HIGHEST); + + run_next_test(); +} + +add_test(function test_regular_request() { + makeRequest(`http://localhost:${port}/resource`); +}); + +add_test(function test_redirect() { + makeRequest(`http://localhost:${port}/redirect`); +}); + +function run_test() { // jshint ignore:line + if (!runningInParent) { + // add a task to report test finished to parent process at the end of test queue, + // since do_register_cleanup is not available in child xpcshell test script. + add_test(function () { + do_send_remote_message('finished'); + run_next_test(); + }); + + // waiting for parent process to assign server port via configPort() + return; + } + + startHttpServer(); + do_register_cleanup(stopHttpServer); + run_next_test(); +} + +// This is used by unit_ipc/test_channel_priority_wrap.js for e10s XPCShell test +function configPort(serverPort) { // jshint ignore:line + port = serverPort; + run_next_test(); +} diff --git a/netwerk/test/unit/xpcshell.ini b/netwerk/test/unit/xpcshell.ini index df56660afc05..9aaca4046d3b 100644 --- a/netwerk/test/unit/xpcshell.ini +++ b/netwerk/test/unit/xpcshell.ini @@ -382,3 +382,4 @@ skip-if = os == "android" [test_rusturl.js] [test_trackingProtection_annotateChannels.js] [test_race_cache_network.js] +[test_channel_priority.js] diff --git a/netwerk/test/unit_ipc/test_channel_priority_wrap.js b/netwerk/test/unit_ipc/test_channel_priority_wrap.js new file mode 100644 index 000000000000..a53a529e1796 --- /dev/null +++ b/netwerk/test/unit_ipc/test_channel_priority_wrap.js @@ -0,0 +1,50 @@ +/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */ +/* Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/publicdomain/zero/1.0/ */ +/* jshint esnext:true, globalstrict:true, moz:true, undef:true, unused:true */ +/* globals Cu, do_register_cleanup, do_test_finished */ +/* globals run_test_in_child, sendCommand, do_await_remote_message */ + +'use strict'; + +/* globals HttpServer */ +Cu.import('resource://testing-common/httpd.js'); + +let httpserver; +let port; + +function startHttpServer() { + httpserver = new HttpServer(); + + httpserver.registerPathHandler('/resource', (metadata, response) => { + response.setStatusLine(metadata.httpVersion, 200, 'OK'); + response.setHeader('Content-Type', 'text/plain', false); + response.setHeader('Cache-Control', 'no-cache', false); + response.bodyOutputStream.write("data", 4); + }); + + httpserver.registerPathHandler('/redirect', (metadata, response) => { + response.setStatusLine(metadata.httpVersion, 302, 'Redirect'); + response.setHeader('Location', '/resource', false); + response.setHeader('Cache-Control', 'no-cache', false); + }); + + httpserver.start(-1); + port = httpserver.identity.primaryPort; +} + +function stopHttpServer() { + httpserver.stop(()=>{}); +} + +function run_test() { // jshint ignore:line + do_register_cleanup(stopHttpServer); + + run_test_in_child('../unit/test_channel_priority.js', () => { + startHttpServer(); + sendCommand(`configPort(${port});`); + do_await_remote_message('finished').then(() => { + do_test_finished(); + }); + }); +} diff --git a/netwerk/test/unit_ipc/xpcshell.ini b/netwerk/test/unit_ipc/xpcshell.ini index a1f98765643f..8a6a1ea29d4a 100644 --- a/netwerk/test/unit_ipc/xpcshell.ini +++ b/netwerk/test/unit_ipc/xpcshell.ini @@ -55,6 +55,7 @@ support-files = !/netwerk/test/unit/data/signed_win.exe !/netwerk/test/unit/test_alt-data_simple.js !/netwerk/test/unit/test_alt-data_stream.js + !/netwerk/test/unit/test_channel_priority.js [test_bug528292_wrap.js] [test_bug248970_cookie_wrap.js] @@ -99,3 +100,4 @@ skip-if = true [test_channel_id.js] [test_trackingProtection_annotateChannels_wrap1.js] [test_trackingProtection_annotateChannels_wrap2.js] +[test_channel_priority_wrap.js] From bea1853007ce3d48e38ffdb3650c82538cae84ce Mon Sep 17 00:00:00 2001 From: Iris Hsiao Date: Wed, 22 Feb 2017 10:33:56 +0800 Subject: [PATCH 22/48] Backed out changeset e85a00771f86 (bug 1322273) for assertion failures --- js/xpconnect/tests/unit/test_nuke_sandbox.js | 37 ++++--------------- js/xpconnect/wrappers/WrapperFactory.cpp | 38 ++++++++------------ 2 files changed, 21 insertions(+), 54 deletions(-) diff --git a/js/xpconnect/tests/unit/test_nuke_sandbox.js b/js/xpconnect/tests/unit/test_nuke_sandbox.js index 9659902610d8..a4dd25498af1 100644 --- a/js/xpconnect/tests/unit/test_nuke_sandbox.js +++ b/js/xpconnect/tests/unit/test_nuke_sandbox.js @@ -4,46 +4,20 @@ /* See https://bugzilla.mozilla.org/show_bug.cgi?id=769273 */ -const {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components; - -const global = this; - function run_test() { - var ifacePointer = Cc["@mozilla.org/supports-interface-pointer;1"] - .createInstance(Ci.nsISupportsInterfacePointer); - - var sb = Cu.Sandbox(global); + var sb = Components.utils.Sandbox("http://www.blah.com"); sb.prop = "prop" - sb.ifacePointer = ifacePointer - - var refToObjFromSb = Cu.evalInSandbox(` - Components.utils.import("resource://gre/modules/XPCOMUtils.jsm"); - - ifacePointer.data = { - QueryInterface: XPCOMUtils.generateQI([]), - wrappedJSObject: {foo: "bar"}, - }; - - var a = {prop2:'prop2'}; - a - `, sb); - - equal(ifacePointer.data.wrappedJSObject.foo, "bar", - "Got expected wrapper into sandbox") - - Cu.nukeSandbox(sb); - ok(Cu.isDeadWrapper(sb), "sb should be dead"); - ok(Cu.isDeadWrapper(ifacePointer.data.wrappedJSObject), - "Wrapper retrieved via XPConnect should be dead"); - + var refToObjFromSb = Components.utils.evalInSandbox("var a = {prop2:'prop2'}; a", sb); + Components.utils.nukeSandbox(sb); + do_check_true(Components.utils.isDeadWrapper(sb), "sb should be dead"); try{ sb.prop; do_check_true(false); } catch (e) { do_check_true(e.toString().indexOf("can't access dead object") > -1); } - + Components.utils.isDeadWrapper(refToObjFromSb, "ref to object from sb should be dead"); try{ refToObjFromSb.prop2; @@ -51,4 +25,5 @@ function run_test() } catch (e) { do_check_true(e.toString().indexOf("can't access dead object") > -1); } + } diff --git a/js/xpconnect/wrappers/WrapperFactory.cpp b/js/xpconnect/wrappers/WrapperFactory.cpp index c9ae96b7ff92..bdb727841f08 100644 --- a/js/xpconnect/wrappers/WrapperFactory.cpp +++ b/js/xpconnect/wrappers/WrapperFactory.cpp @@ -181,24 +181,6 @@ WrapperFactory::PrepareForWrapping(JSContext* cx, HandleObject scope, ExposeObjectToActiveJS(obj); } - // If we've somehow gotten to this point after either the source or target - // compartment has been nuked, return a DeadObjectProxy to prevent further - // access. - JSCompartment* origin = js::GetObjectCompartment(obj); - JSCompartment* target = js::GetObjectCompartment(scope); - if (CompartmentPrivate::Get(origin)->wasNuked || - CompartmentPrivate::Get(target)->wasNuked) { - NS_WARNING("Trying to create a wrapper into or out of a nuked compartment"); - - RootedObject ccw(cx, Wrapper::New(cx, obj, &CrossCompartmentWrapper::singleton)); - - NukeCrossCompartmentWrapper(cx, ccw); - - retObj.set(ccw); - return; - } - - // If we've got a WindowProxy, there's nothing special that needs to be // done here, and we can move on to the next phase of wrapping. We handle // this case first to allow us to assert against wrappers below. @@ -350,10 +332,8 @@ DEBUG_CheckUnwrapSafety(HandleObject obj, const js::Wrapper* handler, JSCompartment* origin, JSCompartment* target) { if (CompartmentPrivate::Get(origin)->wasNuked || CompartmentPrivate::Get(target)->wasNuked) { - // If either compartment has already been nuked, we should have returned - // a dead wrapper from our prewrap callback, and this function should - // not be called. - MOZ_ASSERT_UNREACHABLE("CheckUnwrapSafety called for a dead wrapper"); + // If either compartment has already been nuked, we should have an opaque wrapper. + MOZ_ASSERT(handler->hasSecurityPolicy()); } else if (AccessCheck::isChrome(target) || xpc::IsUniversalXPConnectEnabled(target)) { // If the caller is chrome (or effectively so), unwrap should always be allowed. MOZ_ASSERT(!handler->hasSecurityPolicy()); @@ -477,9 +457,21 @@ WrapperFactory::Rewrap(JSContext* cx, HandleObject existing, HandleObject obj) // First, handle the special cases. // + // If we've somehow gotten to this point after either the source or target + // compartment has been nuked, return an opaque wrapper to prevent further + // access. + // Ideally, we should return a DeadProxyObject instead of a wrapper in this + // case (bug 1322273). + if (CompartmentPrivate::Get(origin)->wasNuked || + CompartmentPrivate::Get(target)->wasNuked) { + NS_WARNING("Trying to create a wrapper into or out of a nuked compartment"); + + wrapper = &FilteringWrapper::singleton; + } + // If UniversalXPConnect is enabled, this is just some dumb mochitest. Use // a vanilla CCW. - if (xpc::IsUniversalXPConnectEnabled(target)) { + else if (xpc::IsUniversalXPConnectEnabled(target)) { CrashIfNotInAutomation(); wrapper = &CrossCompartmentWrapper::singleton; } From f604ffe72d061a2332787c3bb635bfe42da68e85 Mon Sep 17 00:00:00 2001 From: James Cheng Date: Fri, 17 Feb 2017 11:10:05 +0800 Subject: [PATCH 23/48] Bug 1340172 - Disable EME on Fennec(Only pref on for Nightly). r=cpearce MozReview-Commit-ID: 66YOK9r1yb0 --HG-- extra : rebase_source : d409b097f88279b358ac6f7caf302ea7ad3e2e17 --- mobile/android/app/mobile.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/mobile/android/app/mobile.js b/mobile/android/app/mobile.js index c0b395033d32..17c6a7a4997b 100644 --- a/mobile/android/app/mobile.js +++ b/mobile/android/app/mobile.js @@ -628,8 +628,10 @@ pref("media.mediasource.enabled", true); pref("media.mediadrm-widevinecdm.visible", true); +#ifdef NIGHTLY_BUILD // Enable EME (Encrypted Media Extensions) pref("media.eme.enabled", true); +#endif // optimize images memory usage pref("image.downscale-during-decode.enabled", true); From 8eebddf88eb2c4afb4e5f26b3f95179b653c1dc2 Mon Sep 17 00:00:00 2001 From: Bob Silverberg Date: Tue, 14 Feb 2017 15:23:46 -0500 Subject: [PATCH 24/48] Bug 1338312 - browser.sessions.getRecentlyClosed returns incorrect information for tabs in closed windows, r=aswan MozReview-Commit-ID: FrUhiR9Q9aV --HG-- extra : rebase_source : 10eabf425631f2d39eecc595b57fb7966eb168fd --- browser/components/extensions/ext-utils.js | 5 +-- .../browser_ext_sessions_getRecentlyClosed.js | 33 +++++++++++++++++++ 2 files changed, 36 insertions(+), 2 deletions(-) diff --git a/browser/components/extensions/ext-utils.js b/browser/components/extensions/ext-utils.js index 3ff88cd0545c..2bfe44f75163 100644 --- a/browser/components/extensions/ext-utils.js +++ b/browser/components/extensions/ext-utils.js @@ -544,8 +544,9 @@ class Tab extends TabBase { if (extension.tabManager.hasTabPermission(tabData)) { let entries = tabData.state ? tabData.state.entries : tabData.entries; - result.url = entries[0].url; - result.title = entries[0].title; + let entry = entries[entries.length - 1]; + result.url = entry.url; + result.title = entry.title; if (tabData.image) { result.favIconUrl = tabData.image; } diff --git a/browser/components/extensions/test/browser/browser_ext_sessions_getRecentlyClosed.js b/browser/components/extensions/test/browser/browser_ext_sessions_getRecentlyClosed.js index 413f7bde601f..546753b6f84b 100644 --- a/browser/components/extensions/test/browser/browser_ext_sessions_getRecentlyClosed.js +++ b/browser/components/extensions/test/browser/browser_ext_sessions_getRecentlyClosed.js @@ -95,3 +95,36 @@ add_task(function* test_sessions_get_recently_closed() { yield extension.unload(); }); + +add_task(function* test_sessions_get_recently_closed_navigated() { + function background() { + browser.sessions.getRecentlyClosed({maxResults: 1}).then(recentlyClosed => { + let tab = recentlyClosed[0].window.tabs[0]; + browser.test.assertEq("http://example.com/", tab.url, + "Tab in closed window has the expected url."); + browser.test.assertTrue(tab.title.includes("mochitest index"), + "Tab in closed window has the expected title."); + browser.test.notifyPass("getRecentlyClosed with navigation"); + }); + } + + let extension = ExtensionTestUtils.loadExtension({ + manifest: { + permissions: ["sessions", "tabs"], + }, + background, + }); + + // Test with a window with navigation history. + let win = yield BrowserTestUtils.openNewBrowserWindow(); + for (let url of ["about:robots", "about:mozilla", "http://example.com/"]) { + yield BrowserTestUtils.loadURI(win.gBrowser.selectedBrowser, url); + yield BrowserTestUtils.browserLoaded(win.gBrowser.selectedBrowser); + } + + yield BrowserTestUtils.closeWindow(win); + + yield extension.startup(); + yield extension.awaitFinish(); + yield extension.unload(); +}); From 5ab18de3329e2f4ec86ee0e2f16a0d0736bf0563 Mon Sep 17 00:00:00 2001 From: Bob Silverberg Date: Wed, 15 Feb 2017 12:39:03 -0500 Subject: [PATCH 25/48] Bug 1339868 - browsingData.settings includes an invalid property in its returned objects, r=aswan Also fixes browsingData.settings() does not work if "Time range to clear" is set to "Everything". MozReview-Commit-ID: 5GtwYF6xCSj --HG-- extra : rebase_source : adbb4d9142a2b8086a6e03bc23d84b7e3921aea6 --- .../components/extensions/ext-browsingData.js | 15 ++-- .../test_ext_browsingData_settings.js | 85 ++++++++++++++----- 2 files changed, 72 insertions(+), 28 deletions(-) diff --git a/browser/components/extensions/ext-browsingData.js b/browser/components/extensions/ext-browsingData.js index cb99d2123109..a927b42682cd 100644 --- a/browser/components/extensions/ext-browsingData.js +++ b/browser/components/extensions/ext-browsingData.js @@ -187,21 +187,24 @@ extensions.registerSchemaAPI("browsingData", "addon_parent", context => { // since will be the start of what is returned by Sanitizer.getClearRange // divided by 1000 to convert to ms. - let since = Sanitizer.getClearRange()[0] / 1000; + // If Sanitizer.getClearRange returns undefined that means the range is + // currently "Everything", so we should set since to 0. + let clearRange = Sanitizer.getClearRange(); + let since = clearRange ? clearRange[0] / 1000 : 0; let options = {since}; let dataToRemove = {}; let dataRemovalPermitted = {}; for (let item of PREF_LIST) { - dataToRemove[item] = Preferences.get(`${PREF_DOMAIN}${item}`); + // The property formData needs a different case than the + // formdata preference. + const name = item === "formdata" ? "formData" : item; + dataToRemove[name] = Preferences.get(`${PREF_DOMAIN}${item}`); // Firefox doesn't have the same concept of dataRemovalPermitted // as Chrome, so it will always be true. - dataRemovalPermitted[item] = true; + dataRemovalPermitted[name] = true; } - // formData has a different case than the pref formdata. - dataToRemove.formData = Preferences.get(`${PREF_DOMAIN}formdata`); - dataRemovalPermitted.formData = true; return Promise.resolve({options, dataToRemove, dataRemovalPermitted}); }, diff --git a/browser/components/extensions/test/xpcshell/test_ext_browsingData_settings.js b/browser/components/extensions/test/xpcshell/test_ext_browsingData_settings.js index 68ed74d05ea2..a641db7f2d16 100644 --- a/browser/components/extensions/test/xpcshell/test_ext_browsingData_settings.js +++ b/browser/components/extensions/test/xpcshell/test_ext_browsingData_settings.js @@ -2,12 +2,15 @@ /* vim: set sts=2 sw=2 et tw=80: */ "use strict"; +XPCOMUtils.defineLazyModuleGetter(this, "Preferences", + "resource://gre/modules/Preferences.jsm"); XPCOMUtils.defineLazyModuleGetter(this, "Sanitizer", "resource:///modules/Sanitizer.jsm"); const PREF_DOMAIN = "privacy.cpd."; +const SETTINGS_LIST = ["cache", "cookies", "history", "formData", "downloads"].sort(); -add_task(function* testSettings() { +add_task(function* testSettingsProperties() { function background() { browser.test.onMessage.addListener(msg => { browser.browsingData.settings().then(settings => { @@ -25,21 +28,19 @@ add_task(function* testSettings() { yield extension.startup(); - let branch = Services.prefs.getBranch(PREF_DOMAIN); - extension.sendMessage("settings"); let settings = yield extension.awaitMessage("settings"); - let since = Sanitizer.getClearRange()[0] / 1000; - - // Because it is based on the current timestamp, we cannot know the exact - // value to expect for since, so allow a 10s variance. - ok(Math.abs(settings.options.since - since) < 10000, - "settings.options contains the expected since value."); + // Verify that we get the keys back we expect. + deepEqual(Object.keys(settings.dataToRemove).sort(), SETTINGS_LIST, + "dataToRemove contains expected properties."); + deepEqual(Object.keys(settings.dataRemovalPermitted).sort(), SETTINGS_LIST, + "dataToRemove contains expected properties."); let dataTypeSet = settings.dataToRemove; for (let key of Object.keys(dataTypeSet)) { - equal(branch.getBoolPref(key.toLowerCase()), dataTypeSet[key], `${key} property of dataToRemove matches the expected pref.`); + equal(Preferences.get(`${PREF_DOMAIN}${key.toLowerCase()}`), dataTypeSet[key], + `${key} property of dataToRemove matches the expected pref.`); } dataTypeSet = settings.dataRemovalPermitted; @@ -48,29 +49,69 @@ add_task(function* testSettings() { } // Explicitly set a pref to both true and false and then check. - const SINGLE_PREF = "cache"; + const SINGLE_OPTION = "cache"; + const SINGLE_PREF = "privacy.cpd.cache"; do_register_cleanup(() => { - branch.clearUserPref(SINGLE_PREF); + Preferences.reset(SINGLE_PREF); }); - branch.setBoolPref(SINGLE_PREF, true); + Preferences.set(SINGLE_PREF, true); extension.sendMessage("settings"); settings = yield extension.awaitMessage("settings"); + equal(settings.dataToRemove[SINGLE_OPTION], true, "Preference that was set to true returns true."); - equal(settings.dataToRemove[SINGLE_PREF], true, "Preference that was set to true returns true."); - - branch.setBoolPref(SINGLE_PREF, false); + Preferences.set(SINGLE_PREF, false); extension.sendMessage("settings"); settings = yield extension.awaitMessage("settings"); - - equal(settings.dataToRemove[SINGLE_PREF], false, "Preference that was set to false returns false."); - - do_register_cleanup(() => { - branch.clearUserPref(SINGLE_PREF); - }); + equal(settings.dataToRemove[SINGLE_OPTION], false, "Preference that was set to false returns false."); + + yield extension.unload(); +}); + +add_task(function* testSettingsSince() { + const TIMESPAN_PREF = "privacy.sanitize.timeSpan"; + const TEST_DATA = { + TIMESPAN_5MIN: Date.now() - 5 * 60 * 1000, + TIMESPAN_HOUR: Date.now() - 60 * 60 * 1000, + TIMESPAN_2HOURS: Date.now() - 2 * 60 * 60 * 1000, + TIMESPAN_EVERYTHING: 0, + }; + + function background() { + browser.test.onMessage.addListener(msg => { + browser.browsingData.settings().then(settings => { + browser.test.sendMessage("settings", settings); + }); + }); + } + + let extension = ExtensionTestUtils.loadExtension({ + background, + manifest: { + permissions: ["browsingData"], + }, + }); + + yield extension.startup(); + + do_register_cleanup(() => { + Preferences.reset(TIMESPAN_PREF); + }); + + for (let timespan in TEST_DATA) { + Preferences.set(TIMESPAN_PREF, Sanitizer[timespan]); + + extension.sendMessage("settings"); + let settings = yield extension.awaitMessage("settings"); + + // Because it is based on the current timestamp, we cannot know the exact + // value to expect for since, so allow a 10s variance. + ok(Math.abs(settings.options.since - TEST_DATA[timespan]) < 10000, + "settings.options contains the expected since value."); + } yield extension.unload(); }); From 994e1136fd69ee01872cc021d28b12d8d2c9180d Mon Sep 17 00:00:00 2001 From: Chris Pearce Date: Wed, 22 Feb 2017 15:55:38 +1300 Subject: [PATCH 26/48] Bug 1341497 - Move WidevineBuffer and WidevineDecryptedBlock into WidevineUtils. r=gerald This makes it easier to reuse in the ChromiumCDM code. Also add an ExtractBuffer() method, which allows us to Move() the contained nsTArray out without needing to copy the data. MozReview-Commit-ID: 9suJSfXTVYy --HG-- extra : rebase_source : 89540b254249833cf8bb09792bb33cc402977d5a --- .../widevine-adapter/WidevineDecryptor.cpp | 60 ------------- .../gmp/widevine-adapter/WidevineUtils.cpp | 87 +++++++++++++++++++ .../gmp/widevine-adapter/WidevineUtils.h | 37 ++++++++ dom/media/gmp/widevine-adapter/moz.build | 5 ++ 4 files changed, 129 insertions(+), 60 deletions(-) diff --git a/dom/media/gmp/widevine-adapter/WidevineDecryptor.cpp b/dom/media/gmp/widevine-adapter/WidevineDecryptor.cpp index 6183e949ab5c..8c9f1c3cab8f 100644 --- a/dom/media/gmp/widevine-adapter/WidevineDecryptor.cpp +++ b/dom/media/gmp/widevine-adapter/WidevineDecryptor.cpp @@ -9,7 +9,6 @@ #include "WidevineUtils.h" #include "WidevineFileIO.h" #include "GMPPlatform.h" -#include #include #include "TimeUnits.h" @@ -161,43 +160,6 @@ WidevineDecryptor::SetServerCertificate(uint32_t aPromiseId, CDM()->SetServerCertificate(aPromiseId, aServerCert, aServerCertSize); } -class WidevineDecryptedBlock : public cdm::DecryptedBlock { -public: - - WidevineDecryptedBlock() - : mBuffer(nullptr) - , mTimestamp(0) - { - } - - ~WidevineDecryptedBlock() override { - if (mBuffer) { - mBuffer->Destroy(); - mBuffer = nullptr; - } - } - - void SetDecryptedBuffer(cdm::Buffer* aBuffer) override { - mBuffer = aBuffer; - } - - cdm::Buffer* DecryptedBuffer() override { - return mBuffer; - } - - void SetTimestamp(int64_t aTimestamp) override { - mTimestamp = aTimestamp; - } - - int64_t Timestamp() const override { - return mTimestamp; - } - -private: - cdm::Buffer* mBuffer; - int64_t mTimestamp; -}; - cdm::Time WidevineDecryptor::ThrottleDecrypt(cdm::Time aWallTime, cdm::Time aSampleDuration) { @@ -327,28 +289,6 @@ WidevineDecryptor::DecryptingComplete() Release(); } -class WidevineBuffer : public cdm::Buffer { -public: - explicit WidevineBuffer(size_t aSize) { - CDM_LOG("WidevineBuffer(size=%" PRIuSIZE ") created", aSize); - mBuffer.SetLength(aSize); - } - ~WidevineBuffer() override { - CDM_LOG("WidevineBuffer(size=%" PRIu32 ") destroyed", Size()); - } - void Destroy() override { delete this; } - uint32_t Capacity() const override { return mBuffer.Length(); }; - uint8_t* Data() override { return mBuffer.Elements(); } - void SetSize(uint32_t aSize) override { mBuffer.SetLength(aSize); } - uint32_t Size() const override { return mBuffer.Length(); } - -private: - WidevineBuffer(const WidevineBuffer&); - void operator=(const WidevineBuffer&); - - nsTArray mBuffer; -}; - Buffer* WidevineDecryptor::Allocate(uint32_t aCapacity) { diff --git a/dom/media/gmp/widevine-adapter/WidevineUtils.cpp b/dom/media/gmp/widevine-adapter/WidevineUtils.cpp index 3eaae43abe69..379286ed71a1 100644 --- a/dom/media/gmp/widevine-adapter/WidevineUtils.cpp +++ b/dom/media/gmp/widevine-adapter/WidevineUtils.cpp @@ -5,6 +5,7 @@ #include "WidevineUtils.h" #include "WidevineDecryptor.h" +#include #include "gmp-api/gmp-errors.h" #include @@ -76,4 +77,90 @@ CDMWrapper::~CDMWrapper() mCDM = nullptr; } +WidevineBuffer::WidevineBuffer(size_t aSize) +{ + CDM_LOG("WidevineBuffer(size=%" PRIuSIZE ") created", aSize); + mBuffer.SetLength(aSize); +} + +WidevineBuffer::~WidevineBuffer() +{ + CDM_LOG("WidevineBuffer(size=%" PRIu32 ") destroyed", Size()); +} + +void +WidevineBuffer::Destroy() +{ + delete this; +} + +uint32_t +WidevineBuffer::Capacity() const +{ + return mBuffer.Length(); +} + +uint8_t* +WidevineBuffer::Data() +{ + return mBuffer.Elements(); +} + +void +WidevineBuffer::SetSize(uint32_t aSize) +{ + mBuffer.SetLength(aSize); +} + +uint32_t +WidevineBuffer::Size() const +{ + return mBuffer.Length(); +} + +nsTArray +WidevineBuffer::ExtractBuffer() { + nsTArray out; + out.SwapElements(mBuffer); + return out; +} + +WidevineDecryptedBlock::WidevineDecryptedBlock() + : mBuffer(nullptr) + , mTimestamp(0) +{ +} + +WidevineDecryptedBlock::~WidevineDecryptedBlock() +{ + if (mBuffer) { + mBuffer->Destroy(); + mBuffer = nullptr; + } +} + +void +WidevineDecryptedBlock::SetDecryptedBuffer(cdm::Buffer* aBuffer) +{ + mBuffer = aBuffer; +} + +cdm::Buffer* +WidevineDecryptedBlock::DecryptedBuffer() +{ + return mBuffer; +} + +void +WidevineDecryptedBlock::SetTimestamp(int64_t aTimestamp) +{ + mTimestamp = aTimestamp; +} + +int64_t +WidevineDecryptedBlock::Timestamp() const +{ + return mTimestamp; +} + } // namespace mozilla diff --git a/dom/media/gmp/widevine-adapter/WidevineUtils.h b/dom/media/gmp/widevine-adapter/WidevineUtils.h index 9c67a20058d0..9c7136d6773e 100644 --- a/dom/media/gmp/widevine-adapter/WidevineUtils.h +++ b/dom/media/gmp/widevine-adapter/WidevineUtils.h @@ -61,6 +61,43 @@ void InitInputBuffer(const GMPEncryptedBufferMetadata* aCrypto, cdm::InputBuffer &aInputBuffer, nsTArray &aSubsamples); +class WidevineBuffer : public cdm::Buffer +{ +public: + explicit WidevineBuffer(size_t aSize); + ~WidevineBuffer() override; + void Destroy() override; + uint32_t Capacity() const override; + uint8_t* Data() override; + void SetSize(uint32_t aSize) override; + uint32_t Size() const override; + + // Moves contents of buffer out into temporary. + // Note: This empties the buffer. + nsTArray ExtractBuffer(); + +private: + nsTArray mBuffer; + WidevineBuffer(const WidevineBuffer&); + void operator=(const WidevineBuffer&); +}; + +class WidevineDecryptedBlock : public cdm::DecryptedBlock +{ +public: + + WidevineDecryptedBlock(); + ~WidevineDecryptedBlock() override; + void SetDecryptedBuffer(cdm::Buffer* aBuffer) override; + cdm::Buffer* DecryptedBuffer() override; + void SetTimestamp(int64_t aTimestamp) override; + int64_t Timestamp() const override; + +private: + cdm::Buffer* mBuffer; + int64_t mTimestamp; +}; + } // namespace mozilla #endif // WidevineUtils_h_ diff --git a/dom/media/gmp/widevine-adapter/moz.build b/dom/media/gmp/widevine-adapter/moz.build index 89152fd664ac..212d7f7794f8 100644 --- a/dom/media/gmp/widevine-adapter/moz.build +++ b/dom/media/gmp/widevine-adapter/moz.build @@ -14,6 +14,11 @@ SOURCES += [ 'WidevineVideoFrame.cpp', ] +EXPORTS += [ + 'WidevineDecryptor.h', + 'WidevineUtils.h' +] + FINAL_LIBRARY = 'xul' LOCAL_INCLUDES += [ From 97fb7c952a6d7c11c462b8073aea89136fae4c54 Mon Sep 17 00:00:00 2001 From: Iris Hsiao Date: Wed, 22 Feb 2017 11:49:25 +0800 Subject: [PATCH 27/48] Backed out changeset 5ec123aec8aa (bug 1341497) for bustage --- .../widevine-adapter/WidevineDecryptor.cpp | 60 +++++++++++++ .../gmp/widevine-adapter/WidevineUtils.cpp | 87 ------------------- .../gmp/widevine-adapter/WidevineUtils.h | 37 -------- dom/media/gmp/widevine-adapter/moz.build | 5 -- 4 files changed, 60 insertions(+), 129 deletions(-) diff --git a/dom/media/gmp/widevine-adapter/WidevineDecryptor.cpp b/dom/media/gmp/widevine-adapter/WidevineDecryptor.cpp index 8c9f1c3cab8f..6183e949ab5c 100644 --- a/dom/media/gmp/widevine-adapter/WidevineDecryptor.cpp +++ b/dom/media/gmp/widevine-adapter/WidevineDecryptor.cpp @@ -9,6 +9,7 @@ #include "WidevineUtils.h" #include "WidevineFileIO.h" #include "GMPPlatform.h" +#include #include #include "TimeUnits.h" @@ -160,6 +161,43 @@ WidevineDecryptor::SetServerCertificate(uint32_t aPromiseId, CDM()->SetServerCertificate(aPromiseId, aServerCert, aServerCertSize); } +class WidevineDecryptedBlock : public cdm::DecryptedBlock { +public: + + WidevineDecryptedBlock() + : mBuffer(nullptr) + , mTimestamp(0) + { + } + + ~WidevineDecryptedBlock() override { + if (mBuffer) { + mBuffer->Destroy(); + mBuffer = nullptr; + } + } + + void SetDecryptedBuffer(cdm::Buffer* aBuffer) override { + mBuffer = aBuffer; + } + + cdm::Buffer* DecryptedBuffer() override { + return mBuffer; + } + + void SetTimestamp(int64_t aTimestamp) override { + mTimestamp = aTimestamp; + } + + int64_t Timestamp() const override { + return mTimestamp; + } + +private: + cdm::Buffer* mBuffer; + int64_t mTimestamp; +}; + cdm::Time WidevineDecryptor::ThrottleDecrypt(cdm::Time aWallTime, cdm::Time aSampleDuration) { @@ -289,6 +327,28 @@ WidevineDecryptor::DecryptingComplete() Release(); } +class WidevineBuffer : public cdm::Buffer { +public: + explicit WidevineBuffer(size_t aSize) { + CDM_LOG("WidevineBuffer(size=%" PRIuSIZE ") created", aSize); + mBuffer.SetLength(aSize); + } + ~WidevineBuffer() override { + CDM_LOG("WidevineBuffer(size=%" PRIu32 ") destroyed", Size()); + } + void Destroy() override { delete this; } + uint32_t Capacity() const override { return mBuffer.Length(); }; + uint8_t* Data() override { return mBuffer.Elements(); } + void SetSize(uint32_t aSize) override { mBuffer.SetLength(aSize); } + uint32_t Size() const override { return mBuffer.Length(); } + +private: + WidevineBuffer(const WidevineBuffer&); + void operator=(const WidevineBuffer&); + + nsTArray mBuffer; +}; + Buffer* WidevineDecryptor::Allocate(uint32_t aCapacity) { diff --git a/dom/media/gmp/widevine-adapter/WidevineUtils.cpp b/dom/media/gmp/widevine-adapter/WidevineUtils.cpp index 379286ed71a1..3eaae43abe69 100644 --- a/dom/media/gmp/widevine-adapter/WidevineUtils.cpp +++ b/dom/media/gmp/widevine-adapter/WidevineUtils.cpp @@ -5,7 +5,6 @@ #include "WidevineUtils.h" #include "WidevineDecryptor.h" -#include #include "gmp-api/gmp-errors.h" #include @@ -77,90 +76,4 @@ CDMWrapper::~CDMWrapper() mCDM = nullptr; } -WidevineBuffer::WidevineBuffer(size_t aSize) -{ - CDM_LOG("WidevineBuffer(size=%" PRIuSIZE ") created", aSize); - mBuffer.SetLength(aSize); -} - -WidevineBuffer::~WidevineBuffer() -{ - CDM_LOG("WidevineBuffer(size=%" PRIu32 ") destroyed", Size()); -} - -void -WidevineBuffer::Destroy() -{ - delete this; -} - -uint32_t -WidevineBuffer::Capacity() const -{ - return mBuffer.Length(); -} - -uint8_t* -WidevineBuffer::Data() -{ - return mBuffer.Elements(); -} - -void -WidevineBuffer::SetSize(uint32_t aSize) -{ - mBuffer.SetLength(aSize); -} - -uint32_t -WidevineBuffer::Size() const -{ - return mBuffer.Length(); -} - -nsTArray -WidevineBuffer::ExtractBuffer() { - nsTArray out; - out.SwapElements(mBuffer); - return out; -} - -WidevineDecryptedBlock::WidevineDecryptedBlock() - : mBuffer(nullptr) - , mTimestamp(0) -{ -} - -WidevineDecryptedBlock::~WidevineDecryptedBlock() -{ - if (mBuffer) { - mBuffer->Destroy(); - mBuffer = nullptr; - } -} - -void -WidevineDecryptedBlock::SetDecryptedBuffer(cdm::Buffer* aBuffer) -{ - mBuffer = aBuffer; -} - -cdm::Buffer* -WidevineDecryptedBlock::DecryptedBuffer() -{ - return mBuffer; -} - -void -WidevineDecryptedBlock::SetTimestamp(int64_t aTimestamp) -{ - mTimestamp = aTimestamp; -} - -int64_t -WidevineDecryptedBlock::Timestamp() const -{ - return mTimestamp; -} - } // namespace mozilla diff --git a/dom/media/gmp/widevine-adapter/WidevineUtils.h b/dom/media/gmp/widevine-adapter/WidevineUtils.h index 9c7136d6773e..9c67a20058d0 100644 --- a/dom/media/gmp/widevine-adapter/WidevineUtils.h +++ b/dom/media/gmp/widevine-adapter/WidevineUtils.h @@ -61,43 +61,6 @@ void InitInputBuffer(const GMPEncryptedBufferMetadata* aCrypto, cdm::InputBuffer &aInputBuffer, nsTArray &aSubsamples); -class WidevineBuffer : public cdm::Buffer -{ -public: - explicit WidevineBuffer(size_t aSize); - ~WidevineBuffer() override; - void Destroy() override; - uint32_t Capacity() const override; - uint8_t* Data() override; - void SetSize(uint32_t aSize) override; - uint32_t Size() const override; - - // Moves contents of buffer out into temporary. - // Note: This empties the buffer. - nsTArray ExtractBuffer(); - -private: - nsTArray mBuffer; - WidevineBuffer(const WidevineBuffer&); - void operator=(const WidevineBuffer&); -}; - -class WidevineDecryptedBlock : public cdm::DecryptedBlock -{ -public: - - WidevineDecryptedBlock(); - ~WidevineDecryptedBlock() override; - void SetDecryptedBuffer(cdm::Buffer* aBuffer) override; - cdm::Buffer* DecryptedBuffer() override; - void SetTimestamp(int64_t aTimestamp) override; - int64_t Timestamp() const override; - -private: - cdm::Buffer* mBuffer; - int64_t mTimestamp; -}; - } // namespace mozilla #endif // WidevineUtils_h_ diff --git a/dom/media/gmp/widevine-adapter/moz.build b/dom/media/gmp/widevine-adapter/moz.build index 212d7f7794f8..89152fd664ac 100644 --- a/dom/media/gmp/widevine-adapter/moz.build +++ b/dom/media/gmp/widevine-adapter/moz.build @@ -14,11 +14,6 @@ SOURCES += [ 'WidevineVideoFrame.cpp', ] -EXPORTS += [ - 'WidevineDecryptor.h', - 'WidevineUtils.h' -] - FINAL_LIBRARY = 'xul' LOCAL_INCLUDES += [ From a9b627ca77254d1824868bb41713a62a2ac60dff Mon Sep 17 00:00:00 2001 From: Phil Ringnalda Date: Tue, 21 Feb 2017 19:58:54 -0800 Subject: [PATCH 28/48] Backed out changeset 14dbbe36e676 (bug 1313459) for browser_ext_browserAction_area.js timeouts --- .../extensions/ext-browserAction.js | 12 +-- .../extensions/schemas/browser_action.json | 6 -- .../test/browser/browser-common.ini | 1 - .../browser/browser_ext_browserAction_area.js | 73 ------------------- 4 files changed, 2 insertions(+), 90 deletions(-) delete mode 100644 browser/components/extensions/test/browser/browser_ext_browserAction_area.js diff --git a/browser/components/extensions/ext-browserAction.js b/browser/components/extensions/ext-browserAction.js index f7562579ccaa..6dbd2663698a 100644 --- a/browser/components/extensions/ext-browserAction.js +++ b/browser/components/extensions/ext-browserAction.js @@ -38,14 +38,7 @@ function isAncestorOrSelf(target, node) { } // WeakMap[Extension -> BrowserAction] -const browserActionMap = new WeakMap(); - -const browserAreas = { - "navbar": CustomizableUI.AREA_NAVBAR, - "menupanel": CustomizableUI.AREA_PANEL, - "tabstrip": CustomizableUI.AREA_TABSTRIP, - "personaltoolbar": CustomizableUI.AREA_BOOKMARKS, -}; +var browserActionMap = new WeakMap(); // Responsible for the browser_action section of the manifest as well // as the associated popup. @@ -69,7 +62,6 @@ function BrowserAction(options, extension) { badgeBackgroundColor: null, icon: IconDetails.normalize({path: options.default_icon}, extension), popup: options.default_popup || "", - area: browserAreas[options.default_area || "navbar"], }; this.browserStyle = options.browser_style || false; @@ -93,7 +85,7 @@ BrowserAction.prototype = { removable: true, label: this.defaults.title || this.extension.name, tooltiptext: this.defaults.title || "", - defaultArea: this.defaults.area, + defaultArea: CustomizableUI.AREA_NAVBAR, onBeforeCreated: document => { let view = document.createElementNS(XUL_NS, "panelview"); diff --git a/browser/components/extensions/schemas/browser_action.json b/browser/components/extensions/schemas/browser_action.json index 575731e68679..1a7da956a13b 100644 --- a/browser/components/extensions/schemas/browser_action.json +++ b/browser/components/extensions/schemas/browser_action.json @@ -31,12 +31,6 @@ "browser_style": { "type": "boolean", "optional": true - }, - "default_area": { - "description": "Defines the location the browserAction will appear by default. The default location is navbar.", - "type": "string", - "enum": ["navbar", "menupanel", "tabstrip", "personaltoolbar"], - "optional": true } }, "optional": true diff --git a/browser/components/extensions/test/browser/browser-common.ini b/browser/components/extensions/test/browser/browser-common.ini index a4676d81bd49..f908835ea766 100644 --- a/browser/components/extensions/test/browser/browser-common.ini +++ b/browser/components/extensions/test/browser/browser-common.ini @@ -24,7 +24,6 @@ support-files = searchSuggestionEngine.sjs ../../../../../toolkit/components/extensions/test/mochitest/head_webrequest.js -[browser_ext_browserAction_area.js] [browser_ext_browserAction_context.js] [browser_ext_browserAction_disabled.js] [browser_ext_browserAction_pageAction_icon.js] diff --git a/browser/components/extensions/test/browser/browser_ext_browserAction_area.js b/browser/components/extensions/test/browser/browser_ext_browserAction_area.js deleted file mode 100644 index d05eeca3cd7a..000000000000 --- a/browser/components/extensions/test/browser/browser_ext_browserAction_area.js +++ /dev/null @@ -1,73 +0,0 @@ -/* -*- Mode: indent-tabs-mode: nil; js-indent-level: 2 -*- */ -/* vim: set sts=2 sw=2 et tw=80: */ -"use strict"; - -var browserAreas = { - "navbar": CustomizableUI.AREA_NAVBAR, - "menupanel": CustomizableUI.AREA_PANEL, - "tabstrip": CustomizableUI.AREA_TABSTRIP, - "personaltoolbar": CustomizableUI.AREA_BOOKMARKS, -}; - -function* testInArea(area) { - let manifest = { - "browser_action": { - "default_popup": "popup.html", - "browser_style": true, - }, - }; - if (area) { - manifest.browser_action.default_area = area; - } - let extension = ExtensionTestUtils.loadExtension({ - manifest, - files: { - "popup.html": ` - - - - - - - `, - - "popup.js": function() { - window.onload = () => { - browser.test.sendMessage("from-popup"); - }; - }, - }, - }); - yield extension.startup(); - let widget = getBrowserActionWidget(extension); - let placement = CustomizableUI.getPlacementOfWidget(widget.id); - is(placement && placement.area, browserAreas[area || "navbar"], `widget located in correct area`); - - clickBrowserAction(extension); - - yield extension.awaitMessage("from-popup"); - - yield extension.unload(); -} - -add_task(function* testBrowserActionDefaultArea() { - yield testInArea(); -}); - -add_task(function* testBrowserActionInToolbar() { - yield testInArea("navbar"); -}); - -add_task(function* testBrowserActionInMenuPanel() { - yield testInArea("menupanel"); -}); - -add_task(function* testBrowserActionInTabStrip() { - yield testInArea("tabstrip"); -}); - -add_task(function* testBrowserActionInPersonalToolbar() { - CustomizableUI.setToolbarVisibility("PersonalToolbar", true); - yield testInArea("personaltoolbar"); - CustomizableUI.setToolbarVisibility("PersonalToolbar", false); -}); From fdeaf1b69e46443c6e2b30991c9b48de16501361 Mon Sep 17 00:00:00 2001 From: Xidorn Quan Date: Tue, 21 Feb 2017 18:56:41 -0800 Subject: [PATCH 29/48] servo: Merge #15669 - Read ServoArcTypeList.h for list of arc types (from upsuper:bindgen-arc-type); r=heycam r? @heycam Source-Repo: https://github.com/servo/servo Source-Revision: 07debf5dc02e48ede1652100377a4c51979ca7e6 --HG-- extra : subtree_source : https%3A//hg.mozilla.org/projects/converted-servo-linear extra : subtree_revision : 226ab816f3326ffaf1cde78ea56a80261499da73 --- servo/components/style/build_gecko.rs | 29 ++++++++++++++++++--------- 1 file changed, 19 insertions(+), 10 deletions(-) diff --git a/servo/components/style/build_gecko.rs b/servo/components/style/build_gecko.rs index b62ec7e0f0c2..8d530f7e34f9 100644 --- a/servo/components/style/build_gecko.rs +++ b/servo/components/style/build_gecko.rs @@ -232,6 +232,24 @@ mod bindings { File::create(&out_file).unwrap().write_all(&result.into_bytes()).expect("Unable to write output"); } + fn get_arc_types() -> Vec { + // Read the file + let mut list_file = File::open(DISTDIR_PATH.join("include/mozilla/ServoArcTypeList.h")) + .expect("Unable to open ServoArcTypeList.h"); + let mut content = String::new(); + list_file.read_to_string(&mut content).expect("Fail to read ServoArcTypeList.h"); + // Remove comments + let block_comment_re = Regex::new(r#"(?s)/\*.*?\*/"#).unwrap(); + let content = block_comment_re.replace_all(&content, ""); + // Extract the list + let re = Regex::new(r#"^SERVO_ARC_TYPE\(\w+,\s*(\w+)\)$"#).unwrap(); + content.lines().map(|line| line.trim()).filter(|line| !line.is_empty()) + .map(|line| re.captures(&line) + .expect(&format!("Unrecognized line in ServoArcTypeList.h: '{}'", line)) + .get(1).unwrap().as_str().to_string()) + .collect() + } + pub fn generate_structs(build_type: BuildType) { let mut builder = Builder::get_initial_builder(build_type) .enable_cxx_namespaces() @@ -600,15 +618,6 @@ mod bindings { let array_types = [ ArrayType { cpp_type: "uintptr_t", rust_type: "usize" }, ]; - let servo_nullable_arc_types = [ - "ServoComputedValues", - "ServoCssRules", - "RawServoStyleSheet", - "RawServoDeclarationBlock", - "RawServoStyleRule", - "RawServoImportRule", - "RawServoAnimationValue", - ]; struct ServoOwnedType { name: &'static str, opaque: bool, @@ -646,7 +655,7 @@ mod bindings { .raw_line(format!("pub type nsTArrayBorrowed_{}<'a> = &'a mut ::gecko_bindings::structs::nsTArray<{}>;", cpp_type, rust_type)) } - for &ty in servo_nullable_arc_types.iter() { + for ty in get_arc_types().iter() { builder = builder .hide_type(format!("{}Strong", ty)) .raw_line(format!("pub type {0}Strong = ::gecko_bindings::sugar::ownership::Strong<{0}>;", ty)) From 436fefadc249dd921304a461bc8293139c4aa4c6 Mon Sep 17 00:00:00 2001 From: Chris Peterson Date: Mon, 20 Feb 2017 14:45:30 -0800 Subject: [PATCH 30/48] Bug 1341162 - Fix -Wunreachable-code-return warning in webrtc/signaling. r=bwc The WebrtcVideoConduit::GetRTCPSenderReport() member function has an unnecessary scope block and unreachable `return false`. media/webrtc/signaling/src/media-conduit/VideoConduit.cpp:847:10 [-Wunreachable-code-return] 'return' will never be executed MozReview-Commit-ID: 1GFcupqcA9k --HG-- extra : rebase_source : c46a012a99c66b3953262ba5f86810d62a5b48cf extra : source : 6ca7c167f10cb234f67c89fb8b64c67f87ca5453 --- .../src/media-conduit/VideoConduit.cpp | 36 +++++++++---------- 1 file changed, 17 insertions(+), 19 deletions(-) diff --git a/media/webrtc/signaling/src/media-conduit/VideoConduit.cpp b/media/webrtc/signaling/src/media-conduit/VideoConduit.cpp index 2383cdf16c29..80edd9d75af0 100755 --- a/media/webrtc/signaling/src/media-conduit/VideoConduit.cpp +++ b/media/webrtc/signaling/src/media-conduit/VideoConduit.cpp @@ -823,26 +823,24 @@ WebrtcVideoConduit::GetRTCPSenderReport(DOMHighResTimeStamp* timestamp, unsigned int* packetsSent, uint64_t* bytesSent) { - { - CSFLogVerbose(logTag, "%s for VideoConduit:%p", __FUNCTION__, this); - MutexAutoLock lock(mCodecMutex); - if (!mSendStream) { - return false; - } - - const webrtc::VideoSendStream::Stats& stats = mSendStream->GetStats(); - *packetsSent = 0; - for (auto entry: stats.substreams){ - *packetsSent += entry.second.rtp_stats.transmitted.packets; - // NG -- per https://www.w3.org/TR/webrtc-stats/ this is only payload bytes - *bytesSent += entry.second.rtp_stats.MediaPayloadBytes(); - } - // Note: timestamp is not correct per the spec... should be time the rtcp - // was received (remote) or sent (local) - *timestamp = webrtc::Clock::GetRealTimeClock()->TimeInMilliseconds(); - return true; + CSFLogVerbose(logTag, "%s for VideoConduit:%p", __FUNCTION__, this); + MutexAutoLock lock(mCodecMutex); + if (!mSendStream) { + return false; } - return false; + + const webrtc::VideoSendStream::Stats& stats = mSendStream->GetStats(); + *packetsSent = 0; + for (auto entry: stats.substreams){ + *packetsSent += entry.second.rtp_stats.transmitted.packets; + // NG -- per https://www.w3.org/TR/webrtc-stats/ this is only payload bytes + *bytesSent += entry.second.rtp_stats.MediaPayloadBytes(); + } + + // Note: timestamp is not correct per the spec... should be time the rtcp + // was received (remote) or sent (local) + *timestamp = webrtc::Clock::GetRealTimeClock()->TimeInMilliseconds(); + return true; } MediaConduitErrorCode From 7e9dbcd83e181a366502d470a05409581891231a Mon Sep 17 00:00:00 2001 From: Jan-Ivar Bruaroey Date: Tue, 21 Feb 2017 14:41:58 -0500 Subject: [PATCH 31/48] Bug 1341409: Fix omission of advanced constraints in applying camera constraints. r=jesup MozReview-Commit-ID: 2qhuv5e6lv9 --HG-- extra : rebase_source : a25747eb160ddd71a241e0f479c7b226cd0e0a6d --- dom/media/webrtc/MediaTrackConstraints.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/dom/media/webrtc/MediaTrackConstraints.cpp b/dom/media/webrtc/MediaTrackConstraints.cpp index de127bdb55d7..2b4d4cafc753 100644 --- a/dom/media/webrtc/MediaTrackConstraints.cpp +++ b/dom/media/webrtc/MediaTrackConstraints.cpp @@ -297,6 +297,10 @@ NormalizedConstraints::NormalizedConstraints( : NormalizedConstraintSet(*aOthers[0]) , mBadConstraint(nullptr) { + for (auto& entry : aOthers[0]->mAdvanced) { + mAdvanced.push_back(entry); + } + // Create a list of member pointers. nsTArray list; NormalizedConstraints dummy(dom::MediaTrackConstraints(), &list); From 6e53176dafbc9dc881677e944dac910bea6dce6f Mon Sep 17 00:00:00 2001 From: Glenn Watson Date: Tue, 21 Feb 2017 20:45:20 -0800 Subject: [PATCH 32/48] servo: Merge #15680 - Rename ScreenPx to DeviceIndependentPixel (from glennw:zoom-wip); r=mbrubeck Source-Repo: https://github.com/servo/servo Source-Revision: 03893e25cc00488dea540ce53865f7f696f8f262 --HG-- extra : subtree_source : https%3A//hg.mozilla.org/projects/converted-servo-linear extra : subtree_revision : b133609385824e996d26af7ee50f139f7f2a6582 --- servo/components/compositing/compositor.rs | 30 +++++++++++----------- servo/components/compositing/touch.rs | 3 +-- servo/components/compositing/windowing.rs | 8 +++--- servo/components/config/opts.rs | 4 +-- servo/components/geometry/lib.rs | 14 +++++----- servo/components/servo/lib.rs | 2 +- servo/components/style_traits/lib.rs | 6 ++--- servo/ports/cef/window.rs | 6 ++--- servo/ports/glutin/window.rs | 14 +++++----- 9 files changed, 43 insertions(+), 44 deletions(-) diff --git a/servo/components/compositing/compositor.rs b/servo/components/compositing/compositor.rs index 2673af8b439d..b7eb2633e68b 100644 --- a/servo/components/compositing/compositor.rs +++ b/servo/components/compositing/compositor.rs @@ -27,7 +27,7 @@ use script_traits::{TouchpadPressurePhase, TouchEventType, TouchId, WindowSizeDa use script_traits::CompositorEvent::{self, MouseMoveEvent, MouseButtonEvent, TouchEvent, TouchpadPressureEvent}; use servo_config::opts; use servo_config::prefs::PREFS; -use servo_geometry::ScreenPx; +use servo_geometry::DeviceIndependentPixel; use servo_url::ServoUrl; use std::collections::HashMap; use std::fs::File; @@ -155,10 +155,10 @@ pub struct IOCompositor { /// "Desktop-style" zoom that resizes the viewport to fit the window. /// See `ViewportPx` docs in util/geom.rs for details. - page_zoom: ScaleFactor, + page_zoom: ScaleFactor, /// The device pixel ratio for this window. - scale_factor: ScaleFactor, + scale_factor: ScaleFactor, channel_to_self: Box, @@ -378,7 +378,7 @@ impl IOCompositor { fn new(window: Rc, state: InitialCompositorState) -> IOCompositor { let window_size = window.framebuffer_size(); - let scale_factor = window.scale_factor(); + let scale_factor = window.hidpi_factor(); let composite_target = match opts::get().output_file { Some(_) => CompositeTarget::PngFile, None => CompositeTarget::Window @@ -756,7 +756,7 @@ impl IOCompositor { } fn send_window_size(&self, size_type: WindowSizeType) { - let dppx = self.page_zoom * self.device_pixels_per_screen_px(); + let dppx = self.page_zoom * self.hidpi_factor(); let initial_viewport = self.window_size.to_f32() / dppx; let visible_viewport = initial_viewport / self.viewport_zoom; let msg = ConstellationMsg::WindowSize(WindowSizeData { @@ -889,7 +889,7 @@ impl IOCompositor { debug!("compositor resizing to {:?}", new_size.to_untyped()); // A size change could also mean a resolution change. - let new_scale_factor = self.window.scale_factor(); + let new_scale_factor = self.window.hidpi_factor(); if self.scale_factor != new_scale_factor { self.scale_factor = new_scale_factor; self.update_zoom_transform(); @@ -948,7 +948,7 @@ impl IOCompositor { }; if let Some(pipeline) = self.pipeline(root_pipeline_id) { - let dppx = self.page_zoom * self.device_pixels_per_screen_px(); + let dppx = self.page_zoom * self.hidpi_factor(); let translated_point = (point / dppx).to_untyped(); let event_to_send = match mouse_window_event { MouseWindowEvent::Click(button, _) => { @@ -986,7 +986,7 @@ impl IOCompositor { return; } - let dppx = self.page_zoom * self.device_pixels_per_screen_px(); + let dppx = self.page_zoom * self.hidpi_factor(); let event_to_send = MouseMoveEvent(Some((cursor / dppx).to_untyped())); let msg = ConstellationControlMsg::SendEvent(root_pipeline_id, event_to_send); if let Some(pipeline) = self.pipeline(root_pipeline_id) { @@ -1012,7 +1012,7 @@ impl IOCompositor { fn on_touch_down(&mut self, identifier: TouchId, point: TypedPoint2D) { self.touch_handler.on_touch_down(identifier, point); - let dppx = self.page_zoom * self.device_pixels_per_screen_px(); + let dppx = self.page_zoom * self.hidpi_factor(); let translated_point = (point / dppx).to_untyped(); self.send_event_to_root_pipeline(TouchEvent(TouchEventType::Down, identifier, @@ -1042,7 +1042,7 @@ impl IOCompositor { }); } TouchAction::DispatchEvent => { - let dppx = self.page_zoom * self.device_pixels_per_screen_px(); + let dppx = self.page_zoom * self.hidpi_factor(); let translated_point = (point / dppx).to_untyped(); self.send_event_to_root_pipeline(TouchEvent(TouchEventType::Move, identifier, @@ -1053,7 +1053,7 @@ impl IOCompositor { } fn on_touch_up(&mut self, identifier: TouchId, point: TypedPoint2D) { - let dppx = self.page_zoom * self.device_pixels_per_screen_px(); + let dppx = self.page_zoom * self.hidpi_factor(); let translated_point = (point / dppx).to_untyped(); self.send_event_to_root_pipeline(TouchEvent(TouchEventType::Up, identifier, @@ -1066,7 +1066,7 @@ impl IOCompositor { fn on_touch_cancel(&mut self, identifier: TouchId, point: TypedPoint2D) { // Send the event to script. self.touch_handler.on_touch_cancel(identifier, point); - let dppx = self.page_zoom * self.device_pixels_per_screen_px(); + let dppx = self.page_zoom * self.hidpi_factor(); let translated_point = (point / dppx).to_untyped(); self.send_event_to_root_pipeline(TouchEvent(TouchEventType::Cancel, identifier, @@ -1078,7 +1078,7 @@ impl IOCompositor { pressure: f32, phase: TouchpadPressurePhase) { if let Some(true) = PREFS.get("dom.forcetouch.enabled").as_boolean() { - let dppx = self.page_zoom * self.device_pixels_per_screen_px(); + let dppx = self.page_zoom * self.hidpi_factor(); let translated_point = (point / dppx).to_untyped(); self.send_event_to_root_pipeline(TouchpadPressureEvent(translated_point, pressure, @@ -1291,7 +1291,7 @@ impl IOCompositor { } } - fn device_pixels_per_screen_px(&self) -> ScaleFactor { + fn hidpi_factor(&self) -> ScaleFactor { match opts::get().device_pixels_per_px { Some(device_pixels_per_px) => ScaleFactor::new(device_pixels_per_px), None => match opts::get().output_file { @@ -1302,7 +1302,7 @@ impl IOCompositor { } fn device_pixels_per_page_px(&self) -> ScaleFactor { - self.viewport_zoom * self.page_zoom * self.device_pixels_per_screen_px() + self.viewport_zoom * self.page_zoom * self.hidpi_factor() } fn update_zoom_transform(&mut self) { diff --git a/servo/components/compositing/touch.rs b/servo/components/compositing/touch.rs index a158c1e5c332..12bc365c77f9 100644 --- a/servo/components/compositing/touch.rs +++ b/servo/components/compositing/touch.rs @@ -7,7 +7,7 @@ use euclid::scale_factor::ScaleFactor; use script_traits::{DevicePixel, EventResult, TouchId}; use self::TouchState::*; -/// Minimum number of `ScreenPx` to begin touch scrolling. +/// Minimum number of `DeviceIndependentPixel` to begin touch scrolling. const TOUCH_PAN_MIN_SCREEN_PX: f32 = 20.0; pub struct TouchHandler { @@ -100,7 +100,6 @@ impl TouchHandler { let action = match self.state { Touching => { let delta = point - old_point; - // TODO let delta: TypedPoint2D<_, ScreenPx> = delta / self.device_pixels_per_screen_px(); if delta.x.abs() > TOUCH_PAN_MIN_SCREEN_PX || delta.y.abs() > TOUCH_PAN_MIN_SCREEN_PX diff --git a/servo/components/compositing/windowing.rs b/servo/components/compositing/windowing.rs index 39b117c85b6d..85d73af2f9f1 100644 --- a/servo/components/compositing/windowing.rs +++ b/servo/components/compositing/windowing.rs @@ -12,7 +12,7 @@ use euclid::size::TypedSize2D; use msg::constellation_msg::{Key, KeyModifiers, KeyState}; use net_traits::net_error_list::NetError; use script_traits::{DevicePixel, MouseButton, TouchEventType, TouchId, TouchpadPressurePhase}; -use servo_geometry::ScreenPx; +use servo_geometry::DeviceIndependentPixel; use servo_url::ServoUrl; use std::fmt::{Debug, Error, Formatter}; use style_traits::cursor::Cursor; @@ -109,7 +109,7 @@ pub trait WindowMethods { /// Returns the size of the window in hardware pixels. fn framebuffer_size(&self) -> TypedSize2D; /// Returns the size of the window in density-independent "px" units. - fn size(&self) -> TypedSize2D; + fn size(&self) -> TypedSize2D; /// Presents the window to the screen (perhaps by page flipping). fn present(&self); @@ -137,8 +137,8 @@ pub trait WindowMethods { /// Called when the tag has finished parsing fn head_parsed(&self); - /// Returns the scale factor of the system (device pixels / screen pixels). - fn scale_factor(&self) -> ScaleFactor; + /// Returns the scale factor of the system (device pixels / device independent pixels). + fn hidpi_factor(&self) -> ScaleFactor; /// Creates a channel to the compositor. The dummy parameter is needed because we don't have /// UFCS in Rust yet. diff --git a/servo/components/config/opts.rs b/servo/components/config/opts.rs index df2bb2e041ee..ca0c24f8d096 100644 --- a/servo/components/config/opts.rs +++ b/servo/components/config/opts.rs @@ -10,7 +10,7 @@ use getopts::Options; use num_cpus; use prefs::{self, PrefValue, PREFS}; use resource_files::set_resources_path; -use servo_geometry::ScreenPx; +use servo_geometry::DeviceIndependentPixel; use servo_url::ServoUrl; use std::borrow::Cow; use std::cmp; @@ -143,7 +143,7 @@ pub struct Opts { pub webdriver_port: Option, /// The initial requested size of the window. - pub initial_window_size: TypedSize2D, + pub initial_window_size: TypedSize2D, /// An optional string allowing the user agent to be set for testing. pub user_agent: Cow<'static, str>, diff --git a/servo/components/geometry/lib.rs b/servo/components/geometry/lib.rs index ddca8d719727..55c1a165295b 100644 --- a/servo/components/geometry/lib.rs +++ b/servo/components/geometry/lib.rs @@ -20,17 +20,17 @@ use std::i32; /// should approximate a device-independent reference length. This unit corresponds to Android's /// "density-independent pixel" (dip), Mac OS X's "point", and Windows "device-independent pixel." /// -/// The relationship between DevicePixel and ScreenPx is defined by the OS. On most low-dpi -/// screens, one ScreenPx is equal to one DevicePixel. But on high-density screens it can be -/// some larger number. For example, by default on Apple "retina" displays, one ScreenPx equals -/// two DevicePixels. On Android "MDPI" displays, one ScreenPx equals 1.5 device pixels. +/// The relationship between DevicePixel and DeviceIndependentPixel is defined by the OS. On most low-dpi +/// screens, one DeviceIndependentPixel is equal to one DevicePixel. But on high-density screens it can be +/// some larger number. For example, by default on Apple "retina" displays, one DeviceIndependentPixel equals +/// two DevicePixels. On Android "MDPI" displays, one DeviceIndependentPixel equals 1.5 device pixels. /// -/// The ratio between ScreenPx and DevicePixel for a given display be found by calling +/// The ratio between DeviceIndependentPixel and DevicePixel for a given display be found by calling /// `servo::windowing::WindowMethods::hidpi_factor`. #[derive(Clone, Copy, Debug)] -pub enum ScreenPx {} +pub enum DeviceIndependentPixel {} -known_heap_size!(0, ScreenPx); +known_heap_size!(0, DeviceIndependentPixel); // An Au is an "App Unit" and represents 1/60th of a CSS pixel. It was // originally proposed in 2002 as a standard unit of measure in Gecko. diff --git a/servo/components/servo/lib.rs b/servo/components/servo/lib.rs index 38b9b7b83250..afda35f1582a 100644 --- a/servo/components/servo/lib.rs +++ b/servo/components/servo/lib.rs @@ -149,7 +149,7 @@ impl Browser where Window: WindowMethods + 'static { let (webrender, webrender_api_sender) = { // TODO(gw): Duplicates device_pixels_per_screen_px from compositor. Tidy up! - let scale_factor = window.scale_factor().get(); + let scale_factor = window.hidpi_factor().get(); let device_pixel_ratio = match opts.device_pixels_per_px { Some(device_pixels_per_px) => device_pixels_per_px, None => match opts.output_file { diff --git a/servo/components/style_traits/lib.rs b/servo/components/style_traits/lib.rs index 4eadd6404026..4ee378833a46 100644 --- a/servo/components/style_traits/lib.rs +++ b/servo/components/style_traits/lib.rs @@ -29,11 +29,11 @@ pub type UnsafeNode = (usize, usize); /// One CSS "px" in the coordinate system of the "initial viewport": /// http://www.w3.org/TR/css-device-adapt/#initial-viewport /// -/// `ViewportPx` is equal to `ScreenPx` times a "page zoom" factor controlled by the user. This is +/// `ViewportPx` is equal to `DeviceIndependentPixel` times a "page zoom" factor controlled by the user. This is /// the desktop-style "full page" zoom that enlarges content but then reflows the layout viewport /// so it still exactly fits the visible area. /// -/// At the default zoom level of 100%, one `PagePx` is equal to one `ScreenPx`. However, if the +/// At the default zoom level of 100%, one `PagePx` is equal to one `DeviceIndependentPixel`. However, if the /// document is zoomed in or out then this scale may be larger or smaller. #[derive(Clone, Copy, Debug)] pub enum ViewportPx {} @@ -50,7 +50,7 @@ pub enum PagePx {} // In summary, the hierarchy of pixel units and the factors to convert from one to the next: // // DevicePixel -// / hidpi_ratio => ScreenPx +// / hidpi_ratio => DeviceIndependentPixel // / desktop_zoom => ViewportPx // / pinch_zoom => PagePx diff --git a/servo/ports/cef/window.rs b/servo/ports/cef/window.rs index 958bc0b22215..4c31a890774e 100644 --- a/servo/ports/cef/window.rs +++ b/servo/ports/cef/window.rs @@ -26,7 +26,7 @@ use gleam::gl; use msg::constellation_msg::{Key, KeyModifiers}; use net_traits::net_error_list::NetError; use script_traits::DevicePixel; -use servo_geometry::ScreenPx; +use servo_geometry::DeviceIndependentPixel; use std::cell::RefCell; use std::ffi::CString; use std::os::raw::{c_char, c_void}; @@ -206,7 +206,7 @@ impl WindowMethods for Window { } } - fn size(&self) -> TypedSize2D { + fn size(&self) -> TypedSize2D { let browser = self.cef_browser.borrow(); match *browser { None => TypedSize2D::new(400.0, 300.0), @@ -250,7 +250,7 @@ impl WindowMethods for Window { } } - fn scale_factor(&self) -> ScaleFactor { + fn hidpi_factor(&self) -> ScaleFactor { if cfg!(target_os="macos") { let browser = self.cef_browser.borrow(); match *browser { diff --git a/servo/ports/glutin/window.rs b/servo/ports/glutin/window.rs index 2ed98b0f6824..338bb056ebd1 100644 --- a/servo/ports/glutin/window.rs +++ b/servo/ports/glutin/window.rs @@ -28,7 +28,7 @@ use script_traits::{DevicePixel, TouchEventType, TouchpadPressurePhase}; use servo_config::opts; use servo_config::prefs::PREFS; use servo_config::resource_files; -use servo_geometry::ScreenPx; +use servo_geometry::DeviceIndependentPixel; use servo_url::ServoUrl; use std::cell::{Cell, RefCell}; #[cfg(any(target_os = "linux", target_os = "macos"))] @@ -193,12 +193,12 @@ pub struct Window { } #[cfg(not(target_os = "windows"))] -fn window_creation_scale_factor() -> ScaleFactor { +fn window_creation_scale_factor() -> ScaleFactor { ScaleFactor::new(1.0) } #[cfg(target_os = "windows")] -fn window_creation_scale_factor() -> ScaleFactor { +fn window_creation_scale_factor() -> ScaleFactor { let hdc = unsafe { user32::GetDC(::std::ptr::null_mut()) }; let ppi = unsafe { gdi32::GetDeviceCaps(hdc, winapi::wingdi::LOGPIXELSY) }; ScaleFactor::new(ppi as f32 / 96.0) @@ -207,7 +207,7 @@ fn window_creation_scale_factor() -> ScaleFactor { impl Window { pub fn new(is_foreground: bool, - window_size: TypedSize2D, + window_size: TypedSize2D, parent: Option) -> Rc { let win_size: TypedSize2D = (window_size.to_f32() * window_creation_scale_factor()) @@ -797,7 +797,7 @@ impl WindowMethods for Window { } } - fn size(&self) -> TypedSize2D { + fn size(&self) -> TypedSize2D { match self.kind { WindowKind::Window(ref window) => { // TODO(ajeffrey): can this fail? @@ -881,7 +881,7 @@ impl WindowMethods for Window { } #[cfg(not(target_os = "windows"))] - fn scale_factor(&self) -> ScaleFactor { + fn hidpi_factor(&self) -> ScaleFactor { match self.kind { WindowKind::Window(ref window) => { ScaleFactor::new(window.hidpi_factor()) @@ -893,7 +893,7 @@ impl WindowMethods for Window { } #[cfg(target_os = "windows")] - fn scale_factor(&self) -> ScaleFactor { + fn hidpi_factor(&self) -> ScaleFactor { let hdc = unsafe { user32::GetDC(::std::ptr::null_mut()) }; let ppi = unsafe { gdi32::GetDeviceCaps(hdc, winapi::wingdi::LOGPIXELSY) }; ScaleFactor::new(ppi as f32 / 96.0) From 7fc9ef1cd2920baa8ca8bd863a32bc417954bfef Mon Sep 17 00:00:00 2001 From: Daosheng Mu Date: Wed, 22 Feb 2017 12:13:30 +0800 Subject: [PATCH 33/48] Bug 1341516 - Fix Oculus Touch ID and poseState; r=kip MozReview-Commit-ID: 9FoLcQmgxjg --HG-- extra : rebase_source : 7409024133b242063644d1bc705e8f91c09e0b7b --- gfx/vr/gfxVROculus.cpp | 32 +++++++++++++++++++++++--------- 1 file changed, 23 insertions(+), 9 deletions(-) diff --git a/gfx/vr/gfxVROculus.cpp b/gfx/vr/gfxVROculus.cpp index 0803b82863a3..555de00b7792 100644 --- a/gfx/vr/gfxVROculus.cpp +++ b/gfx/vr/gfxVROculus.cpp @@ -836,10 +836,20 @@ VRControllerOculus::VRControllerOculus(dom::GamepadHand aHand) : VRControllerHost(VRDeviceType::Oculus) { MOZ_COUNT_CTOR_INHERITED(VRControllerOculus, VRControllerHost); - mControllerInfo.mControllerName.AssignLiteral("Oculus Touch ("); - mControllerInfo.mControllerName.AppendPrintf("%s%s", - GamepadHandValues::strings[uint32_t(aHand)].value, - ")"); + + char* touchID = ""; + switch (aHand) { + case dom::GamepadHand::Left: + touchID = "Oculus Touch (Left)"; + break; + case dom::GamepadHand::Right: + touchID = "Oculus Touch (Right)"; + break; + default: + MOZ_ASSERT(false); + break; + } + mControllerInfo.mControllerName = touchID; mControllerInfo.mMappingType = GamepadMappingType::_empty; mControllerInfo.mHand = aHand; mControllerInfo.mNumButtons = kNumOculusButton; @@ -988,10 +998,13 @@ VRSystemManagerOculus::HandleInput() // Start to process pose ovrTrackingState state = ovr_GetTrackingState(mSession, 0.0, false); - ovrPoseStatef& pose(state.HandPoses[i]); + // HandPoses is ordered by ovrControllerType_LTouch and ovrControllerType_RTouch, + // therefore, we can't get its state by the index of mOculusController. + const uint32_t handIdx = static_cast(controller->GetHand()) - 1; + ovrPoseStatef& pose(state.HandPoses[handIdx]); GamepadPoseState poseState; - if (state.HandStatusFlags[i] & ovrStatus_OrientationTracked) { + if (state.HandStatusFlags[handIdx] & ovrStatus_OrientationTracked) { poseState.flags |= GamepadCapabilityFlags::Cap_Orientation; poseState.orientation[0] = pose.ThePose.Orientation.x; poseState.orientation[1] = pose.ThePose.Orientation.y; @@ -1006,7 +1019,7 @@ VRSystemManagerOculus::HandleInput() poseState.angularAcceleration[1] = pose.AngularAcceleration.y; poseState.angularAcceleration[2] = pose.AngularAcceleration.z; } - if (state.HandStatusFlags[i] & ovrStatus_PositionTracked) { + if (state.HandStatusFlags[handIdx] & ovrStatus_PositionTracked) { poseState.flags |= GamepadCapabilityFlags::Cap_Position; poseState.position[0] = pose.ThePose.Position.x; poseState.position[1] = pose.ThePose.Position.y; @@ -1039,10 +1052,10 @@ VRSystemManagerOculus::HandleButtonPress(uint32_t aControllerIdx, for (uint32_t i = 0; i < kNumOculusButton; ++i) { switch (hand) { - case mozilla::dom::GamepadHand::Left: + case dom::GamepadHand::Left: buttonMask = kOculusTouchLButton[i]; break; - case mozilla::dom::GamepadHand::Right: + case dom::GamepadHand::Right: buttonMask = kOculusTouchRButton[i]; break; default: @@ -1080,6 +1093,7 @@ VRSystemManagerOculus::HandlePoseTracking(uint32_t aControllerIdx, const GamepadPoseState& aPose, VRControllerHost* aController) { + MOZ_ASSERT(aController); if (aPose != aController->GetPose()) { aController->SetPose(aPose); NewPoseState(aControllerIdx, aPose); From 27ba812587c6729ae687cd5a72991eccb5d978c5 Mon Sep 17 00:00:00 2001 From: Zibi Braniecki Date: Fri, 17 Feb 2017 20:06:43 -0800 Subject: [PATCH 34/48] Bug 1312053 - Expose an API to get locale information. r=Waldo MozReview-Commit-ID: LivVJzrb3X1 --HG-- extra : rebase_source : a8c566cf918f01216e9f22e953da935ce41b7654 --- config/check_spidermonkey_style.py | 1 + js/src/builtin/Intl.cpp | 35 +++++++++++++++++ js/src/builtin/Intl.h | 14 +++++++ js/src/builtin/Intl.js | 19 ++++++++++ js/src/shell/js.cpp | 1 + js/src/tests/Intl/getLocaleInfo.js | 38 +++++++++++++++++++ js/src/vm/CommonPropertyNames.h | 3 ++ js/src/vm/SelfHosting.cpp | 1 + toolkit/components/mozintl/MozIntl.cpp | 11 ++++++ toolkit/components/mozintl/mozIMozIntl.idl | 1 + .../components/mozintl/test/test_mozintl.js | 4 ++ 11 files changed, 128 insertions(+) create mode 100644 js/src/tests/Intl/getLocaleInfo.js diff --git a/config/check_spidermonkey_style.py b/config/check_spidermonkey_style.py index fdbb07674a37..c0f722894b26 100644 --- a/config/check_spidermonkey_style.py +++ b/config/check_spidermonkey_style.py @@ -88,6 +88,7 @@ included_inclnames_to_ignore = set([ 'unicode/udat.h', # ICU 'unicode/udatpg.h', # ICU 'unicode/uenum.h', # ICU + 'unicode/uloc.h', # ICU 'unicode/unorm2.h', # ICU 'unicode/unum.h', # ICU 'unicode/unumsys.h', # ICU diff --git a/js/src/builtin/Intl.cpp b/js/src/builtin/Intl.cpp index 8433ae0f190b..b8dda2bc6b9f 100644 --- a/js/src/builtin/Intl.cpp +++ b/js/src/builtin/Intl.cpp @@ -33,6 +33,7 @@ #include "unicode/udat.h" #include "unicode/udatpg.h" #include "unicode/uenum.h" +#include "unicode/uloc.h" #include "unicode/unum.h" #include "unicode/unumsys.h" #include "unicode/upluralrules.h" @@ -167,6 +168,12 @@ uloc_countAvailable() MOZ_CRASH("uloc_countAvailable: Intl API disabled"); } +UBool +uloc_isRightToLeft(const char* locale) +{ + MOZ_CRASH("uloc_isRightToLeft: Intl API disabled"); +} + struct UFormattable; void @@ -4173,6 +4180,34 @@ js::intl_ComputeDisplayNames(JSContext* cx, unsigned argc, Value* vp) return true; } +bool +js::intl_GetLocaleInfo(JSContext* cx, unsigned argc, Value* vp) +{ + CallArgs args = CallArgsFromVp(argc, vp); + MOZ_ASSERT(args.length() == 1); + + JSAutoByteString locale(cx, args[0].toString()); + if (!locale) + return false; + + RootedObject info(cx, NewBuiltinClassInstance(cx)); + if (!info) + return false; + + if (!DefineProperty(cx, info, cx->names().locale, args[0])) + return false; + + bool rtl = uloc_isRightToLeft(icuLocale(locale.ptr())); + + RootedValue dir(cx, StringValue(rtl ? cx->names().rtl : cx->names().ltr)); + + if (!DefineProperty(cx, info, cx->names().direction, dir)) + return false; + + args.rval().setObject(*info); + return true; +} + const Class js::IntlClass = { js_Object_str, JSCLASS_HAS_CACHED_PROTO(JSProto_Intl) diff --git a/js/src/builtin/Intl.h b/js/src/builtin/Intl.h index 1d08153afe07..2be53e8da4d1 100644 --- a/js/src/builtin/Intl.h +++ b/js/src/builtin/Intl.h @@ -509,6 +509,20 @@ intl_GetPluralCategories(JSContext* cx, unsigned argc, Value* vp); extern MOZ_MUST_USE bool intl_GetCalendarInfo(JSContext* cx, unsigned argc, Value* vp); +/** + * Returns a plain object with locale information for a single valid locale + * (callers must perform this validation). The object will have these + * properties: + * + * direction + * a string with a value "ltr" for left-to-right locale, and "rtl" for + * right-to-left locale. + * locale + * a BCP47 compilant locale string for the resolved locale. + */ +extern MOZ_MUST_USE bool +intl_GetLocaleInfo(JSContext* cx, unsigned argc, Value* vp); + /** * Returns an Array with CLDR-based fields display names. * The function takes three arguments: diff --git a/js/src/builtin/Intl.js b/js/src/builtin/Intl.js index 897d8a4fe5f2..941ca68ef06b 100644 --- a/js/src/builtin/Intl.js +++ b/js/src/builtin/Intl.js @@ -3337,3 +3337,22 @@ function Intl_getDisplayNames(locales, options) { return result; } +function Intl_getLocaleInfo(locales) { + const requestedLocales = CanonicalizeLocaleList(locales); + + // In the future, we may want to expose uloc_getAvailable and use it here. + const DateTimeFormat = dateTimeFormatInternalProperties; + const localeData = DateTimeFormat.localeData; + + const localeOpt = new Record(); + localeOpt.localeMatcher = "best fit"; + + const r = ResolveLocale(callFunction(DateTimeFormat.availableLocales, DateTimeFormat), + requestedLocales, + localeOpt, + DateTimeFormat.relevantExtensionKeys, + localeData); + + return intl_GetLocaleInfo(r.locale); +} + diff --git a/js/src/shell/js.cpp b/js/src/shell/js.cpp index 823d47b49190..51306e2f851a 100644 --- a/js/src/shell/js.cpp +++ b/js/src/shell/js.cpp @@ -939,6 +939,7 @@ AddIntlExtras(JSContext* cx, unsigned argc, Value* vp) static const JSFunctionSpec funcs[] = { JS_SELF_HOSTED_FN("getCalendarInfo", "Intl_getCalendarInfo", 1, 0), + JS_SELF_HOSTED_FN("getLocaleInfo", "Intl_getLocaleInfo", 1, 0), JS_SELF_HOSTED_FN("getDisplayNames", "Intl_getDisplayNames", 2, 0), JS_FS_END }; diff --git a/js/src/tests/Intl/getLocaleInfo.js b/js/src/tests/Intl/getLocaleInfo.js new file mode 100644 index 000000000000..22d4f537998e --- /dev/null +++ b/js/src/tests/Intl/getLocaleInfo.js @@ -0,0 +1,38 @@ +// |reftest| skip-if(!this.hasOwnProperty("Intl")||!this.hasOwnProperty("addIntlExtras")) +/* 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/. */ + +// Tests the getCalendarInfo function with a diverse set of arguments. + +function checkLocaleInfo(info, expected) +{ + assertEq(Object.getPrototypeOf(info), Object.prototype); + + assertEq(info.direction, expected.direction); + assertEq(info.locale, expected.locale); +} + +addIntlExtras(Intl); + +let gLI = Intl.getLocaleInfo; + +assertEq(gLI.length, 1); + +checkLocaleInfo(gLI('en-US'), { + direction: "ltr", + locale: "en-US" +}); + +checkLocaleInfo(gLI('fr'), { + direction: "ltr", + locale: "fr" +}); + +checkLocaleInfo(gLI('ar'), { + direction: "rtl", + locale: "ar" +}); + +if (typeof reportCompare === 'function') + reportCompare(0, 0); diff --git a/js/src/vm/CommonPropertyNames.h b/js/src/vm/CommonPropertyNames.h index 4730cb6b90df..7a97e5e75506 100644 --- a/js/src/vm/CommonPropertyNames.h +++ b/js/src/vm/CommonPropertyNames.h @@ -91,6 +91,7 @@ macro(defineSetter, defineSetter, "__defineSetter__") \ macro(delete, delete_, "delete") \ macro(deleteProperty, deleteProperty, "deleteProperty") \ + macro(direction, direction, "direction") \ macro(displayURL, displayURL, "displayURL") \ macro(do, do_, "do") \ macro(done, done, "done") \ @@ -210,6 +211,7 @@ macro(locale, locale, "locale") \ macro(lookupGetter, lookupGetter, "__lookupGetter__") \ macro(lookupSetter, lookupSetter, "__lookupSetter__") \ + macro(ltr, ltr, "ltr") \ macro(MapConstructorInit, MapConstructorInit, "MapConstructorInit") \ macro(MapIterator, MapIterator, "Map Iterator") \ macro(maximumFractionDigits, maximumFractionDigits, "maximumFractionDigits") \ @@ -298,6 +300,7 @@ macro(resumeGenerator, resumeGenerator, "resumeGenerator") \ macro(return, return_, "return") \ macro(revoke, revoke, "revoke") \ + macro(rtl, rtl, "rtl") \ macro(script, script, "script") \ macro(scripts, scripts, "scripts") \ macro(second, second, "second") \ diff --git a/js/src/vm/SelfHosting.cpp b/js/src/vm/SelfHosting.cpp index 89322a379720..52124da7486f 100644 --- a/js/src/vm/SelfHosting.cpp +++ b/js/src/vm/SelfHosting.cpp @@ -2615,6 +2615,7 @@ static const JSFunctionSpec intrinsic_functions[] = { JS_FN("intl_FormatDateTime", intl_FormatDateTime, 2,0), JS_FN("intl_FormatNumber", intl_FormatNumber, 2,0), JS_FN("intl_GetCalendarInfo", intl_GetCalendarInfo, 1,0), + JS_FN("intl_GetLocaleInfo", intl_GetLocaleInfo, 1,0), JS_FN("intl_ComputeDisplayNames", intl_ComputeDisplayNames, 3,0), JS_FN("intl_IsValidTimeZoneName", intl_IsValidTimeZoneName, 1,0), JS_FN("intl_NumberFormat", intl_NumberFormat, 2,0), diff --git a/toolkit/components/mozintl/MozIntl.cpp b/toolkit/components/mozintl/MozIntl.cpp index 432db62b14ba..04d25ec67194 100644 --- a/toolkit/components/mozintl/MozIntl.cpp +++ b/toolkit/components/mozintl/MozIntl.cpp @@ -82,6 +82,17 @@ MozIntl::AddPluralRulesConstructor(JS::Handle val, JSContext* cx) return NS_OK; } +NS_IMETHODIMP +MozIntl::AddGetLocaleInfo(JS::Handle val, JSContext* cx) +{ + static const JSFunctionSpec funcs[] = { + JS_SELF_HOSTED_FN("getLocaleInfo", "Intl_getLocaleInfo", 1, 0), + JS_FS_END + }; + + return AddFunctions(cx, val, funcs); +} + NS_GENERIC_FACTORY_CONSTRUCTOR(MozIntl) NS_DEFINE_NAMED_CID(MOZ_MOZINTL_CID); diff --git a/toolkit/components/mozintl/mozIMozIntl.idl b/toolkit/components/mozintl/mozIMozIntl.idl index e0d88e12a766..31cbb71eceb3 100644 --- a/toolkit/components/mozintl/mozIMozIntl.idl +++ b/toolkit/components/mozintl/mozIMozIntl.idl @@ -10,6 +10,7 @@ interface mozIMozIntl : nsISupports { [implicit_jscontext] void addGetCalendarInfo(in jsval intlObject); [implicit_jscontext] void addGetDisplayNames(in jsval intlObject); + [implicit_jscontext] void addGetLocaleInfo(in jsval intlObject); /** * Adds a PluralRules constructor to the given object. This function may only diff --git a/toolkit/components/mozintl/test/test_mozintl.js b/toolkit/components/mozintl/test/test_mozintl.js index 8d2720bf0152..2f58a44078b2 100644 --- a/toolkit/components/mozintl/test/test_mozintl.js +++ b/toolkit/components/mozintl/test/test_mozintl.js @@ -35,6 +35,7 @@ function test_cross_global(mozIntl) { function test_methods_presence(mozIntl) { equal(mozIntl.addGetCalendarInfo instanceof Function, true); equal(mozIntl.addGetDisplayNames instanceof Function, true); + equal(mozIntl.addGetLocaleInfo instanceof Function, true); let x = {}; @@ -43,4 +44,7 @@ function test_methods_presence(mozIntl) { mozIntl.addGetDisplayNames(x); equal(x.getDisplayNames instanceof Function, true); + + mozIntl.addGetLocaleInfo(x); + equal(x.getLocaleInfo instanceof Function, true); } From 652691c720fa00123e87f52133962e8ffc5f2db4 Mon Sep 17 00:00:00 2001 From: "Alfredo.Yang" Date: Tue, 21 Feb 2017 15:30:03 +0800 Subject: [PATCH 35/48] Bug 1331330 - compare rust parser and stagefright sample table. r=kinetik MozReview-Commit-ID: G6ZqSNNo00J --HG-- extra : rebase_source : ea6df10e95042cf14f65f81850e2a95f4a2ba2b0 --- media/libstagefright/binding/MP4Metadata.cpp | 38 ++++++++++++++------ 1 file changed, 28 insertions(+), 10 deletions(-) diff --git a/media/libstagefright/binding/MP4Metadata.cpp b/media/libstagefright/binding/MP4Metadata.cpp index 2e03b7abc9c5..ccaace08fa93 100644 --- a/media/libstagefright/binding/MP4Metadata.cpp +++ b/media/libstagefright/binding/MP4Metadata.cpp @@ -140,7 +140,7 @@ public: const CryptoFile& Crypto() const; - bool ReadTrackIndex(FallibleTArray& aDest, mozilla::TrackID aTrackID); + bool ReadTrackIndice(mp4parse_byte_data* aIndices, mozilla::TrackID aTrackID); private: void UpdateCrypto(); @@ -363,13 +363,26 @@ MP4Metadata::Crypto() const bool MP4Metadata::ReadTrackIndex(FallibleTArray& aDest, mozilla::TrackID aTrackID) { -#ifdef MOZ_RUST_MP4PARSE - if (mRust && mPreferRust && mRust->ReadTrackIndex(aDest, aTrackID)) { - return true; + bool ret = mStagefright->ReadTrackIndex(aDest, aTrackID); + +#ifndef RELEASE_OR_BETA + if (mRustTestMode && ret && mRust) { + mp4parse_byte_data data = {}; + bool rustRet = mRust->ReadTrackIndice(&data, aTrackID); + MOZ_DIAGNOSTIC_ASSERT(rustRet); + MOZ_DIAGNOSTIC_ASSERT(data.length == aDest.Length()); + for (uint32_t i = 0; i < data.length; i++) { + MOZ_DIAGNOSTIC_ASSERT(data.indices[i].start_offset == aDest[i].start_offset); + MOZ_DIAGNOSTIC_ASSERT(data.indices[i].end_offset == aDest[i].end_offset); + MOZ_DIAGNOSTIC_ASSERT(data.indices[i].start_composition == aDest[i].start_composition); + MOZ_DIAGNOSTIC_ASSERT(data.indices[i].end_composition == aDest[i].end_composition); + MOZ_DIAGNOSTIC_ASSERT(data.indices[i].start_decode == aDest[i].start_decode); + MOZ_DIAGNOSTIC_ASSERT(data.indices[i].sync == aDest[i].sync); + } } - aDest.Clear(); #endif - return mStagefright->ReadTrackIndex(aDest, aTrackID); + + return ret; } static inline bool @@ -391,6 +404,9 @@ ConvertIndex(FallibleTArray& aDest, indice.sync = s_indice.sync; // FIXME: Make this infallible after bug 968520 is done. MOZ_ALWAYS_TRUE(aDest.AppendElement(indice, mozilla::fallible)); + MOZ_LOG(sLog, LogLevel::Debug, ("s_o: %" PRIu64 ", e_o: %" PRIu64 ", s_c: %" PRIu64 ", e_c: %" PRIu64 ", s_d: %" PRIu64 ", sync: %d\n", + indice.start_offset, indice.end_offset, indice.start_composition, indice.end_composition, + indice.start_decode, indice.sync)); } return true; } @@ -851,7 +867,7 @@ MP4MetadataRust::Crypto() const } bool -MP4MetadataRust::ReadTrackIndex(FallibleTArray& aDest, mozilla::TrackID aTrackID) +MP4MetadataRust::ReadTrackIndice(mp4parse_byte_data* aIndices, mozilla::TrackID aTrackID) { uint8_t fragmented = false; auto rv = mp4parse_is_fragmented(mRustParser.get(), aTrackID, &fragmented); @@ -863,10 +879,12 @@ MP4MetadataRust::ReadTrackIndex(FallibleTArray& aDest, mozilla::T return true; } - // For non-fragmented mp4. - NS_WARNING("Not yet implemented"); + rv = mp4parse_get_indice_table(mRustParser.get(), aTrackID, aIndices); + if (rv != MP4PARSE_OK) { + return false; + } - return false; + return true; } /*static*/ bool From daf25d971165ca8fcfa1584e9549046b7859f9ee Mon Sep 17 00:00:00 2001 From: "Alfredo.Yang" Date: Mon, 20 Feb 2017 10:58:10 +0800 Subject: [PATCH 36/48] Bug 1340980 - update rust mp4 parser. r=kinetik MozReview-Commit-ID: HrRkz8Sk0v7 --HG-- extra : rebase_source : d4ea066eb6acbaa648851fd2827e145b84004a14 --- media/libstagefright/binding/DecoderData.cpp | 2 +- .../libstagefright/binding/include/mp4parse.h | 20 +- .../binding/mp4parse-cargo.patch | 5 +- .../binding/mp4parse/Cargo.toml | 4 + .../binding/mp4parse/src/boxes.rs | 2 + .../binding/mp4parse/src/lib.rs | 127 +++++- .../binding/mp4parse/src/tests.rs | 16 + .../binding/mp4parse/tests/public.rs | 3 + .../binding/mp4parse_capi/src/lib.rs | 397 +++++++++++++++++- media/libstagefright/binding/update-rust.sh | 2 +- 10 files changed, 544 insertions(+), 34 deletions(-) diff --git a/media/libstagefright/binding/DecoderData.cpp b/media/libstagefright/binding/DecoderData.cpp index d1971484231f..a06e533b1e62 100644 --- a/media/libstagefright/binding/DecoderData.cpp +++ b/media/libstagefright/binding/DecoderData.cpp @@ -192,7 +192,7 @@ MP4VideoInfo::Update(const MetaData* aMetaData, const char* aMimeType) #ifdef MOZ_RUST_MP4PARSE static void UpdateTrackProtectedInfo(mozilla::TrackInfo& aConfig, - const mp4parser_sinf_info& aSinf) + const mp4parse_sinf_info& aSinf) { if (aSinf.is_encrypted != 0) { aConfig.mCrypto.mValid = true; diff --git a/media/libstagefright/binding/include/mp4parse.h b/media/libstagefright/binding/include/mp4parse.h index 721c1e261bab..1f10293bce07 100644 --- a/media/libstagefright/binding/include/mp4parse.h +++ b/media/libstagefright/binding/include/mp4parse.h @@ -48,20 +48,30 @@ typedef struct mp4parse_track_info { int64_t media_time; } mp4parse_track_info; +typedef struct mp4parse_indice { + uint64_t start_offset; + uint64_t end_offset; + uint64_t start_composition; + uint64_t end_composition; + uint64_t start_decode; + bool sync; +} mp4parse_indice; + typedef struct mp4parse_byte_data { uint32_t length; uint8_t const* data; + mp4parse_indice const* indices; } mp4parse_byte_data; typedef struct mp4parse_pssh_info { mp4parse_byte_data data; } mp4parse_pssh_info; -typedef struct mp4parser_sinf_info { +typedef struct mp4parse_sinf_info { uint32_t is_encrypted; uint8_t iv_size; mp4parse_byte_data kid; -} mp4parser_sinf_info; +} mp4parse_sinf_info; typedef struct mp4parse_track_audio_info { uint16_t channels; @@ -69,7 +79,7 @@ typedef struct mp4parse_track_audio_info { uint32_t sample_rate; uint16_t profile; mp4parse_byte_data codec_specific_config; - mp4parser_sinf_info protected_data; + mp4parse_sinf_info protected_data; } mp4parse_track_audio_info; typedef struct mp4parse_track_video_info { @@ -78,7 +88,7 @@ typedef struct mp4parse_track_video_info { uint16_t image_width; uint16_t image_height; mp4parse_byte_data extra_data; - mp4parser_sinf_info protected_data; + mp4parse_sinf_info protected_data; } mp4parse_track_video_info; typedef struct mp4parse_fragment_info { @@ -116,6 +126,8 @@ mp4parse_error mp4parse_get_track_audio_info(mp4parse_parser* parser, uint32_t t /// Fill the supplied `mp4parse_track_video_info` with metadata for `track`. mp4parse_error mp4parse_get_track_video_info(mp4parse_parser* parser, uint32_t track_index, mp4parse_track_video_info* info); +mp4parse_error mp4parse_get_indice_table(mp4parse_parser* parser, uint32_t track_id, mp4parse_byte_data* indices); + /// Fill the supplied `mp4parse_fragment_info` with metadata from fragmented file. mp4parse_error mp4parse_get_fragment_info(mp4parse_parser* parser, mp4parse_fragment_info* info); diff --git a/media/libstagefright/binding/mp4parse-cargo.patch b/media/libstagefright/binding/mp4parse-cargo.patch index bfa0ab74b424..ec8e3de2919a 100644 --- a/media/libstagefright/binding/mp4parse-cargo.patch +++ b/media/libstagefright/binding/mp4parse-cargo.patch @@ -27,11 +27,14 @@ diff --git a/media/libstagefright/binding/mp4parse_capi/Cargo.toml b/media/libst index aeeebc65..5c0836a 100644 --- a/media/libstagefright/binding/mp4parse_capi/Cargo.toml +++ b/media/libstagefright/binding/mp4parse_capi/Cargo.toml -@@ -18,18 +18,12 @@ exclude = [ +@@ -18,21 +18,12 @@ exclude = [ "*.mp4", ] -build = "build.rs" +- +-[badges] +-travis-ci = { repository = "https://github.com/mozilla/mp4parse-rust" } +build = false [dependencies] diff --git a/media/libstagefright/binding/mp4parse/Cargo.toml b/media/libstagefright/binding/mp4parse/Cargo.toml index 2403005f2de3..44ff9e5a0646 100644 --- a/media/libstagefright/binding/mp4parse/Cargo.toml +++ b/media/libstagefright/binding/mp4parse/Cargo.toml @@ -10,6 +10,7 @@ authors = [ description = "Parser for ISO base media file format (mp4)" documentation = "https://mp4parse-docs.surge.sh/mp4parse/" license = "MPL-2.0" +categories = ["multimedia::video"] repository = "https://github.com/mozilla/mp4parse-rust" @@ -18,6 +19,9 @@ exclude = [ "*.mp4", ] +[badges] +travis-ci = { repository = "https://github.com/mozilla/mp4parse-rust" } + [dependencies] byteorder = "1.0.0" bitreader = { version = "0.2.0" } diff --git a/media/libstagefright/binding/mp4parse/src/boxes.rs b/media/libstagefright/binding/mp4parse/src/boxes.rs index 97f65137ef46..fc9085b4b7d9 100644 --- a/media/libstagefright/binding/mp4parse/src/boxes.rs +++ b/media/libstagefright/binding/mp4parse/src/boxes.rs @@ -134,4 +134,6 @@ box_database!( TrackEncryptionBox 0x74656e63, // "tenc" ProtectionSchemeInformationBox 0x73696e66, // "sinf" OriginalFormatBox 0x66726d61, // "frma" + MP3AudioSampleEntry 0x2e6d7033, // ".mp3" - from F4V. + CompositionOffsetBox 0x63747473, // "ctts" ); diff --git a/media/libstagefright/binding/mp4parse/src/lib.rs b/media/libstagefright/binding/mp4parse/src/lib.rs index 9260a9ec7f76..c6c195355356 100644 --- a/media/libstagefright/binding/mp4parse/src/lib.rs +++ b/media/libstagefright/binding/mp4parse/src/lib.rs @@ -151,46 +151,64 @@ struct MediaHeaderBox { // Chunk offset box 'stco' or 'co64' #[derive(Debug)] -struct ChunkOffsetBox { - offsets: Vec, +pub struct ChunkOffsetBox { + pub offsets: Vec, } // Sync sample box 'stss' #[derive(Debug)] -struct SyncSampleBox { - samples: Vec, +pub struct SyncSampleBox { + pub samples: Vec, } // Sample to chunk box 'stsc' #[derive(Debug)] -struct SampleToChunkBox { - samples: Vec, +pub struct SampleToChunkBox { + pub samples: Vec, } #[derive(Debug)] -struct SampleToChunk { - first_chunk: u32, - samples_per_chunk: u32, - sample_description_index: u32, +pub struct SampleToChunk { + pub first_chunk: u32, + pub samples_per_chunk: u32, + pub sample_description_index: u32, } // Sample size box 'stsz' #[derive(Debug)] -struct SampleSizeBox { - sample_size: u32, - sample_sizes: Vec, +pub struct SampleSizeBox { + pub sample_size: u32, + pub sample_sizes: Vec, } // Time to sample box 'stts' #[derive(Debug)] -struct TimeToSampleBox { - samples: Vec, +pub struct TimeToSampleBox { + pub samples: Vec, +} + +#[repr(C)] +#[derive(Debug)] +pub struct Sample { + pub sample_count: u32, + pub sample_delta: u32, +} + +#[derive(Debug, Clone, Copy)] +pub enum TimeOffsetVersion { + Version0(u32), + Version1(i32), +} + +#[derive(Debug, Clone)] +pub struct TimeOffset { + pub sample_count: u32, + pub time_offset: TimeOffsetVersion, } #[derive(Debug)] -struct Sample { - sample_count: u32, - sample_delta: u32, +pub struct CompositionOffsetBox { + pub samples: Vec, } // Handler reference box 'hdlr' @@ -228,6 +246,7 @@ pub enum AudioCodecSpecific { ES_Descriptor(ES_Descriptor), FLACSpecificBox(FLACSpecificBox), OpusSpecificBox(OpusSpecificBox), + MP3, } #[derive(Debug, Clone)] @@ -396,6 +415,7 @@ pub struct TrackScaledTime(pub u64, pub usize); /// A fragmented file contains no sample data in stts, stsc, and stco. #[derive(Debug, Default)] pub struct EmptySampleTableBoxes { + // TODO: Track has stts, stsc and stco, this structure can be discarded. pub empty_stts : bool, pub empty_stsc : bool, pub empty_stco : bool, @@ -421,6 +441,12 @@ pub struct Track { pub empty_sample_boxes: EmptySampleTableBoxes, pub data: Option, pub tkhd: Option, // TODO(kinetik): find a nicer way to export this. + pub stts: Option, + pub stsc: Option, + pub stsz: Option, + pub stco: Option, // It is for stco or co64. + pub stss: Option, + pub ctts: Option, } impl Track { @@ -840,30 +866,41 @@ fn read_stbl(f: &mut BMFFBox, track: &mut Track) -> Result<()> { } BoxType::TimeToSampleBox => { let stts = read_stts(&mut b)?; - track.empty_sample_boxes.empty_stts = stts.samples.is_empty(); log!("{:?}", stts); + track.empty_sample_boxes.empty_stts = stts.samples.is_empty(); + track.stts = Some(stts); } BoxType::SampleToChunkBox => { let stsc = read_stsc(&mut b)?; - track.empty_sample_boxes.empty_stsc = stsc.samples.is_empty(); log!("{:?}", stsc); + track.empty_sample_boxes.empty_stsc = stsc.samples.is_empty(); + track.stsc = Some(stsc); } BoxType::SampleSizeBox => { let stsz = read_stsz(&mut b)?; log!("{:?}", stsz); + track.stsz = Some(stsz); } BoxType::ChunkOffsetBox => { let stco = read_stco(&mut b)?; track.empty_sample_boxes.empty_stco = stco.offsets.is_empty(); log!("{:?}", stco); + track.stco = Some(stco); } BoxType::ChunkLargeOffsetBox => { let co64 = read_co64(&mut b)?; log!("{:?}", co64); + track.stco = Some(co64); } BoxType::SyncSampleBox => { let stss = read_stss(&mut b)?; log!("{:?}", stss); + track.stss = Some(stss); + } + BoxType::CompositionOffsetBox => { + let ctts = read_ctts(&mut b)?; + log!("{:?}", ctts); + track.ctts = Some(ctts); } _ => skip_box_content(&mut b)?, }; @@ -1115,6 +1152,45 @@ fn read_stsc(src: &mut BMFFBox) -> Result { }) } +fn read_ctts(src: &mut BMFFBox) -> Result { + let (version, _) = read_fullbox_extra(src)?; + + let counts = be_u32(src)?; + + if src.bytes_left() < (counts as usize * 8) { + return Err(Error::InvalidData("insufficient data in 'ctts' box")); + } + + let mut offsets = Vec::new(); + for _ in 0..counts { + let (sample_count, time_offset) = match version { + 0 => { + let count = be_u32(src)?; + let offset = TimeOffsetVersion::Version0(be_u32(src)?); + (count, offset) + }, + 1 => { + let count = be_u32(src)?; + let offset = TimeOffsetVersion::Version1(be_i32(src)?); + (count, offset) + }, + _ => { + return Err(Error::InvalidData("unsupported version in 'ctts' box")); + } + }; + offsets.push(TimeOffset { + sample_count: sample_count, + time_offset: time_offset, + }); + } + + skip_box_remain(src)?; + + Ok(CompositionOffsetBox { + samples: offsets, + }) +} + /// Parse a stsz box. fn read_stsz(src: &mut BMFFBox) -> Result { let (_, _) = read_fullbox_extra(src)?; @@ -1433,7 +1509,6 @@ fn read_dfla(src: &mut BMFFBox) -> Result { if blocks.is_empty() { return Err(Error::InvalidData("FLACSpecificBox missing metadata")); } else if blocks[0].block_type != 0 { - println!("flac metadata block:\n {:?}", blocks[0]); return Err(Error::InvalidData( "FLACSpecificBox must have STREAMINFO metadata first")); } else if blocks[0].data.len() != 34 { @@ -1602,7 +1677,8 @@ fn read_video_sample_entry(src: &mut BMFFBox, track: &mut Track) -> } BoxType::VPCodecConfigurationBox => { // vpcC if (name != BoxType::VP8SampleEntry && - name != BoxType::VP9SampleEntry) || + name != BoxType::VP9SampleEntry && + name != BoxType::ProtectedVisualSampleEntry) || codec_specific.is_some() { return Err(Error::InvalidData("malformed video sample entry")); } @@ -1687,6 +1763,9 @@ fn read_audio_sample_entry(src: &mut BMFFBox, track: &mut Track) -> // Skip chan/etc. for now. let mut codec_specific = None; + if name == BoxType::MP3AudioSampleEntry { + codec_specific = Some(AudioCodecSpecific::MP3); + } let mut protection_info = Vec::new(); let mut iter = src.box_iter(); while let Some(mut b) = iter.next_box()? { @@ -1889,16 +1968,18 @@ fn read_buf(src: &mut T, size: usize) -> Result> { // - zero or more byte strings, with a single null terminating the string. // - zero byte strings with no null terminator (i.e. zero space in the box for the string) // - length-prefixed strings with no null terminator (e.g. bear_rotate_0.mp4) +// - multiple byte strings where more than one byte is a null. fn read_null_terminated_string(src: &mut T, mut size: usize) -> Result { let mut buf = Vec::new(); while size > 0 { let c = src.read_u8()?; + size -= 1; if c == 0 { break; } buf.push(c); - size -= 1; } + skip(src, size)?; String::from_utf8(buf).map_err(From::from) } diff --git a/media/libstagefright/binding/mp4parse/src/tests.rs b/media/libstagefright/binding/mp4parse/src/tests.rs index 15c4cfb5dadf..921168b937ed 100644 --- a/media/libstagefright/binding/mp4parse/src/tests.rs +++ b/media/libstagefright/binding/mp4parse/src/tests.rs @@ -884,3 +884,19 @@ fn read_esds() { assert_eq!(es.audio_channel_count, Some(6)); assert_eq!(es.codec_esds, aac_esds); } + +#[test] +fn read_null_terminated_string() { + let tests = vec![ + vec![0u8], // Short null-terminated string. + vec![65u8, 0u8], // Normal null-terminated string. + vec![], // Empty string (no data). + vec![4u8, 65u8, 66u8, 67u8, 68u8], // Length-prefixed string, not null-terminated. + vec![0u8, 0u8], // Doubly null-terminated string. + ]; + for v in tests.iter() { + let mut c = Cursor::new(v); + super::read_null_terminated_string(&mut c, v.len()).expect("string read failed"); + assert_eq!(c.position(), v.len() as u64); + } +} diff --git a/media/libstagefright/binding/mp4parse/tests/public.rs b/media/libstagefright/binding/mp4parse/tests/public.rs index 09548ea905b4..ab94cd610440 100644 --- a/media/libstagefright/binding/mp4parse/tests/public.rs +++ b/media/libstagefright/binding/mp4parse/tests/public.rs @@ -92,6 +92,9 @@ fn public_api() { assert!(opus.version > 0); "Opus" } + mp4::AudioCodecSpecific::MP3 => { + "MP3" + } }, "ES"); assert!(a.samplesize > 0); assert!(a.samplerate > 0); diff --git a/media/libstagefright/binding/mp4parse_capi/src/lib.rs b/media/libstagefright/binding/mp4parse_capi/src/lib.rs index 443e708bedab..deba559a6084 100644 --- a/media/libstagefright/binding/mp4parse_capi/src/lib.rs +++ b/media/libstagefright/binding/mp4parse_capi/src/lib.rs @@ -55,6 +55,7 @@ use mp4parse::TrackTimeScale; use mp4parse::TrackScaledTime; use mp4parse::serialize_opus_header; use mp4parse::CodecType; +use mp4parse::Track; // rusty-cheddar's C enum generation doesn't namespace enum members by // prefixing them, so we're forced to do it in our member names until @@ -113,17 +114,31 @@ pub struct mp4parse_track_info { // TODO(kinetik): include crypto guff } +#[repr(C)] +#[derive(Default, Debug, PartialEq)] +pub struct mp4parse_indice { + pub start_offset: u64, + pub end_offset: u64, + pub start_composition: u64, + pub end_composition: u64, + pub start_decode: u64, + pub sync: bool, +} + #[repr(C)] pub struct mp4parse_byte_data { pub length: u32, + // cheddar can't handle generic type, so it needs to be multiple data types here. pub data: *const u8, + pub indices: *const mp4parse_indice, } impl Default for mp4parse_byte_data { fn default() -> Self { mp4parse_byte_data { length: 0, - data: std::ptr::null_mut(), + data: std::ptr::null(), + indices: std::ptr::null(), } } } @@ -133,6 +148,10 @@ impl mp4parse_byte_data { self.length = data.len() as u32; self.data = data.as_ptr(); } + fn set_indices(&mut self, data: &Vec) { + self.length = data.len() as u32; + self.indices = data.as_ptr(); + } } #[repr(C)] @@ -143,7 +162,7 @@ pub struct mp4parse_pssh_info { #[repr(C)] #[derive(Default)] -pub struct mp4parser_sinf_info { +pub struct mp4parse_sinf_info { pub is_encrypted: u32, pub iv_size: u8, pub kid: mp4parse_byte_data, @@ -157,7 +176,7 @@ pub struct mp4parse_track_audio_info { pub sample_rate: u32, pub profile: u16, pub codec_specific_config: mp4parse_byte_data, - pub protected_data: mp4parser_sinf_info, + pub protected_data: mp4parse_sinf_info, } #[repr(C)] @@ -168,7 +187,7 @@ pub struct mp4parse_track_video_info { pub image_width: u16, pub image_height: u16, pub extra_data: mp4parse_byte_data, - pub protected_data: mp4parser_sinf_info, + pub protected_data: mp4parse_sinf_info, } #[repr(C)] @@ -187,6 +206,7 @@ struct Wrap { poisoned: bool, opus_header: HashMap>, pssh_data: Vec, + sample_table: HashMap>, } #[repr(C)] @@ -221,6 +241,10 @@ impl mp4parse_parser { fn pssh_data_mut(&mut self) -> &mut Vec { &mut self.0.pssh_data } + + fn sample_table_mut(&mut self) -> &mut HashMap> { + &mut self.0.sample_table + } } #[repr(C)] @@ -266,6 +290,7 @@ pub unsafe extern fn mp4parse_new(io: *const mp4parse_io) -> *mut mp4parse_parse poisoned: false, opus_header: HashMap::new(), pssh_data: Vec::new(), + sample_table: HashMap::new(), })); Box::into_raw(parser) @@ -401,6 +426,8 @@ pub unsafe extern fn mp4parse_get_track_info(parser: *mut mp4parse_parser, track mp4parse_codec::MP4PARSE_CODEC_MP3, AudioCodecSpecific::ES_Descriptor(_) => mp4parse_codec::MP4PARSE_CODEC_UNKNOWN, + AudioCodecSpecific::MP3 => + mp4parse_codec::MP4PARSE_CODEC_MP3, }, Some(SampleEntry::Video(ref video)) => match video.codec_specific { VideoCodecSpecific::VPxConfig(_) => @@ -536,6 +563,7 @@ pub unsafe extern fn mp4parse_get_track_audio_info(parser: *mut mp4parse_parser, } } } + AudioCodecSpecific::MP3 => (), } match audio.protection_info.iter().find(|sinf| sinf.tenc.is_some()) { @@ -615,6 +643,367 @@ pub unsafe extern fn mp4parse_get_track_video_info(parser: *mut mp4parse_parser, MP4PARSE_OK } +#[no_mangle] +pub unsafe extern fn mp4parse_get_indice_table(parser: *mut mp4parse_parser, track_id: u32, indices: *mut mp4parse_byte_data) -> mp4parse_error { + if parser.is_null() || (*parser).poisoned() { + return MP4PARSE_ERROR_BADARG; + } + + // Initialize fields to default values to ensure all fields are always valid. + *indices = Default::default(); + + let context = (*parser).context(); + let tracks = &context.tracks; + let track = match tracks.iter().find(|track| track.track_id == Some(track_id)) { + Some(t) => t, + _ => return MP4PARSE_ERROR_INVALID, + }; + + let index_table = (*parser).sample_table_mut(); + match index_table.get(&track_id) { + Some(v) => { + (*indices).set_indices(v); + return MP4PARSE_OK; + }, + _ => {}, + } + + // Find the track start offset time from 'elst'. + // 'media_time' maps start time onward, 'empty_duration' adds time offset + // before first frame is displayed. + let offset_time = + match (&track.empty_duration, &track.media_time, &context.timescale) { + (&Some(empty_duration), &Some(media_time), &Some(scale)) => { + (empty_duration.0 - media_time.0) as i64 * scale.0 as i64 + }, + (&Some(empty_duration), _, &Some(scale)) => { + empty_duration.0 as i64 * scale.0 as i64 + }, + (_, &Some(media_time), &Some(scale)) => { + (0 - media_time.0) as i64 * scale.0 as i64 + }, + _ => 0, + }; + + match create_sample_table(track, offset_time) { + Some(v) => { + (*indices).set_indices(&v); + index_table.insert(track_id, v); + return MP4PARSE_OK; + }, + _ => {}, + } + + MP4PARSE_ERROR_INVALID +} + +// Convert a 'ctts' compact table to full table by iterator, +// (sample_with_the_same_offset_count, offset) => (offset), (offset), (offset) ... +// +// For example: +// (2, 10), (4, 9) into (10, 10, 9, 9, 9, 9) by calling next_offset_time(). +struct TimeOffsetIterator<'a> { + cur_sample_range: std::ops::Range, + cur_offset: i64, + ctts_iter: Option>, +} + +impl<'a> Iterator for TimeOffsetIterator<'a> { + type Item = i64; + + fn next(&mut self) -> Option { + let has_sample = self.cur_sample_range.next() + .or_else(|| { + // At end of current TimeOffset, find the next TimeOffset. + let iter = match self.ctts_iter { + Some(ref mut v) => v, + _ => return None, + }; + let offset_version; + self.cur_sample_range = match iter.next() { + Some(v) => { + offset_version = v.time_offset; + (0 .. v.sample_count) + }, + _ => { + offset_version = mp4parse::TimeOffsetVersion::Version0(0); + (0 .. 0) + }, + }; + + self.cur_offset = match offset_version { + mp4parse::TimeOffsetVersion::Version0(i) => i as i64, + mp4parse::TimeOffsetVersion::Version1(i) => i as i64, + }; + + self.cur_sample_range.next() + }); + + has_sample.and(Some(self.cur_offset)) + } +} + +impl<'a> TimeOffsetIterator<'a> { + fn next_offset_time(&mut self) -> i64 { + match self.next() { + Some(v) => v as i64, + _ => 0, + } + } +} + +// Convert 'stts' compact table to full table by iterator, +// (sample_count_with_the_same_time, time) => (time, time, time) ... repeats +// sample_count_with_the_same_time. +// +// For example: +// (2, 3000), (1, 2999) to (3000, 3000, 2999). +struct TimeToSampleIteraor<'a> { + cur_sample_count: std::ops::Range, + cur_sample_delta: u32, + stts_iter: std::slice::Iter<'a, mp4parse::Sample>, +} + +impl<'a> Iterator for TimeToSampleIteraor<'a> { + type Item = u32; + + fn next(&mut self) -> Option { + let has_sample = self.cur_sample_count.next() + .or_else(|| { + self.cur_sample_count = match self.stts_iter.next() { + Some(v) => { + self.cur_sample_delta = v.sample_delta; + (0 .. v.sample_count) + }, + _ => (0 .. 0), + }; + + self.cur_sample_count.next() + }); + + has_sample.and(Some(self.cur_sample_delta)) + } +} + +impl<'a> TimeToSampleIteraor<'a> { + fn next_delta(&mut self) -> u32 { + match self.next() { + Some(v) => v, + _ => 0, + } + } +} + +// Convert 'stco' compact table to full table by iterator. +// (start_chunk_num, sample_number) => (start_chunk_num, sample_number), +// (start_chunk_num + 1, sample_number), +// (start_chunk_num + 2, sample_number), +// ... +// (next start_chunk_num, next sample_number), +// ... +// +// For example: +// (1, 5), (5, 10), (9, 2) => (1, 5), (2, 5), (3, 5), (4, 5), (5, 10), (6, 10), +// (7, 10), (8, 10), (9, 2) +struct SampleToChunkIterator<'a> { + chunks: std::ops::Range, + sample_count: u32, + stsc_peek_iter: std::iter::Peekable>, + remain_chunk_count: u32, // total chunk number from 'stco'. +} + +impl<'a> Iterator for SampleToChunkIterator<'a> { + type Item = (u32, u32); + + fn next(&mut self) -> Option<(u32, u32)> { + let has_chunk = self.chunks.next() + .or_else(|| { + self.chunks = match (self.stsc_peek_iter.next(), self.stsc_peek_iter.peek()) { + (Some(next), Some(peek)) => { + self.sample_count = next.samples_per_chunk; + ((next.first_chunk - 1) .. (peek.first_chunk - 1)) + }, + (Some(next), None) => { + self.sample_count = next.samples_per_chunk; + // Total chunk number in 'stsc' could be different to 'stco', + // there could be more chunks at the last 'stsc' record. + ((next.first_chunk - 1) .. next.first_chunk + self.remain_chunk_count -1) + }, + _ => (0 .. 0), + }; + self.remain_chunk_count -= self.chunks.len() as u32; + self.chunks.next() + }); + + has_chunk.map_or(None, |id| { Some((id, self.sample_count)) }) + } +} + +// A helper struct to convert track time to us. +struct PresentationTime { + time: i64, + scale: TrackTimeScale +} + +impl PresentationTime { + fn new(time: i64, scale: TrackTimeScale) -> PresentationTime { + PresentationTime { + time: time, + scale: scale, + } + } + + fn to_us(&self) -> i64 { + let track_time = TrackScaledTime(self.time as u64, self.scale.1); + match track_time_to_us(track_time, self.scale) { + Some(v) => v as i64, + _ => 0, + } + } +} + +fn create_sample_table(track: &Track, track_offset_time: i64) -> Option> { + let timescale = match track.timescale { + Some(t) => t, + _ => return None, + }; + + let (stsc, stco, stsz, stts) = + match (&track.stsc, &track.stco, &track.stsz, &track.stts) { + (&Some(ref a), &Some(ref b), &Some(ref c), &Some(ref d)) => (a, b, c, d), + _ => return None, + }; + + // According to spec, no sync table means every sample is sync sample. + let has_sync_table = match track.stss { + Some(_) => true, + _ => false, + }; + + let mut sample_table = Vec::new(); + let mut sample_size_iter = stsz.sample_sizes.iter(); + + // Get 'stsc' iterator for (chunk_id, chunk_sample_count) and calculate the sample + // offset address. + let stsc_iter = SampleToChunkIterator { + chunks: (0 .. 0), + sample_count: 0, + stsc_peek_iter: stsc.samples.as_slice().iter().peekable(), + remain_chunk_count: stco.offsets.len() as u32, + }; + + for i in stsc_iter { + let chunk_id = i.0 as usize; + let sample_counts = i.1; + let mut cur_position: u64 = stco.offsets[chunk_id]; + for _ in 0 .. sample_counts { + let start_offset = cur_position; + let end_offset = match (stsz.sample_size, sample_size_iter.next()) { + (_, Some(t)) => start_offset + *t as u64, + (t, _) if t > 0 => start_offset + t as u64, + _ => 0, + }; + if end_offset == 0 { + return None; + } + cur_position = end_offset; + + sample_table.push( + mp4parse_indice { + start_offset: start_offset, + end_offset: end_offset, + start_composition: 0, + end_composition: 0, + start_decode: 0, + sync: !has_sync_table, + } + ); + } + } + + // Mark the sync sample in sample_table according to 'stss'. + match &track.stss { + &Some(ref v) => { + for iter in &v.samples { + sample_table[(iter - 1) as usize].sync = true; + } + }, + _ => {} + } + + let ctts_iter = match &track.ctts { + &Some(ref v) => Some(v.samples.as_slice().iter()), + _ => None, + }; + + let mut ctts_offset_iter = TimeOffsetIterator { + cur_sample_range: (0 .. 0), + cur_offset: 0, + ctts_iter: ctts_iter, + }; + + let mut stts_iter = TimeToSampleIteraor { + cur_sample_count: (0 .. 0), + cur_sample_delta: 0, + stts_iter: stts.samples.as_slice().iter(), + }; + + // sum_delta is the sum of stts_iter delta. + // According to sepc: + // decode time => DT(n) = DT(n-1) + STTS(n) + // composition time => CT(n) = DT(n) + CTTS(n) + // Note: + // composition time needs to add the track offset time from 'elst' table. + let mut sum_delta = PresentationTime::new(0, timescale); + for sample in sample_table.as_mut_slice() { + let decode_time = sum_delta.to_us(); + sum_delta.time += stts_iter.next_delta() as i64; + + // ctts_offset is the current sample offset time. + let ctts_offset = PresentationTime::new(ctts_offset_iter.next_offset_time(), timescale); + + let start_composition = (decode_time + ctts_offset.to_us() + track_offset_time) as u64; + let end_composition = (sum_delta.to_us() + ctts_offset.to_us() + track_offset_time) as u64; + + sample.start_decode = decode_time as u64; + sample.start_composition = start_composition; + sample.end_composition = end_composition; + } + + // Correct composition end time due to 'ctts' causes composition time re-ordering. + // + // Composition end time is not in specification. However, gecko needs it, so we need to + // calculate to correct the composition end time. + if track.ctts.is_some() { + // Create an index table refers to sample_table and sorted by start_composisiton time. + let mut sort_table = Vec::new(); + sort_table.reserve(sample_table.len()); + for i in 0 .. sample_table.len() { + sort_table.push(i); + } + + sort_table.sort_by_key(|i| { + match sample_table.get(*i) { + Some(v) => { + v.start_composition + }, + _ => 0, + } + }); + + let iter = sort_table.iter(); + for i in 0 .. (iter.len() - 1) { + let current_index = sort_table[i] as usize; + let peek_index = sort_table[i + 1] as usize; + let next_start_composition_time = sample_table[peek_index].start_composition; + let ref mut sample = sample_table[current_index]; + sample.end_composition = next_start_composition_time; + } + } + + Some(sample_table) +} + /// Fill the supplied `mp4parse_fragment_info` with metadata from fragmented file. #[no_mangle] pub unsafe extern fn mp4parse_get_fragment_info(parser: *mut mp4parse_parser, info: *mut mp4parse_fragment_info) -> mp4parse_error { diff --git a/media/libstagefright/binding/update-rust.sh b/media/libstagefright/binding/update-rust.sh index a8a462f6db2c..7ec3a5149c5e 100755 --- a/media/libstagefright/binding/update-rust.sh +++ b/media/libstagefright/binding/update-rust.sh @@ -2,7 +2,7 @@ # Script to update mp4parse-rust sources to latest upstream # Default version. -VER=v0.6.0 +VER=6dfc85b277f8a072083b71f23cc05981b22a10bc # Accept version or commit from the command line. if test -n "$1"; then From 8f2e3bc3e5b7b30566b9f8ac3ab68b9887b70fb7 Mon Sep 17 00:00:00 2001 From: JW Wang Date: Fri, 17 Feb 2017 19:29:43 +0800 Subject: [PATCH 37/48] Bug 1340969. Part 1 - add ShutdownPromisePool to manage ShutdownPromises. r=jya MozReview-Commit-ID: KAr3Fe8Aeqi --HG-- extra : rebase_source : 3c8d93653f8974d69b356ef49a360105efae28a0 extra : intermediate-source : 5ca91530155e9bae43a349acd30e8e591d1ca928 extra : source : e77a4d9d8c7bfedbe43933781c9090681fdff9af --- dom/media/MediaFormatReader.cpp | 111 ++++++++++++++++++++++---------- dom/media/MediaFormatReader.h | 3 + 2 files changed, 80 insertions(+), 34 deletions(-) diff --git a/dom/media/MediaFormatReader.cpp b/dom/media/MediaFormatReader.cpp index dae5e3c69aa2..f50eeab46863 100644 --- a/dom/media/MediaFormatReader.cpp +++ b/dom/media/MediaFormatReader.cpp @@ -310,6 +310,66 @@ LocalAllocPolicy::Cancel() mTokenRequest.DisconnectIfExists(); } +/** + * This class tracks shutdown promises to ensure all decoders are shut down + * completely before MFR continues the rest of the shutdown procedure. + */ +class MediaFormatReader::ShutdownPromisePool +{ +public: + ShutdownPromisePool() + : mOnShutdownComplete(new ShutdownPromise::Private(__func__)) + { + } + + // Return a promise which will be resolved when all the tracking promises + // are resolved. Note no more promises should be added for tracking once + // this function is called. + RefPtr Shutdown(); + + // Track a shutdown promise. + void Track(RefPtr aPromise); + + // Shut down a decoder and track its shutdown promise. + void ShutdownDecoder(already_AddRefed aDecoder) + { + Track(RefPtr(aDecoder)->Shutdown()); + } + +private: + bool mShutdown = false; + const RefPtr mOnShutdownComplete; + nsTHashtable> mPromises; +}; + +RefPtr +MediaFormatReader::ShutdownPromisePool::Shutdown() +{ + MOZ_DIAGNOSTIC_ASSERT(!mShutdown); + mShutdown = true; + if (mPromises.Count() == 0) { + mOnShutdownComplete->Resolve(true, __func__); + } + return mOnShutdownComplete; +} + +void +MediaFormatReader::ShutdownPromisePool::Track(RefPtr aPromise) +{ + MOZ_DIAGNOSTIC_ASSERT(!mShutdown); + MOZ_DIAGNOSTIC_ASSERT(!mPromises.Contains(aPromise)); + mPromises.PutEntry(aPromise); + aPromise->Then( + AbstractThread::GetCurrent(), __func__, + [aPromise, this]() { + MOZ_DIAGNOSTIC_ASSERT(mPromises.Contains(aPromise)); + mPromises.RemoveEntry(aPromise); + if (mShutdown && mPromises.Count() == 0) { + mOnShutdownComplete->Resolve(true, __func__); + } + }); +} + class MediaFormatReader::DecoderFactory { using InitPromise = MediaDataDecoder::InitPromise; @@ -323,8 +383,10 @@ public: , mOwner(WrapNotNull(aOwner)) { } void CreateDecoder(TrackType aTrack); - // Shutdown any decoder pending initialization. - RefPtr ShutdownDecoder(TrackType aTrack) + + // Shutdown any decoder pending initialization and reset mAudio/mVideo to its + // pristine state so CreateDecoder() is ready to be called again immediately. + void ShutdownDecoder(TrackType aTrack) { MOZ_ASSERT(aTrack == TrackInfo::kAudioTrack || aTrack == TrackInfo::kVideoTrack); @@ -332,18 +394,11 @@ public: data.mPolicy->Cancel(); data.mTokenRequest.DisconnectIfExists(); data.mInitRequest.DisconnectIfExists(); - if (!data.mDecoder) { - return ShutdownPromise::CreateAndResolve(true, __func__); + if (data.mDecoder) { + mOwner->mShutdownPromisePool->ShutdownDecoder(data.mDecoder.forget()); } - if (data.mShutdownRequest.Exists()) { - // A shutdown is already in progress due to a prior initialization error, - // return the existing promise. - data.mShutdownRequest.Disconnect(); - RefPtr p = data.mShutdownPromise.forget(); - return p; - } - RefPtr decoder = data.mDecoder.forget(); - return decoder->Shutdown(); + data.mStage = Stage::None; + MOZ_ASSERT(!data.mToken); } private: @@ -371,8 +426,6 @@ private: RefPtr mDecoder; MozPromiseRequestHolder mTokenRequest; MozPromiseRequestHolder mInitRequest; - MozPromiseRequestHolder mShutdownRequest; - RefPtr mShutdownPromise; } mAudio, mVideo; void RunStage(Data& aData); @@ -583,18 +636,8 @@ MediaFormatReader::DecoderFactory::DoInitDecoder(Data& aData) MOZ_RELEASE_ASSERT(!ownerData.mDecoder, "Can't have a decoder already set"); aData.mStage = Stage::None; - aData.mShutdownPromise = aData.mDecoder->Shutdown(); - aData.mShutdownPromise - ->Then( - mOwner->OwnerThread(), __func__, - [this, &aData, aError]() { - aData.mShutdownRequest.Complete(); - aData.mShutdownPromise = nullptr; - aData.mDecoder = nullptr; - mOwner->NotifyError(aData.mTrack, aError); - }, - []() { MOZ_RELEASE_ASSERT(false, "Can't ever get here"); }) - ->Track(aData.mShutdownRequest); + mOwner->mShutdownPromisePool->ShutdownDecoder(aData.mDecoder.forget()); + mOwner->NotifyError(aData.mTrack, aError); }) ->Track(aData.mInitRequest); } @@ -978,6 +1021,7 @@ MediaFormatReader::MediaFormatReader(AbstractMediaDecoder* aDecoder, , mSeekScheduled(false) , mVideoFrameContainer(aVideoFrameContainer) , mDecoderFactory(new DecoderFactory(this)) + , mShutdownPromisePool(new ShutdownPromisePool()) { MOZ_ASSERT(aDemuxer); MOZ_COUNT_CTOR(MediaFormatReader); @@ -1015,14 +1059,12 @@ MediaFormatReader::Shutdown() mVideo.RejectPromise(NS_ERROR_DOM_MEDIA_CANCELED, __func__); } - nsTArray> promises; - if (HasAudio()) { mAudio.ResetDemuxer(); mAudio.mTrackDemuxer->BreakCycles(); mAudio.mTrackDemuxer = nullptr; mAudio.ResetState(); - promises.AppendElement(ShutdownDecoderWithPromise(TrackInfo::kAudioTrack)); + mShutdownPromisePool->Track(ShutdownDecoderWithPromise(TrackInfo::kAudioTrack)); } if (HasVideo()) { @@ -1030,17 +1072,17 @@ MediaFormatReader::Shutdown() mVideo.mTrackDemuxer->BreakCycles(); mVideo.mTrackDemuxer = nullptr; mVideo.ResetState(); - promises.AppendElement(ShutdownDecoderWithPromise(TrackInfo::kVideoTrack)); + mShutdownPromisePool->Track(ShutdownDecoderWithPromise(TrackInfo::kVideoTrack)); } - promises.AppendElement(mDemuxer->Shutdown()); + mShutdownPromisePool->Track(mDemuxer->Shutdown()); mDemuxer = nullptr; mCompositorUpdatedListener.DisconnectIfExists(); mOnTrackWaitingForKeyListener.Disconnect(); RefPtr p = mShutdownPromise.Ensure(__func__); - ShutdownPromise::All(OwnerThread(), promises) + mShutdownPromisePool->Shutdown() ->Then(OwnerThread(), __func__, this, &MediaFormatReader::TearDownDecoders, &MediaFormatReader::TearDownDecoders); @@ -1075,7 +1117,8 @@ MediaFormatReader::ShutdownDecoderWithPromise(TrackType aTrack) // in the Decoder Factory. // This will be a no-op until we're processing the final decoder shutdown // prior to the MediaFormatReader being shutdown. - return mDecoderFactory->ShutdownDecoder(aTrack); + mDecoderFactory->ShutdownDecoder(aTrack); + return ShutdownPromise::CreateAndResolve(true, __func__); } // Finally, let's just shut down the currently active decoder. diff --git a/dom/media/MediaFormatReader.h b/dom/media/MediaFormatReader.h index 82b796f739ff..0caf8f8a1b5a 100644 --- a/dom/media/MediaFormatReader.h +++ b/dom/media/MediaFormatReader.h @@ -575,6 +575,9 @@ private: class DecoderFactory; UniquePtr mDecoderFactory; + class ShutdownPromisePool; + UniquePtr mShutdownPromisePool; + MediaEventListener mCompositorUpdatedListener; MediaEventListener mOnTrackWaitingForKeyListener; From 92c225d322ce2b844e51efd723a8a9395ac32c48 Mon Sep 17 00:00:00 2001 From: JW Wang Date: Fri, 17 Feb 2017 19:34:03 +0800 Subject: [PATCH 38/48] Bug 1340969. Part 2 - remove MFR::mShutdownPromise by using promise chaining. r=jya MozReview-Commit-ID: 6Oa1yar80aH --HG-- extra : rebase_source : e5fba9cea0ea6c2263d676e8328da50ab335a8d9 extra : intermediate-source : af2cfe6e4c5bb36d5016a2de1c1193aa2ddee0b0 extra : source : 0f94c4404ea9dce4904fb40b215314932f5211aa --- dom/media/MediaFormatReader.cpp | 17 ++++------------- dom/media/MediaFormatReader.h | 3 +-- 2 files changed, 5 insertions(+), 15 deletions(-) diff --git a/dom/media/MediaFormatReader.cpp b/dom/media/MediaFormatReader.cpp index f50eeab46863..89ae656554b7 100644 --- a/dom/media/MediaFormatReader.cpp +++ b/dom/media/MediaFormatReader.cpp @@ -1081,15 +1081,11 @@ MediaFormatReader::Shutdown() mCompositorUpdatedListener.DisconnectIfExists(); mOnTrackWaitingForKeyListener.Disconnect(); - RefPtr p = mShutdownPromise.Ensure(__func__); - mShutdownPromisePool->Shutdown() + mShutdown = true; + return mShutdownPromisePool->Shutdown() ->Then(OwnerThread(), __func__, this, &MediaFormatReader::TearDownDecoders, &MediaFormatReader::TearDownDecoders); - - mShutdown = true; - - return p; } RefPtr @@ -1142,7 +1138,7 @@ MediaFormatReader::ShutdownDecoder(TrackType aTrack) Unused << ShutdownDecoderWithPromise(aTrack); } -void +RefPtr MediaFormatReader::TearDownDecoders() { if (mAudio.mTaskQueue) { @@ -1160,12 +1156,7 @@ MediaFormatReader::TearDownDecoders() mPlatform = nullptr; mVideoFrameContainer = nullptr; - if (mShutdownPromise.IsEmpty()) { - return; - } - - MediaDecoderReader::Shutdown(); - mShutdownPromise.Resolve(true, __func__); + return MediaDecoderReader::Shutdown(); } void diff --git a/dom/media/MediaFormatReader.h b/dom/media/MediaFormatReader.h index 0caf8f8a1b5a..b98e96b11fb3 100644 --- a/dom/media/MediaFormatReader.h +++ b/dom/media/MediaFormatReader.h @@ -595,8 +595,7 @@ private: void ShutdownDecoder(TrackType aTrack); RefPtr ShutdownDecoderWithPromise(TrackType aTrack); - void TearDownDecoders(); - MozPromiseHolder mShutdownPromise; + RefPtr TearDownDecoders(); }; } // namespace mozilla From 28ba840815f397ddc1b4ca42f3b604debaeb0911 Mon Sep 17 00:00:00 2001 From: Iris Hsiao Date: Wed, 22 Feb 2017 15:31:37 +0800 Subject: [PATCH 39/48] Backed out changeset 47b318d87004 (bug 1331330) for bustage --- media/libstagefright/binding/MP4Metadata.cpp | 38 ++++++-------------- 1 file changed, 10 insertions(+), 28 deletions(-) diff --git a/media/libstagefright/binding/MP4Metadata.cpp b/media/libstagefright/binding/MP4Metadata.cpp index ccaace08fa93..2e03b7abc9c5 100644 --- a/media/libstagefright/binding/MP4Metadata.cpp +++ b/media/libstagefright/binding/MP4Metadata.cpp @@ -140,7 +140,7 @@ public: const CryptoFile& Crypto() const; - bool ReadTrackIndice(mp4parse_byte_data* aIndices, mozilla::TrackID aTrackID); + bool ReadTrackIndex(FallibleTArray& aDest, mozilla::TrackID aTrackID); private: void UpdateCrypto(); @@ -363,26 +363,13 @@ MP4Metadata::Crypto() const bool MP4Metadata::ReadTrackIndex(FallibleTArray& aDest, mozilla::TrackID aTrackID) { - bool ret = mStagefright->ReadTrackIndex(aDest, aTrackID); - -#ifndef RELEASE_OR_BETA - if (mRustTestMode && ret && mRust) { - mp4parse_byte_data data = {}; - bool rustRet = mRust->ReadTrackIndice(&data, aTrackID); - MOZ_DIAGNOSTIC_ASSERT(rustRet); - MOZ_DIAGNOSTIC_ASSERT(data.length == aDest.Length()); - for (uint32_t i = 0; i < data.length; i++) { - MOZ_DIAGNOSTIC_ASSERT(data.indices[i].start_offset == aDest[i].start_offset); - MOZ_DIAGNOSTIC_ASSERT(data.indices[i].end_offset == aDest[i].end_offset); - MOZ_DIAGNOSTIC_ASSERT(data.indices[i].start_composition == aDest[i].start_composition); - MOZ_DIAGNOSTIC_ASSERT(data.indices[i].end_composition == aDest[i].end_composition); - MOZ_DIAGNOSTIC_ASSERT(data.indices[i].start_decode == aDest[i].start_decode); - MOZ_DIAGNOSTIC_ASSERT(data.indices[i].sync == aDest[i].sync); - } +#ifdef MOZ_RUST_MP4PARSE + if (mRust && mPreferRust && mRust->ReadTrackIndex(aDest, aTrackID)) { + return true; } + aDest.Clear(); #endif - - return ret; + return mStagefright->ReadTrackIndex(aDest, aTrackID); } static inline bool @@ -404,9 +391,6 @@ ConvertIndex(FallibleTArray& aDest, indice.sync = s_indice.sync; // FIXME: Make this infallible after bug 968520 is done. MOZ_ALWAYS_TRUE(aDest.AppendElement(indice, mozilla::fallible)); - MOZ_LOG(sLog, LogLevel::Debug, ("s_o: %" PRIu64 ", e_o: %" PRIu64 ", s_c: %" PRIu64 ", e_c: %" PRIu64 ", s_d: %" PRIu64 ", sync: %d\n", - indice.start_offset, indice.end_offset, indice.start_composition, indice.end_composition, - indice.start_decode, indice.sync)); } return true; } @@ -867,7 +851,7 @@ MP4MetadataRust::Crypto() const } bool -MP4MetadataRust::ReadTrackIndice(mp4parse_byte_data* aIndices, mozilla::TrackID aTrackID) +MP4MetadataRust::ReadTrackIndex(FallibleTArray& aDest, mozilla::TrackID aTrackID) { uint8_t fragmented = false; auto rv = mp4parse_is_fragmented(mRustParser.get(), aTrackID, &fragmented); @@ -879,12 +863,10 @@ MP4MetadataRust::ReadTrackIndice(mp4parse_byte_data* aIndices, mozilla::TrackID return true; } - rv = mp4parse_get_indice_table(mRustParser.get(), aTrackID, aIndices); - if (rv != MP4PARSE_OK) { - return false; - } + // For non-fragmented mp4. + NS_WARNING("Not yet implemented"); - return true; + return false; } /*static*/ bool From 83077824b8f9b1d24133c93ee9d4df91b3f8f3ca Mon Sep 17 00:00:00 2001 From: Chris Pearce Date: Wed, 22 Feb 2017 15:55:38 +1300 Subject: [PATCH 40/48] Bug 1341497 - Move WidevineBuffer and WidevineDecryptedBlock into WidevineUtils. r=gerald This makes it easier to reuse in the ChromiumCDM code. Also add an ExtractBuffer() method, which allows us to Move() the contained nsTArray out without needing to copy the data. MozReview-Commit-ID: 9suJSfXTVYy --HG-- extra : rebase_source : 6eec99eb5329f3b8c3bb14d22459fee3bd95caf5 --- .../widevine-adapter/WidevineDecryptor.cpp | 60 ------------- .../gmp/widevine-adapter/WidevineUtils.cpp | 88 +++++++++++++++++++ .../gmp/widevine-adapter/WidevineUtils.h | 37 ++++++++ dom/media/gmp/widevine-adapter/moz.build | 5 ++ 4 files changed, 130 insertions(+), 60 deletions(-) diff --git a/dom/media/gmp/widevine-adapter/WidevineDecryptor.cpp b/dom/media/gmp/widevine-adapter/WidevineDecryptor.cpp index 6183e949ab5c..8c9f1c3cab8f 100644 --- a/dom/media/gmp/widevine-adapter/WidevineDecryptor.cpp +++ b/dom/media/gmp/widevine-adapter/WidevineDecryptor.cpp @@ -9,7 +9,6 @@ #include "WidevineUtils.h" #include "WidevineFileIO.h" #include "GMPPlatform.h" -#include #include #include "TimeUnits.h" @@ -161,43 +160,6 @@ WidevineDecryptor::SetServerCertificate(uint32_t aPromiseId, CDM()->SetServerCertificate(aPromiseId, aServerCert, aServerCertSize); } -class WidevineDecryptedBlock : public cdm::DecryptedBlock { -public: - - WidevineDecryptedBlock() - : mBuffer(nullptr) - , mTimestamp(0) - { - } - - ~WidevineDecryptedBlock() override { - if (mBuffer) { - mBuffer->Destroy(); - mBuffer = nullptr; - } - } - - void SetDecryptedBuffer(cdm::Buffer* aBuffer) override { - mBuffer = aBuffer; - } - - cdm::Buffer* DecryptedBuffer() override { - return mBuffer; - } - - void SetTimestamp(int64_t aTimestamp) override { - mTimestamp = aTimestamp; - } - - int64_t Timestamp() const override { - return mTimestamp; - } - -private: - cdm::Buffer* mBuffer; - int64_t mTimestamp; -}; - cdm::Time WidevineDecryptor::ThrottleDecrypt(cdm::Time aWallTime, cdm::Time aSampleDuration) { @@ -327,28 +289,6 @@ WidevineDecryptor::DecryptingComplete() Release(); } -class WidevineBuffer : public cdm::Buffer { -public: - explicit WidevineBuffer(size_t aSize) { - CDM_LOG("WidevineBuffer(size=%" PRIuSIZE ") created", aSize); - mBuffer.SetLength(aSize); - } - ~WidevineBuffer() override { - CDM_LOG("WidevineBuffer(size=%" PRIu32 ") destroyed", Size()); - } - void Destroy() override { delete this; } - uint32_t Capacity() const override { return mBuffer.Length(); }; - uint8_t* Data() override { return mBuffer.Elements(); } - void SetSize(uint32_t aSize) override { mBuffer.SetLength(aSize); } - uint32_t Size() const override { return mBuffer.Length(); } - -private: - WidevineBuffer(const WidevineBuffer&); - void operator=(const WidevineBuffer&); - - nsTArray mBuffer; -}; - Buffer* WidevineDecryptor::Allocate(uint32_t aCapacity) { diff --git a/dom/media/gmp/widevine-adapter/WidevineUtils.cpp b/dom/media/gmp/widevine-adapter/WidevineUtils.cpp index 3eaae43abe69..e7eb02873a3d 100644 --- a/dom/media/gmp/widevine-adapter/WidevineUtils.cpp +++ b/dom/media/gmp/widevine-adapter/WidevineUtils.cpp @@ -5,10 +5,12 @@ #include "WidevineUtils.h" #include "WidevineDecryptor.h" +#include #include "gmp-api/gmp-errors.h" #include #include +#include namespace mozilla { @@ -76,4 +78,90 @@ CDMWrapper::~CDMWrapper() mCDM = nullptr; } +WidevineBuffer::WidevineBuffer(size_t aSize) +{ + CDM_LOG("WidevineBuffer(size=%" PRIuSIZE ") created", aSize); + mBuffer.SetLength(aSize); +} + +WidevineBuffer::~WidevineBuffer() +{ + CDM_LOG("WidevineBuffer(size=%" PRIu32 ") destroyed", Size()); +} + +void +WidevineBuffer::Destroy() +{ + delete this; +} + +uint32_t +WidevineBuffer::Capacity() const +{ + return mBuffer.Length(); +} + +uint8_t* +WidevineBuffer::Data() +{ + return mBuffer.Elements(); +} + +void +WidevineBuffer::SetSize(uint32_t aSize) +{ + mBuffer.SetLength(aSize); +} + +uint32_t +WidevineBuffer::Size() const +{ + return mBuffer.Length(); +} + +nsTArray +WidevineBuffer::ExtractBuffer() { + nsTArray out; + out.SwapElements(mBuffer); + return out; +} + +WidevineDecryptedBlock::WidevineDecryptedBlock() + : mBuffer(nullptr) + , mTimestamp(0) +{ +} + +WidevineDecryptedBlock::~WidevineDecryptedBlock() +{ + if (mBuffer) { + mBuffer->Destroy(); + mBuffer = nullptr; + } +} + +void +WidevineDecryptedBlock::SetDecryptedBuffer(cdm::Buffer* aBuffer) +{ + mBuffer = aBuffer; +} + +cdm::Buffer* +WidevineDecryptedBlock::DecryptedBuffer() +{ + return mBuffer; +} + +void +WidevineDecryptedBlock::SetTimestamp(int64_t aTimestamp) +{ + mTimestamp = aTimestamp; +} + +int64_t +WidevineDecryptedBlock::Timestamp() const +{ + return mTimestamp; +} + } // namespace mozilla diff --git a/dom/media/gmp/widevine-adapter/WidevineUtils.h b/dom/media/gmp/widevine-adapter/WidevineUtils.h index 9c67a20058d0..9c7136d6773e 100644 --- a/dom/media/gmp/widevine-adapter/WidevineUtils.h +++ b/dom/media/gmp/widevine-adapter/WidevineUtils.h @@ -61,6 +61,43 @@ void InitInputBuffer(const GMPEncryptedBufferMetadata* aCrypto, cdm::InputBuffer &aInputBuffer, nsTArray &aSubsamples); +class WidevineBuffer : public cdm::Buffer +{ +public: + explicit WidevineBuffer(size_t aSize); + ~WidevineBuffer() override; + void Destroy() override; + uint32_t Capacity() const override; + uint8_t* Data() override; + void SetSize(uint32_t aSize) override; + uint32_t Size() const override; + + // Moves contents of buffer out into temporary. + // Note: This empties the buffer. + nsTArray ExtractBuffer(); + +private: + nsTArray mBuffer; + WidevineBuffer(const WidevineBuffer&); + void operator=(const WidevineBuffer&); +}; + +class WidevineDecryptedBlock : public cdm::DecryptedBlock +{ +public: + + WidevineDecryptedBlock(); + ~WidevineDecryptedBlock() override; + void SetDecryptedBuffer(cdm::Buffer* aBuffer) override; + cdm::Buffer* DecryptedBuffer() override; + void SetTimestamp(int64_t aTimestamp) override; + int64_t Timestamp() const override; + +private: + cdm::Buffer* mBuffer; + int64_t mTimestamp; +}; + } // namespace mozilla #endif // WidevineUtils_h_ diff --git a/dom/media/gmp/widevine-adapter/moz.build b/dom/media/gmp/widevine-adapter/moz.build index 89152fd664ac..212d7f7794f8 100644 --- a/dom/media/gmp/widevine-adapter/moz.build +++ b/dom/media/gmp/widevine-adapter/moz.build @@ -14,6 +14,11 @@ SOURCES += [ 'WidevineVideoFrame.cpp', ] +EXPORTS += [ + 'WidevineDecryptor.h', + 'WidevineUtils.h' +] + FINAL_LIBRARY = 'xul' LOCAL_INCLUDES += [ From 0ca5ea4955c3fcab4df9f403b29638477bd6bf3a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Cobos=20=C3=81lvarez?= Date: Tue, 21 Feb 2017 16:56:43 +0100 Subject: [PATCH 41/48] Bug 1322317: Don't call FinishStyle off-main-thread for reset structs. r=heycam MozReview-Commit-ID: FoWbLjt97Uu --HG-- extra : rebase_source : 00f5565a9c3bd09b7d2ed7c6aadd2d58ec0e1ec4 --- layout/style/nsStyleContext.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/layout/style/nsStyleContext.h b/layout/style/nsStyleContext.h index 94dc4ba14dea..9b7f9ce0d4dc 100644 --- a/layout/style/nsStyleContext.h +++ b/layout/style/nsStyleContext.h @@ -692,6 +692,9 @@ private: newData = mSource.AsGeckoRuleNode()-> \ GetStyle##name_(this); \ } else { \ + if (!aComputeData) { \ + return nullptr; \ + } \ newData = \ Servo_GetStyle##name_(mSource.AsServoComputedValues()); \ /* perform any remaining main thread work on the struct */ \ From 6ebbfba25f4a8dd8b795caffb07aa8ad23ff77f8 Mon Sep 17 00:00:00 2001 From: Shing Lyu Date: Fri, 17 Feb 2017 14:39:24 +0800 Subject: [PATCH 42/48] Bug 1337229 - Implement deep operator== for RawServoAnimationValue r=hiro,manishearth MozReview-Commit-ID: Euvv9zarFe3 --HG-- extra : rebase_source : b67bb89ed35dca04d6dc81afdfbea701fdede449 --- dom/animation/KeyframeEffectReadOnly.cpp | 1 - dom/animation/KeyframeEffectReadOnly.h | 2 +- layout/style/ServoBindingList.h | 3 +++ layout/style/StyleAnimationValue.h | 6 +----- layout/style/StyleAnimationValueInlines.h | 10 ++++++++++ servo/ports/geckolib/glue.rs | 10 ++++++++++ 6 files changed, 25 insertions(+), 7 deletions(-) diff --git a/dom/animation/KeyframeEffectReadOnly.cpp b/dom/animation/KeyframeEffectReadOnly.cpp index 4b8dd1ff5510..ce310434fafa 100644 --- a/dom/animation/KeyframeEffectReadOnly.cpp +++ b/dom/animation/KeyframeEffectReadOnly.cpp @@ -18,7 +18,6 @@ #include "mozilla/LookAndFeel.h" // For LookAndFeel::GetInt #include "mozilla/KeyframeUtils.h" #include "mozilla/ServoBindings.h" -#include "mozilla/StyleAnimationValueInlines.h" #include "Layers.h" // For Layer #include "nsComputedDOMStyle.h" // nsComputedDOMStyle::GetStyleContextForElement #include "nsContentUtils.h" // nsContentUtils::ReportToConsole diff --git a/dom/animation/KeyframeEffectReadOnly.h b/dom/animation/KeyframeEffectReadOnly.h index bbcbddb0e521..134c4f94de2c 100644 --- a/dom/animation/KeyframeEffectReadOnly.h +++ b/dom/animation/KeyframeEffectReadOnly.h @@ -23,7 +23,7 @@ #include "mozilla/KeyframeEffectParams.h" // RawServoDeclarationBlock and associated RefPtrTraits #include "mozilla/ServoBindingTypes.h" -#include "mozilla/StyleAnimationValue.h" +#include "mozilla/StyleAnimationValueInlines.h" #include "mozilla/dom/AnimationEffectReadOnly.h" #include "mozilla/dom/BindingDeclarations.h" #include "mozilla/dom/Element.h" diff --git a/layout/style/ServoBindingList.h b/layout/style/ServoBindingList.h index b6d4791a5b80..e82920e9d8b1 100644 --- a/layout/style/ServoBindingList.h +++ b/layout/style/ServoBindingList.h @@ -130,6 +130,9 @@ SERVO_BINDING_FUNC(Servo_AnimationValue_GetOpacity, float, SERVO_BINDING_FUNC(Servo_AnimationValue_GetTransform, void, RawServoAnimationValueBorrowed value, RefPtr* list) +SERVO_BINDING_FUNC(Servo_AnimationValue_DeepEqual, bool, + RawServoAnimationValueBorrowed, + RawServoAnimationValueBorrowed) // Style attribute SERVO_BINDING_FUNC(Servo_ParseStyleAttribute, RawServoDeclarationBlockStrong, diff --git a/layout/style/StyleAnimationValue.h b/layout/style/StyleAnimationValue.h index b08bb21a820b..d51d4698387d 100644 --- a/layout/style/StyleAnimationValue.h +++ b/layout/style/StyleAnimationValue.h @@ -576,11 +576,7 @@ struct AnimationValue StyleAnimationValue mGecko; RefPtr mServo; - bool operator==(const AnimationValue& aOther) const - { - // FIXME: Bug 1337229: add a deep == impl for RawServoAnimationValue. - return mGecko == aOther.mGecko && mServo == aOther.mServo; - } + inline bool operator==(const AnimationValue& aOther) const; bool IsNull() const { return mGecko.IsNull() && !mServo; } diff --git a/layout/style/StyleAnimationValueInlines.h b/layout/style/StyleAnimationValueInlines.h index 0f6b2deb9ec8..6babcdbe2eaf 100644 --- a/layout/style/StyleAnimationValueInlines.h +++ b/layout/style/StyleAnimationValueInlines.h @@ -11,6 +11,16 @@ namespace mozilla { +bool +AnimationValue::operator==(const AnimationValue& aOther) const +{ + // mGecko and mServo are mutual exclusive, one of them must be null + if (mServo) { + return Servo_AnimationValue_DeepEqual(mServo, aOther.mServo); + } + return mGecko == aOther.mGecko; +} + float AnimationValue::GetOpacity() const { diff --git a/servo/ports/geckolib/glue.rs b/servo/ports/geckolib/glue.rs index 54aac9b46948..3a69843c79a1 100644 --- a/servo/ports/geckolib/glue.rs +++ b/servo/ports/geckolib/glue.rs @@ -343,6 +343,16 @@ pub extern "C" fn Servo_AnimationValue_Release(anim: RawServoAnimationValueBorro unsafe { AnimationValue::release(anim) }; } + #[no_mangle] +pub extern "C" fn Servo_AnimationValue_DeepEqual(this: RawServoAnimationValueBorrowed, + other: RawServoAnimationValueBorrowed) + -> bool +{ + let this_value = AnimationValue::as_arc(&this); + let other_value = AnimationValue::as_arc(&other); + this_value == other_value +} + #[no_mangle] pub extern "C" fn Servo_StyleWorkerThreadCount() -> u32 { *NUM_THREADS as u32 From 2f68e50e6c55ef8c02e9bfef23ccd6f4be8ce0ab Mon Sep 17 00:00:00 2001 From: Fred Lin Date: Wed, 8 Feb 2017 14:20:44 +0800 Subject: [PATCH 43/48] Bug 1316291 - PART 1:Rename the requests-menu CSS classes in netmonitor.css;r=Honza MozReview-Commit-ID: DceweCXElI4 --HG-- extra : rebase_source : c900d38b4e6ffb7bf8a6aa16e9f3b6106f63f6c9 --- .../components/request-list-content.js | 6 +- .../components/request-list-empty.js | 6 +- .../components/request-list-header.js | 16 +- .../components/request-list-item.js | 40 ++-- .../client/netmonitor/components/toolbar.js | 8 +- .../netmonitor/request-list-context-menu.js | 26 +-- .../client/netmonitor/request-list-tooltip.js | 2 +- .../shared/components/headers-panel.js | 2 +- .../shared/components/timings-panel.js | 8 +- .../test/browser_net_accessibility-02.js | 2 +- .../netmonitor/test/browser_net_autoscroll.js | 4 +- .../netmonitor/test/browser_net_cause.js | 2 +- .../netmonitor/test/browser_net_clear.js | 2 +- .../test/browser_net_copy_as_curl.js | 2 +- .../test/browser_net_copy_headers.js | 4 +- .../browser_net_copy_image_as_data_uri.js | 4 +- .../test/browser_net_copy_params.js | 8 +- .../test/browser_net_copy_response.js | 2 +- .../browser_net_copy_svg_image_as_data_uri.js | 2 +- .../netmonitor/test/browser_net_copy_url.js | 2 +- .../netmonitor/test/browser_net_filter-01.js | 65 +++--- .../netmonitor/test/browser_net_filter-02.js | 4 +- .../netmonitor/test/browser_net_filter-03.js | 8 +- .../test/browser_net_footer-summary.js | 4 +- .../test/browser_net_icon-preview.js | 10 +- .../test/browser_net_image-tooltip.js | 6 +- .../test/browser_net_open_request_in_tab.js | 2 +- .../test/browser_net_reload-button.js | 2 +- .../test/browser_net_reload-markers.js | 2 +- .../test/browser_net_security-icon-click.js | 2 +- .../test/browser_net_security-state.js | 4 +- .../browser_net_simple-request-details.js | 12 +- .../test/browser_net_simple-request.js | 8 +- .../netmonitor/test/browser_net_sort-01.js | 12 +- .../netmonitor/test/browser_net_sort-02.js | 46 ++-- .../test/browser_net_statistics-02.js | 10 +- .../test/browser_net_status-codes.js | 2 +- .../test/browser_net_timeline_ticks.js | 14 +- .../test/browser_net_timing-division.js | 6 +- .../test/components/filter-buttons.test.js | 4 +- devtools/client/netmonitor/test/head.js | 46 ++-- devtools/client/themes/netmonitor.css | 218 +++++++++--------- 42 files changed, 318 insertions(+), 317 deletions(-) diff --git a/devtools/client/netmonitor/components/request-list-content.js b/devtools/client/netmonitor/components/request-list-content.js index d176c9c88eeb..a6afa89ee31f 100644 --- a/devtools/client/netmonitor/components/request-list-content.js +++ b/devtools/client/netmonitor/components/request-list-content.js @@ -158,9 +158,9 @@ const RequestListContent = createClass({ return false; } - if (requestItem.responseContent && target.closest(".requests-menu-icon-and-file")) { + if (requestItem.responseContent && target.closest(".requests-list-icon-and-file")) { return setTooltipImageContent(tooltip, itemEl, requestItem); - } else if (requestItem.cause && target.closest(".requests-menu-cause-stack")) { + } else if (requestItem.cause && target.closest(".requests-list-cause-stack")) { return setTooltipStackTraceContent(tooltip, requestItem); } @@ -237,7 +237,7 @@ const RequestListContent = createClass({ return ( div({ ref: "contentEl", - className: "requests-menu-contents", + className: "requests-list-contents", tabIndex: 0, onKeyDown: this.onKeyDown, }, diff --git a/devtools/client/netmonitor/components/request-list-empty.js b/devtools/client/netmonitor/components/request-list-empty.js index b089b1db7054..21f2e234623c 100644 --- a/devtools/client/netmonitor/components/request-list-empty.js +++ b/devtools/client/netmonitor/components/request-list-empty.js @@ -31,14 +31,14 @@ const RequestListEmptyNotice = createClass({ render() { return div( { - id: "requests-menu-empty-notice", + id: "requests-list-empty-notice", className: "request-list-empty-notice", }, div({ id: "notice-reload-message" }, span(null, L10N.getStr("netmonitor.reloadNotice1")), button( { - id: "requests-menu-reload-notice-button", + id: "requests-list-reload-notice-button", className: "devtools-button", "data-standalone": true, onClick: this.props.onReloadClick, @@ -50,7 +50,7 @@ const RequestListEmptyNotice = createClass({ div({ id: "notice-perf-message" }, span(null, L10N.getStr("netmonitor.perfNotice1")), button({ - id: "requests-menu-perf-notice-button", + id: "requests-list-perf-notice-button", title: L10N.getStr("netmonitor.perfNotice3"), className: "devtools-button", "data-standalone": true, diff --git a/devtools/client/netmonitor/components/request-list-header.js b/devtools/client/netmonitor/components/request-list-header.js index e45e24aa7a70..8495af390458 100644 --- a/devtools/client/netmonitor/components/request-list-header.js +++ b/devtools/client/netmonitor/components/request-list-header.js @@ -78,7 +78,7 @@ const RequestListHeader = createClass({ const { sort, scale, waterfallWidth, onHeaderClick } = this.props; return div( - { id: "requests-menu-toolbar", className: "devtools-toolbar" }, + { id: "requests-list-toolbar", className: "devtools-toolbar" }, div({ id: "toolbar-labels" }, HEADERS.map(header => { const name = header.name; @@ -96,8 +96,8 @@ const RequestListHeader = createClass({ return div( { - id: `requests-menu-${boxName}-header-box`, - className: `requests-menu-header requests-menu-${boxName}`, + id: `requests-list-${boxName}-header-box`, + className: `requests-list-header requests-list-${boxName}`, key: name, ref: "header", // Used to style the next column. @@ -105,8 +105,8 @@ const RequestListHeader = createClass({ }, button( { - id: `requests-menu-${name}-button`, - className: `requests-menu-header-button requests-menu-${name}`, + id: `requests-list-${name}-button`, + className: `requests-list-header-button requests-list-${name}`, "data-sorted": sorted, title: sortedTitle, onClick: () => onHeaderClick(name), @@ -163,7 +163,7 @@ function waterfallDivisionLabels(waterfallWidth, scale) { labels.push(div( { key: labels.length, - className: "requests-menu-timings-division", + className: "requests-list-timings-division", "data-division-scale": divisionScale, style: { width } }, @@ -175,11 +175,11 @@ function waterfallDivisionLabels(waterfallWidth, scale) { } function WaterfallLabel(waterfallWidth, scale, label) { - let className = "button-text requests-menu-waterfall-label-wrapper"; + let className = "button-text requests-list-waterfall-label-wrapper"; if (waterfallWidth != null && scale != null) { label = waterfallDivisionLabels(waterfallWidth, scale); - className += " requests-menu-waterfall-visible"; + className += " requests-list-waterfall-visible"; } return div({ className }, label); diff --git a/devtools/client/netmonitor/components/request-list-item.js b/devtools/client/netmonitor/components/request-list-item.js index 75cecf850533..2c6aa1dce051 100644 --- a/devtools/client/netmonitor/components/request-list-item.js +++ b/devtools/client/netmonitor/components/request-list-item.js @@ -175,9 +175,9 @@ const StatusColumn = createFactory(createClass({ } return ( - div({ className: "requests-menu-subitem requests-menu-status", title }, - div({ className: "requests-menu-status-icon", "data-code": code }), - span({ className: "subitem-label requests-menu-status-code" }, status), + div({ className: "requests-list-subitem requests-list-status", title }, + div({ className: "requests-list-status-icon", "data-code": code }), + span({ className: "subitem-label requests-list-status-code" }, status) ) ); } @@ -197,8 +197,8 @@ const MethodColumn = createFactory(createClass({ render() { const { method } = this.props.item; return ( - div({ className: "requests-menu-subitem requests-menu-method-box" }, - span({ className: "subitem-label requests-menu-method" }, method) + div({ className: "requests-list-subitem requests-list-method-box" }, + span({ className: "subitem-label requests-list-method" }, method) ) ); } @@ -224,15 +224,15 @@ const FileColumn = createFactory(createClass({ const { urlDetails, responseContentDataUri } = this.props.item; return ( - div({ className: "requests-menu-subitem requests-menu-icon-and-file" }, + div({ className: "requests-list-subitem requests-list-icon-and-file" }, img({ - className: "requests-menu-icon", + className: "requests-list-icon", src: responseContentDataUri, hidden: !responseContentDataUri, "data-type": responseContentDataUri ? "thumbnail" : undefined, }), div({ - className: "subitem-label requests-menu-file", + className: "subitem-label requests-list-file", title: urlDetails.unicodeUrl, }, urlDetails.baseNameWithQuery, @@ -277,13 +277,13 @@ const DomainColumn = createFactory(createClass({ let title = urlDetails.host + (remoteAddress ? ` (${remoteAddress})` : ""); return ( - div({ className: "requests-menu-subitem requests-menu-security-and-domain" }, + div({ className: "requests-list-subitem requests-list-security-and-domain" }, div({ className: iconClassList.join(" "), title: iconTitle, onClick: onSecurityIconClick, }), - span({ className: "subitem-label requests-menu-domain", title }, urlDetails.host), + span({ className: "subitem-label requests-list-domain", title }, urlDetails.host), ) ); } @@ -316,11 +316,11 @@ const CauseColumn = createFactory(createClass({ return ( div({ - className: "requests-menu-subitem requests-menu-cause", + className: "requests-list-subitem requests-list-cause", title: causeUri, }, span({ - className: "requests-menu-cause-stack", + className: "requests-list-cause-stack", hidden: !causeHasStack, }, "JS"), span({ className: "subitem-label" }, causeType), @@ -356,7 +356,7 @@ const TypeColumn = createFactory(createClass({ return ( div({ - className: "requests-menu-subitem requests-menu-type", + className: "requests-list-subitem requests-list-type", title: mimeType, }, span({ className: "subitem-label" }, abbrevType), @@ -401,7 +401,7 @@ const TransferredSizeColumn = createFactory(createClass({ return ( div({ - className: "requests-menu-subitem requests-menu-transferred", + className: "requests-list-subitem requests-list-transferred", title: text, }, span({ className }, text), @@ -431,7 +431,7 @@ const ContentSizeColumn = createFactory(createClass({ return ( div({ - className: "requests-menu-subitem subitem-label requests-menu-size", + className: "requests-list-subitem subitem-label requests-list-size", title: text, }, span({ className: "subitem-label" }, text), @@ -464,9 +464,9 @@ const WaterfallColumn = createFactory(createClass({ const { item, firstRequestStartedMillis } = this.props; return ( - div({ className: "requests-menu-subitem requests-menu-waterfall" }, + div({ className: "requests-list-subitem requests-list-waterfall" }, div({ - className: "requests-menu-timings", + className: "requests-list-timings", style: { paddingInlineStart: `${item.startedMillis - firstRequestStartedMillis}px`, }, @@ -499,7 +499,7 @@ function timingBoxes(item) { if (width > 0) { boxes.push(div({ key, - className: "requests-menu-timings-box " + key, + className: "requests-list-timings-box " + key, style: { width } })); } @@ -510,8 +510,8 @@ function timingBoxes(item) { let text = L10N.getFormatStr("networkMenu.totalMS", totalTime); boxes.push(div({ key: "total", - className: "requests-menu-timings-total", - title: text, + className: "requests-list-timings-total", + title: text }, text)); } diff --git a/devtools/client/netmonitor/components/toolbar.js b/devtools/client/netmonitor/components/toolbar.js index cf5fc827bc66..a2a19f6eaa28 100644 --- a/devtools/client/netmonitor/components/toolbar.js +++ b/devtools/client/netmonitor/components/toolbar.js @@ -101,7 +101,7 @@ const Toolbar = createClass({ return ( button({ - id: `requests-menu-filter-${type}-button`, + id: `requests-list-filter-${type}-button`, className: classList.join(" "), key: type, onClick: this.toggleRequestFilterType, @@ -118,16 +118,16 @@ const Toolbar = createClass({ span({ className: "devtools-toolbar devtools-toolbar-container" }, span({ className: "devtools-toolbar-group" }, button({ - id: "requests-menu-clear-button", + id: "requests-list-clear-button", className: "devtools-button devtools-clear-icon", title: TOOLBAR_CLEAR, onClick: clearRequests, }), - div({ id: "requests-menu-filter-buttons" }, buttons), + div({ id: "requests-list-filter-buttons" }, buttons), ), span({ className: "devtools-toolbar-group" }, button({ - id: "requests-menu-network-summary-button", + id: "requests-list-network-summary-button", className: "devtools-button", title: count ? text : L10N.getStr("netmonitor.toolbar.perf"), onClick: openStatistics, diff --git a/devtools/client/netmonitor/request-list-context-menu.js b/devtools/client/netmonitor/request-list-context-menu.js index 0bc0f742d217..a7762acce277 100644 --- a/devtools/client/netmonitor/request-list-context-menu.js +++ b/devtools/client/netmonitor/request-list-context-menu.js @@ -50,7 +50,7 @@ RequestListContextMenu.prototype = { let menu = new Menu(); menu.append(new MenuItem({ - id: "request-menu-context-copy-url", + id: "request-list-context-copy-url", label: L10N.getStr("netmonitor.context.copyUrl"), accesskey: L10N.getStr("netmonitor.context.copyUrl.accesskey"), visible: !!selectedRequest, @@ -58,7 +58,7 @@ RequestListContextMenu.prototype = { })); menu.append(new MenuItem({ - id: "request-menu-context-copy-url-params", + id: "request-list-context-copy-url-params", label: L10N.getStr("netmonitor.context.copyUrlParams"), accesskey: L10N.getStr("netmonitor.context.copyUrlParams.accesskey"), visible: !!(selectedRequest && getUrlQuery(selectedRequest.url)), @@ -66,7 +66,7 @@ RequestListContextMenu.prototype = { })); menu.append(new MenuItem({ - id: "request-menu-context-copy-post-data", + id: "request-list-context-copy-post-data", label: L10N.getStr("netmonitor.context.copyPostData"), accesskey: L10N.getStr("netmonitor.context.copyPostData.accesskey"), visible: !!(selectedRequest && selectedRequest.requestPostData), @@ -74,7 +74,7 @@ RequestListContextMenu.prototype = { })); menu.append(new MenuItem({ - id: "request-menu-context-copy-as-curl", + id: "request-list-context-copy-as-curl", label: L10N.getStr("netmonitor.context.copyAsCurl"), accesskey: L10N.getStr("netmonitor.context.copyAsCurl.accesskey"), visible: !!selectedRequest, @@ -87,7 +87,7 @@ RequestListContextMenu.prototype = { })); menu.append(new MenuItem({ - id: "request-menu-context-copy-request-headers", + id: "request-list-context-copy-request-headers", label: L10N.getStr("netmonitor.context.copyRequestHeaders"), accesskey: L10N.getStr("netmonitor.context.copyRequestHeaders.accesskey"), visible: !!(selectedRequest && selectedRequest.requestHeaders), @@ -95,7 +95,7 @@ RequestListContextMenu.prototype = { })); menu.append(new MenuItem({ - id: "response-menu-context-copy-response-headers", + id: "response-list-context-copy-response-headers", label: L10N.getStr("netmonitor.context.copyResponseHeaders"), accesskey: L10N.getStr("netmonitor.context.copyResponseHeaders.accesskey"), visible: !!(selectedRequest && selectedRequest.responseHeaders), @@ -103,7 +103,7 @@ RequestListContextMenu.prototype = { })); menu.append(new MenuItem({ - id: "request-menu-context-copy-response", + id: "request-list-context-copy-response", label: L10N.getStr("netmonitor.context.copyResponse"), accesskey: L10N.getStr("netmonitor.context.copyResponse.accesskey"), visible: !!(selectedRequest && @@ -114,7 +114,7 @@ RequestListContextMenu.prototype = { })); menu.append(new MenuItem({ - id: "request-menu-context-copy-image-as-data-uri", + id: "request-list-context-copy-image-as-data-uri", label: L10N.getStr("netmonitor.context.copyImageAsDataUri"), accesskey: L10N.getStr("netmonitor.context.copyImageAsDataUri.accesskey"), visible: !!(selectedRequest && @@ -129,7 +129,7 @@ RequestListContextMenu.prototype = { })); menu.append(new MenuItem({ - id: "request-menu-context-copy-all-as-har", + id: "request-list-context-copy-all-as-har", label: L10N.getStr("netmonitor.context.copyAllAsHar"), accesskey: L10N.getStr("netmonitor.context.copyAllAsHar.accesskey"), visible: this.sortedRequests.size > 0, @@ -137,7 +137,7 @@ RequestListContextMenu.prototype = { })); menu.append(new MenuItem({ - id: "request-menu-context-save-all-as-har", + id: "request-list-context-save-all-as-har", label: L10N.getStr("netmonitor.context.saveAllAsHar"), accesskey: L10N.getStr("netmonitor.context.saveAllAsHar.accesskey"), visible: this.sortedRequests.size > 0, @@ -150,7 +150,7 @@ RequestListContextMenu.prototype = { })); menu.append(new MenuItem({ - id: "request-menu-context-resend", + id: "request-list-context-resend", label: L10N.getStr("netmonitor.context.editAndResend"), accesskey: L10N.getStr("netmonitor.context.editAndResend.accesskey"), visible: !!(window.NetMonitorController.supportsCustomRequest && @@ -164,7 +164,7 @@ RequestListContextMenu.prototype = { })); menu.append(new MenuItem({ - id: "request-menu-context-newtab", + id: "request-list-context-newtab", label: L10N.getStr("netmonitor.context.newTab"), accesskey: L10N.getStr("netmonitor.context.newTab.accesskey"), visible: !!selectedRequest, @@ -172,7 +172,7 @@ RequestListContextMenu.prototype = { })); menu.append(new MenuItem({ - id: "request-menu-context-perf", + id: "request-list-context-perf", label: L10N.getStr("netmonitor.context.perfTools"), accesskey: L10N.getStr("netmonitor.context.perfTools.accesskey"), visible: !!window.NetMonitorController.supportsPerfStats, diff --git a/devtools/client/netmonitor/request-list-tooltip.js b/devtools/client/netmonitor/request-list-tooltip.js index 9ebba990578d..1a6d1900f336 100644 --- a/devtools/client/netmonitor/request-list-tooltip.js +++ b/devtools/client/netmonitor/request-list-tooltip.js @@ -32,7 +32,7 @@ async function setTooltipImageContent(tooltip, itemEl, requestItem) { let options = { maxDim, naturalWidth, naturalHeight }; setImageTooltip(tooltip, tooltip.doc, src, options); - return itemEl.querySelector(".requests-menu-icon"); + return itemEl.querySelector(".requests-list-icon"); } async function setTooltipStackTraceContent(tooltip, requestItem) { diff --git a/devtools/client/netmonitor/shared/components/headers-panel.js b/devtools/client/netmonitor/shared/components/headers-panel.js index 1108ec227f20..7ab65b5461f4 100644 --- a/devtools/client/netmonitor/shared/components/headers-panel.js +++ b/devtools/client/netmonitor/shared/components/headers-panel.js @@ -178,7 +178,7 @@ const HeadersPanel = createClass({ className: "tabpanel-summary-label headers-summary-label", }, SUMMARY_STATUS), div({ - className: "requests-menu-status-icon", + className: "requests-list-status-icon", "data-code": code, }), input({ diff --git a/devtools/client/netmonitor/shared/components/timings-panel.js b/devtools/client/netmonitor/shared/components/timings-panel.js index 44b3e6d6197f..53d63eebac2f 100644 --- a/devtools/client/netmonitor/shared/components/timings-panel.js +++ b/devtools/client/netmonitor/shared/components/timings-panel.js @@ -40,20 +40,20 @@ function TimingsPanel({ span({ className: "tabpanel-summary-label timings-label" }, L10N.getStr(`netmonitor.timings.${type}`) ), - div({ className: "requests-menu-timings-container" }, + div({ className: "requests-list-timings-container" }, span({ - className: "requests-menu-timings-offset", + className: "requests-list-timings-offset", style: { width: `calc(${offsetScale} * (100% - ${TIMINGS_END_PADDING})`, }, }), span({ - className: `requests-menu-timings-box ${type}`, + className: `requests-list-timings-box ${type}`, style: { width: `calc(${timelineScale} * (100% - ${TIMINGS_END_PADDING}))`, }, }), - span({ className: "requests-menu-timings-total" }, + span({ className: "requests-list-timings-total" }, L10N.getFormatStr("networkMenu.totalMS", timings[type]) ) ), diff --git a/devtools/client/netmonitor/test/browser_net_accessibility-02.js b/devtools/client/netmonitor/test/browser_net_accessibility-02.js index 7e4523698259..1fa389e20d23 100644 --- a/devtools/client/netmonitor/test/browser_net_accessibility-02.js +++ b/devtools/client/netmonitor/test/browser_net_accessibility-02.js @@ -36,7 +36,7 @@ add_task(function* () { }); yield wait; - document.querySelector(".requests-menu-contents").focus(); + document.querySelector(".requests-list-contents").focus(); check(-1, false); diff --git a/devtools/client/netmonitor/test/browser_net_autoscroll.js b/devtools/client/netmonitor/test/browser_net_autoscroll.js index c0bcf3d32e69..bdafc8aa4274 100644 --- a/devtools/client/netmonitor/test/browser_net_autoscroll.js +++ b/devtools/client/netmonitor/test/browser_net_autoscroll.js @@ -16,7 +16,7 @@ add_task(function* () { // Wait until the first request makes the empty notice disappear yield waitForRequestListToAppear(); - let requestsContainer = document.querySelector(".requests-menu-contents"); + let requestsContainer = document.querySelector(".requests-list-contents"); ok(requestsContainer, "Container element exists as expected."); // (1) Check that the scroll position is maintained at the bottom @@ -57,7 +57,7 @@ add_task(function* () { function waitForRequestListToAppear() { info("Waiting until the empty notice disappears and is replaced with the list"); - return waitUntil(() => !!document.querySelector(".requests-menu-contents")); + return waitUntil(() => !!document.querySelector(".requests-list-contents")); } function* waitForRequestsToOverflowContainer() { diff --git a/devtools/client/netmonitor/test/browser_net_cause.js b/devtools/client/netmonitor/test/browser_net_cause.js index 756f6a7d223c..ea353925d728 100644 --- a/devtools/client/netmonitor/test/browser_net_cause.js +++ b/devtools/client/netmonitor/test/browser_net_cause.js @@ -145,7 +145,7 @@ add_task(function* () { // Sort the requests by cause and check the order EventUtils.sendMouseEvent({ type: "click" }, - document.querySelector("#requests-menu-cause-button")); + document.querySelector("#requests-list-cause-button")); let expectedOrder = EXPECTED_REQUESTS.map(r => r.causeType).sort(); expectedOrder.forEach((expectedCause, i) => { const cause = getSortedRequests(gStore.getState()).get(i).cause.type; diff --git a/devtools/client/netmonitor/test/browser_net_clear.js b/devtools/client/netmonitor/test/browser_net_clear.js index 11e5702d9502..caf77a3505a9 100644 --- a/devtools/client/netmonitor/test/browser_net_clear.js +++ b/devtools/client/netmonitor/test/browser_net_clear.js @@ -16,7 +16,7 @@ add_task(function* () { let { EVENTS } = windowRequire("devtools/client/netmonitor/constants"); let detailsPane = document.querySelector("#details-pane"); let detailsPanelToggleButton = document.querySelector(".network-details-panel-toggle"); - let clearButton = document.querySelector("#requests-menu-clear-button"); + let clearButton = document.querySelector("#requests-list-clear-button"); gStore.dispatch(Actions.batchEnable(false)); diff --git a/devtools/client/netmonitor/test/browser_net_copy_as_curl.js b/devtools/client/netmonitor/test/browser_net_copy_as_curl.js index dd1ed13e6f45..1267d7e2f3f5 100644 --- a/devtools/client/netmonitor/test/browser_net_copy_as_curl.js +++ b/devtools/client/netmonitor/test/browser_net_copy_as_curl.js @@ -59,7 +59,7 @@ add_task(function* () { // Context menu is appending in XUL document, we must select it from // toolbox.doc monitor.toolbox.doc - .querySelector("#request-menu-context-copy-as-curl").click(); + .querySelector("#request-list-context-copy-as-curl").click(); }, function validate(result) { if (typeof result !== "string") { return false; diff --git a/devtools/client/netmonitor/test/browser_net_copy_headers.js b/devtools/client/netmonitor/test/browser_net_copy_headers.js index 0fcf53efdd68..fb41c1728311 100644 --- a/devtools/client/netmonitor/test/browser_net_copy_headers.js +++ b/devtools/client/netmonitor/test/browser_net_copy_headers.js @@ -44,7 +44,7 @@ add_task(function* () { // Context menu is appending in XUL document, we must select it from // toolbox.doc monitor.toolbox.doc - .querySelector("#request-menu-context-copy-request-headers").click(); + .querySelector("#request-list-context-copy-request-headers").click(); }, function validate(result) { // Sometimes, a "Cookie" header is left over from other tests. Remove it: result = String(result).replace(/Cookie: [^\n]+\n/, ""); @@ -69,7 +69,7 @@ add_task(function* () { // Context menu is appending in XUL document, we must select it from // _oolbox.doc monitor.toolbox.doc - .querySelector("#response-menu-context-copy-response-headers").click(); + .querySelector("#response-list-context-copy-response-headers").click(); }, function validate(result) { // Fake the "Last-Modified" and "Date" headers because they will vary: result = String(result) diff --git a/devtools/client/netmonitor/test/browser_net_copy_image_as_data_uri.js b/devtools/client/netmonitor/test/browser_net_copy_image_as_data_uri.js index f1d2c042a446..6beb81aa3a1a 100644 --- a/devtools/client/netmonitor/test/browser_net_copy_image_as_data_uri.js +++ b/devtools/client/netmonitor/test/browser_net_copy_image_as_data_uri.js @@ -28,8 +28,8 @@ add_task(function* () { // Context menu is appending in XUL document, we must select it from // toolbox.doc monitor.toolbox.doc - .querySelector("#request-menu-context-copy-image-as-data-uri").click(); - }, TEST_IMAGE_DATA_URI); + .querySelector("#request-list-context-copy-image-as-data-uri").click(); + }, TEST_IMAGE_DATA_URI); ok(true, "Clipboard contains the currently selected image as data uri."); diff --git a/devtools/client/netmonitor/test/browser_net_copy_params.js b/devtools/client/netmonitor/test/browser_net_copy_params.js index 354177d13e7b..96a3fbada4dc 100644 --- a/devtools/client/netmonitor/test/browser_net_copy_params.js +++ b/devtools/client/netmonitor/test/browser_net_copy_params.js @@ -63,7 +63,7 @@ add_task(function* () { EventUtils.sendMouseEvent({ type: "contextmenu" }, document.querySelectorAll(".request-list-item")[index]); let copyUrlParamsNode = monitor.toolbox.doc - .querySelector("#request-menu-context-copy-url-params"); + .querySelector("#request-list-context-copy-url-params"); is(!!copyUrlParamsNode, !hidden, "The \"Copy URL Parameters\" context menu item should" + (hidden ? " " : " not ") + "be hidden."); @@ -76,7 +76,7 @@ add_task(function* () { document.querySelectorAll(".request-list-item")[index]); yield waitForClipboardPromise(function setup() { monitor.toolbox.doc - .querySelector("#request-menu-context-copy-url-params").click(); + .querySelector("#request-list-context-copy-url-params").click(); }, queryString); ok(true, "The url query string copied from the selected item is correct."); } @@ -87,7 +87,7 @@ add_task(function* () { EventUtils.sendMouseEvent({ type: "contextmenu" }, document.querySelectorAll(".request-list-item")[index]); let copyPostDataNode = monitor.toolbox.doc - .querySelector("#request-menu-context-copy-post-data"); + .querySelector("#request-list-context-copy-post-data"); is(!!copyPostDataNode, !hidden, "The \"Copy POST Data\" context menu item should" + (hidden ? " " : " not ") + "be hidden."); @@ -100,7 +100,7 @@ add_task(function* () { document.querySelectorAll(".request-list-item")[index]); yield waitForClipboardPromise(function setup() { monitor.toolbox.doc - .querySelector("#request-menu-context-copy-post-data").click(); + .querySelector("#request-list-context-copy-post-data").click(); }, postData); ok(true, "The post data string copied from the selected item is correct."); } diff --git a/devtools/client/netmonitor/test/browser_net_copy_response.js b/devtools/client/netmonitor/test/browser_net_copy_response.js index 8ea68090f6b6..510b1653a9d7 100644 --- a/devtools/client/netmonitor/test/browser_net_copy_response.js +++ b/devtools/client/netmonitor/test/browser_net_copy_response.js @@ -30,7 +30,7 @@ add_task(function* () { // Context menu is appending in XUL document, we must select it from // toolbox.doc monitor.toolbox.doc - .querySelector("#request-menu-context-copy-response").click(); + .querySelector("#request-list-context-copy-response").click(); }, EXPECTED_RESULT); yield teardown(monitor); diff --git a/devtools/client/netmonitor/test/browser_net_copy_svg_image_as_data_uri.js b/devtools/client/netmonitor/test/browser_net_copy_svg_image_as_data_uri.js index e01355f95600..d0d3398ac533 100644 --- a/devtools/client/netmonitor/test/browser_net_copy_svg_image_as_data_uri.js +++ b/devtools/client/netmonitor/test/browser_net_copy_svg_image_as_data_uri.js @@ -30,7 +30,7 @@ add_task(function* () { // Context menu is appending in XUL document, we must select it from // toolbox.doc monitor.toolbox.doc - .querySelector("#request-menu-context-copy-image-as-data-uri").click(); + .querySelector("#request-list-context-copy-image-as-data-uri").click(); }, function check(text) { return text.startsWith("data:") && !/undefined/.test(text); }); diff --git a/devtools/client/netmonitor/test/browser_net_copy_url.js b/devtools/client/netmonitor/test/browser_net_copy_url.js index f8c8005b799b..e7ecacc3d45c 100644 --- a/devtools/client/netmonitor/test/browser_net_copy_url.js +++ b/devtools/client/netmonitor/test/browser_net_copy_url.js @@ -31,7 +31,7 @@ add_task(function* () { // Context menu is appending in XUL document, we must select it from // toolbox.doc monitor.toolbox.doc - .querySelector("#request-menu-context-copy-url").click(); + .querySelector("#request-list-context-copy-url").click(); }, requestItem.url); yield teardown(monitor); diff --git a/devtools/client/netmonitor/test/browser_net_filter-01.js b/devtools/client/netmonitor/test/browser_net_filter-01.js index 4f0b0ac2d4bc..7f92f5c13b5c 100644 --- a/devtools/client/netmonitor/test/browser_net_filter-01.js +++ b/devtools/client/netmonitor/test/browser_net_filter-01.js @@ -166,93 +166,94 @@ add_task(function* () { testContents([1, 1, 1, 1, 1, 1, 1, 1, 1]); EventUtils.sendMouseEvent({ type: "click" }, - document.querySelector("#requests-menu-filter-html-button")); + document.querySelector("#requests-list-filter-html-button")); testFilterButtons(monitor, "html"); testContents([1, 0, 0, 0, 0, 0, 0, 0, 0]); // Reset filters EventUtils.sendMouseEvent({ type: "click" }, - document.querySelector("#requests-menu-filter-all-button")); + document.querySelector("#requests-list-filter-all-button")); EventUtils.sendMouseEvent({ type: "click" }, - document.querySelector("#requests-menu-filter-css-button")); + document.querySelector("#requests-list-filter-css-button")); testFilterButtons(monitor, "css"); testContents([0, 1, 0, 0, 0, 0, 0, 0, 0]); EventUtils.sendMouseEvent({ type: "click" }, - document.querySelector("#requests-menu-filter-all-button")); + document.querySelector("#requests-list-filter-all-button")); EventUtils.sendMouseEvent({ type: "click" }, - document.querySelector("#requests-menu-filter-js-button")); + document.querySelector("#requests-list-filter-js-button")); testFilterButtons(monitor, "js"); testContents([0, 0, 1, 0, 0, 0, 0, 0, 0]); EventUtils.sendMouseEvent({ type: "click" }, - document.querySelector("#requests-menu-filter-all-button")); + document.querySelector("#requests-list-filter-all-button")); EventUtils.sendMouseEvent({ type: "click" }, - document.querySelector("#requests-menu-filter-xhr-button")); + document.querySelector("#requests-list-filter-xhr-button")); testFilterButtons(monitor, "xhr"); testContents([1, 1, 1, 1, 1, 1, 1, 1, 0]); EventUtils.sendMouseEvent({ type: "click" }, - document.querySelector("#requests-menu-filter-all-button")); + document.querySelector("#requests-list-filter-all-button")); EventUtils.sendMouseEvent({ type: "click" }, - document.querySelector("#requests-menu-filter-fonts-button")); + document.querySelector("#requests-list-filter-fonts-button")); testFilterButtons(monitor, "fonts"); testContents([0, 0, 0, 1, 0, 0, 0, 0, 0]); EventUtils.sendMouseEvent({ type: "click" }, - document.querySelector("#requests-menu-filter-all-button")); + document.querySelector("#requests-list-filter-all-button")); EventUtils.sendMouseEvent({ type: "click" }, - document.querySelector("#requests-menu-filter-images-button")); + document.querySelector("#requests-list-filter-images-button")); testFilterButtons(monitor, "images"); testContents([0, 0, 0, 0, 1, 0, 0, 0, 0]); EventUtils.sendMouseEvent({ type: "click" }, - document.querySelector("#requests-menu-filter-all-button")); + document.querySelector("#requests-list-filter-all-button")); EventUtils.sendMouseEvent({ type: "click" }, - document.querySelector("#requests-menu-filter-media-button")); + document.querySelector("#requests-list-filter-media-button")); testFilterButtons(monitor, "media"); testContents([0, 0, 0, 0, 0, 1, 1, 0, 0]); EventUtils.sendMouseEvent({ type: "click" }, - document.querySelector("#requests-menu-filter-all-button")); + document.querySelector("#requests-list-filter-all-button")); EventUtils.sendMouseEvent({ type: "click" }, - document.querySelector("#requests-menu-filter-flash-button")); + document.querySelector("#requests-list-filter-flash-button")); testFilterButtons(monitor, "flash"); testContents([0, 0, 0, 0, 0, 0, 0, 1, 0]); EventUtils.sendMouseEvent({ type: "click" }, - document.querySelector("#requests-menu-filter-all-button")); + document.querySelector("#requests-list-filter-all-button")); EventUtils.sendMouseEvent({ type: "click" }, - document.querySelector("#requests-menu-filter-ws-button")); + document.querySelector("#requests-list-filter-ws-button")); testFilterButtons(monitor, "ws"); testContents([0, 0, 0, 0, 0, 0, 0, 0, 1]); EventUtils.sendMouseEvent({ type: "click" }, - document.querySelector("#requests-menu-filter-all-button")); + document.querySelector("#requests-list-filter-all-button")); + testFilterButtons(monitor, "all"); testContents([1, 1, 1, 1, 1, 1, 1, 1, 1]); // Text in filter box that matches nothing should hide all. EventUtils.sendMouseEvent({ type: "click" }, - document.querySelector("#requests-menu-filter-all-button")); + document.querySelector("#requests-list-filter-all-button")); setFreetextFilter("foobar"); testContents([0, 0, 0, 0, 0, 0, 0, 0, 0]); // Text in filter box that matches should filter out everything else. EventUtils.sendMouseEvent({ type: "click" }, - document.querySelector("#requests-menu-filter-all-button")); + document.querySelector("#requests-list-filter-all-button")); setFreetextFilter("sample"); testContents([1, 1, 1, 0, 0, 0, 0, 0, 0]); // Text in filter box that matches should filter out everything else. EventUtils.sendMouseEvent({ type: "click" }, - document.querySelector("#requests-menu-filter-all-button")); + document.querySelector("#requests-list-filter-all-button")); setFreetextFilter("SAMPLE"); testContents([1, 1, 1, 0, 0, 0, 0, 0, 0]); // Test negative filtering (only show unmatched items) EventUtils.sendMouseEvent({ type: "click" }, - document.querySelector("#requests-menu-filter-all-button")); + document.querySelector("#requests-list-filter-all-button")); setFreetextFilter("-sample"); testContents([0, 0, 0, 1, 1, 1, 1, 1, 1]); @@ -261,9 +262,9 @@ add_task(function* () { // Enable filtering for html and css; should show request of both type. setFreetextFilter(""); EventUtils.sendMouseEvent({ type: "click" }, - document.querySelector("#requests-menu-filter-html-button")); + document.querySelector("#requests-list-filter-html-button")); EventUtils.sendMouseEvent({ type: "click" }, - document.querySelector("#requests-menu-filter-css-button")); + document.querySelector("#requests-list-filter-css-button")); testFilterButtonsCustom(monitor, [0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0]); testContents([1, 1, 0, 0, 0, 0, 0, 0, 0]); @@ -273,35 +274,35 @@ add_task(function* () { testContents([1, 1, 0, 0, 0, 0, 0, 0, 0]); EventUtils.sendMouseEvent({ type: "click" }, - document.querySelector("#requests-menu-filter-flash-button")); + document.querySelector("#requests-list-filter-flash-button")); setFreetextFilter(""); testFilterButtonsCustom(monitor, [0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0]); testContents([1, 1, 0, 0, 0, 0, 0, 1, 0]); // Disable some filters. Only one left active. EventUtils.sendMouseEvent({ type: "click" }, - document.querySelector("#requests-menu-filter-css-button")); + document.querySelector("#requests-list-filter-css-button")); EventUtils.sendMouseEvent({ type: "click" }, - document.querySelector("#requests-menu-filter-flash-button")); + document.querySelector("#requests-list-filter-flash-button")); testFilterButtons(monitor, "html"); testContents([1, 0, 0, 0, 0, 0, 0, 0, 0]); // Disable last active filter. Should toggle to all. EventUtils.sendMouseEvent({ type: "click" }, - document.querySelector("#requests-menu-filter-html-button")); + document.querySelector("#requests-list-filter-html-button")); testFilterButtons(monitor, "all"); testContents([1, 1, 1, 1, 1, 1, 1, 1, 1]); // Enable few filters and click on all. Only "all" should be checked. EventUtils.sendMouseEvent({ type: "click" }, - document.querySelector("#requests-menu-filter-html-button")); + document.querySelector("#requests-list-filter-html-button")); EventUtils.sendMouseEvent({ type: "click" }, - document.querySelector("#requests-menu-filter-css-button")); + document.querySelector("#requests-list-filter-css-button")); EventUtils.sendMouseEvent({ type: "click" }, - document.querySelector("#requests-menu-filter-ws-button")); + document.querySelector("#requests-list-filter-ws-button")); testFilterButtonsCustom(monitor, [0, 1, 1, 0, 0, 0, 0, 0, 0, 1]); EventUtils.sendMouseEvent({ type: "click" }, - document.querySelector("#requests-menu-filter-all-button")); + document.querySelector("#requests-list-filter-all-button")); testFilterButtons(monitor, "all"); testContents([1, 1, 1, 1, 1, 1, 1, 1, 1]); diff --git a/devtools/client/netmonitor/test/browser_net_filter-02.js b/devtools/client/netmonitor/test/browser_net_filter-02.js index 4b3cdf92ab4b..bac648960c37 100644 --- a/devtools/client/netmonitor/test/browser_net_filter-02.js +++ b/devtools/client/netmonitor/test/browser_net_filter-02.js @@ -166,7 +166,7 @@ add_task(function* () { info("Testing html filtering."); EventUtils.sendMouseEvent({ type: "click" }, - document.querySelector("#requests-menu-filter-html-button")); + document.querySelector("#requests-list-filter-html-button")); testFilterButtons(monitor, "html"); testContents([1, 0, 0, 0, 0, 0, 0, 0, 0]); @@ -191,7 +191,7 @@ add_task(function* () { info("Resetting filters."); EventUtils.sendMouseEvent({ type: "click" }, - document.querySelector("#requests-menu-filter-all-button")); + document.querySelector("#requests-list-filter-all-button")); testFilterButtons(monitor, "all"); testContents([1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]); diff --git a/devtools/client/netmonitor/test/browser_net_filter-03.js b/devtools/client/netmonitor/test/browser_net_filter-03.js index 3421450bc3b6..9b1f55209231 100644 --- a/devtools/client/netmonitor/test/browser_net_filter-03.js +++ b/devtools/client/netmonitor/test/browser_net_filter-03.js @@ -64,13 +64,13 @@ add_task(function* () { info("Sorting by size, ascending."); EventUtils.sendMouseEvent({ type: "click" }, - document.querySelector("#requests-menu-size-button")); + document.querySelector("#requests-list-size-button")); testFilterButtons(monitor, "all"); testContents([6, 4, 5, 0, 1, 2, 3], 7, 6); info("Testing html filtering."); EventUtils.sendMouseEvent({ type: "click" }, - document.querySelector("#requests-menu-filter-html-button")); + document.querySelector("#requests-list-filter-html-button")); testFilterButtons(monitor, "html"); testContents([6, 4, 5, 0, 1, 2, 3], 1, 6); @@ -98,9 +98,9 @@ add_task(function* () { function resetSorting() { EventUtils.sendMouseEvent({ type: "click" }, - document.querySelector("#requests-menu-waterfall-button")); + document.querySelector("#requests-list-waterfall-button")); EventUtils.sendMouseEvent({ type: "click" }, - document.querySelector("#requests-menu-size-button")); + document.querySelector("#requests-list-size-button")); } function getSelectedIndex(state) { diff --git a/devtools/client/netmonitor/test/browser_net_footer-summary.js b/devtools/client/netmonitor/test/browser_net_footer-summary.js index 7eaada4c2943..fa3007f71825 100644 --- a/devtools/client/netmonitor/test/browser_net_footer-summary.js +++ b/devtools/client/netmonitor/test/browser_net_footer-summary.js @@ -40,7 +40,7 @@ add_task(function* () { let buttons = ["html", "css", "js", "xhr", "fonts", "images", "media", "flash"]; for (let button of buttons) { - let buttonEl = document.querySelector(`#requests-menu-filter-${button}-button`); + let buttonEl = document.querySelector(`#requests-list-filter-${button}-button`); EventUtils.sendMouseEvent({ type: "click" }, buttonEl); testStatus(); } @@ -49,7 +49,7 @@ add_task(function* () { yield teardown(monitor); function testStatus() { - let value = document.querySelector("#requests-menu-network-summary-button").textContent; + let value = document.querySelector("#requests-list-network-summary-button").textContent; info("Current summary: " + value); let state = gStore.getState(); diff --git a/devtools/client/netmonitor/test/browser_net_icon-preview.js b/devtools/client/netmonitor/test/browser_net_icon-preview.js index f9b2d13dc38f..ac872f2f63ab 100644 --- a/devtools/client/netmonitor/test/browser_net_icon-preview.js +++ b/devtools/client/netmonitor/test/browser_net_icon-preview.js @@ -62,11 +62,11 @@ add_task(function* () { } function checkImageThumbnail() { - is(document.querySelectorAll(".requests-menu-icon[data-type=thumbnail]").length, 1, + is(document.querySelectorAll(".requests-list-icon[data-type=thumbnail]").length, 1, "There should be only one image request with a thumbnail displayed."); - is(document.querySelector(".requests-menu-icon[data-type=thumbnail]").src, TEST_IMAGE_DATA_URI, - "The image requests-menu-icon thumbnail is displayed correctly."); - is(document.querySelector(".requests-menu-icon[data-type=thumbnail]").hidden, false, - "The image requests-menu-icon thumbnail should not be hidden."); + is(document.querySelector(".requests-list-icon[data-type=thumbnail]").src, TEST_IMAGE_DATA_URI, + "The image requests-list-icon thumbnail is displayed correctly."); + is(document.querySelector(".requests-list-icon[data-type=thumbnail]").hidden, false, + "The image requests-list-icon thumbnail should not be hidden."); } }); diff --git a/devtools/client/netmonitor/test/browser_net_image-tooltip.js b/devtools/client/netmonitor/test/browser_net_image-tooltip.js index 56604e57d659..43c031e37bd1 100644 --- a/devtools/client/netmonitor/test/browser_net_image-tooltip.js +++ b/devtools/client/netmonitor/test/browser_net_image-tooltip.js @@ -55,7 +55,7 @@ add_task(function* test() { document.querySelectorAll(".request-list-item")[1]); info("Checking if the image thumbnail is hidden when mouse leaves the menu widget"); - let requestsListContents = document.querySelector(".requests-menu-contents"); + let requestsListContents = document.querySelector(".requests-list-contents"); EventUtils.synthesizeMouse(requestsListContents, 0, 0, { type: "mouseout" }, monitor.panelWin); yield waitUntil(() => !toolboxDoc.querySelector(".tooltip-container.tooltip-visible")); @@ -72,7 +72,7 @@ add_task(function* test() { * with the expected content. */ function* showTooltipAndVerify(toolboxDoc, target) { - let anchor = target.querySelector(".requests-menu-file"); + let anchor = target.querySelector(".requests-list-file"); yield showTooltipOn(toolboxDoc, anchor); info("Tooltip was successfully opened for the image request."); @@ -95,7 +95,7 @@ add_task(function* test() { */ function* hideTooltipAndVerify(toolboxDoc, target) { // Hovering over the "method" column hides the tooltip. - let anchor = target.querySelector(".requests-menu-method"); + let anchor = target.querySelector(".requests-list-method"); let win = anchor.ownerDocument.defaultView; EventUtils.synthesizeMouseAtCenter(anchor, { type: "mousemove" }, win); diff --git a/devtools/client/netmonitor/test/browser_net_open_request_in_tab.js b/devtools/client/netmonitor/test/browser_net_open_request_in_tab.js index e3d5ba4d5632..842efb7df23a 100644 --- a/devtools/client/netmonitor/test/browser_net_open_request_in_tab.js +++ b/devtools/client/netmonitor/test/browser_net_open_request_in_tab.js @@ -35,7 +35,7 @@ add_task(function* () { // Context menu is appending in XUL document, we must select it from // toolbox.doc monitor.toolbox.doc - .querySelector("#request-menu-context-newtab").click(); + .querySelector("#request-list-context-newtab").click(); yield onTabOpen; ok(true, "A new tab has been opened"); diff --git a/devtools/client/netmonitor/test/browser_net_reload-button.js b/devtools/client/netmonitor/test/browser_net_reload-button.js index b42bb42021c1..3e4534999990 100644 --- a/devtools/client/netmonitor/test/browser_net_reload-button.js +++ b/devtools/client/netmonitor/test/browser_net_reload-button.js @@ -15,7 +15,7 @@ add_task(function* () { let wait = waitForNetworkEvents(monitor, 1); EventUtils.sendMouseEvent({ type: "click" }, - document.querySelector("#requests-menu-reload-notice-button")); + document.querySelector("#requests-list-reload-notice-button")); yield wait; is(document.querySelectorAll(".request-list-item").length, 1, diff --git a/devtools/client/netmonitor/test/browser_net_reload-markers.js b/devtools/client/netmonitor/test/browser_net_reload-markers.js index 0c6efa53d513..23d5f1559cb4 100644 --- a/devtools/client/netmonitor/test/browser_net_reload-markers.js +++ b/devtools/client/netmonitor/test/browser_net_reload-markers.js @@ -13,7 +13,7 @@ add_task(function* () { let { document, windowRequire } = monitor.panelWin; let { EVENTS } = windowRequire("devtools/client/netmonitor/constants"); - let button = document.querySelector("#requests-menu-reload-notice-button"); + let button = document.querySelector("#requests-list-reload-notice-button"); button.click(); let markers = []; diff --git a/devtools/client/netmonitor/test/browser_net_security-icon-click.js b/devtools/client/netmonitor/test/browser_net_security-icon-click.js index 15211324c28a..5464e1499e1a 100644 --- a/devtools/client/netmonitor/test/browser_net_security-icon-click.js +++ b/devtools/client/netmonitor/test/browser_net_security-icon-click.js @@ -32,7 +32,7 @@ add_task(function* () { info("Sorting the items by filename."); EventUtils.sendMouseEvent({ type: "click" }, - document.querySelector("#requests-menu-file-button")); + document.querySelector("#requests-list-file-button")); info("Testing that security icon can be clicked after the items were sorted."); diff --git a/devtools/client/netmonitor/test/browser_net_security-state.js b/devtools/client/netmonitor/test/browser_net_security-state.js index 27476e2d5449..2d937cf25b72 100644 --- a/devtools/client/netmonitor/test/browser_net_security-state.js +++ b/devtools/client/netmonitor/test/browser_net_security-state.js @@ -29,8 +29,8 @@ add_task(function* () { yield performRequests(); for (let subitemNode of Array.from(document.querySelectorAll( - "requests-menu-subitem.requests-menu-security-and-domain"))) { - let domain = subitemNode.querySelector(".requests-menu-domain").textContent; + "requests-list-subitem.requests-list-security-and-domain"))) { + let domain = subitemNode.querySelector(".requests-list-domain").textContent; info("Found a request to " + domain); ok(domain in EXPECTED_SECURITY_STATES, "Domain " + domain + " was expected."); diff --git a/devtools/client/netmonitor/test/browser_net_simple-request-details.js b/devtools/client/netmonitor/test/browser_net_simple-request-details.js index bdc40585e70b..43d119111096 100644 --- a/devtools/client/netmonitor/test/browser_net_simple-request-details.js +++ b/devtools/client/netmonitor/test/browser_net_simple-request-details.js @@ -245,27 +245,27 @@ add_task(function* () { is(tabEl.getAttribute("selected"), "true", "The timings tab in the network details pane should be selected."); - ok(tabpanel.querySelector("#timings-summary-blocked .requests-menu-timings-total") + ok(tabpanel.querySelector("#timings-summary-blocked .requests-list-timings-total") .getAttribute("value").match(/[0-9]+/), "The blocked timing info does not appear to be correct."); - ok(tabpanel.querySelector("#timings-summary-dns .requests-menu-timings-total") + ok(tabpanel.querySelector("#timings-summary-dns .requests-list-timings-total") .getAttribute("value").match(/[0-9]+/), "The dns timing info does not appear to be correct."); - ok(tabpanel.querySelector("#timings-summary-connect .requests-menu-timings-total") + ok(tabpanel.querySelector("#timings-summary-connect .requests-list-timings-total") .getAttribute("value").match(/[0-9]+/), "The connect timing info does not appear to be correct."); - ok(tabpanel.querySelector("#timings-summary-send .requests-menu-timings-total") + ok(tabpanel.querySelector("#timings-summary-send .requests-list-timings-total") .getAttribute("value").match(/[0-9]+/), "The send timing info does not appear to be correct."); - ok(tabpanel.querySelector("#timings-summary-wait .requests-menu-timings-total") + ok(tabpanel.querySelector("#timings-summary-wait .requests-list-timings-total") .getAttribute("value").match(/[0-9]+/), "The wait timing info does not appear to be correct."); - ok(tabpanel.querySelector("#timings-summary-receive .requests-menu-timings-total") + ok(tabpanel.querySelector("#timings-summary-receive .requests-list-timings-total") .getAttribute("value").match(/[0-9]+/), "The receive timing info does not appear to be correct."); } diff --git a/devtools/client/netmonitor/test/browser_net_simple-request.js b/devtools/client/netmonitor/test/browser_net_simple-request.js index f7051c16ddee..840999f1ef13 100644 --- a/devtools/client/netmonitor/test/browser_net_simple-request.js +++ b/devtools/client/netmonitor/test/browser_net_simple-request.js @@ -29,7 +29,7 @@ add_task(function* () { is(document.querySelector(".network-details-panel-toggle").hasAttribute("disabled"), true, "The pane toggle button should be disabled when the frontend is opened."); - ok(document.querySelector("#requests-menu-empty-notice"), + ok(document.querySelector("#requests-list-empty-notice"), "An empty notice should be displayed when the frontend is opened."); is(gStore.getState().requests.requests.size, 0, "The requests menu should be empty when the frontend is opened."); @@ -41,7 +41,7 @@ add_task(function* () { is(document.querySelector(".network-details-panel-toggle").hasAttribute("disabled"), false, "The pane toggle button should be enabled after the first request."); - ok(!document.querySelector("#requests-menu-empty-notice"), + ok(!document.querySelector("#requests-list-empty-notice"), "The empty notice should be hidden after the first request."); is(gStore.getState().requests.requests.size, 1, "The requests menu should not be empty after the first request."); @@ -53,7 +53,7 @@ add_task(function* () { is(document.querySelector(".network-details-panel-toggle").hasAttribute("disabled"), false, "The pane toggle button should be still be enabled after a reload."); - ok(!document.querySelector("#requests-menu-empty-notice"), + ok(!document.querySelector("#requests-list-empty-notice"), "The empty notice should be still hidden after a reload."); is(gStore.getState().requests.requests.size, 1, "The requests menu should not be empty after a reload."); @@ -65,7 +65,7 @@ add_task(function* () { is(document.querySelector(".network-details-panel-toggle").hasAttribute("disabled"), true, "The pane toggle button should be disabled when after clear."); - ok(document.querySelector("#requests-menu-empty-notice"), + ok(document.querySelector("#requests-list-empty-notice"), "An empty notice should be displayed again after clear."); is(gStore.getState().requests.requests.size, 0, "The requests menu should be empty after clear."); diff --git a/devtools/client/netmonitor/test/browser_net_sort-01.js b/devtools/client/netmonitor/test/browser_net_sort-01.js index 657347af8dda..ab746055ebb6 100644 --- a/devtools/client/netmonitor/test/browser_net_sort-01.js +++ b/devtools/client/netmonitor/test/browser_net_sort-01.js @@ -66,7 +66,7 @@ add_task(function* () { info("Testing status sort, ascending."); EventUtils.sendMouseEvent({ type: "click" }, - document.querySelector("#requests-menu-status-button")); + document.querySelector("#requests-list-status-button")); testHeaders("status", "ascending"); testContents([0, 1, 2, 3, 4], 0); @@ -81,7 +81,7 @@ add_task(function* () { info("Testing status sort, descending."); EventUtils.sendMouseEvent({ type: "click" }, - document.querySelector("#requests-menu-status-button")); + document.querySelector("#requests-list-status-button")); testHeaders("status", "descending"); testContents([9, 8, 7, 6, 5, 4, 3, 2, 1, 0], 9); @@ -96,13 +96,13 @@ add_task(function* () { info("Testing status sort yet again, ascending."); EventUtils.sendMouseEvent({ type: "click" }, - document.querySelector("#requests-menu-status-button")); + document.querySelector("#requests-list-status-button")); testHeaders("status", "ascending"); testContents([0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14], 0); info("Testing status sort yet again, descending."); EventUtils.sendMouseEvent({ type: "click" }, - document.querySelector("#requests-menu-status-button")); + document.querySelector("#requests-list-status-button")); testHeaders("status", "descending"); testContents([14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0], 14); @@ -110,8 +110,8 @@ add_task(function* () { function testHeaders(sortType, direction) { let doc = monitor.panelWin.document; - let target = doc.querySelector("#requests-menu-" + sortType + "-button"); - let headers = doc.querySelectorAll(".requests-menu-header-button"); + let target = doc.querySelector("#requests-list-" + sortType + "-button"); + let headers = doc.querySelectorAll(".requests-list-header-button"); for (let header of headers) { if (header != target) { diff --git a/devtools/client/netmonitor/test/browser_net_sort-02.js b/devtools/client/netmonitor/test/browser_net_sort-02.js index 3cc2abd46042..83f98b35ee21 100644 --- a/devtools/client/netmonitor/test/browser_net_sort-02.js +++ b/devtools/client/netmonitor/test/browser_net_sort-02.js @@ -66,127 +66,127 @@ add_task(function* () { info("Testing status sort, ascending."); EventUtils.sendMouseEvent({ type: "click" }, - document.querySelector("#requests-menu-status-button")); + document.querySelector("#requests-list-status-button")); testHeaders("status", "ascending"); testContents([0, 1, 2, 3, 4]); info("Testing status sort, descending."); EventUtils.sendMouseEvent({ type: "click" }, - document.querySelector("#requests-menu-status-button")); + document.querySelector("#requests-list-status-button")); testHeaders("status", "descending"); testContents([4, 3, 2, 1, 0]); info("Testing status sort, ascending. Checking sort loops correctly."); EventUtils.sendMouseEvent({ type: "click" }, - document.querySelector("#requests-menu-status-button")); + document.querySelector("#requests-list-status-button")); testHeaders("status", "ascending"); testContents([0, 1, 2, 3, 4]); info("Testing method sort, ascending."); EventUtils.sendMouseEvent({ type: "click" }, - document.querySelector("#requests-menu-method-button")); + document.querySelector("#requests-list-method-button")); testHeaders("method", "ascending"); testContents([0, 1, 2, 3, 4]); info("Testing method sort, descending."); EventUtils.sendMouseEvent({ type: "click" }, - document.querySelector("#requests-menu-method-button")); + document.querySelector("#requests-list-method-button")); testHeaders("method", "descending"); testContents([4, 3, 2, 1, 0]); info("Testing method sort, ascending. Checking sort loops correctly."); EventUtils.sendMouseEvent({ type: "click" }, - document.querySelector("#requests-menu-method-button")); + document.querySelector("#requests-list-method-button")); testHeaders("method", "ascending"); testContents([0, 1, 2, 3, 4]); info("Testing file sort, ascending."); EventUtils.sendMouseEvent({ type: "click" }, - document.querySelector("#requests-menu-file-button")); + document.querySelector("#requests-list-file-button")); testHeaders("file", "ascending"); testContents([0, 1, 2, 3, 4]); info("Testing file sort, descending."); EventUtils.sendMouseEvent({ type: "click" }, - document.querySelector("#requests-menu-file-button")); + document.querySelector("#requests-list-file-button")); testHeaders("file", "descending"); testContents([4, 3, 2, 1, 0]); info("Testing file sort, ascending. Checking sort loops correctly."); EventUtils.sendMouseEvent({ type: "click" }, - document.querySelector("#requests-menu-file-button")); + document.querySelector("#requests-list-file-button")); testHeaders("file", "ascending"); testContents([0, 1, 2, 3, 4]); info("Testing type sort, ascending."); EventUtils.sendMouseEvent({ type: "click" }, - document.querySelector("#requests-menu-type-button")); + document.querySelector("#requests-list-type-button")); testHeaders("type", "ascending"); testContents([0, 1, 2, 3, 4]); info("Testing type sort, descending."); EventUtils.sendMouseEvent({ type: "click" }, - document.querySelector("#requests-menu-type-button")); + document.querySelector("#requests-list-type-button")); testHeaders("type", "descending"); testContents([4, 3, 2, 1, 0]); info("Testing type sort, ascending. Checking sort loops correctly."); EventUtils.sendMouseEvent({ type: "click" }, - document.querySelector("#requests-menu-type-button")); + document.querySelector("#requests-list-type-button")); testHeaders("type", "ascending"); testContents([0, 1, 2, 3, 4]); info("Testing transferred sort, ascending."); EventUtils.sendMouseEvent({ type: "click" }, - document.querySelector("#requests-menu-transferred-button")); + document.querySelector("#requests-list-transferred-button")); testHeaders("transferred", "ascending"); testContents([0, 1, 2, 3, 4]); info("Testing transferred sort, descending."); EventUtils.sendMouseEvent({ type: "click" }, - document.querySelector("#requests-menu-transferred-button")); + document.querySelector("#requests-list-transferred-button")); testHeaders("transferred", "descending"); testContents([4, 3, 2, 1, 0]); info("Testing transferred sort, ascending. Checking sort loops correctly."); EventUtils.sendMouseEvent({ type: "click" }, - document.querySelector("#requests-menu-transferred-button")); + document.querySelector("#requests-list-transferred-button")); testHeaders("transferred", "ascending"); testContents([0, 1, 2, 3, 4]); info("Testing size sort, ascending."); EventUtils.sendMouseEvent({ type: "click" }, - document.querySelector("#requests-menu-size-button")); + document.querySelector("#requests-list-size-button")); testHeaders("size", "ascending"); testContents([0, 1, 2, 3, 4]); info("Testing size sort, descending."); EventUtils.sendMouseEvent({ type: "click" }, - document.querySelector("#requests-menu-size-button")); + document.querySelector("#requests-list-size-button")); testHeaders("size", "descending"); testContents([4, 3, 2, 1, 0]); info("Testing size sort, ascending. Checking sort loops correctly."); EventUtils.sendMouseEvent({ type: "click" }, - document.querySelector("#requests-menu-size-button")); + document.querySelector("#requests-list-size-button")); testHeaders("size", "ascending"); testContents([0, 1, 2, 3, 4]); info("Testing waterfall sort, ascending."); EventUtils.sendMouseEvent({ type: "click" }, - document.querySelector("#requests-menu-waterfall-button")); + document.querySelector("#requests-list-waterfall-button")); testHeaders("waterfall", "ascending"); testContents([0, 2, 4, 3, 1]); info("Testing waterfall sort, descending."); EventUtils.sendMouseEvent({ type: "click" }, - document.querySelector("#requests-menu-waterfall-button")); + document.querySelector("#requests-list-waterfall-button")); testHeaders("waterfall", "descending"); testContents([4, 2, 0, 1, 3]); info("Testing waterfall sort, ascending. Checking sort loops correctly."); EventUtils.sendMouseEvent({ type: "click" }, - document.querySelector("#requests-menu-waterfall-button")); + document.querySelector("#requests-list-waterfall-button")); testHeaders("waterfall", "ascending"); testContents([0, 2, 4, 3, 1]); @@ -201,8 +201,8 @@ add_task(function* () { function testHeaders(sortType, direction) { let doc = monitor.panelWin.document; - let target = doc.querySelector("#requests-menu-" + sortType + "-button"); - let headers = doc.querySelectorAll(".requests-menu-header-button"); + let target = doc.querySelector("#requests-list-" + sortType + "-button"); + let headers = doc.querySelectorAll(".requests-list-header-button"); for (let header of headers) { if (header != target) { diff --git a/devtools/client/netmonitor/test/browser_net_statistics-02.js b/devtools/client/netmonitor/test/browser_net_statistics-02.js index 10a3988e9a45..9fcbf985c2e4 100644 --- a/devtools/client/netmonitor/test/browser_net_statistics-02.js +++ b/devtools/client/netmonitor/test/browser_net_statistics-02.js @@ -17,15 +17,15 @@ add_task(function* () { let Actions = windowRequire("devtools/client/netmonitor/actions/index"); EventUtils.sendMouseEvent({ type: "click" }, - document.querySelector("#requests-menu-filter-html-button")); + document.querySelector("#requests-list-filter-html-button")); EventUtils.sendMouseEvent({ type: "click" }, - document.querySelector("#requests-menu-filter-css-button")); + document.querySelector("#requests-list-filter-css-button")); EventUtils.sendMouseEvent({ type: "click" }, - document.querySelector("#requests-menu-filter-js-button")); + document.querySelector("#requests-list-filter-js-button")); EventUtils.sendMouseEvent({ type: "click" }, - document.querySelector("#requests-menu-filter-ws-button")); + document.querySelector("#requests-list-filter-ws-button")); EventUtils.sendMouseEvent({ type: "click" }, - document.querySelector("#requests-menu-filter-other-button")); + document.querySelector("#requests-list-filter-other-button")); testFilterButtonsCustom(monitor, [0, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1]); info("The correct filtering predicates are used before entering perf. analysis mode."); diff --git a/devtools/client/netmonitor/test/browser_net_status-codes.js b/devtools/client/netmonitor/test/browser_net_status-codes.js index aca5119e7be8..088e69337de3 100644 --- a/devtools/client/netmonitor/test/browser_net_status-codes.js +++ b/devtools/client/netmonitor/test/browser_net_status-codes.js @@ -165,7 +165,7 @@ add_task(function* () { is(summaryValues[0].value, uri, "The url summary value is incorrect."); is(summaryValues[1].value, method, "The method summary value is incorrect."); - is(panel.querySelector(".requests-menu-status-icon").dataset.code, status, + is(panel.querySelector(".requests-list-status-icon").dataset.code, status, "The status summary code is incorrect."); is(summaryValues[3].value, status + " " + statusText, "The status summary value is incorrect."); diff --git a/devtools/client/netmonitor/test/browser_net_timeline_ticks.js b/devtools/client/netmonitor/test/browser_net_timeline_ticks.js index 14bfd046e87e..7a15bf9e765f 100644 --- a/devtools/client/netmonitor/test/browser_net_timeline_ticks.js +++ b/devtools/client/netmonitor/test/browser_net_timeline_ticks.js @@ -19,14 +19,14 @@ add_task(function* () { // Disable transferred size column support for this test. // Without this, the waterfall only has enough room for one division, which // would remove most of the value of this test. - // $("#requests-menu-transferred-header-box").hidden = true; - // $("#requests-menu-item-template .requests-menu-transferred").hidden = true; + // $("#requests-list-transferred-header-box").hidden = true; + // $("#requests-list-item-template .requests-list-transferred").hidden = true; RequestsMenu.lazyUpdate = false; - ok($("#requests-menu-waterfall-label"), + ok($("#requests-list-waterfall-label"), "An timeline label should be displayed when the frontend is opened."); - ok($all(".requests-menu-timings-division").length == 0, + ok($all(".requests-list-timings-division").length == 0, "No tick labels should be displayed when the frontend is opened."); ok(!RequestsMenu._canvas, "No canvas should be created when the frontend is opened."); @@ -41,12 +41,12 @@ add_task(function* () { NetMonitorController.NetworkEventsHandler.clearMarkers(); RequestsMenu._flushWaterfallViews(true); - ok(!$("#requests-menu-waterfall-label"), + ok(!$("#requests-list-waterfall-label"), "The timeline label should be hidden after the first request."); - ok($all(".requests-menu-timings-division").length >= 3, + ok($all(".requests-list-timings-division").length >= 3, "There should be at least 3 tick labels in the network requests header."); - let timingDivisionEls = $all(".requests-menu-timings-division"); + let timingDivisionEls = $all(".requests-list-timings-division"); is(timingDivisionEls[0].textContent, L10N.getFormatStr("networkMenu.millisecond", 0), "The first tick label has correct value"); is(timingDivisionEls[1].textContent, L10N.getFormatStr("networkMenu.millisecond", 80), diff --git a/devtools/client/netmonitor/test/browser_net_timing-division.js b/devtools/client/netmonitor/test/browser_net_timing-division.js index 1d9cf182e912..d6b174ba4e66 100644 --- a/devtools/client/netmonitor/test/browser_net_timing-division.js +++ b/devtools/client/netmonitor/test/browser_net_timing-division.js @@ -25,11 +25,11 @@ add_task(function* () { yield wait; let milDivs = document.querySelectorAll( - ".requests-menu-timings-division[data-division-scale=millisecond]"); + ".requests-list-timings-division[data-division-scale=millisecond]"); let secDivs = document.querySelectorAll( - ".requests-menu-timings-division[data-division-scale=second]"); + ".requests-list-timings-division[data-division-scale=second]"); let minDivs = document.querySelectorAll( - ".requests-menu-timings-division[data-division-scale=minute]"); + ".requests-list-timings-division[data-division-scale=minute]"); info("Number of millisecond divisions: " + milDivs.length); info("Number of second divisions: " + secDivs.length); diff --git a/devtools/client/netmonitor/test/components/filter-buttons.test.js b/devtools/client/netmonitor/test/components/filter-buttons.test.js index 557b3c9afeac..3a9cc603273c 100644 --- a/devtools/client/netmonitor/test/components/filter-buttons.test.js +++ b/devtools/client/netmonitor/test/components/filter-buttons.test.js @@ -94,8 +94,8 @@ function asExpected(wrapper, expectTypes, description) { let className = expectTypes[type] ? "devtools-button checked" : "devtools-button"; it(`'${type}' button is ${checked} ${description}`, () => { - expect(wrapper.find(`#requests-menu-filter-${type}-button`).html()) - .toBe(``); }); } diff --git a/devtools/client/netmonitor/test/head.js b/devtools/client/netmonitor/test/head.js index 29a75bb32fba..e02498a6ef89 100644 --- a/devtools/client/netmonitor/test/head.js +++ b/devtools/client/netmonitor/test/head.js @@ -275,32 +275,32 @@ function verifyRequestItemTarget(document, requestList, requestItem, aMethod, is(requestItem.url, aUrl, "The attached url is correct."); } - is(target.querySelector(".requests-menu-method").textContent, + is(target.querySelector(".requests-list-method").textContent, aMethod, "The displayed method is correct."); if (fuzzyUrl) { - ok(target.querySelector(".requests-menu-file").textContent.startsWith( + ok(target.querySelector(".requests-list-file").textContent.startsWith( name + (query ? "?" + query : "")), "The displayed file is correct."); - ok(target.querySelector(".requests-menu-file").getAttribute("title").startsWith(unicodeUrl), + ok(target.querySelector(".requests-list-file").getAttribute("title").startsWith(unicodeUrl), "The tooltip file is correct."); } else { - is(target.querySelector(".requests-menu-file").textContent, + is(target.querySelector(".requests-list-file").textContent, name + (query ? "?" + query : ""), "The displayed file is correct."); - is(target.querySelector(".requests-menu-file").getAttribute("title"), + is(target.querySelector(".requests-list-file").getAttribute("title"), unicodeUrl, "The tooltip file is correct."); } - is(target.querySelector(".requests-menu-domain").textContent, + is(target.querySelector(".requests-list-domain").textContent, hostPort, "The displayed domain is correct."); let domainTooltip = hostPort + (remoteAddress ? " (" + remoteAddress + ")" : ""); - is(target.querySelector(".requests-menu-domain").getAttribute("title"), + is(target.querySelector(".requests-list-domain").getAttribute("title"), domainTooltip, "The tooltip domain is correct."); if (status !== undefined) { - let value = target.querySelector(".requests-menu-status-icon").getAttribute("data-code"); - let codeValue = target.querySelector(".requests-menu-status-code").textContent; - let tooltip = target.querySelector(".requests-menu-status").getAttribute("title"); + let value = target.querySelector(".requests-list-status-icon").getAttribute("data-code"); + let codeValue = target.querySelector(".requests-list-status-code").textContent; + let tooltip = target.querySelector(".requests-list-status").getAttribute("title"); info("Displayed status: " + value); info("Displayed code: " + codeValue); info("Tooltip status: " + tooltip); @@ -309,40 +309,40 @@ function verifyRequestItemTarget(document, requestList, requestItem, aMethod, is(tooltip, status + " " + statusText, "The tooltip status is correct."); } if (cause !== undefined) { - let value = target.querySelector(".requests-menu-cause > .subitem-label").textContent; - let tooltip = target.querySelector(".requests-menu-cause").getAttribute("title"); + let value = target.querySelector(".requests-list-cause > .subitem-label").textContent; + let tooltip = target.querySelector(".requests-list-cause").getAttribute("title"); info("Displayed cause: " + value); info("Tooltip cause: " + tooltip); is(value, cause.type, "The displayed cause is correct."); is(tooltip, cause.loadingDocumentUri, "The tooltip cause is correct.") } if (type !== undefined) { - let value = target.querySelector(".requests-menu-type").textContent; - let tooltip = target.querySelector(".requests-menu-type").getAttribute("title"); + let value = target.querySelector(".requests-list-type").textContent; + let tooltip = target.querySelector(".requests-list-type").getAttribute("title"); info("Displayed type: " + value); info("Tooltip type: " + tooltip); is(value, type, "The displayed type is correct."); is(tooltip, fullMimeType, "The tooltip type is correct."); } if (transferred !== undefined) { - let value = target.querySelector(".requests-menu-transferred").textContent; - let tooltip = target.querySelector(".requests-menu-transferred").getAttribute("title"); + let value = target.querySelector(".requests-list-transferred").textContent; + let tooltip = target.querySelector(".requests-list-transferred").getAttribute("title"); info("Displayed transferred size: " + value); info("Tooltip transferred size: " + tooltip); is(value, transferred, "The displayed transferred size is correct."); is(tooltip, transferred, "The tooltip transferred size is correct."); } if (size !== undefined) { - let value = target.querySelector(".requests-menu-size").textContent; - let tooltip = target.querySelector(".requests-menu-size").getAttribute("title"); + let value = target.querySelector(".requests-list-size").textContent; + let tooltip = target.querySelector(".requests-list-size").getAttribute("title"); info("Displayed size: " + value); info("Tooltip size: " + tooltip); is(value, size, "The displayed size is correct."); is(tooltip, size, "The tooltip size is correct."); } if (time !== undefined) { - let value = target.querySelector(".requests-menu-timings-total").textContent; - let tooltip = target.querySelector(".requests-menu-timings-total").getAttribute("title"); + let value = target.querySelector(".requests-list-timings-total").textContent; + let tooltip = target.querySelector(".requests-list-timings-total").getAttribute("title"); info("Displayed time: " + value); info("Tooltip time: " + tooltip); ok(~~(value.match(/[0-9]+/)) >= 0, "The displayed time is correct."); @@ -385,9 +385,9 @@ function waitFor(subject, eventName) { */ function testFilterButtons(monitor, filterType) { let doc = monitor.panelWin.document; - let target = doc.querySelector("#requests-menu-filter-" + filterType + "-button"); + let target = doc.querySelector("#requests-list-filter-" + filterType + "-button"); ok(target, `Filter button '${filterType}' was found`); - let buttons = [...doc.querySelectorAll("#requests-menu-filter-buttons button")]; + let buttons = [...doc.querySelectorAll("#requests-list-filter-buttons button")]; ok(buttons.length > 0, "More than zero filter buttons were found"); // Only target should be checked. @@ -405,7 +405,7 @@ function testFilterButtons(monitor, filterType) { */ function testFilterButtonsCustom(aMonitor, aIsChecked) { let doc = aMonitor.panelWin.document; - let buttons = doc.querySelectorAll("#requests-menu-filter-buttons button"); + let buttons = doc.querySelectorAll("#requests-list-filter-buttons button"); for (let i = 0; i < aIsChecked.length; i++) { let button = buttons[i]; if (aIsChecked[i]) { diff --git a/devtools/client/themes/netmonitor.css b/devtools/client/themes/netmonitor.css index 250bdc46dc6f..5a0e295674c5 100644 --- a/devtools/client/themes/netmonitor.css +++ b/devtools/client/themes/netmonitor.css @@ -100,18 +100,18 @@ margin-top: 2px; } -#requests-menu-perf-notice-button { +#requests-list-perf-notice-button { min-width: 30px; min-height: 26px; margin: 0 5px; vertical-align: middle; } -#requests-menu-perf-notice-button::before { +#requests-list-perf-notice-button::before { background-image: url(images/profiler-stopwatch.svg); } -#requests-menu-reload-notice-button { +#requests-list-reload-notice-button { font-size: inherit; min-height: 26px; margin: 0 5px; @@ -119,21 +119,21 @@ /* Network requests table */ -#requests-menu-toolbar { +#requests-list-toolbar { display: flex; padding: 0; } -#requests-menu-filter-buttons { +#requests-list-filter-buttons { display: flex; flex-wrap: nowrap; } -.theme-firebug #requests-menu-toolbar { +.theme-firebug #requests-list-toolbar { height: 19px !important; } -.requests-menu-contents { +.requests-list-contents { display: flex; flex-direction: column; overflow-x: hidden; @@ -142,7 +142,7 @@ --timings-rev-scale: 1; } -.requests-menu-subitem { +.requests-list-subitem { display: flex; flex: none; box-sizing: border-box; @@ -157,12 +157,12 @@ text-overflow: ellipsis; } -.requests-menu-header { +.requests-list-header { display: flex; flex: none; } -.requests-menu-header-button { +.requests-list-header-button { display: flex; align-items: center; flex: auto; @@ -187,27 +187,27 @@ font-weight: inherit !important; } -.requests-menu-header-button::-moz-focus-inner { +.requests-list-header-button::-moz-focus-inner { border: 0; padding: 0; } -.requests-menu-header:first-child .requests-menu-header-button { +.requests-list-header:first-child .requests-list-header-button { border-width: 0; } -.requests-menu-header-button:hover { +.requests-list-header-button:hover { background-color: rgba(0, 0, 0, 0.1); } -.requests-menu-header-button > .button-text { +.requests-list-header-button > .button-text { flex: auto; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; } -.requests-menu-header-button > .button-icon { +.requests-list-header-button > .button-icon { flex: none; height: 4px; margin-inline-start: 3px; @@ -215,32 +215,32 @@ width: 7px; } -.requests-menu-header-button[data-sorted=ascending] > .button-icon { +.requests-list-header-button[data-sorted=ascending] > .button-icon { background-image: var(--sort-ascending-image); } -.requests-menu-header-button[data-sorted=descending] > .button-icon { +.requests-list-header-button[data-sorted=descending] > .button-icon { background-image: var(--sort-descending-image); } -.requests-menu-waterfall-label-wrapper { +.requests-list-waterfall-label-wrapper { display: flex; } -.requests-menu-header-button[data-sorted], -.requests-menu-header-button[data-sorted]:hover { +.requests-list-header-button[data-sorted], +.requests-list-header-button[data-sorted]:hover { background-color: var(--theme-selection-background); color: var(--theme-selection-color); } -.requests-menu-header-button[data-sorted], -.requests-menu-header[data-active] + .requests-menu-header .requests-menu-header-button { +.requests-list-header-button[data-sorted], +.requests-list-header[data-active] + .requests-list-header .requests-list-header-button { border-image: linear-gradient(var(--theme-splitter-color), var(--theme-splitter-color)) 1 1; } /* Firebug theme support for Network panel header */ -.theme-firebug .requests-menu-header { +.theme-firebug .requests-list-header { padding: 0 !important; font-weight: bold; background: linear-gradient(rgba(255, 255, 255, 0.05), @@ -248,24 +248,24 @@ #C8D2DC; } -.theme-firebug .requests-menu-header-button { +.theme-firebug .requests-list-header-button { min-height: 17px; } -.theme-firebug .requests-menu-header-button > .button-icon { +.theme-firebug .requests-list-header-button > .button-icon { height: 7px; } -.theme-firebug .requests-menu-header-button[data-sorted] { +.theme-firebug .requests-list-header-button[data-sorted] { background-color: #AAC3DC; } -:root[platform="linux"].theme-firebug .requests-menu-header-button[data-sorted] { +:root[platform="linux"].theme-firebug .requests-list-header-button[data-sorted] { background-color: #FAC8AF !important; color: inherit !important; } -.theme-firebug .requests-menu-header:hover:active { +.theme-firebug .requests-list-header:hover:active { background-image: linear-gradient(rgba(0, 0, 0, 0.1), transparent); } @@ -273,35 +273,35 @@ /* Network requests table: specific column dimensions */ -.requests-menu-status { +.requests-list-status { max-width: 6em; text-align: center; width: 10vw; } -.requests-menu-method, -.requests-menu-method-box { +.requests-list-method, +.requests-list-method-box { max-width: 7em; text-align: center; width: 10vw; } -.requests-menu-icon-and-file { +.requests-list-icon-and-file { width: 22vw; } -.requests-menu-icon { +.requests-list-icon { background: transparent; width: 15px; height: 15px; margin-inline-end: 4px; } -.requests-menu-icon { +.requests-list-icon { outline: 1px solid var(--table-splitter-color); } -.requests-menu-security-and-domain { +.requests-list-security-and-domain { width: 14vw; } @@ -336,25 +336,25 @@ background-image: url(chrome://devtools/skin/images/globe.svg); } -.requests-menu-type, -.requests-menu-size { +.requests-list-type, +.requests-list-size { max-width: 6em; width: 8vw; justify-content: center; } -.requests-menu-transferred { +.requests-list-transferred { max-width: 8em; width: 8vw; justify-content: center; } -.requests-menu-cause { +.requests-list-cause { max-width: 8em; width: 8vw; } -.requests-menu-cause-stack { +.requests-list-cause-stack { background-color: var(--theme-body-color-alt); color: var(--theme-body-background); font-size: 8px; @@ -367,19 +367,19 @@ -moz-user-select: none; } -.request-list-item.selected .requests-menu-transferred.theme-comment { +.request-list-item.selected .requests-list-transferred.theme-comment { color: var(--theme-selection-color); } /* Network requests table: status codes */ -.requests-menu-status-code { +.requests-list-status-code { margin-inline-start: 3px !important; width: 3em; margin-inline-end: -3em !important; } -.requests-menu-status-icon { +.requests-list-status-icon { background: #fff; height: 10px; width: 10px; @@ -390,29 +390,29 @@ box-sizing: border-box; } -.request-list-item.selected .requests-menu-status-icon { +.request-list-item.selected .requests-list-status-icon { filter: brightness(1.3); } -.requests-menu-status-icon:not([data-code]) { +.requests-list-status-icon:not([data-code]) { background-color: var(--theme-content-color2); } -.requests-menu-status-icon[data-code="cached"] { +.requests-list-status-icon[data-code="cached"] { border: 2px solid var(--theme-content-color2); background-color: transparent; } -.requests-menu-status-icon[data-code^="1"] { +.requests-list-status-icon[data-code^="1"] { background-color: var(--theme-highlight-blue); } -.requests-menu-status-icon[data-code^="2"] { +.requests-list-status-icon[data-code^="2"] { background-color: var(--theme-highlight-green); } /* 3xx are triangles */ -.requests-menu-status-icon[data-code^="3"] { +.requests-list-status-icon[data-code^="3"] { background-color: transparent; width: 0; height: 0; @@ -423,12 +423,12 @@ } /* 4xx and 5xx are squares - error codes */ -.requests-menu-status-icon[data-code^="4"] { +.requests-list-status-icon[data-code^="4"] { background-color: var(--theme-highlight-red); border-radius: 0; /* squares */ } -.requests-menu-status-icon[data-code^="5"] { +.requests-list-status-icon[data-code^="5"] { background-color: var(--theme-highlight-pink); border-radius: 0; transform: rotate(45deg); @@ -436,16 +436,16 @@ /* Network requests table: waterfall header */ -.requests-menu-waterfall { +.requests-list-waterfall { flex: auto; padding-inline-start: 0; } -.requests-menu-waterfall-label-wrapper:not(.requests-menu-waterfall-visible) { +.requests-list-waterfall-label-wrapper:not(.requests-list-waterfall-visible) { padding-inline-start: 16px; } -.requests-menu-timings-division { +.requests-list-timings-division { padding-top: 2px; padding-inline-start: 4px; font-size: 75%; @@ -457,34 +457,34 @@ flex: initial; } -.requests-menu-timings-division:not(:first-child) { +.requests-list-timings-division:not(:first-child) { border-inline-start: 1px dashed; } -.requests-menu-timings-division:-moz-locale-dir(ltr) { +.requests-list-timings-division:-moz-locale-dir(ltr) { transform-origin: left center; } -.requests-menu-timings-division:-moz-locale-dir(rtl) { +.requests-list-timings-division:-moz-locale-dir(rtl) { transform-origin: right center; } -.theme-dark .requests-menu-timings-division { +.theme-dark .requests-list-timings-division { border-inline-start-color: #5a6169 !important; } -.theme-light .requests-menu-timings-division { +.theme-light .requests-list-timings-division { border-inline-start-color: #585959 !important; } -.requests-menu-timings-division[data-division-scale=second], -.requests-menu-timings-division[data-division-scale=minute] { +.requests-list-timings-division[data-division-scale=second], +.requests-list-timings-division[data-division-scale=minute] { font-weight: 600; } /* Network requests table: waterfall items */ -.requests-menu-subitem.requests-menu-waterfall { +.requests-list-subitem.requests-list-waterfall { padding-inline-start: 0; padding-inline-end: 4px; /* Background created on a in js. */ @@ -494,34 +494,34 @@ background-position: left center; } -.requests-menu-subitem.requests-menu-waterfall:-moz-locale-dir(rtl) { +.requests-list-subitem.requests-list-waterfall:-moz-locale-dir(rtl) { background-position: right center; } -.requests-menu-timings { +.requests-list-timings { display: flex; flex: none; align-items: center; transform: scaleX(var(--timings-scale)); } -.requests-menu-timings:-moz-locale-dir(ltr) { +.requests-list-timings:-moz-locale-dir(ltr) { transform-origin: left center; } -.requests-menu-timings:-moz-locale-dir(rtl) { +.requests-list-timings:-moz-locale-dir(rtl) { transform-origin: right center; } -.requests-menu-timings-total:-moz-locale-dir(ltr) { +.requests-list-timings-total:-moz-locale-dir(ltr) { transform-origin: left center; } -.requests-menu-timings-total:-moz-locale-dir(rtl) { +.requests-list-timings-total:-moz-locale-dir(rtl) { transform-origin: right center; } -.requests-menu-timings-total { +.requests-list-timings-total { display: inline-block; padding-inline-start: 4px; font-size: 85%; @@ -531,37 +531,37 @@ transform: scaleX(var(--timings-rev-scale)); } -.requests-menu-timings-box { +.requests-list-timings-box { display: inline-block; height: 9px; } -.theme-firebug .requests-menu-timings-box { +.theme-firebug .requests-list-timings-box { background-image: linear-gradient(rgba(255, 255, 255, 0.3), rgba(0, 0, 0, 0.2)); height: 16px; } -.requests-menu-timings-box.blocked { +.requests-list-timings-box.blocked { background-color: var(--timing-blocked-color); } -.requests-menu-timings-box.dns { +.requests-list-timings-box.dns { background-color: var(--timing-dns-color); } -.requests-menu-timings-box.connect { +.requests-list-timings-box.connect { background-color: var(--timing-connect-color); } -.requests-menu-timings-box.send { +.requests-list-timings-box.send { background-color: var(--timing-send-color); } -.requests-menu-timings-box.wait { +.requests-list-timings-box.wait { background-color: var(--timing-wait-color); } -.requests-menu-timings-box.receive { +.requests-list-timings-box.receive { background-color: var(--timing-receive-color); } @@ -595,27 +595,27 @@ background: #EFEFEF; } -.theme-firebug .requests-menu-subitem { +.theme-firebug .requests-list-subitem { padding: 1px; } /* HTTP Status Column */ -.theme-firebug .requests-menu-subitem.requests-menu-status { +.theme-firebug .requests-list-subitem.requests-list-status { font-weight: bold; } /* Method Column */ -.theme-firebug .requests-menu-subitem.requests-menu-method-box { +.theme-firebug .requests-list-subitem.requests-list-method-box { color: rgb(128, 128, 128); } -.request-list-item.selected .requests-menu-method { +.request-list-item.selected .requests-list-method { color: var(--theme-selection-color); } /* Size Column */ -.theme-firebug .requests-menu-subitem.requests-menu-size { +.theme-firebug .requests-list-subitem.requests-list-size { justify-content: end; padding-inline-end: 4px; } @@ -706,23 +706,23 @@ width: 10em; } -.requests-menu-timings-container { +.requests-list-timings-container { display: flex; flex: 1; align-items: center; } -.requests-menu-timings-offset { +.requests-list-timings-offset { transition: width 0.2s ease-out; } -.requests-menu-timings-box { +.requests-list-timings-box { border: none; min-width: 1px; transition: width 0.2s ease-out; } -.theme-firebug .requests-menu-timings-total { +.theme-firebug .requests-list-timings-total { color: var(--theme-body-color); } @@ -805,7 +805,7 @@ /* Performance analysis buttons */ -#requests-menu-network-summary-button { +#requests-list-network-summary-button { display: flex; flex-wrap: nowrap; align-items: center; @@ -818,7 +818,7 @@ min-width: 0; } -#requests-menu-network-summary-button > .summary-info-icon { +#requests-list-network-summary-button > .summary-info-icon { background-image: url(images/profiler-stopwatch.svg); filter: var(--icon-filter); width: 16px; @@ -826,13 +826,13 @@ opacity: 0.8; } -#requests-menu-network-summary-button > .summary-info-text { +#requests-list-network-summary-button > .summary-info-text { opacity: 0.8; margin-inline-start: 0.5em; } -#requests-menu-network-summary-button:hover > .summary-info-icon, -#requests-menu-network-summary-button:hover > .summary-info-text { +#requests-list-network-summary-button:hover > .summary-info-icon, +#requests-list-network-summary-button:hover > .summary-info-text { opacity: 1; } @@ -1010,51 +1010,51 @@ @media (max-width: 700px) { #toolbar-spacer, .network-details-panel-toggle, - #requests-menu-network-summary-button > .summary-info-text { + #requests-list-network-summary-button > .summary-info-text { display: none; } - #requests-menu-toolbar { + #requests-list-toolbar { height: 22px; } - .requests-menu-header-button { + .requests-list-header-button { min-height: 22px; padding-left: 8px; } - .requests-menu-status { + .requests-list-status { max-width: none; width: 10vw; } - .requests-menu-status-code { + .requests-list-status-code { width: auto; } - .requests-menu-method, - .requests-menu-method-box { + .requests-list-method, + .requests-list-method-box { max-width: none; width: 12vw; } - .requests-menu-icon-and-file { + .requests-list-icon-and-file { width: 22vw; } - .requests-menu-security-and-domain { + .requests-list-security-and-domain { width: 16vw; } - .requests-menu-cause, - .requests-menu-type, - .requests-menu-transferred, - .requests-menu-size { + .requests-list-cause, + .requests-list-type, + .requests-list-transferred, + .requests-list-size { max-width: none; width: 10vw; } - .requests-menu-waterfall { + .requests-list-waterfall { display: none; } @@ -1071,11 +1071,11 @@ } /* Platform overrides (copied in from the old platform specific files) */ -:root[platform="win"] .requests-menu-header-button > .button-box { +:root[platform="win"] .requests-list-header-button > .button-box { padding: 0; } -:root[platform="win"] .requests-menu-timings-division { +:root[platform="win"] .requests-list-timings-division { padding-top: 1px; font-size: 90%; } @@ -1090,7 +1090,7 @@ /* Responsive sidebar */ @media (max-width: 700px) { - :root[platform="linux"] .requests-menu-header-button { + :root[platform="linux"] .requests-list-header-button { font-size: 85%; } } @@ -1233,7 +1233,7 @@ margin-inline-end: 6px; } -.headers-summary .requests-menu-status-icon { +.headers-summary .requests-list-status-icon { min-width: 10px; } From ae29d01f9adb4231cd6961f3bcbd14dcd1aee98e Mon Sep 17 00:00:00 2001 From: Fred Lin Date: Mon, 13 Feb 2017 14:29:39 +0800 Subject: [PATCH 44/48] Bug 1316291 - PART 2:remove request-list elements with fixed ID;r=Honza MozReview-Commit-ID: 2myRfMX3XQB --HG-- extra : rebase_source : 9aa85177752492a0e6d83fe911f52bbd1619ac07 --- .../netmonitor/components/request-list-empty.js | 13 +++++-------- .../netmonitor/components/request-list-header.js | 4 ++-- .../netmonitor/test/browser_net_reload-button.js | 2 +- .../netmonitor/test/browser_net_reload-markers.js | 3 +-- .../netmonitor/test/browser_net_simple-request.js | 8 ++++---- devtools/client/themes/netmonitor.css | 10 +++++----- 6 files changed, 18 insertions(+), 22 deletions(-) diff --git a/devtools/client/netmonitor/components/request-list-empty.js b/devtools/client/netmonitor/components/request-list-empty.js index 21f2e234623c..8ddd1f1916bc 100644 --- a/devtools/client/netmonitor/components/request-list-empty.js +++ b/devtools/client/netmonitor/components/request-list-empty.js @@ -31,15 +31,13 @@ const RequestListEmptyNotice = createClass({ render() { return div( { - id: "requests-list-empty-notice", - className: "request-list-empty-notice", + className: "requests-list-empty-notice", }, - div({ id: "notice-reload-message" }, + div({ className: "notice-reload-message" }, span(null, L10N.getStr("netmonitor.reloadNotice1")), button( { - id: "requests-list-reload-notice-button", - className: "devtools-button", + className: "devtools-toolbarbutton requests-list-reload-notice-button", "data-standalone": true, onClick: this.props.onReloadClick, }, @@ -47,12 +45,11 @@ const RequestListEmptyNotice = createClass({ ), span(null, L10N.getStr("netmonitor.reloadNotice3")) ), - div({ id: "notice-perf-message" }, + div({ className: "notice-perf-message" }, span(null, L10N.getStr("netmonitor.perfNotice1")), button({ - id: "requests-list-perf-notice-button", title: L10N.getStr("netmonitor.perfNotice3"), - className: "devtools-button", + className: "devtools-button requests-list-perf-notice-button", "data-standalone": true, onClick: this.props.onPerfClick, }), diff --git a/devtools/client/netmonitor/components/request-list-header.js b/devtools/client/netmonitor/components/request-list-header.js index 8495af390458..24362dbb129d 100644 --- a/devtools/client/netmonitor/components/request-list-header.js +++ b/devtools/client/netmonitor/components/request-list-header.js @@ -78,8 +78,8 @@ const RequestListHeader = createClass({ const { sort, scale, waterfallWidth, onHeaderClick } = this.props; return div( - { id: "requests-list-toolbar", className: "devtools-toolbar" }, - div({ id: "toolbar-labels" }, + { className: "devtools-toolbar requests-list-toolbar" }, + div({ className: "toolbar-labels" }, HEADERS.map(header => { const name = header.name; const boxName = header.boxName || name; diff --git a/devtools/client/netmonitor/test/browser_net_reload-button.js b/devtools/client/netmonitor/test/browser_net_reload-button.js index 3e4534999990..b8f910f113ff 100644 --- a/devtools/client/netmonitor/test/browser_net_reload-button.js +++ b/devtools/client/netmonitor/test/browser_net_reload-button.js @@ -15,7 +15,7 @@ add_task(function* () { let wait = waitForNetworkEvents(monitor, 1); EventUtils.sendMouseEvent({ type: "click" }, - document.querySelector("#requests-list-reload-notice-button")); + document.querySelector(".requests-list-reload-notice-button")); yield wait; is(document.querySelectorAll(".request-list-item").length, 1, diff --git a/devtools/client/netmonitor/test/browser_net_reload-markers.js b/devtools/client/netmonitor/test/browser_net_reload-markers.js index 23d5f1559cb4..1a7953b9cb01 100644 --- a/devtools/client/netmonitor/test/browser_net_reload-markers.js +++ b/devtools/client/netmonitor/test/browser_net_reload-markers.js @@ -12,8 +12,7 @@ add_task(function* () { info("Starting test... "); let { document, windowRequire } = monitor.panelWin; - let { EVENTS } = windowRequire("devtools/client/netmonitor/constants"); - let button = document.querySelector("#requests-list-reload-notice-button"); + let button = document.querySelector(".requests-list-reload-notice-button"); button.click(); let markers = []; diff --git a/devtools/client/netmonitor/test/browser_net_simple-request.js b/devtools/client/netmonitor/test/browser_net_simple-request.js index 840999f1ef13..b43a9e9d7495 100644 --- a/devtools/client/netmonitor/test/browser_net_simple-request.js +++ b/devtools/client/netmonitor/test/browser_net_simple-request.js @@ -29,7 +29,7 @@ add_task(function* () { is(document.querySelector(".network-details-panel-toggle").hasAttribute("disabled"), true, "The pane toggle button should be disabled when the frontend is opened."); - ok(document.querySelector("#requests-list-empty-notice"), + ok(document.querySelector(".requests-list-empty-notice"), "An empty notice should be displayed when the frontend is opened."); is(gStore.getState().requests.requests.size, 0, "The requests menu should be empty when the frontend is opened."); @@ -41,7 +41,7 @@ add_task(function* () { is(document.querySelector(".network-details-panel-toggle").hasAttribute("disabled"), false, "The pane toggle button should be enabled after the first request."); - ok(!document.querySelector("#requests-list-empty-notice"), + ok(!document.querySelector(".requests-list-empty-notice"), "The empty notice should be hidden after the first request."); is(gStore.getState().requests.requests.size, 1, "The requests menu should not be empty after the first request."); @@ -53,7 +53,7 @@ add_task(function* () { is(document.querySelector(".network-details-panel-toggle").hasAttribute("disabled"), false, "The pane toggle button should be still be enabled after a reload."); - ok(!document.querySelector("#requests-list-empty-notice"), + ok(!document.querySelector(".requests-list-empty-notice"), "The empty notice should be still hidden after a reload."); is(gStore.getState().requests.requests.size, 1, "The requests menu should not be empty after a reload."); @@ -65,7 +65,7 @@ add_task(function* () { is(document.querySelector(".network-details-panel-toggle").hasAttribute("disabled"), true, "The pane toggle button should be disabled when after clear."); - ok(document.querySelector("#requests-list-empty-notice"), + ok(document.querySelector(".requests-list-empty-notice"), "An empty notice should be displayed again after clear."); is(gStore.getState().requests.requests.size, 0, "The requests menu should be empty after clear."); diff --git a/devtools/client/themes/netmonitor.css b/devtools/client/themes/netmonitor.css index 5a0e295674c5..d1efe5823290 100644 --- a/devtools/client/themes/netmonitor.css +++ b/devtools/client/themes/netmonitor.css @@ -11,7 +11,7 @@ box-sizing: border-box; } -#toolbar-labels { +.toolbar-labels { overflow: hidden; display: flex; flex: auto; @@ -96,22 +96,22 @@ font-size: 120%; } -#notice-perf-message { +.notice-perf-message { margin-top: 2px; } -#requests-list-perf-notice-button { +.requests-list-perf-notice-button { min-width: 30px; min-height: 26px; margin: 0 5px; vertical-align: middle; } -#requests-list-perf-notice-button::before { +.requests-list-perf-notice-button::before { background-image: url(images/profiler-stopwatch.svg); } -#requests-list-reload-notice-button { +.requests-list-reload-notice-button { font-size: inherit; min-height: 26px; margin: 0 5px; From b06f37f079798fb8b30476419dc5dfa8578cb563 Mon Sep 17 00:00:00 2001 From: Fred Lin Date: Mon, 13 Feb 2017 13:19:55 +0800 Subject: [PATCH 45/48] Bug 1316291 - PART 3:Remove toolbar elements with fixed IDs;r=Honza MozReview-Commit-ID: 6vQaGZdBd0d --HG-- extra : rebase_source : 5db0a73a1b497f9823aa0ae4b14f699171b12c06 --- .../client/netmonitor/components/toolbar.js | 9 +-- .../netmonitor/test/browser_net_clear.js | 2 +- .../netmonitor/test/browser_net_filter-01.js | 64 +++++++++---------- .../netmonitor/test/browser_net_filter-02.js | 4 +- .../netmonitor/test/browser_net_filter-03.js | 2 +- .../test/browser_net_footer-summary.js | 6 +- .../test/browser_net_statistics-02.js | 10 +-- .../test/components/filter-buttons.test.js | 4 +- devtools/client/netmonitor/test/head.js | 2 +- devtools/client/themes/netmonitor.css | 20 +++--- 10 files changed, 60 insertions(+), 63 deletions(-) diff --git a/devtools/client/netmonitor/components/toolbar.js b/devtools/client/netmonitor/components/toolbar.js index a2a19f6eaa28..71111b8ee369 100644 --- a/devtools/client/netmonitor/components/toolbar.js +++ b/devtools/client/netmonitor/components/toolbar.js @@ -96,12 +96,11 @@ const Toolbar = createClass({ .replace("#4", getFormattedTime(millis)); let buttons = requestFilterTypes.map(([type, checked]) => { - let classList = ["devtools-button"]; + let classList = ["devtools-button", `requests-list-filter-${type}-button`]; checked && classList.push("checked"); return ( button({ - id: `requests-list-filter-${type}-button`, className: classList.join(" "), key: type, onClick: this.toggleRequestFilterType, @@ -118,8 +117,7 @@ const Toolbar = createClass({ span({ className: "devtools-toolbar devtools-toolbar-container" }, span({ className: "devtools-toolbar-group" }, button({ - id: "requests-list-clear-button", - className: "devtools-button devtools-clear-icon", + className: "devtools-button devtools-clear-icon requests-list-clear-button", title: TOOLBAR_CLEAR, onClick: clearRequests, }), @@ -127,8 +125,7 @@ const Toolbar = createClass({ ), span({ className: "devtools-toolbar-group" }, button({ - id: "requests-list-network-summary-button", - className: "devtools-button", + className: "devtools-button requests-list-network-summary-button", title: count ? text : L10N.getStr("netmonitor.toolbar.perf"), onClick: openStatistics, }, diff --git a/devtools/client/netmonitor/test/browser_net_clear.js b/devtools/client/netmonitor/test/browser_net_clear.js index caf77a3505a9..15a38005928b 100644 --- a/devtools/client/netmonitor/test/browser_net_clear.js +++ b/devtools/client/netmonitor/test/browser_net_clear.js @@ -16,7 +16,7 @@ add_task(function* () { let { EVENTS } = windowRequire("devtools/client/netmonitor/constants"); let detailsPane = document.querySelector("#details-pane"); let detailsPanelToggleButton = document.querySelector(".network-details-panel-toggle"); - let clearButton = document.querySelector("#requests-list-clear-button"); + let clearButton = document.querySelector(".requests-list-clear-button"); gStore.dispatch(Actions.batchEnable(false)); diff --git a/devtools/client/netmonitor/test/browser_net_filter-01.js b/devtools/client/netmonitor/test/browser_net_filter-01.js index 7f92f5c13b5c..53e77694d017 100644 --- a/devtools/client/netmonitor/test/browser_net_filter-01.js +++ b/devtools/client/netmonitor/test/browser_net_filter-01.js @@ -166,94 +166,94 @@ add_task(function* () { testContents([1, 1, 1, 1, 1, 1, 1, 1, 1]); EventUtils.sendMouseEvent({ type: "click" }, - document.querySelector("#requests-list-filter-html-button")); + document.querySelector(".requests-list-filter-html-button")); testFilterButtons(monitor, "html"); testContents([1, 0, 0, 0, 0, 0, 0, 0, 0]); // Reset filters EventUtils.sendMouseEvent({ type: "click" }, - document.querySelector("#requests-list-filter-all-button")); + document.querySelector(".requests-list-filter-all-button")); EventUtils.sendMouseEvent({ type: "click" }, - document.querySelector("#requests-list-filter-css-button")); + document.querySelector(".requests-list-filter-css-button")); testFilterButtons(monitor, "css"); testContents([0, 1, 0, 0, 0, 0, 0, 0, 0]); EventUtils.sendMouseEvent({ type: "click" }, - document.querySelector("#requests-list-filter-all-button")); + document.querySelector(".requests-list-filter-all-button")); EventUtils.sendMouseEvent({ type: "click" }, - document.querySelector("#requests-list-filter-js-button")); + document.querySelector(".requests-list-filter-js-button")); testFilterButtons(monitor, "js"); testContents([0, 0, 1, 0, 0, 0, 0, 0, 0]); EventUtils.sendMouseEvent({ type: "click" }, - document.querySelector("#requests-list-filter-all-button")); + document.querySelector(".requests-list-filter-all-button")); EventUtils.sendMouseEvent({ type: "click" }, - document.querySelector("#requests-list-filter-xhr-button")); + document.querySelector(".requests-list-filter-xhr-button")); testFilterButtons(monitor, "xhr"); testContents([1, 1, 1, 1, 1, 1, 1, 1, 0]); EventUtils.sendMouseEvent({ type: "click" }, - document.querySelector("#requests-list-filter-all-button")); + document.querySelector(".requests-list-filter-all-button")); EventUtils.sendMouseEvent({ type: "click" }, - document.querySelector("#requests-list-filter-fonts-button")); + document.querySelector(".requests-list-filter-fonts-button")); testFilterButtons(monitor, "fonts"); testContents([0, 0, 0, 1, 0, 0, 0, 0, 0]); EventUtils.sendMouseEvent({ type: "click" }, - document.querySelector("#requests-list-filter-all-button")); + document.querySelector(".requests-list-filter-all-button")); EventUtils.sendMouseEvent({ type: "click" }, - document.querySelector("#requests-list-filter-images-button")); + document.querySelector(".requests-list-filter-images-button")); testFilterButtons(monitor, "images"); testContents([0, 0, 0, 0, 1, 0, 0, 0, 0]); EventUtils.sendMouseEvent({ type: "click" }, - document.querySelector("#requests-list-filter-all-button")); + document.querySelector(".requests-list-filter-all-button")); EventUtils.sendMouseEvent({ type: "click" }, - document.querySelector("#requests-list-filter-media-button")); + document.querySelector(".requests-list-filter-media-button")); testFilterButtons(monitor, "media"); testContents([0, 0, 0, 0, 0, 1, 1, 0, 0]); EventUtils.sendMouseEvent({ type: "click" }, - document.querySelector("#requests-list-filter-all-button")); + document.querySelector(".requests-list-filter-all-button")); EventUtils.sendMouseEvent({ type: "click" }, - document.querySelector("#requests-list-filter-flash-button")); + document.querySelector(".requests-list-filter-flash-button")); testFilterButtons(monitor, "flash"); testContents([0, 0, 0, 0, 0, 0, 0, 1, 0]); EventUtils.sendMouseEvent({ type: "click" }, - document.querySelector("#requests-list-filter-all-button")); + document.querySelector(".requests-list-filter-all-button")); EventUtils.sendMouseEvent({ type: "click" }, - document.querySelector("#requests-list-filter-ws-button")); + document.querySelector(".requests-list-filter-ws-button")); testFilterButtons(monitor, "ws"); testContents([0, 0, 0, 0, 0, 0, 0, 0, 1]); EventUtils.sendMouseEvent({ type: "click" }, - document.querySelector("#requests-list-filter-all-button")); + document.querySelector(".requests-list-filter-all-button")); testFilterButtons(monitor, "all"); testContents([1, 1, 1, 1, 1, 1, 1, 1, 1]); // Text in filter box that matches nothing should hide all. EventUtils.sendMouseEvent({ type: "click" }, - document.querySelector("#requests-list-filter-all-button")); + document.querySelector(".requests-list-filter-all-button")); setFreetextFilter("foobar"); testContents([0, 0, 0, 0, 0, 0, 0, 0, 0]); // Text in filter box that matches should filter out everything else. EventUtils.sendMouseEvent({ type: "click" }, - document.querySelector("#requests-list-filter-all-button")); + document.querySelector(".requests-list-filter-all-button")); setFreetextFilter("sample"); testContents([1, 1, 1, 0, 0, 0, 0, 0, 0]); // Text in filter box that matches should filter out everything else. EventUtils.sendMouseEvent({ type: "click" }, - document.querySelector("#requests-list-filter-all-button")); + document.querySelector(".requests-list-filter-all-button")); setFreetextFilter("SAMPLE"); testContents([1, 1, 1, 0, 0, 0, 0, 0, 0]); // Test negative filtering (only show unmatched items) EventUtils.sendMouseEvent({ type: "click" }, - document.querySelector("#requests-list-filter-all-button")); + document.querySelector(".requests-list-filter-all-button")); setFreetextFilter("-sample"); testContents([0, 0, 0, 1, 1, 1, 1, 1, 1]); @@ -262,9 +262,9 @@ add_task(function* () { // Enable filtering for html and css; should show request of both type. setFreetextFilter(""); EventUtils.sendMouseEvent({ type: "click" }, - document.querySelector("#requests-list-filter-html-button")); + document.querySelector(".requests-list-filter-html-button")); EventUtils.sendMouseEvent({ type: "click" }, - document.querySelector("#requests-list-filter-css-button")); + document.querySelector(".requests-list-filter-css-button")); testFilterButtonsCustom(monitor, [0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0]); testContents([1, 1, 0, 0, 0, 0, 0, 0, 0]); @@ -274,35 +274,35 @@ add_task(function* () { testContents([1, 1, 0, 0, 0, 0, 0, 0, 0]); EventUtils.sendMouseEvent({ type: "click" }, - document.querySelector("#requests-list-filter-flash-button")); + document.querySelector(".requests-list-filter-flash-button")); setFreetextFilter(""); testFilterButtonsCustom(monitor, [0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0]); testContents([1, 1, 0, 0, 0, 0, 0, 1, 0]); // Disable some filters. Only one left active. EventUtils.sendMouseEvent({ type: "click" }, - document.querySelector("#requests-list-filter-css-button")); + document.querySelector(".requests-list-filter-css-button")); EventUtils.sendMouseEvent({ type: "click" }, - document.querySelector("#requests-list-filter-flash-button")); + document.querySelector(".requests-list-filter-flash-button")); testFilterButtons(monitor, "html"); testContents([1, 0, 0, 0, 0, 0, 0, 0, 0]); // Disable last active filter. Should toggle to all. EventUtils.sendMouseEvent({ type: "click" }, - document.querySelector("#requests-list-filter-html-button")); + document.querySelector(".requests-list-filter-html-button")); testFilterButtons(monitor, "all"); testContents([1, 1, 1, 1, 1, 1, 1, 1, 1]); // Enable few filters and click on all. Only "all" should be checked. EventUtils.sendMouseEvent({ type: "click" }, - document.querySelector("#requests-list-filter-html-button")); + document.querySelector(".requests-list-filter-html-button")); EventUtils.sendMouseEvent({ type: "click" }, - document.querySelector("#requests-list-filter-css-button")); + document.querySelector(".requests-list-filter-css-button")); EventUtils.sendMouseEvent({ type: "click" }, - document.querySelector("#requests-list-filter-ws-button")); + document.querySelector(".requests-list-filter-ws-button")); testFilterButtonsCustom(monitor, [0, 1, 1, 0, 0, 0, 0, 0, 0, 1]); EventUtils.sendMouseEvent({ type: "click" }, - document.querySelector("#requests-list-filter-all-button")); + document.querySelector(".requests-list-filter-all-button")); testFilterButtons(monitor, "all"); testContents([1, 1, 1, 1, 1, 1, 1, 1, 1]); diff --git a/devtools/client/netmonitor/test/browser_net_filter-02.js b/devtools/client/netmonitor/test/browser_net_filter-02.js index bac648960c37..39e466960964 100644 --- a/devtools/client/netmonitor/test/browser_net_filter-02.js +++ b/devtools/client/netmonitor/test/browser_net_filter-02.js @@ -166,7 +166,7 @@ add_task(function* () { info("Testing html filtering."); EventUtils.sendMouseEvent({ type: "click" }, - document.querySelector("#requests-list-filter-html-button")); + document.querySelector(".requests-list-filter-html-button")); testFilterButtons(monitor, "html"); testContents([1, 0, 0, 0, 0, 0, 0, 0, 0]); @@ -191,7 +191,7 @@ add_task(function* () { info("Resetting filters."); EventUtils.sendMouseEvent({ type: "click" }, - document.querySelector("#requests-list-filter-all-button")); + document.querySelector(".requests-list-filter-all-button")); testFilterButtons(monitor, "all"); testContents([1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]); diff --git a/devtools/client/netmonitor/test/browser_net_filter-03.js b/devtools/client/netmonitor/test/browser_net_filter-03.js index 9b1f55209231..e445afb9d4a1 100644 --- a/devtools/client/netmonitor/test/browser_net_filter-03.js +++ b/devtools/client/netmonitor/test/browser_net_filter-03.js @@ -70,7 +70,7 @@ add_task(function* () { info("Testing html filtering."); EventUtils.sendMouseEvent({ type: "click" }, - document.querySelector("#requests-list-filter-html-button")); + document.querySelector(".requests-list-filter-html-button")); testFilterButtons(monitor, "html"); testContents([6, 4, 5, 0, 1, 2, 3], 1, 6); diff --git a/devtools/client/netmonitor/test/browser_net_footer-summary.js b/devtools/client/netmonitor/test/browser_net_footer-summary.js index fa3007f71825..852c2f0a3392 100644 --- a/devtools/client/netmonitor/test/browser_net_footer-summary.js +++ b/devtools/client/netmonitor/test/browser_net_footer-summary.js @@ -40,7 +40,7 @@ add_task(function* () { let buttons = ["html", "css", "js", "xhr", "fonts", "images", "media", "flash"]; for (let button of buttons) { - let buttonEl = document.querySelector(`#requests-list-filter-${button}-button`); + let buttonEl = document.querySelector(`.requests-list-filter-${button}-button`); EventUtils.sendMouseEvent({ type: "click" }, buttonEl); testStatus(); } @@ -49,8 +49,8 @@ add_task(function* () { yield teardown(monitor); function testStatus() { - let value = document.querySelector("#requests-list-network-summary-button").textContent; - info("Current summary: " + value); + let value = document.querySelector(".requests-list-network-summary-button").textContent; + info("Current summary: " + value); let state = gStore.getState(); let totalRequestsCount = state.requests.requests.size; diff --git a/devtools/client/netmonitor/test/browser_net_statistics-02.js b/devtools/client/netmonitor/test/browser_net_statistics-02.js index 9fcbf985c2e4..65d1e8b06a74 100644 --- a/devtools/client/netmonitor/test/browser_net_statistics-02.js +++ b/devtools/client/netmonitor/test/browser_net_statistics-02.js @@ -17,15 +17,15 @@ add_task(function* () { let Actions = windowRequire("devtools/client/netmonitor/actions/index"); EventUtils.sendMouseEvent({ type: "click" }, - document.querySelector("#requests-list-filter-html-button")); + document.querySelector(".requests-list-filter-html-button")); EventUtils.sendMouseEvent({ type: "click" }, - document.querySelector("#requests-list-filter-css-button")); + document.querySelector(".requests-list-filter-css-button")); EventUtils.sendMouseEvent({ type: "click" }, - document.querySelector("#requests-list-filter-js-button")); + document.querySelector(".requests-list-filter-js-button")); EventUtils.sendMouseEvent({ type: "click" }, - document.querySelector("#requests-list-filter-ws-button")); + document.querySelector(".requests-list-filter-ws-button")); EventUtils.sendMouseEvent({ type: "click" }, - document.querySelector("#requests-list-filter-other-button")); + document.querySelector(".requests-list-filter-other-button")); testFilterButtonsCustom(monitor, [0, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1]); info("The correct filtering predicates are used before entering perf. analysis mode."); diff --git a/devtools/client/netmonitor/test/components/filter-buttons.test.js b/devtools/client/netmonitor/test/components/filter-buttons.test.js index 3a9cc603273c..65081ffeb75c 100644 --- a/devtools/client/netmonitor/test/components/filter-buttons.test.js +++ b/devtools/client/netmonitor/test/components/filter-buttons.test.js @@ -94,8 +94,8 @@ function asExpected(wrapper, expectTypes, description) { let className = expectTypes[type] ? "devtools-button checked" : "devtools-button"; it(`'${type}' button is ${checked} ${description}`, () => { - expect(wrapper.find(`#requests-list-filter-${type}-button`).html()) - .toBe(``); }); } diff --git a/devtools/client/netmonitor/test/head.js b/devtools/client/netmonitor/test/head.js index e02498a6ef89..13585517ca28 100644 --- a/devtools/client/netmonitor/test/head.js +++ b/devtools/client/netmonitor/test/head.js @@ -385,7 +385,7 @@ function waitFor(subject, eventName) { */ function testFilterButtons(monitor, filterType) { let doc = monitor.panelWin.document; - let target = doc.querySelector("#requests-list-filter-" + filterType + "-button"); + let target = doc.querySelector(".requests-list-filter-" + filterType + "-button"); ok(target, `Filter button '${filterType}' was found`); let buttons = [...doc.querySelectorAll("#requests-list-filter-buttons button")]; ok(buttons.length > 0, "More than zero filter buttons were found"); diff --git a/devtools/client/themes/netmonitor.css b/devtools/client/themes/netmonitor.css index d1efe5823290..afd9b8fe8773 100644 --- a/devtools/client/themes/netmonitor.css +++ b/devtools/client/themes/netmonitor.css @@ -119,17 +119,17 @@ /* Network requests table */ -#requests-list-toolbar { +.requests-list-toolbar { display: flex; padding: 0; } -#requests-list-filter-buttons { +.requests-list-filter-buttons { display: flex; flex-wrap: nowrap; } -.theme-firebug #requests-list-toolbar { +.theme-firebug .requests-list-toolbar { height: 19px !important; } @@ -805,7 +805,7 @@ /* Performance analysis buttons */ -#requests-list-network-summary-button { +.requests-list-network-summary-button { display: flex; flex-wrap: nowrap; align-items: center; @@ -818,7 +818,7 @@ min-width: 0; } -#requests-list-network-summary-button > .summary-info-icon { +.requests-list-network-summary-button > .summary-info-icon { background-image: url(images/profiler-stopwatch.svg); filter: var(--icon-filter); width: 16px; @@ -826,13 +826,13 @@ opacity: 0.8; } -#requests-list-network-summary-button > .summary-info-text { +.requests-list-network-summary-button > .summary-info-text { opacity: 0.8; margin-inline-start: 0.5em; } -#requests-list-network-summary-button:hover > .summary-info-icon, -#requests-list-network-summary-button:hover > .summary-info-text { +.requests-list-network-summary-button:hover > .summary-info-icon, +.requests-list-network-summary-button:hover > .summary-info-text { opacity: 1; } @@ -1010,11 +1010,11 @@ @media (max-width: 700px) { #toolbar-spacer, .network-details-panel-toggle, - #requests-list-network-summary-button > .summary-info-text { + .requests-list-network-summary-button > .summary-info-text { display: none; } - #requests-list-toolbar { + .requests-list-toolbar { height: 22px; } From 688b3f7d84e66f963028314c6b9cae54126b402a Mon Sep 17 00:00:00 2001 From: Alessio Placitelli Date: Wed, 15 Feb 2017 18:54:44 +0100 Subject: [PATCH 46/48] Bug 1329099 - Document CSS Use Counters mechanism. r=froydnj,gfritzsche MozReview-Commit-ID: GpaqYZP76Oc --HG-- extra : rebase_source : c4f9d7eea326a01906c17c111d51b0cc10cf9836 --- .../telemetry/docs/collection/index.rst | 1 + .../docs/collection/use-counters.rst | 74 +++++++++++++++++++ 2 files changed, 75 insertions(+) create mode 100644 toolkit/components/telemetry/docs/collection/use-counters.rst diff --git a/toolkit/components/telemetry/docs/collection/index.rst b/toolkit/components/telemetry/docs/collection/index.rst index 191872a9e5fc..9d85f5e17513 100644 --- a/toolkit/components/telemetry/docs/collection/index.rst +++ b/toolkit/components/telemetry/docs/collection/index.rst @@ -20,6 +20,7 @@ The current data collection possibilities include: * :doc:`measuring elapsed time ` * :doc:`custom pings ` * :doc:`stack capture ` allow recording application call stacks +* :doc:`Use counters ` measure the usage of web platform features .. toctree:: :maxdepth: 2 diff --git a/toolkit/components/telemetry/docs/collection/use-counters.rst b/toolkit/components/telemetry/docs/collection/use-counters.rst new file mode 100644 index 000000000000..14861a2f034d --- /dev/null +++ b/toolkit/components/telemetry/docs/collection/use-counters.rst @@ -0,0 +1,74 @@ +============ +Use Counters +============ + +Use counters are used to report Telemetry statistics on whether individual documents +use a given WebIDL method or attribute (getters and setters are reported separately), CSS +property and deprecated DOM operations. + +The API +======= +The process to add a new use counter is different depending on the type feature that needs +to be measured. In general, for each defined use counter, two separate boolean histograms are generated: + +- one describes the use of the tracked feature for individual documents and has the ``_DOCUMENT`` suffix; +- the other describes the use of the same thing for top-level pages (basically what we think of as a *web page*) and has the ``_PAGE`` suffix. + +Using two histograms is particularly suited to measure how many sites would be affected by +removing the tracked feature. + +Example scenarios: + +- Site *X* triggers use counter *Y*. We report "used" (true) in both the ``_DOCUMENT`` and ``_PAGE`` histograms. +- Site *X* does not trigger use counter *Y*. We report "unused" (false) in both the ``_DOCUMENT`` and ``_PAGE`` histograms. +- Site *X* has an iframe for site *W*. Site *W* triggers use counter *Y*, but site *X* does not. We report one "used" and one "unused" in the individual ``_DOCUMENT`` histogram and one "used" in the top-level ``_PAGE`` histogram. + +Deprecated DOM operations +------------------------- +Use counters for deprecated DOM operations are declared in the `nsDeprecatedOperationList.h `_ file. The counters are +registered through the ``DEPRECATED_OPERATION(DeprecationReference)`` macro. The provided +parameter must have the same value of the deprecation note added to the *IDL* file. + +See this `changeset `_ for a sample +deprecated operation. + +The UseCounters registry +------------------------ +Use counters for WebIDL methods/attributes and CSS properties are registered in the `UseCounters.conf `_ file. The format of this file is very strict. Each line can be: + +1. a blank line +2. a comment, which is a line that begins with ``//`` +3. one of three possible use counter declarations: + + * ``method .`` + * ``attribute .`` + * ``property `` + +CSS properties +~~~~~~~~~~~~~~ +The CSS property method name should be identical to the ``method`` argument of ``CSS_PROP()`` and related macros. The only differences are that all hyphens are removed and CamelCase naming is used. See `nsCSSPropList.h `_ for further details. + +WebIDL methods and attributes +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Additionally to having a new entry added to the `UseCounters.conf `_ file, WebIDL methods and attributes must have a ``[UseCounter]`` extended attribute in the Web IDL file in order for the counters to be incremented. + +Both additions are required because generating things from bindings codegen and ensuring all the dependencies are correct would have been rather difficult, and annotating the WebIDL files does nothing for identifying CSS property usage, which we would also like to track. + +The processor script +==================== +The definition files are processed twice: + +- once to generate two C++ headers files, included by the web platform components (e.g. DOM) that own the features to be tracked; +- the other time by the Telemetry component, to generate the histogram definitions that make the collection system work. + +.. note:: + + The histograms that are generated out of use counters are set to *never* expire and are *opt-in*. + +gen-usecounters.py +------------------ +This script is called by the build system to generate: + +- the ``PropertyUseCounterMap.inc`` C++ header for the CSS properties; +- the ``UseCounterList.h`` header for the WebIDL, out of the definition files. + From eb16544eaf49954af2eff45b263140c2fce10ec2 Mon Sep 17 00:00:00 2001 From: Iris Hsiao Date: Wed, 22 Feb 2017 17:31:04 +0800 Subject: [PATCH 47/48] Backed out changeset 3cf38f4d7395 (bug 1322317) for stylo test failure --- layout/style/nsStyleContext.h | 3 --- 1 file changed, 3 deletions(-) diff --git a/layout/style/nsStyleContext.h b/layout/style/nsStyleContext.h index 9b7f9ce0d4dc..94dc4ba14dea 100644 --- a/layout/style/nsStyleContext.h +++ b/layout/style/nsStyleContext.h @@ -692,9 +692,6 @@ private: newData = mSource.AsGeckoRuleNode()-> \ GetStyle##name_(this); \ } else { \ - if (!aComputeData) { \ - return nullptr; \ - } \ newData = \ Servo_GetStyle##name_(mSource.AsServoComputedValues()); \ /* perform any remaining main thread work on the struct */ \ From 7a962a70f2014871d1673585278c56662c993f0e Mon Sep 17 00:00:00 2001 From: Iris Hsiao Date: Wed, 22 Feb 2017 17:40:13 +0800 Subject: [PATCH 48/48] Backed out changeset 2d21596af124 (bug 1337229) for developer's request --- dom/animation/KeyframeEffectReadOnly.cpp | 1 + dom/animation/KeyframeEffectReadOnly.h | 2 +- layout/style/ServoBindingList.h | 3 --- layout/style/StyleAnimationValue.h | 6 +++++- layout/style/StyleAnimationValueInlines.h | 10 ---------- servo/ports/geckolib/glue.rs | 10 ---------- 6 files changed, 7 insertions(+), 25 deletions(-) diff --git a/dom/animation/KeyframeEffectReadOnly.cpp b/dom/animation/KeyframeEffectReadOnly.cpp index ce310434fafa..4b8dd1ff5510 100644 --- a/dom/animation/KeyframeEffectReadOnly.cpp +++ b/dom/animation/KeyframeEffectReadOnly.cpp @@ -18,6 +18,7 @@ #include "mozilla/LookAndFeel.h" // For LookAndFeel::GetInt #include "mozilla/KeyframeUtils.h" #include "mozilla/ServoBindings.h" +#include "mozilla/StyleAnimationValueInlines.h" #include "Layers.h" // For Layer #include "nsComputedDOMStyle.h" // nsComputedDOMStyle::GetStyleContextForElement #include "nsContentUtils.h" // nsContentUtils::ReportToConsole diff --git a/dom/animation/KeyframeEffectReadOnly.h b/dom/animation/KeyframeEffectReadOnly.h index 134c4f94de2c..bbcbddb0e521 100644 --- a/dom/animation/KeyframeEffectReadOnly.h +++ b/dom/animation/KeyframeEffectReadOnly.h @@ -23,7 +23,7 @@ #include "mozilla/KeyframeEffectParams.h" // RawServoDeclarationBlock and associated RefPtrTraits #include "mozilla/ServoBindingTypes.h" -#include "mozilla/StyleAnimationValueInlines.h" +#include "mozilla/StyleAnimationValue.h" #include "mozilla/dom/AnimationEffectReadOnly.h" #include "mozilla/dom/BindingDeclarations.h" #include "mozilla/dom/Element.h" diff --git a/layout/style/ServoBindingList.h b/layout/style/ServoBindingList.h index e82920e9d8b1..b6d4791a5b80 100644 --- a/layout/style/ServoBindingList.h +++ b/layout/style/ServoBindingList.h @@ -130,9 +130,6 @@ SERVO_BINDING_FUNC(Servo_AnimationValue_GetOpacity, float, SERVO_BINDING_FUNC(Servo_AnimationValue_GetTransform, void, RawServoAnimationValueBorrowed value, RefPtr* list) -SERVO_BINDING_FUNC(Servo_AnimationValue_DeepEqual, bool, - RawServoAnimationValueBorrowed, - RawServoAnimationValueBorrowed) // Style attribute SERVO_BINDING_FUNC(Servo_ParseStyleAttribute, RawServoDeclarationBlockStrong, diff --git a/layout/style/StyleAnimationValue.h b/layout/style/StyleAnimationValue.h index d51d4698387d..b08bb21a820b 100644 --- a/layout/style/StyleAnimationValue.h +++ b/layout/style/StyleAnimationValue.h @@ -576,7 +576,11 @@ struct AnimationValue StyleAnimationValue mGecko; RefPtr mServo; - inline bool operator==(const AnimationValue& aOther) const; + bool operator==(const AnimationValue& aOther) const + { + // FIXME: Bug 1337229: add a deep == impl for RawServoAnimationValue. + return mGecko == aOther.mGecko && mServo == aOther.mServo; + } bool IsNull() const { return mGecko.IsNull() && !mServo; } diff --git a/layout/style/StyleAnimationValueInlines.h b/layout/style/StyleAnimationValueInlines.h index 6babcdbe2eaf..0f6b2deb9ec8 100644 --- a/layout/style/StyleAnimationValueInlines.h +++ b/layout/style/StyleAnimationValueInlines.h @@ -11,16 +11,6 @@ namespace mozilla { -bool -AnimationValue::operator==(const AnimationValue& aOther) const -{ - // mGecko and mServo are mutual exclusive, one of them must be null - if (mServo) { - return Servo_AnimationValue_DeepEqual(mServo, aOther.mServo); - } - return mGecko == aOther.mGecko; -} - float AnimationValue::GetOpacity() const { diff --git a/servo/ports/geckolib/glue.rs b/servo/ports/geckolib/glue.rs index 3a69843c79a1..54aac9b46948 100644 --- a/servo/ports/geckolib/glue.rs +++ b/servo/ports/geckolib/glue.rs @@ -343,16 +343,6 @@ pub extern "C" fn Servo_AnimationValue_Release(anim: RawServoAnimationValueBorro unsafe { AnimationValue::release(anim) }; } - #[no_mangle] -pub extern "C" fn Servo_AnimationValue_DeepEqual(this: RawServoAnimationValueBorrowed, - other: RawServoAnimationValueBorrowed) - -> bool -{ - let this_value = AnimationValue::as_arc(&this); - let other_value = AnimationValue::as_arc(&other); - this_value == other_value -} - #[no_mangle] pub extern "C" fn Servo_StyleWorkerThreadCount() -> u32 { *NUM_THREADS as u32