diff options
548 files changed, 13611 insertions, 15926 deletions
diff --git a/.gitignore b/.gitignore index e96d93837e1..d8247de857d 100644 --- a/.gitignore +++ b/.gitignore @@ -9,20 +9,12 @@ /python/_virtualenv /python/tidy/servo_tidy.egg-info *~ -*# -*.o -*.so -*.dylib -*.dSYM -*.dll -*.dummy *.pkl *.pyc *.swp *.swo *.csv .DS_Store -servo-test Servo.app .config.mk.last /glfw diff --git a/.mailmap b/.mailmap new file mode 100644 index 00000000000..ead257b2c87 --- /dev/null +++ b/.mailmap @@ -0,0 +1,94 @@ +Achal Shah <achals@gmail.com> <achal@uber.com> +Adenilson Cavalcanti <cavalcantii@gmail.com> <a.cavalcanti@samsung.com> +Adenilson Cavalcanti <cavalcantii@gmail.com> <a.cavalcanti@sisa.samsung.com> +Adrian Heine <mail@adrianheine.de> +Agoston Szepessy <agszepp@gmail.com> +Alexander Popiak <alex@zenguard.org> <alexander.popiak@gmail.com> +Alexandrov Sergey <splavgm@gmail.com> +Antonio de Luna <tonydelun@gmail.com> +Askeing Yen (fyen) <askeing@gmail.com> +Attila Dusnoki <dati91@gmail.com> <dati91@users.noreply.github.com> +bd339 <bd339@tuta.io> <bd339@localhost.localdomain> +Beomjin Kim <beomjin.kim@lge.com> <memory128m@gmail.com> +Bogdan Cuza <bogdan.cuza@hotmail.com> <boghison22@gmail.com> +bors-servo <release+servo@mozilla.com> <lbergstrom+bors@mozilla.com> +bors-servo <release+servo@mozilla.com> <metajack+bors@gmail.com> +Brian Anderson <banderson@mozilla.com> <andersrb@gmail.com> +Brian J. Burg <burg@cs.washington.edu> +Clark Gaebel <cgaebel@mozilla.com> <cg.wowus.cg@gmail.com> +Clark Gaebel <cgaebel@mozilla.com> <cgaebel@uwaterloo.ca> +Connor Brewster <connor.brewster@eagles.oc.edu> <brewsterc@my.caspercollege.edu> +Daniel Robertson <dan.robertson@anidata.org> <danlrobertson89@gmail.com> +Daniel Robertson <dan.robertson@anidata.org> <drobertson@tripwire.com> +David Raifaizen <d-raif@hotmail.com> David Raifaizen <whoknows> +Dirkjan Ochtman <dirkjan@ochtman.nl> <d.ochtman@activevideo.com> +edunham <edunham@mozilla.com> <github@edunham.net> +Emilio Cobos Álvarez <emilio@crisal.io> <ecoal95@gmail.com> +Emilio Cobos Álvarez <emilio@crisal.io> <me@emiliocobos.me> +Felipe Lacerda <fegolac@gmail.com> +Glenn Watson <gw@intuitionlibrary.com> <github@intuitionlibrary.com> +Glenn Watson <gw@intuitionlibrary.com> <glennw@users.noreply.github.com> +Gregory Terzian <gterzian@users.noreply.github.com> +Guillaume Gomez <guillaume1.gomez@gmail.com> +hgentry <harrison@gentryville.net> <harrison.c.gentry@gmail.com> +Hugo Thiessard <hugo.thiessard@etu.u-bordeaux.fr> <hugo.thiessard@opmbx.org> +HyunJune Kim <hyunjune.kim@samsung.com> <hykim0777@gmail.com> +Ilyong Cho <ilyoan@gmail.com> +Jacob Parker <j3parker@csclub.uwaterloo.ca> <j@cob.xxx> +James Graham <james@hoppipolla.co.uk> +Jansen Jan <farodin91@sek-server.de> <farodin91@googlemail.com> +Jason Williams <jase.williams@gmail.com> +Jason Williams <jase.williams@gmail.com> <Jayflux@users.noreply.github.com> +Jason Williams <jase.williams@gmail.com> <willij87@mc-s083267.local> +Jinwoo Ahn <jinwoo.ahn@lge.com> +JJ Weber <jjweber@gmail.com> +Junyoung Cho <june0.cho@samsung.com> +Junyoung Cho <june0.cho@samsung.com> <jun0cho@gmail.com> +Kamil Muszyński <muszynski.kamil@gmail.com> <KamilM1@verifone.com> +Keegan McAllister <kmcallister@mozilla.com> <mcallister.keegan@gmail.com> +Kuba Birecki <kuba.birecki@crystalplanet.io> <kuba.birecki@crystalplanet-studio.com> +Lars Bergstrom <lars@lars.com> <larsberg@mozilla.com> +Lars Bergstrom <lars@lars.com> <lbergstrom@mozilla.com> +Luqman Aden <me@luqman.ca> <laden@csclub.uwaterloo.ca> +Manish Goregaokar <manishsmail@gmail.com> <Manishearth@users.noreply.github.com> +Margaret Meyerhofer <mmeyerhofer@mozilla.com> <mmeyerho@andrew> +Martin Robinson <mrobinson@igalia.com> <martin.james.robinson@gmail.com> +Mike Blumenkrantz <zmike@osg.samsung.com> <i@zmike.ninja> +Mike Blumenkrantz <zmike@osg.samsung.com> <michael.blumenkrantz@gmail.com> +Mike Blumenkrantz <zmike@osg.samsung.com> <zmike@samsung.com> +Ms2ger <Ms2ger@gmail.com> <ms2ger@gmail.com> +Nicholas Nethercote <nnethercote@mozilla.com> <n.nethercote@gmail.com> +Nicolas <ashlebede@gmail.com> +patrick kim <ksh8281@gmail.com> +Patrick Trottier <patrick.arrow206@outlook.com> <ptrottier@localhost.localdomain> +Per Lundberg <perlun@gmail.com> <per.lundberg@ecraft.com> +Pierre Louis Aublin <pierre-louis.aublin@inria.fr> <pierrelouis.aublin@gmail.com> +Prabhjyot Singh Sodhi <prabhjyotsingh95@gmail.com> <prabhyotsingh95@gmail.com> +Ravi Shankar <wafflespeanut@gmail.com> +Rohan Prinja <rohan.prinja@gmail.com> <rohan.prinja@samsung.com> +Rohan Prinja <rohan.prinja@gmail.com> <rohan@cs.unc.edu> +Rohit Zambre <rzambre@uci.edu> <RZ13@dhcp-v007-158.mobile.uci.edu> +Rohit Zambre <rzambre@uci.edu> <RZ13@dhcp-v058-081.mobile.uci.edu> +Roman Klauke <romaaan.git@gmail.com> <romankl@users.noreply.github.com> +rwakulszowa <rwakulszowa1@gmail.com> <rwa@localhost.localdomain> +rwakulszowa <rwakulszowa1@gmail.com> <zajactomasz1@yahoo.com> +Seth Fowler <seth@mozilla.com> <mark.seth.fowler@gmail.com> +Shing Lyu <shing.lyu@gmail.com> <slyu@mozilla.com> +Stephen (Ziyun) Li <stephen.liziyun@gmail.com> <stephen.li@D2L.com> +Tamir Duberstein <tamird@gmail.com> <tamird@squareup.com> +Tetsuharu OHZEKI <saneyuki.snyk@gmail.com> <saneyuki.s.snyk@gmail.com> +Thiago Pontes <github@thiago.me> <email@thiago.me> +Thiago Pontes <github@thiago.me> <thiagopnts@gmail.com> +Tim Kuehn <tkuehn@cmu.edu> +Tim Kuehn <tkuehn@cmu.edu> <tkuehn@host-7-125.mv.mozilla.com> +Valentin Fokin <fokinv@inf.u-szeged.hu> +Valentin Fokin <fokinv@inf.u-szeged.hu> <fokin.valentin@stud.u-szeged.hu> +Valentin Fokin <fokinv@inf.u-szeged.hu> <fokinvalen@gmail.com> +Xidorn Quan <me@upsuper.org> <github@upsuper.org> +Ying-Ruei Liang (KK) <thumbd03803@gmail.com> +Yongjin Kim <aydin.kim@samsung.com> +Yongjin Kim <aydin.kim@samsung.com> <aydin.kim@servo64.(none)> +Young-il Choi <duddlf.choi@samsung.com> +Youngmin Yoo <youngmin.yoo@samsung.com> +Zakor Gyula <zakorgy@inf.u-szeged.hu> +Zakor Gyula <zakorgy@inf.u-szeged.hu> <gyula.zakor@gmail.com> diff --git a/Cargo.lock b/Cargo.lock index 679a7b7fe2d..708d7c10694 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3,20 +3,20 @@ name = "webdriver_server" version = "0.0.1" dependencies = [ "cookie 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)", - "euclid 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)", - "hyper 0.9.11 (registry+https://github.com/rust-lang/crates.io-index)", - "image 0.10.3 (registry+https://github.com/rust-lang/crates.io-index)", + "euclid 0.10.3 (registry+https://github.com/rust-lang/crates.io-index)", + "hyper 0.9.14 (registry+https://github.com/rust-lang/crates.io-index)", + "image 0.10.4 (registry+https://github.com/rust-lang/crates.io-index)", "ipc-channel 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", "msg 0.0.1", "net_traits 0.0.1", "plugins 0.0.1", - "regex 0.1.76 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc-serialize 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)", + "regex 0.1.80 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-serialize 0.3.22 (registry+https://github.com/rust-lang/crates.io-index)", "script_traits 0.0.1", + "servo_config 0.0.1", "servo_url 0.0.1", "url 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "util 0.0.1", "uuid 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "webdriver 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -40,12 +40,17 @@ version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] +name = "android_injected_glue" +version = "0.2.1" +source = "git+https://github.com/mmatyas/android-rs-injected-glue#d3223d1273d0dafcf06d6a6405fedfffbf257300" + +[[package]] name = "angle" version = "0.1.2" source = "git+https://github.com/servo/angle?branch=servo#99128001400771ee9c8a74dcf54cf6fe11b1e532" dependencies = [ - "cmake 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.17 (registry+https://github.com/rust-lang/crates.io-index)", + "cmake 0.1.20 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -54,18 +59,26 @@ version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "heapsize 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", - "num-traits 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc-serialize 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 0.8.18 (registry+https://github.com/rust-lang/crates.io-index)", + "num-traits 0.1.36 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-serialize 0.3.22 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 0.8.20 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "arrayvec" -version = "0.3.17" +version = "0.3.20" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "nodrop 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", - "odds 0.2.16 (registry+https://github.com/rust-lang/crates.io-index)", + "odds 0.2.25 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "aster" +version = "0.34.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "syntex_syntax 0.50.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -74,30 +87,30 @@ version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "mp3-metadata 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", - "mp4parse 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", + "mp4parse 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", "ogg_metadata 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "azure" -version = "0.9.1" -source = "git+https://github.com/servo/rust-azure#d817e7e1b1af6896f778d0cc0693e0a1573f3a48" +version = "0.9.2" +source = "git+https://github.com/servo/rust-azure#a6219cee8d273528207b42353a6c153e69ece5ff" dependencies = [ - "cmake 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)", + "cmake 0.1.20 (registry+https://github.com/rust-lang/crates.io-index)", "core-foundation 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", "core-graphics 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", "core-text 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "euclid 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)", - "freetype 0.1.2 (git+https://github.com/servo/rust-freetype)", + "euclid 0.10.3 (registry+https://github.com/rust-lang/crates.io-index)", + "freetype 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", "heapsize 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", "heapsize_derive 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.17 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 0.8.18 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_derive 0.8.18 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 0.8.20 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive 0.8.20 (registry+https://github.com/rust-lang/crates.io-index)", "servo-egl 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "servo-freetype-sys 4.0.3 (registry+https://github.com/rust-lang/crates.io-index)", "servo-skia 0.20130412.24 (registry+https://github.com/rust-lang/crates.io-index)", - "x11 2.8.0 (registry+https://github.com/rust-lang/crates.io-index)", + "x11 2.11.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -105,22 +118,22 @@ name = "backtrace" version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "backtrace-sys 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", + "backtrace-sys 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", "cfg-if 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "dbghelp-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.17 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc-demangle 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-demangle 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "backtrace-sys" -version = "0.1.4" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "gcc 0.3.35 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.17 (registry+https://github.com/rust-lang/crates.io-index)", + "gcc 0.3.40 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -129,9 +142,9 @@ version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "byteorder 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)", - "num-traits 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc-serialize 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 0.8.18 (registry+https://github.com/rust-lang/crates.io-index)", + "num-traits 0.1.36 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-serialize 0.3.22 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 0.8.20 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -170,9 +183,8 @@ dependencies = [ "bluetooth_traits 0.0.1", "device 0.0.1 (git+https://github.com/servo/devices)", "ipc-channel 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)", - "tinyfiledialogs 0.1.0 (git+https://github.com/jdm/tinyfiledialogs)", - "util 0.0.1", + "rand 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)", + "tinyfiledialogs 2.5.9 (git+https://github.com/jdm/tinyfiledialogs)", "uuid 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -181,10 +193,10 @@ name = "bluetooth_traits" version = "0.0.1" dependencies = [ "ipc-channel 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", - "regex 0.1.76 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 0.8.18 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_derive 0.8.18 (registry+https://github.com/rust-lang/crates.io-index)", - "util 0.0.1", + "regex 0.1.80 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 0.8.20 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive 0.8.20 (registry+https://github.com/rust-lang/crates.io-index)", + "servo_config 0.0.1", ] [[package]] @@ -197,7 +209,7 @@ name = "blurmock" version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "rustc-serialize 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-serialize 0.3.22 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -206,12 +218,12 @@ version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "dbus 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc-serialize 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-serialize 0.3.22 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "brotli" -version = "1.0.6" +version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "alloc-no-stdlib 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -220,13 +232,13 @@ dependencies = [ [[package]] name = "browserhtml" version = "0.1.17" -source = "git+https://github.com/browserhtml/browserhtml?branch=crate#aafbb0996b02d1fadd4713c96e3d22b542f175a1" +source = "git+https://github.com/browserhtml/browserhtml?branch=crate#cbb020096c77f5d2547e575c0e19003a6d2a614a" [[package]] name = "build-apk" version = "0.0.1" dependencies = [ - "walkdir 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", + "walkdir 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -243,16 +255,17 @@ source = "registry+https://github.com/rust-lang/crates.io-index" name = "canvas" version = "0.0.1" dependencies = [ - "azure 0.9.1 (git+https://github.com/servo/rust-azure)", + "azure 0.9.2 (git+https://github.com/servo/rust-azure)", "canvas_traits 0.0.1", - "euclid 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)", - "gleam 0.2.24 (registry+https://github.com/rust-lang/crates.io-index)", + "cssparser 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", + "euclid 0.10.3 (registry+https://github.com/rust-lang/crates.io-index)", + "gleam 0.2.29 (registry+https://github.com/rust-lang/crates.io-index)", "ipc-channel 0.5.1 (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.35 (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.5.1 (registry+https://github.com/rust-lang/crates.io-index)", "plugins 0.0.1", - "util 0.0.1", + "servo_config 0.0.1", "webrender_traits 0.11.0 (git+https://github.com/servo/webrender)", ] @@ -260,15 +273,14 @@ dependencies = [ name = "canvas_traits" version = "0.0.1" dependencies = [ - "azure 0.9.1 (git+https://github.com/servo/rust-azure)", "cssparser 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", - "euclid 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)", + "euclid 0.10.3 (registry+https://github.com/rust-lang/crates.io-index)", "heapsize 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", "heapsize_derive 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", "ipc-channel 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", "plugins 0.0.1", - "serde 0.8.18 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_derive 0.8.18 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 0.8.20 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive 0.8.20 (registry+https://github.com/rust-lang/crates.io-index)", "webrender_traits 0.11.0 (git+https://github.com/servo/webrender)", ] @@ -277,8 +289,16 @@ name = "caseless" version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "regex 0.1.76 (registry+https://github.com/rust-lang/crates.io-index)", - "unicode-normalization 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", + "regex 0.1.80 (registry+https://github.com/rust-lang/crates.io-index)", + "unicode-normalization 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "cexpr" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "nom 1.2.4 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -291,8 +311,20 @@ name = "cgl" version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "gleam 0.2.24 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.17 (registry+https://github.com/rust-lang/crates.io-index)", + "gleam 0.2.29 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "clang-sys" +version = "0.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "bitflags 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", + "glob 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)", + "libloading 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -300,33 +332,33 @@ name = "clippy_lints" version = "0.0.98" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "matches 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", + "matches 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", "quine-mc_cluskey 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)", - "regex-syntax 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc-serialize 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)", + "regex-syntax 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-serialize 0.3.22 (registry+https://github.com/rust-lang/crates.io-index)", "semver 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", "toml 0.1.30 (registry+https://github.com/rust-lang/crates.io-index)", - "unicode-normalization 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", + "unicode-normalization 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "cmake" -version = "0.1.17" +version = "0.1.20" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "gcc 0.3.35 (registry+https://github.com/rust-lang/crates.io-index)", + "gcc 0.3.40 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "cocoa" -version = "0.5.0" +version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "bitflags 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", "block 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", "core-graphics 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.17 (registry+https://github.com/rust-lang/crates.io-index)", - "objc 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)", + "objc 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -338,26 +370,26 @@ source = "registry+https://github.com/rust-lang/crates.io-index" name = "compiletest_helper" version = "0.0.1" dependencies = [ - "compiletest_rs 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)", + "compiletest_rs 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "compiletest_rs" -version = "0.2.4" +version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc-serialize 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-serialize 0.3.22 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "compositing" version = "0.0.1" dependencies = [ - "euclid 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)", + "euclid 0.10.3 (registry+https://github.com/rust-lang/crates.io-index)", "gfx_traits 0.0.1", - "gleam 0.2.24 (registry+https://github.com/rust-lang/crates.io-index)", - "image 0.10.3 (registry+https://github.com/rust-lang/crates.io-index)", + "gleam 0.2.29 (registry+https://github.com/rust-lang/crates.io-index)", + "image 0.10.4 (registry+https://github.com/rust-lang/crates.io-index)", "ipc-channel 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", "msg 0.0.1", @@ -365,12 +397,13 @@ dependencies = [ "plugins 0.0.1", "profile_traits 0.0.1", "script_traits 0.0.1", - "serde 0.8.18 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_derive 0.8.18 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 0.8.20 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive 0.8.20 (registry+https://github.com/rust-lang/crates.io-index)", + "servo_config 0.0.1", + "servo_geometry 0.0.1", "servo_url 0.0.1", "style_traits 0.0.1", "time 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)", - "util 0.0.1", "webrender 0.11.0 (git+https://github.com/servo/webrender)", "webrender_traits 0.11.0 (git+https://github.com/servo/webrender)", ] @@ -386,7 +419,7 @@ dependencies = [ "compositing 0.0.1", "debugger 0.0.1", "devtools_traits 0.0.1", - "euclid 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)", + "euclid 0.10.3 (registry+https://github.com/rust-lang/crates.io-index)", "gaol 0.0.1 (git+https://github.com/servo/gaol)", "gfx 0.0.1", "gfx_traits 0.0.1", @@ -398,13 +431,14 @@ dependencies = [ "offscreen_gl_context 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", "plugins 0.0.1", "profile_traits 0.0.1", - "rand 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)", "script_traits 0.0.1", - "serde 0.8.18 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_derive 0.8.18 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 0.8.20 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive 0.8.20 (registry+https://github.com/rust-lang/crates.io-index)", + "servo_config 0.0.1", + "servo_remutex 0.0.1", "servo_url 0.0.1", "style_traits 0.0.1", - "util 0.0.1", "webrender_traits 0.11.0 (git+https://github.com/servo/webrender)", ] @@ -413,8 +447,8 @@ name = "content-blocker" version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "regex 0.1.76 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)", + "regex 0.1.80 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 0.8.4 (registry+https://github.com/rust-lang/crates.io-index)", "url 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -424,7 +458,7 @@ version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "openssl 0.7.14 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc-serialize 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-serialize 0.3.22 (registry+https://github.com/rust-lang/crates.io-index)", "time 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)", "url 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -435,7 +469,7 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "core-foundation-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.17 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -443,7 +477,7 @@ name = "core-foundation-sys" version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.2.17 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -452,8 +486,8 @@ version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "core-foundation 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.17 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 0.8.18 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 0.8.20 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -463,7 +497,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "core-foundation 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", "core-graphics 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.17 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -478,8 +512,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "encoding 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)", "heapsize 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", - "matches 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 0.8.18 (registry+https://github.com/rust-lang/crates.io-index)", + "matches 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 0.8.20 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -496,7 +530,7 @@ name = "dbus" version = "0.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.2.17 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)", "pkg-config 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -513,7 +547,6 @@ name = "debugger" version = "0.0.1" dependencies = [ "log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", - "util 0.0.1", "ws 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -522,7 +555,7 @@ name = "deque" version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "rand 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -541,17 +574,16 @@ version = "0.0.1" dependencies = [ "devtools_traits 0.0.1", "encoding 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)", - "hyper 0.9.11 (registry+https://github.com/rust-lang/crates.io-index)", + "hyper 0.9.14 (registry+https://github.com/rust-lang/crates.io-index)", "hyper_serde 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", "ipc-channel 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", "msg 0.0.1", "plugins 0.0.1", - "serde 0.8.18 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_derive 0.8.18 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 0.8.20 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive 0.8.20 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 0.8.4 (registry+https://github.com/rust-lang/crates.io-index)", "time 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)", - "util 0.0.1", ] [[package]] @@ -561,22 +593,22 @@ dependencies = [ "bitflags 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", "heapsize 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", "heapsize_derive 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", - "hyper 0.9.11 (registry+https://github.com/rust-lang/crates.io-index)", + "hyper 0.9.14 (registry+https://github.com/rust-lang/crates.io-index)", "hyper_serde 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", "ipc-channel 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", "msg 0.0.1", - "serde 0.8.18 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_derive 0.8.18 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 0.8.20 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive 0.8.20 (registry+https://github.com/rust-lang/crates.io-index)", "servo_url 0.0.1", "time 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "dlib" -version = "0.3.0" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libloading 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)", + "libloading 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -595,15 +627,15 @@ dependencies = [ [[package]] name = "dwrote" -version = "0.1.2" +version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "gdi32-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.17 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 0.8.18 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_codegen 0.8.18 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 0.8.20 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_codegen 0.8.20 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -611,25 +643,26 @@ dependencies = [ name = "embedding" version = "0.0.1" dependencies = [ - "cocoa 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", + "cocoa 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)", "compositing 0.0.1", "devtools 0.0.1", - "euclid 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)", + "euclid 0.10.3 (registry+https://github.com/rust-lang/crates.io-index)", "gfx_traits 0.0.1", - "gleam 0.2.24 (registry+https://github.com/rust-lang/crates.io-index)", + "gleam 0.2.29 (registry+https://github.com/rust-lang/crates.io-index)", "glutin_app 0.0.1", - "libc 0.2.17 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)", "libservo 0.0.1", "log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", "msg 0.0.1", "net_traits 0.0.1", - "objc 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "objc 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", "plugins 0.0.1", "script_traits 0.0.1", + "servo_config 0.0.1", + "servo_geometry 0.0.1", "servo_url 0.0.1", "style_traits 0.0.1", - "util 0.0.1", - "x11 2.8.0 (registry+https://github.com/rust-lang/crates.io-index)", + "x11 2.11.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -696,38 +729,39 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "energymon" -version = "0.2.0" -source = "git+https://github.com/energymon/energymon-rust.git#7b30c4d88ac1fcfaf7755081ebdd810c5dcf4fea" +version = "0.3.0" +source = "git+https://github.com/energymon/energymon-rust.git#89daf8f37858eab96ad8eec7cc81accb17b2411e" dependencies = [ "energy-monitor 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "energymon-default-sys 0.2.0 (git+https://github.com/energymon/energymon-sys.git)", - "libc 0.2.17 (registry+https://github.com/rust-lang/crates.io-index)", + "energymon-default-sys 0.3.0 (git+https://github.com/energymon/energymon-sys.git)", + "libc 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "energymon-builder" -version = "0.2.0" -source = "git+https://github.com/energymon/energymon-sys.git#a0fb99b0312372958b110ae6378b5c89c2287172" +version = "0.3.0" +source = "git+https://github.com/energymon/energymon-sys.git#f8d77ea2906b25f9c0fd358aa9d300a46dc3e97c" dependencies = [ + "cmake 0.1.20 (registry+https://github.com/rust-lang/crates.io-index)", "pkg-config 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "energymon-default-sys" -version = "0.2.0" -source = "git+https://github.com/energymon/energymon-sys.git#a0fb99b0312372958b110ae6378b5c89c2287172" +version = "0.3.0" +source = "git+https://github.com/energymon/energymon-sys.git#f8d77ea2906b25f9c0fd358aa9d300a46dc3e97c" dependencies = [ - "energymon-builder 0.2.0 (git+https://github.com/energymon/energymon-sys.git)", - "energymon-sys 0.2.0 (git+https://github.com/energymon/energymon-sys.git)", - "libc 0.2.17 (registry+https://github.com/rust-lang/crates.io-index)", + "energymon-builder 0.3.0 (git+https://github.com/energymon/energymon-sys.git)", + "energymon-sys 0.3.0 (git+https://github.com/energymon/energymon-sys.git)", + "libc 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "energymon-sys" -version = "0.2.0" -source = "git+https://github.com/energymon/energymon-sys.git#a0fb99b0312372958b110ae6378b5c89c2287172" +version = "0.3.0" +source = "git+https://github.com/energymon/energymon-sys.git#f8d77ea2906b25f9c0fd358aa9d300a46dc3e97c" dependencies = [ - "libc 0.2.17 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -735,28 +769,28 @@ name = "enum_primitive" version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "num 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)", + "num 0.1.36 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "env_logger" -version = "0.3.4" +version = "0.3.5" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", - "regex 0.1.76 (registry+https://github.com/rust-lang/crates.io-index)", + "regex 0.1.80 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "euclid" -version = "0.10.2" +version = "0.10.3" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "heapsize 0.3.7 (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.35 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc-serialize 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 0.8.18 (registry+https://github.com/rust-lang/crates.io-index)", + "num-traits 0.1.36 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-serialize 0.3.22 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 0.8.20 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -764,7 +798,7 @@ name = "expat-sys" version = "2.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "cmake 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)", + "cmake 0.1.20 (registry+https://github.com/rust-lang/crates.io-index)", "pkg-config 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -773,7 +807,7 @@ name = "flate2" version = "0.2.14" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.2.17 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)", "miniz-sys 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -787,26 +821,18 @@ name = "fontsan" version = "0.3.2" source = "git+https://github.com/servo/fontsan#ab68da1723827d6302653ccb76c1d215d36b7d4c" dependencies = [ - "cmake 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.17 (registry+https://github.com/rust-lang/crates.io-index)", + "cmake 0.1.20 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)", "miniz-sys 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "freetype" -version = "0.1.2" -source = "git+https://github.com/servo/rust-freetype#66a466247490cbf27410ffd652454a417f79f33e" -dependencies = [ - "libc 0.2.17 (registry+https://github.com/rust-lang/crates.io-index)", - "servo-freetype-sys 4.0.3 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "freetype" -version = "0.1.2" +version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.2.17 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)", + "servo-freetype-sys 4.0.3 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -815,7 +841,7 @@ version = "0.2.5" 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)", - "libc 0.2.17 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -833,14 +859,14 @@ name = "gaol" version = "0.0.1" source = "git+https://github.com/servo/gaol#c67de2fb4469bfc4f5258602ec30579844edafec" dependencies = [ - "libc 0.2.17 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "gcc" -version = "0.3.35" +version = "0.3.40" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -858,13 +884,13 @@ version = "0.0.1" dependencies = [ "app_units 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "cssparser 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", - "env_logger 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", - "euclid 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.17 (registry+https://github.com/rust-lang/crates.io-index)", + "env_logger 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", + "euclid 0.10.3 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", - "num_cpus 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "parking_lot 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", + "num_cpus 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "parking_lot 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", "selectors 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)", "servo_url 0.0.1", "style 0.0.1", @@ -887,29 +913,30 @@ dependencies = [ "core-foundation 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", "core-graphics 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", "core-text 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "dwrote 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "euclid 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)", + "dwrote 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", + "euclid 0.10.3 (registry+https://github.com/rust-lang/crates.io-index)", "fnv 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", "fontsan 0.3.2 (git+https://github.com/servo/fontsan)", - "freetype 0.1.2 (git+https://github.com/servo/rust-freetype)", + "freetype 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", "gfx_traits 0.0.1", "harfbuzz-sys 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", "heapsize 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", "heapsize_derive 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", "ipc-channel 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.17 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", "msg 0.0.1", "net_traits 0.0.1", "ordered-float 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", "plugins 0.0.1", "range 0.0.1", - "rustc-serialize 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 0.8.18 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_derive 0.8.18 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-serialize 0.3.22 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 0.8.20 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive 0.8.20 (registry+https://github.com/rust-lang/crates.io-index)", "servo-fontconfig 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "servo_atoms 0.0.1", + "servo_geometry 0.0.1", "servo_url 0.0.1", "simd 0.1.1 (git+https://github.com/huonw/simd)", "smallvec 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", @@ -917,7 +944,6 @@ dependencies = [ "style_traits 0.0.1", "time 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)", "unicode-script 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "util 0.0.1", "webrender_traits 0.11.0 (git+https://github.com/servo/webrender)", "xi-unicode 0.0.1 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -939,9 +965,9 @@ dependencies = [ "heapsize_derive 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", "plugins 0.0.1", "range 0.0.1", - "rustc-serialize 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 0.8.18 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_derive 0.8.18 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-serialize 0.3.22 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 0.8.20 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive 0.8.20 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -960,12 +986,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "khronos_api 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", - "xml-rs 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", + "xml-rs 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "gleam" -version = "0.2.24" +version = "0.2.29" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "gl_generator 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)", @@ -983,10 +1009,10 @@ version = "0.0.1" dependencies = [ "bitflags 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", "compositing 0.0.1", - "euclid 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)", + "euclid 0.10.3 (registry+https://github.com/rust-lang/crates.io-index)", "gdi32-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "gfx_traits 0.0.1", - "gleam 0.2.24 (registry+https://github.com/rust-lang/crates.io-index)", + "gleam 0.2.29 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", "msg 0.0.1", "net_traits 0.0.1", @@ -995,12 +1021,13 @@ dependencies = [ "script_traits 0.0.1", "servo-egl 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "servo-glutin 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)", + "servo_config 0.0.1", + "servo_geometry 0.0.1", "servo_url 0.0.1", "style_traits 0.0.1", "user32-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "util 0.0.1", "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", - "x11 2.8.0 (registry+https://github.com/rust-lang/crates.io-index)", + "x11 2.11.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1010,7 +1037,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "gl_generator 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)", "khronos_api 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.17 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1018,8 +1045,8 @@ name = "harfbuzz-sys" version = "0.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "cmake 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.17 (registry+https://github.com/rust-lang/crates.io-index)", + "cmake 0.1.20 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)", "pkg-config 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1036,8 +1063,8 @@ name = "heapsize_derive" version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "quote 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 0.10.3 (registry+https://github.com/rust-lang/crates.io-index)", + "quote 0.3.10 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 0.10.5 (registry+https://github.com/rust-lang/crates.io-index)", "synstructure 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1047,7 +1074,7 @@ version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "heartbeats-simple-sys 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.17 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1055,8 +1082,8 @@ name = "heartbeats-simple-sys" version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "cmake 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.17 (registry+https://github.com/rust-lang/crates.io-index)", + "cmake 0.1.20 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)", "pkg-config 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1080,9 +1107,9 @@ dependencies = [ "mac 0.0.2 (registry+https://github.com/rust-lang/crates.io-index)", "phf 0.7.20 (registry+https://github.com/rust-lang/crates.io-index)", "phf_codegen 0.7.20 (registry+https://github.com/rust-lang/crates.io-index)", - "quote 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc-serialize 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 0.10.3 (registry+https://github.com/rust-lang/crates.io-index)", + "quote 0.3.10 (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.5 (registry+https://github.com/rust-lang/crates.io-index)", "tendril 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1094,28 +1121,28 @@ dependencies = [ "heapsize 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", "heapsize_derive 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", "string_cache 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "string_cache_codegen 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "string_cache_codegen 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "httparse" -version = "1.1.2" +version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "hyper" -version = "0.9.11" +version = "0.9.14" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "cookie 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)", - "httparse 1.1.2 (registry+https://github.com/rust-lang/crates.io-index)", + "httparse 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "language-tags 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)", "mime 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", - "num_cpus 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "num_cpus 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "openssl 0.7.14 (registry+https://github.com/rust-lang/crates.io-index)", "openssl-verify 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc-serialize 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-serialize 0.3.22 (registry+https://github.com/rust-lang/crates.io-index)", "solicit 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)", "time 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)", "traitobject 0.0.1 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1130,9 +1157,9 @@ version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "cookie 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)", - "hyper 0.9.11 (registry+https://github.com/rust-lang/crates.io-index)", + "hyper 0.9.14 (registry+https://github.com/rust-lang/crates.io-index)", "mime 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 0.8.18 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 0.8.20 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1140,24 +1167,24 @@ name = "idna" version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "matches 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "unicode-bidi 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", - "unicode-normalization 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", + "matches 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", + "unicode-bidi 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)", + "unicode-normalization 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "image" -version = "0.10.3" +version = "0.10.4" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "byteorder 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)", "enum_primitive 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "gif 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", "glob 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", - "jpeg-decoder 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", + "jpeg-decoder 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", "num-iter 0.1.32 (registry+https://github.com/rust-lang/crates.io-index)", "num-rational 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)", - "num-traits 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)", + "num-traits 0.1.36 (registry+https://github.com/rust-lang/crates.io-index)", "png 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)", "scoped_threadpool 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1167,9 +1194,9 @@ name = "immeta" version = "0.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "arrayvec 0.3.17 (registry+https://github.com/rust-lang/crates.io-index)", + "arrayvec 0.3.20 (registry+https://github.com/rust-lang/crates.io-index)", "byteorder 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)", - "num-traits 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)", + "num-traits 0.1.36 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1184,9 +1211,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "cgl 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", "core-foundation 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", - "gleam 0.2.24 (registry+https://github.com/rust-lang/crates.io-index)", + "gleam 0.2.29 (registry+https://github.com/rust-lang/crates.io-index)", "leaky-cow 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.17 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1195,10 +1222,10 @@ version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "bincode 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.17 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 0.8.18 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 0.8.20 (registry+https://github.com/rust-lang/crates.io-index)", "uuid 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1209,33 +1236,33 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "jpeg-decoder" -version = "0.1.8" +version = "0.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "byteorder 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)", - "rayon 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rayon 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "js" version = "0.1.3" -source = "git+https://github.com/servo/rust-mozjs#342f304a455080acf64f5ceb40a7f8059481ca01" +source = "git+https://github.com/servo/rust-mozjs#15ff1e83446e998112dcde731610e8b60cc32abf" dependencies = [ - "cmake 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)", + "cmake 0.1.20 (registry+https://github.com/rust-lang/crates.io-index)", "heapsize 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.17 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", "mozjs_sys 0.0.0 (git+https://github.com/servo/mozjs)", - "num-traits 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)", + "num-traits 0.1.36 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "jstraceable_derive" version = "0.0.1" dependencies = [ - "quote 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 0.10.3 (registry+https://github.com/rust-lang/crates.io-index)", + "quote 0.3.10 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 0.10.5 (registry+https://github.com/rust-lang/crates.io-index)", "synstructure 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1266,7 +1293,7 @@ dependencies = [ "bitflags 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", "canvas_traits 0.0.1", "cssparser 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", - "euclid 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)", + "euclid 0.10.3 (registry+https://github.com/rust-lang/crates.io-index)", "fnv 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", "gfx 0.0.1", "gfx_traits 0.0.1", @@ -1274,30 +1301,30 @@ dependencies = [ "heapsize_derive 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", "html5ever-atoms 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "ipc-channel 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.17 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", "msg 0.0.1", "net_traits 0.0.1", "ordered-float 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", - "parking_lot 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", + "parking_lot 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", "plugins 0.0.1", "profile_traits 0.0.1", "range 0.0.1", - "rayon 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rayon 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", "script_layout_interface 0.0.1", "script_traits 0.0.1", "selectors 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 0.8.18 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_derive 0.8.18 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 0.8.20 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive 0.8.20 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 0.8.4 (registry+https://github.com/rust-lang/crates.io-index)", "servo_atoms 0.0.1", + "servo_config 0.0.1", "servo_url 0.0.1", "smallvec 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", "style 0.0.1", "style_traits 0.0.1", - "unicode-bidi 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", + "unicode-bidi 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)", "unicode-script 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "util 0.0.1", "webrender_traits 0.11.0 (git+https://github.com/servo/webrender)", ] @@ -1313,7 +1340,7 @@ name = "layout_thread" version = "0.0.1" dependencies = [ "app_units 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "euclid 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)", + "euclid 0.10.3 (registry+https://github.com/rust-lang/crates.io-index)", "fnv 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", "gfx 0.0.1", "gfx_traits 0.0.1", @@ -1322,23 +1349,24 @@ dependencies = [ "ipc-channel 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", "layout 0.0.1", "layout_traits 0.0.1", - "lazy_static 0.2.1 (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)", "msg 0.0.1", "net_traits 0.0.1", - "parking_lot 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", + "parking_lot 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", "plugins 0.0.1", "profile_traits 0.0.1", - "rayon 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rayon 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", "script 0.0.1", "script_layout_interface 0.0.1", "script_traits 0.0.1", "selectors 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_derive 0.8.18 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive 0.8.20 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 0.8.4 (registry+https://github.com/rust-lang/crates.io-index)", + "servo_config 0.0.1", + "servo_geometry 0.0.1", "servo_url 0.0.1", "style 0.0.1", - "util 0.0.1", "webrender_traits 0.11.0 (git+https://github.com/servo/webrender)", ] @@ -1363,7 +1391,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "lazy_static" -version = "0.2.1" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -1380,18 +1408,37 @@ dependencies = [ ] [[package]] +name = "libbindgen" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "aster 0.34.0 (registry+https://github.com/rust-lang/crates.io-index)", + "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.12.0 (registry+https://github.com/rust-lang/crates.io-index)", + "env_logger 0.3.5 (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)", + "quasi 0.26.0 (registry+https://github.com/rust-lang/crates.io-index)", + "quasi_codegen 0.26.0 (registry+https://github.com/rust-lang/crates.io-index)", + "regex 0.1.80 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-serialize 0.3.22 (registry+https://github.com/rust-lang/crates.io-index)", + "syntex_syntax 0.50.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] name = "libc" -version = "0.2.17" +version = "0.2.18" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "libloading" -version = "0.2.4" +version = "0.3.1" 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)", - "lazy_static 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", - "target_build_utils 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", + "target_build_utils 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1419,15 +1466,15 @@ dependencies = [ "debugger 0.0.1", "devtools 0.0.1", "devtools_traits 0.0.1", - "env_logger 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", - "euclid 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)", + "env_logger 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", + "euclid 0.10.3 (registry+https://github.com/rust-lang/crates.io-index)", "gaol 0.0.1 (git+https://github.com/servo/gaol)", "gfx 0.0.1", - "gleam 0.2.24 (registry+https://github.com/rust-lang/crates.io-index)", + "gleam 0.2.29 (registry+https://github.com/rust-lang/crates.io-index)", "ipc-channel 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", "layout 0.0.1", "layout_thread 0.0.1", - "libc 0.2.17 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", "msg 0.0.1", "net 0.0.1", @@ -1438,11 +1485,11 @@ dependencies = [ "script 0.0.1", "script_layout_interface 0.0.1", "script_traits 0.0.1", + "servo_config 0.0.1", "servo_url 0.0.1", "sig 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "style 0.0.1", "url 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "util 0.0.1", "webdriver_server 0.0.1", "webrender 0.11.0 (git+https://github.com/servo/webrender)", "webrender_traits 0.11.0 (git+https://github.com/servo/webrender)", @@ -1450,11 +1497,11 @@ dependencies = [ [[package]] name = "libz-sys" -version = "1.0.6" +version = "1.0.10" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "gcc 0.3.35 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.17 (registry+https://github.com/rust-lang/crates.io-index)", + "gcc 0.3.40 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)", "pkg-config 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1478,12 +1525,12 @@ name = "malloc_buf" version = "0.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.2.17 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "matches" -version = "0.1.2" +version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -1491,7 +1538,7 @@ name = "memchr" version = "0.1.11" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.2.17 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1501,7 +1548,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "fs2 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)", "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.17 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1511,12 +1558,12 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 0.8.18 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 0.8.20 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "mime_guess" -version = "1.8.0" +version = "1.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "mime 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1530,8 +1577,8 @@ name = "miniz-sys" version = "0.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "gcc 0.3.35 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.17 (registry+https://github.com/rust-lang/crates.io-index)", + "gcc 0.3.40 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1540,9 +1587,9 @@ version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "bytes 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.17 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", - "miow 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", + "miow 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", "net2 0.2.26 (registry+https://github.com/rust-lang/crates.io-index)", "nix 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", "slab 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1552,7 +1599,7 @@ dependencies = [ [[package]] name = "miow" -version = "0.1.3" +version = "0.1.5" 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)", @@ -1566,8 +1613,8 @@ name = "mozjs_sys" version = "0.0.0" source = "git+https://github.com/servo/mozjs#f7917c480e3378441ee54c0554f6a3af9fb57464" dependencies = [ - "libc 0.2.17 (registry+https://github.com/rust-lang/crates.io-index)", - "libz-sys 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)", + "libz-sys 1.0.10 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1577,7 +1624,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "mp4parse" -version = "0.5.0" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "byteorder 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1592,8 +1639,8 @@ dependencies = [ "heapsize 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", "heapsize_derive 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", "plugins 0.0.1", - "serde 0.8.18 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_derive 0.8.18 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 0.8.20 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive 0.8.20 (registry+https://github.com/rust-lang/crates.io-index)", "webrender_traits 0.11.0 (git+https://github.com/servo/webrender)", ] @@ -1602,36 +1649,36 @@ name = "net" version = "0.0.1" dependencies = [ "bitflags 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", - "brotli 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", + "brotli 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)", "content-blocker 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "cookie 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)", "devtools_traits 0.0.1", "flate2 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)", - "hyper 0.9.11 (registry+https://github.com/rust-lang/crates.io-index)", + "hyper 0.9.14 (registry+https://github.com/rust-lang/crates.io-index)", "hyper_serde 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", "immeta 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", "ipc-channel 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 0.2.1 (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)", - "matches 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", + "matches 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", "mime 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", - "mime_guess 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)", + "mime_guess 1.8.1 (registry+https://github.com/rust-lang/crates.io-index)", "msg 0.0.1", "net_traits 0.0.1", "openssl 0.7.14 (registry+https://github.com/rust-lang/crates.io-index)", "openssl-verify 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "plugins 0.0.1", "profile_traits 0.0.1", - "rustc-serialize 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 0.8.18 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_derive 0.8.18 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-serialize 0.3.22 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 0.8.20 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive 0.8.20 (registry+https://github.com/rust-lang/crates.io-index)", + "servo_config 0.0.1", "servo_url 0.0.1", "threadpool 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)", "time 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)", - "tinyfiledialogs 0.1.0 (git+https://github.com/jdm/tinyfiledialogs)", + "tinyfiledialogs 2.5.9 (git+https://github.com/jdm/tinyfiledialogs)", "unicase 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "url 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "util 0.0.1", "uuid 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "webrender_traits 0.11.0 (git+https://github.com/servo/webrender)", "websocket 0.17.1 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1644,7 +1691,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "cfg-if 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.17 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", "ws2_32-sys 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1657,7 +1704,7 @@ dependencies = [ "cookie 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)", "devtools_traits 0.0.1", "flate2 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)", - "hyper 0.9.11 (registry+https://github.com/rust-lang/crates.io-index)", + "hyper 0.9.14 (registry+https://github.com/rust-lang/crates.io-index)", "hyper_serde 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", "ipc-channel 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", "msg 0.0.1", @@ -1665,34 +1712,33 @@ dependencies = [ "net_traits 0.0.1", "plugins 0.0.1", "profile_traits 0.0.1", + "servo_config 0.0.1", "servo_url 0.0.1", "time 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)", "unicase 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "url 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "util 0.0.1", ] [[package]] name = "net_traits" version = "0.0.1" dependencies = [ - "bluetooth_traits 0.0.1", "cookie 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)", "heapsize 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", "heapsize_derive 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", - "hyper 0.9.11 (registry+https://github.com/rust-lang/crates.io-index)", + "hyper 0.9.14 (registry+https://github.com/rust-lang/crates.io-index)", "hyper_serde 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", - "image 0.10.3 (registry+https://github.com/rust-lang/crates.io-index)", + "image 0.10.4 (registry+https://github.com/rust-lang/crates.io-index)", "ipc-channel 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 0.2.1 (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)", "msg 0.0.1", - "num-traits 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 0.8.18 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_derive 0.8.18 (registry+https://github.com/rust-lang/crates.io-index)", + "num-traits 0.1.36 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 0.8.20 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive 0.8.20 (registry+https://github.com/rust-lang/crates.io-index)", + "servo_config 0.0.1", "servo_url 0.0.1", "url 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "util 0.0.1", "uuid 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "webrender_traits 0.11.0 (git+https://github.com/servo/webrender)", "websocket 0.17.1 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1711,7 +1757,7 @@ version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "bitflags 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.17 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1719,7 +1765,7 @@ name = "nodrop" version = "0.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "odds 0.2.16 (registry+https://github.com/rust-lang/crates.io-index)", + "odds 0.2.25 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1733,12 +1779,12 @@ version = "0.1.0" [[package]] name = "num" -version = "0.1.35" +version = "0.1.36" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "num-integer 0.1.32 (registry+https://github.com/rust-lang/crates.io-index)", "num-iter 0.1.32 (registry+https://github.com/rust-lang/crates.io-index)", - "num-traits 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)", + "num-traits 0.1.36 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1747,9 +1793,9 @@ version = "0.1.35" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "num-integer 0.1.32 (registry+https://github.com/rust-lang/crates.io-index)", - "num-traits 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc-serialize 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)", + "num-traits 0.1.36 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-serialize 0.3.22 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1757,7 +1803,7 @@ name = "num-integer" version = "0.1.32" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "num-traits 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)", + "num-traits 0.1.36 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1766,7 +1812,7 @@ version = "0.1.32" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "num-integer 0.1.32 (registry+https://github.com/rust-lang/crates.io-index)", - "num-traits 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)", + "num-traits 0.1.36 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1776,26 +1822,26 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "num-bigint 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)", "num-integer 0.1.32 (registry+https://github.com/rust-lang/crates.io-index)", - "num-traits 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc-serialize 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)", + "num-traits 0.1.36 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-serialize 0.3.22 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "num-traits" -version = "0.1.35" +version = "0.1.36" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "num_cpus" -version = "1.1.0" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.2.17 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "objc" -version = "0.2.1" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "malloc_buf 0.0.6 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1803,7 +1849,7 @@ dependencies = [ [[package]] name = "odds" -version = "0.2.16" +version = "0.2.25" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -1813,18 +1859,18 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "cgl 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", "core-foundation 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", - "euclid 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)", + "euclid 0.10.3 (registry+https://github.com/rust-lang/crates.io-index)", "gdi32-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "gl_generator 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)", - "gleam 0.2.24 (registry+https://github.com/rust-lang/crates.io-index)", + "gleam 0.2.29 (registry+https://github.com/rust-lang/crates.io-index)", "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 0.2.1 (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)", "osmesa-sys 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 0.8.18 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 0.8.20 (registry+https://github.com/rust-lang/crates.io-index)", "user32-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", - "x11 2.8.0 (registry+https://github.com/rust-lang/crates.io-index)", + "x11 2.11.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1855,9 +1901,9 @@ version = "0.7.14" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "bitflags 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", - "gcc 0.3.35 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.17 (registry+https://github.com/rust-lang/crates.io-index)", + "gcc 0.3.40 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)", "openssl-sys 0.7.17 (registry+https://github.com/rust-lang/crates.io-index)", "openssl-sys-extras 0.7.14 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1868,7 +1914,7 @@ version = "0.7.17" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "gdi32-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.17 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)", "libressl-pnacl-sys 2.1.6 (registry+https://github.com/rust-lang/crates.io-index)", "pkg-config 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", "user32-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1879,8 +1925,8 @@ name = "openssl-sys-extras" version = "0.7.14" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "gcc 0.3.35 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.17 (registry+https://github.com/rust-lang/crates.io-index)", + "gcc 0.3.40 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)", "openssl-sys 0.7.17 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1897,14 +1943,14 @@ name = "ordered-float" version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "num-traits 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)", + "num-traits 0.1.36 (registry+https://github.com/rust-lang/crates.io-index)", "unreachable 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "osmesa-src" version = "12.0.1" -source = "git+https://github.com/servo/osmesa-src#ec520f5f2230e96dc94658d100fa882b0076a397" +source = "git+https://github.com/servo/osmesa-src#42509fbd70d0e54e1278849b771ea1cb1c3386f4" [[package]] name = "osmesa-sys" @@ -1921,21 +1967,21 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "parking_lot" -version = "0.3.3" +version = "0.3.6" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "owning_ref 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", - "parking_lot_core 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", + "parking_lot_core 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "parking_lot_core" -version = "0.1.4" +version = "0.2.0" 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)", - "libc 0.2.17 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)", "smallvec 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1963,7 +2009,7 @@ version = "0.7.20" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "phf_shared 0.7.20 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -2029,17 +2075,17 @@ version = "0.0.1" dependencies = [ "heartbeats-simple 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "ipc-channel 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.17 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", "plugins 0.0.1", "profile_traits 0.0.1", - "regex 0.1.76 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 0.8.18 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_derive 0.8.18 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)", + "regex 0.1.80 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 0.8.20 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive 0.8.20 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 0.8.4 (registry+https://github.com/rust-lang/crates.io-index)", + "servo_config 0.0.1", "task_info 0.0.1", "time 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)", - "util 0.0.1", ] [[package]] @@ -2056,23 +2102,44 @@ name = "profile_traits" version = "0.0.1" dependencies = [ "energy-monitor 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "energymon 0.2.0 (git+https://github.com/energymon/energymon-rust.git)", + "energymon 0.3.0 (git+https://github.com/energymon/energymon-rust.git)", "ipc-channel 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", "plugins 0.0.1", - "serde 0.8.18 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_derive 0.8.18 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 0.8.20 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive 0.8.20 (registry+https://github.com/rust-lang/crates.io-index)", + "servo_config 0.0.1", "signpost 0.1.0 (git+https://github.com/pcwalton/signpost.git)", "time 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)", - "util 0.0.1", +] + +[[package]] +name = "quasi" +version = "0.26.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "syntex_errors 0.50.0 (registry+https://github.com/rust-lang/crates.io-index)", + "syntex_syntax 0.50.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "quasi_codegen" +version = "0.26.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "aster 0.34.0 (registry+https://github.com/rust-lang/crates.io-index)", + "syntex 0.50.0 (registry+https://github.com/rust-lang/crates.io-index)", + "syntex_errors 0.50.0 (registry+https://github.com/rust-lang/crates.io-index)", + "syntex_syntax 0.50.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "quickersort" -version = "2.1.0" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "num-traits 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)", + "nodrop 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", + "num-traits 0.1.36 (registry+https://github.com/rust-lang/crates.io-index)", "unreachable 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -2083,15 +2150,15 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "quote" -version = "0.3.5" +version = "0.3.10" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "rand" -version = "0.3.14" +version = "0.3.15" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.2.17 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -2100,21 +2167,21 @@ version = "0.0.1" dependencies = [ "heapsize 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", "heapsize_derive 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", - "num-traits 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc-serialize 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 0.8.18 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_derive 0.8.18 (registry+https://github.com/rust-lang/crates.io-index)", + "num-traits 0.1.36 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-serialize 0.3.22 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 0.8.20 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive 0.8.20 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "rayon" -version = "0.5.0" +version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "deque 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.17 (registry+https://github.com/rust-lang/crates.io-index)", - "num_cpus 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)", + "num_cpus 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -2124,34 +2191,34 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "ref_slice" -version = "1.1.0" +version = "1.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "regex" -version = "0.1.76" +version = "0.1.80" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "aho-corasick 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)", "memchr 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)", - "regex-syntax 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", - "thread_local 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", + "regex-syntax 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", + "thread_local 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)", "utf8-ranges 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "regex-syntax" -version = "0.3.5" +version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "rustc-demangle" -version = "0.1.1" +version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "rustc-serialize" -version = "0.3.19" +version = "0.3.22" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -2178,57 +2245,58 @@ dependencies = [ "bluetooth_traits 0.0.1", "canvas_traits 0.0.1", "caseless 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "cmake 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)", + "cmake 0.1.20 (registry+https://github.com/rust-lang/crates.io-index)", "cookie 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)", "cssparser 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", "devtools_traits 0.0.1", "encoding 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)", - "euclid 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)", + "euclid 0.10.3 (registry+https://github.com/rust-lang/crates.io-index)", "fnv 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", "gfx_traits 0.0.1", "heapsize 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", "heapsize_derive 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", "html5ever 0.10.3 (registry+https://github.com/rust-lang/crates.io-index)", "html5ever-atoms 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "hyper 0.9.11 (registry+https://github.com/rust-lang/crates.io-index)", + "hyper 0.9.14 (registry+https://github.com/rust-lang/crates.io-index)", "hyper_serde 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", - "image 0.10.3 (registry+https://github.com/rust-lang/crates.io-index)", + "image 0.10.4 (registry+https://github.com/rust-lang/crates.io-index)", "ipc-channel 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", "js 0.1.3 (git+https://github.com/servo/rust-mozjs)", "jstraceable_derive 0.0.1", - "libc 0.2.17 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", "mime 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", - "mime_guess 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)", + "mime_guess 1.8.1 (registry+https://github.com/rust-lang/crates.io-index)", "msg 0.0.1", "net_traits 0.0.1", - "num-traits 0.1.35 (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.5.1 (registry+https://github.com/rust-lang/crates.io-index)", "open 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "parking_lot 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", + "parking_lot 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", "phf 0.7.20 (registry+https://github.com/rust-lang/crates.io-index)", "phf_macros 0.7.20 (registry+https://github.com/rust-lang/crates.io-index)", "plugins 0.0.1", "profile_traits 0.0.1", - "rand 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)", "range 0.0.1", "ref_filter_map 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", - "ref_slice 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "regex 0.1.76 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc-serialize 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)", + "ref_slice 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "regex 0.1.80 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-serialize 0.3.22 (registry+https://github.com/rust-lang/crates.io-index)", "script_layout_interface 0.0.1", "script_traits 0.0.1", "selectors 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 0.8.18 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 0.8.20 (registry+https://github.com/rust-lang/crates.io-index)", "servo_atoms 0.0.1", + "servo_config 0.0.1", + "servo_geometry 0.0.1", "servo_url 0.0.1", "smallvec 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", "style 0.0.1", "style_traits 0.0.1", "time 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)", - "tinyfiledialogs 0.1.0 (git+https://github.com/jdm/tinyfiledialogs)", + "tinyfiledialogs 2.5.9 (git+https://github.com/jdm/tinyfiledialogs)", "url 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "util 0.0.1", "uuid 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "webrender_traits 0.11.0 (git+https://github.com/servo/webrender)", "websocket 0.17.1 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2243,13 +2311,13 @@ dependencies = [ "bitflags 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", "canvas_traits 0.0.1", "cssparser 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", - "euclid 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)", + "euclid 0.10.3 (registry+https://github.com/rust-lang/crates.io-index)", "gfx_traits 0.0.1", "heapsize 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", "heapsize_derive 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", "html5ever-atoms 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "ipc-channel 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.17 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", "msg 0.0.1", "net_traits 0.0.1", @@ -2282,22 +2350,22 @@ dependencies = [ "canvas_traits 0.0.1", "cookie 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)", "devtools_traits 0.0.1", - "euclid 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)", + "euclid 0.10.3 (registry+https://github.com/rust-lang/crates.io-index)", "gfx_traits 0.0.1", "heapsize 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", "heapsize_derive 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", - "hyper 0.9.11 (registry+https://github.com/rust-lang/crates.io-index)", + "hyper 0.9.14 (registry+https://github.com/rust-lang/crates.io-index)", "hyper_serde 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", "ipc-channel 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.17 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)", "msg 0.0.1", "net_traits 0.0.1", "offscreen_gl_context 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", "plugins 0.0.1", "profile_traits 0.0.1", - "rustc-serialize 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 0.8.18 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_derive 0.8.18 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-serialize 0.3.22 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 0.8.20 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive 0.8.20 (registry+https://github.com/rust-lang/crates.io-index)", "servo_url 0.0.1", "style_traits 0.0.1", "time 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2312,7 +2380,7 @@ dependencies = [ "bitflags 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", "cssparser 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", "fnv 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", - "matches 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", + "matches 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -2330,46 +2398,46 @@ dependencies = [ [[package]] name = "serde" -version = "0.8.18" +version = "0.8.20" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "serde_codegen" -version = "0.8.18" +version = "0.8.20" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "quote 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_codegen_internals 0.11.1 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 0.10.3 (registry+https://github.com/rust-lang/crates.io-index)", + "quote 0.3.10 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_codegen_internals 0.11.2 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 0.10.5 (registry+https://github.com/rust-lang/crates.io-index)", "syntex 0.50.0 (registry+https://github.com/rust-lang/crates.io-index)", "syntex_syntax 0.50.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "serde_codegen_internals" -version = "0.11.1" +version = "0.11.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "syn 0.10.3 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 0.10.5 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "serde_derive" -version = "0.8.18" +version = "0.8.20" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "serde_codegen 0.8.18 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_codegen 0.8.20 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "serde_json" -version = "0.8.1" +version = "0.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "dtoa 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", "itoa 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "num-traits 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 0.8.18 (registry+https://github.com/rust-lang/crates.io-index)", + "num-traits 0.1.36 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 0.8.20 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -2377,13 +2445,14 @@ name = "servo" version = "0.0.1" dependencies = [ "android_glue 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "android_injected_glue 0.2.1 (git+https://github.com/mmatyas/android-rs-injected-glue)", "backtrace 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", "browserhtml 0.1.17 (git+https://github.com/browserhtml/browserhtml?branch=crate)", "compiletest_helper 0.0.1", "gfx_tests 0.0.1", "glutin_app 0.0.1", "layout_tests 0.0.1", - "libc 0.2.17 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)", "libservo 0.0.1", "log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", "net_tests 0.0.1", @@ -2392,9 +2461,10 @@ dependencies = [ "plugin_compiletest 0.0.1", "profile_tests 0.0.1", "script_tests 0.0.1", + "servo_config_tests 0.0.1", + "servo_remutex_tests 0.0.1", "sig 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "style_tests 0.0.1", - "util_tests 0.0.1", ] [[package]] @@ -2402,7 +2472,7 @@ name = "servo-egl" version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.2.17 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -2410,7 +2480,7 @@ name = "servo-fontconfig" version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.2.17 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)", "servo-fontconfig-sys 4.0.2 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -2429,7 +2499,7 @@ name = "servo-freetype-sys" version = "4.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "cmake 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)", + "cmake 0.1.20 (registry+https://github.com/rust-lang/crates.io-index)", "pkg-config 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -2440,17 +2510,17 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "android_glue 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "cgl 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", - "cocoa 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", + "cocoa 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)", "core-foundation 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", "core-graphics 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", "dwmapi-sys 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "gdi32-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "gl_generator 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)", - "image 0.10.3 (registry+https://github.com/rust-lang/crates.io-index)", + "image 0.10.4 (registry+https://github.com/rust-lang/crates.io-index)", "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.17 (registry+https://github.com/rust-lang/crates.io-index)", - "objc 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)", + "objc 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", "osmesa-sys 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "shared_library 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", "shell32-sys 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2459,7 +2529,7 @@ dependencies = [ "wayland-kbd 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", "wayland-window 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", - "x11-dl 2.8.0 (registry+https://github.com/rust-lang/crates.io-index)", + "x11-dl 2.11.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -2468,18 +2538,18 @@ version = "0.20130412.24" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "cgl 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", - "cmake 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)", - "euclid 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)", + "cmake 0.1.20 (registry+https://github.com/rust-lang/crates.io-index)", + "euclid 0.10.3 (registry+https://github.com/rust-lang/crates.io-index)", "expat-sys 2.1.4 (registry+https://github.com/rust-lang/crates.io-index)", - "gleam 0.2.24 (registry+https://github.com/rust-lang/crates.io-index)", + "gleam 0.2.29 (registry+https://github.com/rust-lang/crates.io-index)", "glx 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "io-surface 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.17 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)", "servo-egl 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "servo-fontconfig-sys 4.0.2 (registry+https://github.com/rust-lang/crates.io-index)", "servo-freetype-sys 4.0.3 (registry+https://github.com/rust-lang/crates.io-index)", "servo-glutin 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)", - "x11 2.8.0 (registry+https://github.com/rust-lang/crates.io-index)", + "x11 2.11.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -2487,7 +2557,59 @@ name = "servo_atoms" version = "0.0.1" dependencies = [ "string_cache 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "string_cache_codegen 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "string_cache_codegen 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "servo_config" +version = "0.0.1" +dependencies = [ + "bitflags 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", + "env_logger 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", + "euclid 0.10.3 (registry+https://github.com/rust-lang/crates.io-index)", + "getopts 0.2.14 (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)", + "num_cpus 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "plugins 0.0.1", + "rustc-serialize 0.3.22 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 0.8.20 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive 0.8.20 (registry+https://github.com/rust-lang/crates.io-index)", + "servo_geometry 0.0.1", + "servo_url 0.0.1", + "url 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "xdg 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "servo_config_tests" +version = "0.0.1" +dependencies = [ + "servo_config 0.0.1", +] + +[[package]] +name = "servo_geometry" +version = "0.0.1" +dependencies = [ + "app_units 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "euclid 0.10.3 (registry+https://github.com/rust-lang/crates.io-index)", + "heapsize 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "servo_remutex" +version = "0.0.1" +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)", +] + +[[package]] +name = "servo_remutex_tests" +version = "0.0.1" +dependencies = [ + "servo_remutex 0.0.1", ] [[package]] @@ -2496,8 +2618,8 @@ version = "0.0.1" dependencies = [ "heapsize 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", "heapsize_derive 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 0.8.18 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_derive 0.8.18 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 0.8.20 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive 0.8.20 (registry+https://github.com/rust-lang/crates.io-index)", "url 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -2511,8 +2633,8 @@ name = "shared_library" version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "lazy_static 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.17 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -2532,7 +2654,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "signpost" version = "0.1.0" -source = "git+https://github.com/pcwalton/signpost.git#81803b4d09af51a3a1133a62ef8dbb3cf0595de9" +source = "git+https://github.com/pcwalton/signpost.git#7ed712507f343c38646b9d1fefd049166f9c9a18" [[package]] name = "simd" @@ -2565,19 +2687,20 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "debug_unreachable 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "heapsize 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", "phf_shared 0.7.20 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 0.8.18 (registry+https://github.com/rust-lang/crates.io-index)", - "string_cache_codegen 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 0.8.20 (registry+https://github.com/rust-lang/crates.io-index)", + "string_cache_codegen 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "string_cache_shared 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "string_cache_codegen" -version = "0.3.0" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "phf_generator 0.7.20 (registry+https://github.com/rust-lang/crates.io-index)", + "string_cache_shared 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -2594,38 +2717,41 @@ dependencies = [ "cfg-if 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "cssparser 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", "encoding 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)", - "euclid 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)", + "euclid 0.10.3 (registry+https://github.com/rust-lang/crates.io-index)", "fnv 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", "heapsize 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", "heapsize_derive 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", "html5ever-atoms 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", + "libbindgen 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", - "matches 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", + "matches 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", "nsstring_vendor 0.1.0", "num-integer 0.1.32 (registry+https://github.com/rust-lang/crates.io-index)", - "num-traits 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)", - "num_cpus 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "num-traits 0.1.36 (registry+https://github.com/rust-lang/crates.io-index)", + "num_cpus 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "ordered-float 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", "owning_ref 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", - "parking_lot 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", - "plugins 0.0.1", - "quickersort 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)", - "rayon 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc-serialize 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)", + "parking_lot 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", + "phf 0.7.20 (registry+https://github.com/rust-lang/crates.io-index)", + "phf_codegen 0.7.20 (registry+https://github.com/rust-lang/crates.io-index)", + "quickersort 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)", + "rayon 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", + "regex 0.1.80 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-serialize 0.3.22 (registry+https://github.com/rust-lang/crates.io-index)", "selectors 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 0.8.18 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_derive 0.8.18 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 0.8.20 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive 0.8.20 (registry+https://github.com/rust-lang/crates.io-index)", "servo_atoms 0.0.1", + "servo_config 0.0.1", "servo_url 0.0.1", "smallvec 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", "style_traits 0.0.1", "time 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)", - "unicode-segmentation 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "util 0.0.1", - "walkdir 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", + "unicode-segmentation 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", + "walkdir 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -2634,17 +2760,19 @@ version = "0.0.1" dependencies = [ "app_units 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "cssparser 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", - "euclid 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)", + "euclid 0.10.3 (registry+https://github.com/rust-lang/crates.io-index)", "html5ever-atoms 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", + "matches 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", "owning_ref 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", - "parking_lot 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc-serialize 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)", + "parking_lot 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", + "rayon 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-serialize 0.3.22 (registry+https://github.com/rust-lang/crates.io-index)", "selectors 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)", "servo_atoms 0.0.1", + "servo_config 0.0.1", "servo_url 0.0.1", "style 0.0.1", "style_traits 0.0.1", - "util 0.0.1", ] [[package]] @@ -2653,12 +2781,12 @@ version = "0.0.1" dependencies = [ "app_units 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "cssparser 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", - "euclid 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)", + "euclid 0.10.3 (registry+https://github.com/rust-lang/crates.io-index)", "heapsize 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", "heapsize_derive 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc-serialize 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 0.8.18 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_derive 0.8.18 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-serialize 0.3.22 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 0.8.20 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive 0.8.20 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -2667,14 +2795,14 @@ version = "0.0.1" dependencies = [ "app_units 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "cssparser 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", - "env_logger 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", - "euclid 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)", + "env_logger 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", + "euclid 0.10.3 (registry+https://github.com/rust-lang/crates.io-index)", "geckoservo 0.0.1", - "lazy_static 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.17 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", - "num_cpus 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "parking_lot 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", + "num_cpus 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "parking_lot 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", "selectors 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)", "servo_url 0.0.1", "style 0.0.1", @@ -2683,10 +2811,10 @@ dependencies = [ [[package]] name = "syn" -version = "0.10.3" +version = "0.10.5" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "quote 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", + "quote 0.3.10 (registry+https://github.com/rust-lang/crates.io-index)", "unicode-xid 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -2695,8 +2823,8 @@ name = "synstructure" version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "quote 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 0.10.3 (registry+https://github.com/rust-lang/crates.io-index)", + "quote 0.3.10 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 0.10.5 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -2713,9 +2841,9 @@ name = "syntex_errors" version = "0.50.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.2.17 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc-serialize 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-serialize 0.3.22 (registry+https://github.com/rust-lang/crates.io-index)", "syntex_pos 0.50.0 (registry+https://github.com/rust-lang/crates.io-index)", "term 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)", "unicode-xid 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2726,7 +2854,7 @@ name = "syntex_pos" version = "0.50.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "rustc-serialize 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-serialize 0.3.22 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -2735,9 +2863,9 @@ version = "0.50.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "bitflags 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.17 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc-serialize 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-serialize 0.3.22 (registry+https://github.com/rust-lang/crates.io-index)", "syntex_errors 0.50.0 (registry+https://github.com/rust-lang/crates.io-index)", "syntex_pos 0.50.0 (registry+https://github.com/rust-lang/crates.io-index)", "term 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2746,17 +2874,19 @@ dependencies = [ [[package]] name = "target_build_utils" -version = "0.1.1" +version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "serde_json 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)", + "phf 0.7.20 (registry+https://github.com/rust-lang/crates.io-index)", + "phf_codegen 0.7.20 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 0.8.4 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "task_info" version = "0.0.1" dependencies = [ - "gcc 0.3.35 (registry+https://github.com/rust-lang/crates.io-index)", + "gcc 0.3.40 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -2764,7 +2894,7 @@ name = "tempdir" version = "0.3.5" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "rand 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -2773,8 +2903,8 @@ version = "2.1.4" 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)", - "libc 0.2.17 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)", "rustc_version 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -2805,12 +2935,12 @@ version = "2.0.0" 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)", - "libc 0.2.17 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "thread_local" -version = "0.2.6" +version = "0.2.7" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "thread-id 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2827,18 +2957,18 @@ version = "0.1.35" 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)", - "libc 0.2.17 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc-serialize 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-serialize 0.3.22 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "tinyfiledialogs" -version = "0.1.0" -source = "git+https://github.com/jdm/tinyfiledialogs#41d4268b6852ca5e53a484f0f915a9b63bca1707" +version = "2.5.9" +source = "git+https://github.com/jdm/tinyfiledialogs#4bf666ab49bf9aafcbbc34b6d4383db00d737654" dependencies = [ - "gcc 0.3.35 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.17 (registry+https://github.com/rust-lang/crates.io-index)", + "gcc 0.3.40 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -2846,7 +2976,7 @@ name = "toml" version = "0.1.30" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "rustc-serialize 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-serialize 0.3.22 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -2869,15 +2999,15 @@ dependencies = [ [[package]] name = "unicode-bidi" -version = "0.2.3" +version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "matches 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", + "matches 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "unicode-normalization" -version = "0.1.2" +version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -2890,7 +3020,7 @@ dependencies = [ [[package]] name = "unicode-segmentation" -version = "0.1.2" +version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -2914,9 +3044,9 @@ dependencies = [ "encoding 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)", "heapsize 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", "idna 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "matches 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc-serialize 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 0.8.18 (registry+https://github.com/rust-lang/crates.io-index)", + "matches 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-serialize 0.3.22 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 0.8.20 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -2933,7 +3063,7 @@ name = "utf-8" version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "matches 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", + "matches 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -2942,41 +3072,12 @@ version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] -name = "util" -version = "0.0.1" -dependencies = [ - "app_units 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "bitflags 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", - "env_logger 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", - "euclid 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)", - "getopts 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)", - "heapsize 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", - "num_cpus 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "plugins 0.0.1", - "rustc-serialize 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 0.8.18 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_derive 0.8.18 (registry+https://github.com/rust-lang/crates.io-index)", - "servo_url 0.0.1", - "url 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "xdg 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "util_tests" -version = "0.0.1" -dependencies = [ - "util 0.0.1", -] - -[[package]] name = "uuid" version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "rand 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 0.8.18 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 0.8.20 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -2986,7 +3087,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "walkdir" -version = "0.1.6" +version = "0.1.8" 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)", @@ -3000,8 +3101,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "bitflags 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", "crossbeam 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)", - "dlib 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.17 (registry+https://github.com/rust-lang/crates.io-index)", + "dlib 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)", "wayland-scanner 0.5.11 (registry+https://github.com/rust-lang/crates.io-index)", "wayland-sys 0.5.11 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -3012,7 +3113,7 @@ version = "0.3.6" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "bitflags 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", - "dlib 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "dlib 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)", "memmap 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", "wayland-client 0.5.12 (registry+https://github.com/rust-lang/crates.io-index)", @@ -3023,7 +3124,7 @@ name = "wayland-scanner" version = "0.5.11" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "xml-rs 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", + "xml-rs 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -3031,7 +3132,7 @@ name = "wayland-sys" version = "0.5.11" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "dlib 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "dlib 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -3051,17 +3152,17 @@ version = "0.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "cookie 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)", - "hyper 0.9.11 (registry+https://github.com/rust-lang/crates.io-index)", + "hyper 0.9.14 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", - "regex 0.1.76 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc-serialize 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)", + "regex 0.1.80 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-serialize 0.3.22 (registry+https://github.com/rust-lang/crates.io-index)", "time 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "webrender" version = "0.11.0" -source = "git+https://github.com/servo/webrender#c4a0c01f7a249a5786a5f32922574feb56b370b2" +source = "git+https://github.com/servo/webrender#845dcc9f0a2abdbe24754fb830897b0e3666e336" dependencies = [ "app_units 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "bincode 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -3070,16 +3171,16 @@ dependencies = [ "byteorder 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)", "core-graphics 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", "core-text 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "dwrote 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "euclid 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)", + "dwrote 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", + "euclid 0.10.3 (registry+https://github.com/rust-lang/crates.io-index)", "fnv 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", - "freetype 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "gleam 0.2.24 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "freetype 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", + "gleam 0.2.29 (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)", - "num-traits 0.1.35 (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.5.1 (registry+https://github.com/rust-lang/crates.io-index)", - "rayon 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", + "threadpool 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)", "time 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)", "webrender_traits 0.11.0 (git+https://github.com/servo/webrender)", ] @@ -3087,19 +3188,19 @@ dependencies = [ [[package]] name = "webrender_traits" version = "0.11.0" -source = "git+https://github.com/servo/webrender#c4a0c01f7a249a5786a5f32922574feb56b370b2" +source = "git+https://github.com/servo/webrender#845dcc9f0a2abdbe24754fb830897b0e3666e336" dependencies = [ "app_units 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "byteorder 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)", "core-graphics 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", - "dwrote 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "euclid 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)", - "gleam 0.2.24 (registry+https://github.com/rust-lang/crates.io-index)", + "dwrote 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", + "euclid 0.10.3 (registry+https://github.com/rust-lang/crates.io-index)", + "gleam 0.2.29 (registry+https://github.com/rust-lang/crates.io-index)", "heapsize 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", "ipc-channel 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", "offscreen_gl_context 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 0.8.18 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_derive 0.8.18 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 0.8.20 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive 0.8.20 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -3109,11 +3210,11 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "bitflags 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", "byteorder 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)", - "hyper 0.9.11 (registry+https://github.com/rust-lang/crates.io-index)", + "hyper 0.9.14 (registry+https://github.com/rust-lang/crates.io-index)", "net2 0.2.26 (registry+https://github.com/rust-lang/crates.io-index)", "openssl 0.7.14 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc-serialize 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-serialize 0.3.22 (registry+https://github.com/rust-lang/crates.io-index)", "unicase 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "url 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -3133,10 +3234,10 @@ name = "ws" version = "0.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "httparse 1.1.2 (registry+https://github.com/rust-lang/crates.io-index)", + "httparse 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", "mio 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)", "sha1 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "url 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -3152,20 +3253,20 @@ dependencies = [ [[package]] name = "x11" -version = "2.8.0" +version = "2.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.2.17 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)", "pkg-config 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "x11-dl" -version = "2.8.0" +version = "2.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "lazy_static 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.17 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)", "pkg-config 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -3181,7 +3282,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "xml-rs" -version = "0.3.4" +version = "0.3.5" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "bitflags 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -3197,7 +3298,7 @@ dependencies = [ "mac 0.0.2 (registry+https://github.com/rust-lang/crates.io-index)", "phf 0.7.20 (registry+https://github.com/rust-lang/crates.io-index)", "phf_codegen 0.7.20 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc-serialize 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-serialize 0.3.22 (registry+https://github.com/rust-lang/crates.io-index)", "tendril 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", "time 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -3206,13 +3307,15 @@ dependencies = [ "checksum aho-corasick 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)" = "ca972c2ea5f742bfce5687b9aef75506a764f61d37f8f649047846a9686ddb66" "checksum alloc-no-stdlib 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b21f6ad9c9957eb5d70c3dee16d31c092b3cab339628f821766b05e6833d72b8" "checksum android_glue 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7e2b80445d331077679dfc6f3014f3e9ab7083e588423d35041d3fc017198189" +"checksum android_injected_glue 0.2.1 (git+https://github.com/mmatyas/android-rs-injected-glue)" = "<none>" "checksum angle 0.1.2 (git+https://github.com/servo/angle?branch=servo)" = "<none>" "checksum app_units 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "636ee56f12e31dbc11dc0a1ac6004f08b04e6e6595963716fc8130e90d4e04cf" -"checksum arrayvec 0.3.17 (registry+https://github.com/rust-lang/crates.io-index)" = "80a137392e2e92ce7387c063d98a11f0d47115426c5f8759657af3c7b385c860" +"checksum arrayvec 0.3.20 (registry+https://github.com/rust-lang/crates.io-index)" = "d89f1b0e242270b5b797778af0c8d182a1a2ccac5d8d6fadf414223cc0fab096" +"checksum aster 0.34.0 (registry+https://github.com/rust-lang/crates.io-index)" = "88bb8ecdf6a7eaddb7bfd872ebf5e085d343ca42ce98c582dba8046e3450b524" "checksum audio-video-metadata 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "03da2550cb89fe3faf218c179261c26cf7891c4234707c15f5d09ebb32ae2400" -"checksum azure 0.9.1 (git+https://github.com/servo/rust-azure)" = "<none>" +"checksum azure 0.9.2 (git+https://github.com/servo/rust-azure)" = "<none>" "checksum backtrace 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "346d7644f0b5f9bc73082d3b2236b69a05fd35cce0cfa3724e184e6a5c9e2a2f" -"checksum backtrace-sys 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "ff73785ae8e06bb4a7b09e09f06d7434f9748b86d2f67bdf334b603354497e08" +"checksum backtrace-sys 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "3602e8d8c43336088a8505fa55cae2b3884a9be29440863a11528a42f46f6bb7" "checksum bincode 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "9fbba641f73d3e74a5431d4a6d9e42a70bcce76d466d796c852ba1db31ba41bc" "checksum bit-set 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d9bf6104718e80d7b26a68fdbacff3481cfc05df670821affc7e9cbc1884400c" "checksum bit-vec 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)" = "5b97c2c8e8bbb4251754f559df8af22fb264853c7d009084a576cdf12565089d" @@ -3222,18 +3325,20 @@ dependencies = [ "checksum blurdroid 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f4a86fbb3818e7f850410e026bfac7742fe86cbf4acf49f5752936b32d1f7eb8" "checksum blurmock 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "68dd72da3a3bb40f3d3bdd366c4cf8e2b1d208c366304f382c80cef8126ca8da" "checksum blurz 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "4d49796c8d5a1b5f6b2b8686e46ed4ab842987c477f765b69f1d3e8df6072608" -"checksum brotli 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)" = "bff2d5511b5ba5840f46cc3f9c0c3ab09db20e9b9a4db344ef7df3fb547a627a" +"checksum brotli 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)" = "53c6bf6d5a852a221369ffb01ea08fdaf89d5cbd6e12a4b8802cdb322a93c6cd" "checksum browserhtml 0.1.17 (git+https://github.com/browserhtml/browserhtml?branch=crate)" = "<none>" "checksum byteorder 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)" = "0fc10e8cc6b2580fda3f36eb6dc5316657f812a3df879a44a66fc9f0fdbc4855" "checksum bytes 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c129aff112dcc562970abb69e2508b40850dd24c274761bb50fb8a0067ba6c27" "checksum caseless 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b6893f86ac0c9275b5cbba9212ccd71020b447d4c3e2eebad70e1bc47fdd6dfb" +"checksum cexpr 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "393a5f0088efbe41f9d1fcd062f24e83c278608420e62109feb2c8abee07de7d" "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.12.0 (registry+https://github.com/rust-lang/crates.io-index)" = "822ea22bbbef9f5934e9477860545fb0311a1759e43a276de42e2856c605aa2b" "checksum clippy_lints 0.0.98 (registry+https://github.com/rust-lang/crates.io-index)" = "4329699b62341fd3ce3ebe13ade6c87d35b8778091e0c2f6da51399e081b9671" -"checksum cmake 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)" = "dfcf5bcece56ef953b8ea042509e9dcbdfe97820b7e20d86beb53df30ed94978" -"checksum cocoa 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "6d24ed9a15e9c0892cdb20c7acc3e50441501b990ee6dc318c176981829a7941" +"checksum cmake 0.1.20 (registry+https://github.com/rust-lang/crates.io-index)" = "a3a6805df695087e7c1bcd9a82e03ad6fb864c8e67ac41b1348229ce5b7f0407" +"checksum cocoa 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "1e1be5fd98bb7e8ef0eea233a4984f4e85ecdcfa002a90b8b12b7a20faf44dc1" "checksum color_quant 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a475fc4af42d83d28adf72968d9bcfaf035a1a9381642d8e85d8a04957767b0d" -"checksum compiletest_rs 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)" = "28d60af0dbee4912f00dda79ac3b06d1ca44b641d69359e6f1d4df7c985521d2" +"checksum compiletest_rs 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)" = "f3f344389765ad7bec166f64c1b39ed6dd2b54d81c4c5dd8af789169351d380c" "checksum content-blocker 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "1b0d86cb81505503bbfb0d47cf7e12be2e69205a75e70c4da84998e39b96b7f1" "checksum cookie 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)" = "0e3d6405328b6edb412158b3b7710e2634e23f3614b9bb1c412df7952489a626" "checksum core-foundation 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "20a6d0448d3a99d977ae4a2aa5a98d886a923e863e81ad9ff814645b6feb3bbd" @@ -3247,10 +3352,10 @@ dependencies = [ "checksum debug_unreachable 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "9a032eac705ca39214d169f83e3d3da290af06d8d1d344d1baad2fd002dca4b3" "checksum deque 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "1614659040e711785ed8ea24219140654da1729f3ec8a47a9719d041112fe7bf" "checksum device 0.0.1 (git+https://github.com/servo/devices)" = "<none>" -"checksum dlib 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8bd015f00d33d7e4ff66f1589fb824ccf3ccb10209b66c7b756f26ba9aa90215" +"checksum dlib 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "148bce4ce1c36c4509f29cb54e62c2bd265551a9b00b38070fad551a851866ec" "checksum dtoa 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "0dd841b58510c9618291ffa448da2e4e0f699d984d436122372f446dae62263d" "checksum dwmapi-sys 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "07c4c7cc7b396419bc0a4d90371d0cee16cb5053b53647d287c0b728000c41fe" -"checksum dwrote 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f8e46f81d58183d91a9d2dbd020538d8aef38e7d291aeae336d7f3ac15f941c0" +"checksum dwrote 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "22f91bd605c96566d22699af63ad29a7417bd8a9493570450634858e80c27ff3" "checksum encoding 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)" = "6b0d943856b990d12d3b55b359144ff341533e516d94098b1d3fc1ac666d36ec" "checksum encoding-index-japanese 1.20141219.5 (registry+https://github.com/rust-lang/crates.io-index)" = "04e8b2ff42e9a05335dbf8b5c6f7567e5591d0d916ccef4e0b1710d32a0d0c91" "checksum encoding-index-korean 1.20141219.5 (registry+https://github.com/rust-lang/crates.io-index)" = "4dc33fb8e6bcba213fe2f14275f0963fd16f0a02c878e3095ecfdf5bee529d81" @@ -3259,28 +3364,27 @@ dependencies = [ "checksum encoding-index-tradchinese 1.20141219.5 (registry+https://github.com/rust-lang/crates.io-index)" = "fd0e20d5688ce3cab59eb3ef3a2083a5c77bf496cb798dc6fcdb75f323890c18" "checksum encoding_index_tests 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "a246d82be1c9d791c5dfde9a2bd045fc3cbba3fa2b11ad558f27d01712f00569" "checksum energy-monitor 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fe872d0664f1cc60db36349af245d892ee67d3c8f78055df0ebc43271fd4e05c" -"checksum energymon 0.2.0 (git+https://github.com/energymon/energymon-rust.git)" = "<none>" -"checksum energymon-builder 0.2.0 (git+https://github.com/energymon/energymon-sys.git)" = "<none>" -"checksum energymon-default-sys 0.2.0 (git+https://github.com/energymon/energymon-sys.git)" = "<none>" -"checksum energymon-sys 0.2.0 (git+https://github.com/energymon/energymon-sys.git)" = "<none>" +"checksum energymon 0.3.0 (git+https://github.com/energymon/energymon-rust.git)" = "<none>" +"checksum energymon-builder 0.3.0 (git+https://github.com/energymon/energymon-sys.git)" = "<none>" +"checksum energymon-default-sys 0.3.0 (git+https://github.com/energymon/energymon-sys.git)" = "<none>" +"checksum energymon-sys 0.3.0 (git+https://github.com/energymon/energymon-sys.git)" = "<none>" "checksum enum_primitive 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f79eff5be92a4d7d5bddf7daa7d650717ea71628634efe6ca7bcda85b2183c23" -"checksum env_logger 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "82dcb9ceed3868a03b335657b85a159736c961900f7e7747d3b0b97b9ccb5ccb" -"checksum euclid 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)" = "44ef2a3e4a621518e488db36820a12b49a9d5004764b8daf1458bbe5d7c9b626" +"checksum env_logger 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "15abd780e45b3ea4f76b4e9a26ff4843258dd8a3eed2775a0e7368c2e7936c2f" +"checksum euclid 0.10.3 (registry+https://github.com/rust-lang/crates.io-index)" = "0c274f13773ec277a48408d0c7a8dc935ad4bfe190f4cfccd0126d203afc3c83" "checksum expat-sys 2.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "cef36cd1a8a02d28b91d97347c63247b9e4cb8a8e36df36f8201dc87a1c0859c" "checksum flate2 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)" = "3eeb481e957304178d2e782f2da1257f1434dfecbae883bafb61ada2a9fea3bb" "checksum fnv 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)" = "6cc484842f1e2884faf56f529f960cc12ad8c71ce96cc7abba0a067c98fee344" "checksum fontsan 0.3.2 (git+https://github.com/servo/fontsan)" = "<none>" -"checksum freetype 0.1.2 (git+https://github.com/servo/rust-freetype)" = "<none>" -"checksum freetype 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6a89563eaf185762cf495c56cb16277549d2aaa7b1240d93338e8429fa33acd1" +"checksum freetype 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "812b23abc34a2cd1e1a0635a8d65e9bc83f2dd6e7879b92683ed0b9faaa629e5" "checksum fs2 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)" = "bcd414e5a1a979b931bb92f41b7a54106d3f6d2e6c253e9ce943b7cd468251ef" "checksum futf 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e7a9689380a2553b51c564b3d9178075c68ebd0b397972c783acfd28b46c28ad" "checksum gaol 0.0.1 (git+https://github.com/servo/gaol)" = "<none>" -"checksum gcc 0.3.35 (registry+https://github.com/rust-lang/crates.io-index)" = "91ecd03771effb0c968fd6950b37e89476a578aaf1c70297d8e92b6516ec3312" +"checksum gcc 0.3.40 (registry+https://github.com/rust-lang/crates.io-index)" = "872db9e59486ef2b14f8e8c10e9ef02de2bccef6363d7f34835dedb386b3d950" "checksum gdi32-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "0912515a8ff24ba900422ecda800b52f4016a56251922d397c576bf92c690518" "checksum getopts 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)" = "d9047cfbd08a437050b363d35ef160452c5fe8ea5187ae0a624708c91581d685" "checksum gif 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "01c7c19a035de94bd7afbaa62c241aadfbdf1a70f560b348d2312eafa566ca16" "checksum gl_generator 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f1d8edc81c5ae84605a62f5dac661a2313003b26d59839f81d47d46cf0f16a55" -"checksum gleam 0.2.24 (registry+https://github.com/rust-lang/crates.io-index)" = "b04d6c8a1df841e48dfe99ed67829c9d1d17b1bb3e44c5f3283992010e20359b" +"checksum gleam 0.2.29 (registry+https://github.com/rust-lang/crates.io-index)" = "1b83402229bde9d923f0b92811be017f9df5946ee86f8647367b1e02bcf5c293" "checksum glob 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "8be18de09a56b60ed0edf84bc9df007e30040691af7acd1c41874faac5895bfb" "checksum glx 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "b280007fa9c7442cfd1e0b1addb8d1a59240267110e8705f8f7e2c7bfb7e2f72" "checksum harfbuzz-sys 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "6b76113246f5c089dcf272cf89c3f61168a4d77b50ec5b2c1fab8c628c9ea762" @@ -3291,57 +3395,58 @@ dependencies = [ "checksum hpack 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3d2da7d3a34cf6406d9d700111b8eafafe9a251de41ae71d8052748259343b58" "checksum html5ever 0.10.3 (registry+https://github.com/rust-lang/crates.io-index)" = "45815593feb142cf01121b9f413d8630c9902192d160e494a579c50628eef498" "checksum html5ever-atoms 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "fd3fc831590ee7fcf693c673e4e3cbe14fbda44dc0f26d9bdc79cfc9f551dc05" -"checksum httparse 1.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "46534074dbb80b070d60a5cb8ecadd8963a00a438ae1a95268850a7ef73b67ae" -"checksum hyper 0.9.11 (registry+https://github.com/rust-lang/crates.io-index)" = "edd47c66782933e546a32ae89ca3c49263b2ba9bc29f3a0d5c52fff48e0ac67c" +"checksum httparse 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a6e7a63e511f9edffbab707141fbb8707d1a3098615fb2adbd5769cdfcc9b17d" +"checksum hyper 0.9.14 (registry+https://github.com/rust-lang/crates.io-index)" = "bcb3fc65554155980167fb821d05c7c66177f92464976c0b676a19d9e03387a7" "checksum hyper_serde 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "572d2168173019de312a050a24f2ad33ac2ac7895a2139fbf21ee6b6f470a24e" "checksum idna 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1053236e00ce4f668aeca4a769a09b3bf5a682d802abd6f3cb39374f6b162c11" -"checksum image 0.10.3 (registry+https://github.com/rust-lang/crates.io-index)" = "559d5ebbe9ec73111799e49c07717944b244f8accf5de33a8a8128bc3ecd2e00" +"checksum image 0.10.4 (registry+https://github.com/rust-lang/crates.io-index)" = "76df2dce95fef56fd35dbc41c36e37b19aede703c6be7739e8b65d5788ffc728" "checksum immeta 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "3e76ecb1d64979a91c7fc5b7c0495ef1467e3cbff759044f2b88878a5a845ef7" "checksum inflate 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "e7e0062d2dc2f17d2f13750d95316ae8a2ff909af0fda957084f5defd87c43bb" "checksum io-surface 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3c93eb4952ee5b903c4193391779f90209e1b75ba55911097fa494f35e975846" "checksum ipc-channel 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "675587430ede6756dd03fdfdf9888f22f83855fd131c8451d842a710b059e571" "checksum itoa 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ae3088ea4baeceb0284ee9eea42f591226e6beaecf65373e41b38d95a1b8e7a1" -"checksum jpeg-decoder 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "4be50b418a1fc5d198588d9a4f682ef808a55db4084dce39d09bb0562525bb8c" +"checksum jpeg-decoder 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)" = "f5c064189dd32804b645d90406c24c23b5feed62dcf31bf3a97763ff20f5d689" "checksum js 0.1.3 (git+https://github.com/servo/rust-mozjs)" = "<none>" "checksum kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d" "checksum khronos_api 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "09c9d3760673c427d46f91a0350f0a84a52e6bc5a84adf26dc610b6c52436630" "checksum language-tags 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "a91d884b6667cd606bb5a69aa0c99ba811a115fc68915e7056ec08a46e93199a" "checksum lazy_static 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)" = "cf186d1a8aa5f5bee5fd662bc9c1b949e0259e1bcc379d1f006847b0080c7417" -"checksum lazy_static 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "49247ec2a285bb3dcb23cbd9c35193c025e7251bfce77c1d5da97e6362dffe7f" +"checksum lazy_static 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6abe0ee2e758cd6bc8a2cd56726359007748fbf4128da998b65d0b70f881e19b" "checksum leak 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "bd100e01f1154f2908dfa7d02219aeab25d0b9c7fa955164192e3245255a0c73" "checksum leaky-cow 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "40a8225d44241fd324a8af2806ba635fc7c8a7e9a7de4d5cf3ef54e71f5926fc" -"checksum libc 0.2.17 (registry+https://github.com/rust-lang/crates.io-index)" = "044d1360593a78f5c8e5e710beccdc24ab71d1f01bc19a29bcacdba22e8475d8" -"checksum libloading 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)" = "eceb2637ee9a27c7f19764048a9f377e40e3a70a322722f348e6bc7704d565f2" +"checksum libbindgen 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "b08a166f5cce21f217bcf61f73f166bb9fb5618b8db893c1bc5d24912f2b4988" +"checksum libc 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)" = "a51822fc847e7a8101514d1d44e354ba2ffa7d4c194dcab48870740e327cac70" +"checksum libloading 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "84816a8c6ed8163dfe0dbdd2b09d35c6723270ea77a4c7afa4bedf038a36cb99" "checksum libressl-pnacl-sys 2.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "cbc058951ab6a3ef35ca16462d7642c4867e6403520811f28537a4e2f2db3e71" -"checksum libz-sys 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)" = "40f2df7730b5d29426c3e44ce4d088d8c5def6471c2c93ba98585b89fb201ce6" +"checksum libz-sys 1.0.10 (registry+https://github.com/rust-lang/crates.io-index)" = "905c72a0c260bcd89ddca5afa1c46bebd29b52878a3d58c86865ea42402f88e6" "checksum log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "ab83497bf8bf4ed2a74259c1c802351fcd67a65baa86394b6ba73c36f4838054" "checksum lzw 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7d947cbb889ed21c2a84be6ffbaebf5b4e0f4340638cba0444907e38b56be084" "checksum mac 0.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "1b1db08c0d0ddbb591e65f1da58d1cefccc94a2faa0c55bf979ce215a3e04d5e" "checksum malloc_buf 0.0.6 (registry+https://github.com/rust-lang/crates.io-index)" = "62bb907fe88d54d8d9ce32a3cceab4218ed2f6b7d35617cafe9adf84e43919cb" -"checksum matches 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "15305656809ce5a4805b1ff2946892810992197ce1270ff79baded852187942e" +"checksum matches 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "efd7622e3022e1a6eaa602c4cea8912254e5582c9c692e9167714182244801b1" "checksum memchr 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)" = "d8b629fb514376c675b98c1421e80b151d3817ac42d7c667717d282761418d20" "checksum memmap 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "f20f72ed93291a72e22e8b16bb18762183bb4943f0f483da5b8be1a9e8192752" "checksum mime 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "b5c93a4bd787ddc6e7833c519b73a50883deb5863d76d9b71eb8216fb7f94e66" -"checksum mime_guess 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e9a7d89cb3bce9145b0d0339a0588b044e3e3e3faa1dcd74822ebdc36bfac020" +"checksum mime_guess 1.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "76da6df85047af8c0edfa53f48eb1073012ce1cc95c8fedc0a374f659a89dd65" "checksum miniz-sys 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "9d1f4d337a01c32e1f2122510fed46393d53ca35a7f429cb0450abaedfa3ed54" "checksum mio 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a637d1ca14eacae06296a008fa7ad955347e34efcb5891cfd8ba05491a37907e" -"checksum miow 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "d5bfc6782530ac8ace97af10a540054a37126b63b0702ddaaa243b73b5745b9a" +"checksum miow 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "3e690c5df6b2f60acd45d56378981e827ff8295562fc8d34f573deb267a59cd1" "checksum mozjs_sys 0.0.0 (git+https://github.com/servo/mozjs)" = "<none>" "checksum mp3-metadata 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "2f61cf32f7fc3cec83a15a255ac60bceb6cac59a7ce190cb824ca25c0fce0feb" -"checksum mp4parse 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1e3d4b79704ee1a9d307a92d2cb2c7186a8eb7e40bfca41e1c2fa9fcb152390a" +"checksum mp4parse 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "1e1736d06703a9cb5228b5a8151acc79bf5ba7669a810243852bcad4d3a25504" "checksum net2 0.2.26 (registry+https://github.com/rust-lang/crates.io-index)" = "5edf9cb6be97212423aed9413dd4729d62b370b5e1c571750e882cebbbc1e3e2" "checksum nix 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "bfb3ddedaa14746434a02041940495bf11325c22f6d36125d3bdd56090d50a79" "checksum nodrop 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "0dbbadd3f4c98dea0bd3d9b4be4c0cdaf1ab57035cb2e41fce3983db5add7cc5" "checksum nom 1.2.4 (registry+https://github.com/rust-lang/crates.io-index)" = "a5b8c256fd9471521bcb84c3cdba98921497f1a331cbc15b8030fc63b82050ce" -"checksum num 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)" = "5a9699207fab8b02bd0e56f8f06fee3f26d640303130de548898b4c9704f6d01" +"checksum num 0.1.36 (registry+https://github.com/rust-lang/crates.io-index)" = "bde7c03b09e7c6a301ee81f6ddf66d7a28ec305699e3d3b056d2fc56470e3120" "checksum num-bigint 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)" = "88b14378471f7c2adc5262f05b4701ef53e8da376453a8d8fee48e51db745e49" "checksum num-integer 0.1.32 (registry+https://github.com/rust-lang/crates.io-index)" = "fb24d9bfb3f222010df27995441ded1e954f8f69cd35021f6bef02ca9552fb92" "checksum num-iter 0.1.32 (registry+https://github.com/rust-lang/crates.io-index)" = "287a1c9969a847055e1122ec0ea7a5c5d6f72aad97934e131c83d5c08ab4e45c" "checksum num-rational 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)" = "54ff603b8334a72fbb27fe66948aac0abaaa40231b3cecd189e76162f6f38aaf" -"checksum num-traits 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)" = "8359ea48994f253fa958b5b90b013728b06f54872e5a58bce39540fcdd0f2527" -"checksum num_cpus 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8890e6084723d57d0df8d2720b0d60c6ee67d6c93e7169630e4371e88765dcad" -"checksum objc 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7c9311aa5acd7bee14476afa0f0557f564e9d0d61218a8b833d9b1f871fa5fba" -"checksum odds 0.2.16 (registry+https://github.com/rust-lang/crates.io-index)" = "f3701cfdec1676e319ad37ff96c31de39df8c92006032976153366f52693bf40" +"checksum num-traits 0.1.36 (registry+https://github.com/rust-lang/crates.io-index)" = "a16a42856a256b39c6d3484f097f6713e14feacd9bfb02290917904fae46c81c" +"checksum num_cpus 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "55aabf4e2d6271a2e4e4c0f2ea1f5b07cc589cc1a9e9213013b54a76678ca4f3" +"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.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2fe2fe54ba2b6ea8f43a17b16c13168c5bbf008e0fc91b34122a11f637e2728a" "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" @@ -3354,8 +3459,8 @@ dependencies = [ "checksum osmesa-src 12.0.1 (git+https://github.com/servo/osmesa-src)" = "<none>" "checksum osmesa-sys 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "88cfece6e95d2e717e0872a7f53a8684712ad13822a7979bc760b9c77ec0013b" "checksum owning_ref 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "8d91377085359426407a287ab16884a0111ba473aa6844ff01d4ec20ce3d75e7" -"checksum parking_lot 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "3562f3de7bdff194212be82366abf5c6565aff8a433b71c53c63d0e7c9913878" -"checksum parking_lot_core 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "06f24c980718110494e9cfb7db7438895c3f54505101bb6170329d5e43a53f64" +"checksum parking_lot 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "e1435e7a2a00dfebededd6c6bdbd54008001e94b4a2aadd6aef0dc4c56317621" +"checksum parking_lot_core 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fb1b97670a2ffadce7c397fb80a3d687c4f3060140b885621ef1653d0e5d5068" "checksum phf 0.7.20 (registry+https://github.com/rust-lang/crates.io-index)" = "0c6afb2057bb5f846a7b75703f90bc1cef4970c35209f712925db7768e999202" "checksum phf_codegen 0.7.20 (registry+https://github.com/rust-lang/crates.io-index)" = "6b63f121bf9a128f2172a65d8313a8e0e79d63874eeb4b4b7d82e6dda6b62f7c" "checksum phf_generator 0.7.20 (registry+https://github.com/rust-lang/crates.io-index)" = "50ffbd7970f75afa083c5dd7b6830c97b72b81579c7a92d8134ef2ee6c0c7eb0" @@ -3364,27 +3469,29 @@ dependencies = [ "checksum pkg-config 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)" = "8cee804ecc7eaf201a4a207241472cc870e825206f6c031e3ee2a72fa425f2fa" "checksum pnacl-build-helper 1.4.10 (registry+https://github.com/rust-lang/crates.io-index)" = "61c9231d31aea845007443d62fcbb58bb6949ab9c18081ee1e09920e0cf1118b" "checksum png 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "06208e2ee243e3118a55dda9318f821f206d8563fb8d4df258767f8e62bb0997" -"checksum quickersort 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e952ea7699262481636004bc4ab8afaccf2bc13f91b79d1aee6617bd8fc39651" +"checksum quasi 0.26.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8ab7992920bf5bc5f1ed6fdc49090bf665cd00b3aa4b78c16ac3465286257db1" +"checksum quasi_codegen 0.26.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d52e5e2c92ffdad67a9b86ad27ad999bf1a652723f1d4cc93b7cf6c272b5f8e0" +"checksum quickersort 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "14ae8f367c38c78abd03114e524b55a817885446662413fbca951f42848450c5" "checksum quine-mc_cluskey 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)" = "07589615d719a60c8dd8a4622e7946465dfef20d1a428f969e3443e7386d5f45" -"checksum quote 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "ea1e0c9bc6bfb0a60d539aab6e338207c1a5456e62f5bd5375132cee119aa4b3" -"checksum rand 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)" = "2791d88c6defac799c3f20d74f094ca33b9332612d9aef9078519c82e4fe04a5" -"checksum rayon 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3b6a6e05e0e6b703e9f2ad266eb63f3712e693a17a2702b95a23de14ce8defa9" +"checksum quote 0.3.10 (registry+https://github.com/rust-lang/crates.io-index)" = "6732e32663c9c271bfc7c1823486b471f18c47a2dbf87c066897b7b51afc83be" +"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 ref_filter_map 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2b5ceb840e4009da4841ed22a15eb49f64fdd00a2138945c5beacf506b2fb5ed" -"checksum ref_slice 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "546bb4aa91c85f232732cc5b3c8097ea97ae9a77304f9ab4df8b203ff7672dad" -"checksum regex 0.1.76 (registry+https://github.com/rust-lang/crates.io-index)" = "63b49f873f36ddc838d773972511e5fed2ef7350885af07d58e2f48ce8073dcd" -"checksum regex-syntax 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "279401017ae31cf4e15344aa3f085d0e2e5c1e70067289ef906906fdbe92c8fd" -"checksum rustc-demangle 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c4c2d35b2ed94cec4fad26a36eee4d6eff394ce70a8ceea064b0b6ca42ea4cf0" -"checksum rustc-serialize 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)" = "6159e4e6e559c81bd706afe9c8fd68f547d3e851ce12e76b1de7914bab61691b" +"checksum ref_slice 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "825740057197b7d43025e7faf6477eaabc03434e153233da02d1f44602f71527" +"checksum regex 0.1.80 (registry+https://github.com/rust-lang/crates.io-index)" = "4fd4ace6a8cf7860714a2c2280d6c1f7e6a413486c13298bbc86fd3da019402f" +"checksum regex-syntax 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)" = "f9ec002c35e86791825ed294b50008eea9ddfc8def4420124fbc6b08db834957" +"checksum rustc-demangle 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "1430d286cadb237c17c885e25447c982c97113926bb579f4379c0eca8d9586dc" +"checksum rustc-serialize 0.3.22 (registry+https://github.com/rust-lang/crates.io-index)" = "237546c689f20bb44980270c73c3b9edd0891c1be49cc1274406134a66d3957b" "checksum rustc_version 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "c5f5376ea5e30ce23c03eb77cbe4962b988deead10910c372b226388b594c084" "checksum scoped_threadpool 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "3ef399c8893e8cb7aa9696e895427fab3a6bf265977bb96e126f24ddd2cda85a" "checksum selectors 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)" = "75b127ac14249f6ce720277f6a163b3837706e9dc1ad4e2948db55f262f11a97" "checksum semver 0.1.20 (registry+https://github.com/rust-lang/crates.io-index)" = "d4f410fedcf71af0345d7607d246e7ad15faaadd49d240ee3b24e5dc21a820ac" "checksum semver 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "2d5b7638a1f03815d94e88cb3b3c08e87f0db4d683ef499d1836aaf70a45623f" -"checksum serde 0.8.18 (registry+https://github.com/rust-lang/crates.io-index)" = "d9b524a2fac246f45c36a7f3a5742c19dcb0b2d1252d1ad5458ca07f26e04a57" -"checksum serde_codegen 0.8.18 (registry+https://github.com/rust-lang/crates.io-index)" = "d658b798b60791e72c4d518bed618b12318527c7a5adae41c23da61fa3656bd6" -"checksum serde_codegen_internals 0.11.1 (registry+https://github.com/rust-lang/crates.io-index)" = "59933a62554548c690d2673c5164f0c4a46be7c5731edfd94b0ecb1048940732" -"checksum serde_derive 0.8.18 (registry+https://github.com/rust-lang/crates.io-index)" = "d91be8acdeb9128d3a074986a36b90fc8ad0a3001c6bd1231aea219ae790aa4a" -"checksum serde_json 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0e10f8a9d94b06cf5d3bef66475f04c8ff90950f1be7004c357ff9472ccbaebc" +"checksum serde 0.8.20 (registry+https://github.com/rust-lang/crates.io-index)" = "793aa8d4a777e46a68bbf88998cd957e638427ba5bfb0de22c92ff277b65bd21" +"checksum serde_codegen 0.8.20 (registry+https://github.com/rust-lang/crates.io-index)" = "460354e47fffa7cf0c96fcf9a040fd170e957f43dd8032531083866eb4a51c11" +"checksum serde_codegen_internals 0.11.2 (registry+https://github.com/rust-lang/crates.io-index)" = "55224f713f022184a1c332dc5c8b1ac634d25a355d54836386771947f12585e0" +"checksum serde_derive 0.8.20 (registry+https://github.com/rust-lang/crates.io-index)" = "18030bce88caabea7707ea4150557377f4b08df5ba3909b2c6a9cb34967c9f30" +"checksum serde_json 0.8.4 (registry+https://github.com/rust-lang/crates.io-index)" = "3f7d3c184d35801fb8b32b46a7d58d57dbcc150b0eb2b46a1eb79645e8ecfd5b" "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" "checksum servo-fontconfig-sys 4.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "a0af4a4d7746467921486e5c5420f815cc016a6bf5574210d8e9c00f4afae224" @@ -3401,32 +3508,32 @@ dependencies = [ "checksum smallvec 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "fcc8d19212aacecf95e4a7a2179b26f7aeb9732a915cf01f05b0d3e044865410" "checksum solicit 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)" = "172382bac9424588d7840732b250faeeef88942e37b6e35317dce98cafdd75b2" "checksum string_cache 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c4d192db2123fac37399e1ca61557904a5c3fb6fc24c73d2e47b15d20dc32470" -"checksum string_cache_codegen 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ff92eda33653ce0ec418b61dbb939b777cc45c0a88528d4020f1b3241b409006" +"checksum string_cache_codegen 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0c9dfe1a7c8bba1ecb90730d269fdc08afe93d23c28dd6c4aa5cabd79a05a05e" "checksum string_cache_shared 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b1884d1bc09741d466d9b14e6d37ac89d6909cbcac41dd9ae982d4d063bbedfc" -"checksum syn 0.10.3 (registry+https://github.com/rust-lang/crates.io-index)" = "94e7d81ecd16d39f16193af05b8d5a0111b9d8d2f3f78f31760f327a247da777" +"checksum syn 0.10.5 (registry+https://github.com/rust-lang/crates.io-index)" = "1a437f8b4353179418870f014113876cd4cd4f642e42dbc5ed4f328d5f808246" "checksum synstructure 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e13808dc5a739d5ff1cff4a2361afdf4ec52d42221c7ddc1d8c438f5a53746a7" "checksum syntex 0.50.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3bd253b0d7d787723a33384d426f0ebec7f8edccfaeb2022d0177162bb134da0" "checksum syntex_errors 0.50.0 (registry+https://github.com/rust-lang/crates.io-index)" = "84822a1178204a191239ad844599f8c85c128cf9f4173397def4eb46b55b0aa1" "checksum syntex_pos 0.50.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a43abded5057c75bac8555e46ec913ce502efb418267b1ab8e9783897470c7db" "checksum syntex_syntax 0.50.0 (registry+https://github.com/rust-lang/crates.io-index)" = "6ef781e4b60f03431f1b5b59843546ce60ae029a787770cf8e0969ac1fd063a5" -"checksum target_build_utils 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7a1be18d4d908e4e5697908de04fdd5099505463fc8eaf1ceb8133ae486936aa" +"checksum target_build_utils 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "54c550e226618cd35334b75e92bfa5437c61474bdb75c38bf330ab5a8037b77c" "checksum tempdir 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "87974a6f5c1dfb344d733055601650059a3363de2a6104819293baff662132d6" "checksum tempfile 2.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "9270837a93bad1b1dac18fe67e786b3c960513af86231f6f4f57fddd594ff0c8" "checksum tendril 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "cebf864c2d90394a1b66d6fe45963f9a177f2af81a0edea5060f77627f9c4587" "checksum term 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)" = "3deff8a2b3b6607d6d7cc32ac25c0b33709453ca9cceac006caac51e963cf94a" "checksum thread-id 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a9539db560102d1cef46b8b78ce737ff0bb64e7e18d35b2a5688f7d097d0ff03" -"checksum thread_local 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "55dd963dbaeadc08aa7266bf7f91c3154a7805e32bb94b820b769d2ef3b4744d" +"checksum thread_local 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)" = "8576dbbfcaef9641452d5cf0df9b0e7eeab7694956dd33bb61515fb8f18cfdd5" "checksum threadpool 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "59f6d3eff89920113dac9db44dde461d71d01e88a5b57b258a0466c32b5d7fe1" "checksum time 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)" = "3c7ec6d62a20df54e07ab3b78b9a3932972f4b7981de295563686849eb3989af" -"checksum tinyfiledialogs 0.1.0 (git+https://github.com/jdm/tinyfiledialogs)" = "<none>" +"checksum tinyfiledialogs 2.5.9 (git+https://github.com/jdm/tinyfiledialogs)" = "<none>" "checksum toml 0.1.30 (registry+https://github.com/rust-lang/crates.io-index)" = "0590d72182e50e879c4da3b11c6488dae18fccb1ae0c7a3eda18e16795844796" "checksum traitobject 0.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "07eaeb7689bb7fca7ce15628319635758eda769fed481ecfe6686ddef2600616" "checksum typeable 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "1410f6f91f21d1612654e7cc69193b0334f909dcf2c790c4826254fbb86f8887" "checksum unicase 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "13a5906ca2b98c799f4b1ab4557b76367ebd6ae5ef14930ec841c74aed5f3764" -"checksum unicode-bidi 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "c1f7ceb96afdfeedee42bade65a0d585a6a0106f681b6749c8ff4daa8df30b3f" -"checksum unicode-normalization 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "26643a2f83bac55f1976fb716c10234485f9202dcd65cfbdf9da49867b271172" +"checksum unicode-bidi 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)" = "b61814f3e7fd0e0f15370f767c7c943e08bc2e3214233ae8f88522b334ceb778" +"checksum unicode-normalization 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "5e94e9f6961090fcc75180629c4ef33e5310d6ed2c0dd173f4ca63c9043b669e" "checksum unicode-script 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "e5430ae21ef212551680d0021fc7dbd936e8b268c5ea8fdae8814e0b2496d80f" -"checksum unicode-segmentation 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "b905d0fc2a1f0befd86b0e72e31d1787944efef9d38b9358a9e92a69757f7e3b" +"checksum unicode-segmentation 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "c3bc443ded17b11305ffffe6b37e2076f328a5a8cb6aa877b1b98f77699e98b5" "checksum unicode-xid 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "36dff09cafb4ec7c8cf0023eb0b686cb6ce65499116a12201c9e11840ca01beb" "checksum unreachable 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "1f2ae5ddb18e1c92664717616dd9549dde73f539f01bd7b77c2edb2446bdff91" "checksum url 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "afe9ec54bc4db14bc8744b7fed060d785ac756791450959b2248443319d5b119" @@ -3435,7 +3542,7 @@ dependencies = [ "checksum utf8-ranges 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "a1ca13c08c41c9c3e04224ed9ff80461d97e121589ff27c753a16cb10830ae0f" "checksum uuid 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "1a9ff57156caf7e22f37baf3c9d8f6ce8194842c23419dafcb0716024514d162" "checksum void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d" -"checksum walkdir 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "d42144c31c9909882ce76e696b306b88a5b091721251137d5d522d1ef3da7cf9" +"checksum walkdir 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "c66c0b9792f0a765345452775f3adbd28dde9d33f30d13e5dcc5ae17cf6f3780" "checksum wayland-client 0.5.12 (registry+https://github.com/rust-lang/crates.io-index)" = "ced3094c157b5cc0a08d40530e1a627d9f88b9a436971338d2646439128a559e" "checksum wayland-kbd 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "73bc10e84c1da90777beffecd24742baea17564ffc2a9918af41871c748eb050" "checksum wayland-scanner 0.5.11 (registry+https://github.com/rust-lang/crates.io-index)" = "5a1869370d6bafcbabae8724511d803f4e209a70e94ad94a4249269534364f66" @@ -3449,9 +3556,9 @@ dependencies = [ "checksum winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2d315eee3b34aca4797b2da6b13ed88266e6d612562a0c46390af8299fc699bc" "checksum ws 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)" = "7c47e9ca2f5c47d27f731b1bb9bb50cc05f9886bb84fbd52afa0ff97f4f61b06" "checksum ws2_32-sys 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d59cefebd0c892fa2dd6de581e937301d8552cb44489cdff035c6187cb63fa5e" -"checksum x11 2.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "bfc828b6baf54ccdde44e0b5f16e035ab9c54f60a0f0c218fb5ddbc6ab38a2a9" -"checksum x11-dl 2.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "6acc29bdc98d7565e18dc71b3e933aa94a195d0c2f4ec84f675679d9744b0d6b" +"checksum x11 2.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "be719a282c8d2debd87999849347346259c58ff0acdac3f7f3b48b58652dd773" +"checksum x11-dl 2.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "4e4c7f0a7fb861a1bde4aa23bbda9509bda6b87de4d47c322f86e4c88241ebdd" "checksum xdg 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "77b831a5ba77110f438f0ac5583aafeb087f70432998ba6b7dcb1d32185db453" "checksum xi-unicode 0.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "315c4e158d7fa277e3ea35b32e50bc07e9a0c8de9130a7cc4bdeab42ddc7b442" -"checksum xml-rs 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "65e74b96bd3179209dc70a980da6df843dff09e46eee103a0376c0949257e3ef" +"checksum xml-rs 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "f2b15eed12692bd59d15e98ee7f8dc8408465b992d8ddb4d1672c24865132ec7" "checksum xml5ever 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1a3aa816561c8d68419dec4c43df33974940cd6a03e376dfc497ec3e46fb7755" diff --git a/cargo-commit-hash b/cargo-commit-hash index 8092107d38a..102f1ddd105 100644 --- a/cargo-commit-hash +++ b/cargo-commit-hash @@ -1 +1 @@ -5e3221eac240f1e2c719524ea3c15fde9329dec2 +16f38c1102bddc8e6b6a4322ae41489b769884dc diff --git a/components/atoms/static_atoms.txt b/components/atoms/static_atoms.txt index 2ac84aa2f4e..e59c9cad809 100644 --- a/components/atoms/static_atoms.txt +++ b/components/atoms/static_atoms.txt @@ -32,21 +32,6 @@ number dir -bottom -top -left -right -width -height -margin-bottom -margin-top -margin-left -margin-right -padding-bottom -padding-top -padding-left -padding-right - DOMContentLoaded select input @@ -80,3 +65,4 @@ fetch characteristicvaluechanged fullscreenchange fullscreenerror +gattserverdisconnected diff --git a/components/bluetooth/Cargo.toml b/components/bluetooth/Cargo.toml index 7ee5f430751..b94363904e1 100644 --- a/components/bluetooth/Cargo.toml +++ b/components/bluetooth/Cargo.toml @@ -15,7 +15,6 @@ bluetooth_traits = {path = "../bluetooth_traits"} device = {git = "https://github.com/servo/devices", features = ["bluetooth-test"]} ipc-channel = "0.5" rand = "0.3" -util = {path = "../util"} uuid = {version = "0.3.1", features = ["v4"]} [target.'cfg(target_os = "linux")'.dependencies] diff --git a/components/bluetooth/lib.rs b/components/bluetooth/lib.rs index 0207c9e6f74..8af1fab71da 100644 --- a/components/bluetooth/lib.rs +++ b/components/bluetooth/lib.rs @@ -10,13 +10,12 @@ extern crate ipc_channel; extern crate rand; #[cfg(target_os = "linux")] extern crate tinyfiledialogs; -extern crate util; extern crate uuid; pub mod test; use bluetooth_traits::{BluetoothCharacteristicMsg, BluetoothDescriptorMsg, BluetoothServiceMsg}; -use bluetooth_traits::{BluetoothDeviceMsg, BluetoothRequest, BluetoothResponse}; +use bluetooth_traits::{BluetoothDeviceMsg, BluetoothRequest, BluetoothResponse, GATTType}; use bluetooth_traits::{BluetoothError, BluetoothResponseResult, BluetoothResult}; use bluetooth_traits::blocklist::{uuid_is_blocklisted, Blocklist}; use bluetooth_traits::scanfilter::{BluetoothScanfilter, BluetoothScanfilterSequence, RequestDeviceoptions}; @@ -29,7 +28,6 @@ use std::collections::{HashMap, HashSet}; use std::string::String; use std::thread; use std::time::Duration; -use util::thread::spawn_named; // A transaction not completed within 30 seconds shall time out. Such a transaction shall be considered to have failed. // https://www.bluetooth.org/DocMan/handlers/DownloadDoc.ashx?doc_id=286439 (Vol. 3, page 480) @@ -66,20 +64,6 @@ macro_rules! return_if_cached( ); ); -macro_rules! get_adapter_or_return_error( - ($bl_manager:expr, $sender:expr) => ( - match $bl_manager.get_or_create_adapter() { - Some(adapter) => { - if !adapter.is_powered().unwrap_or(false) { - return drop($sender.send(Err(BluetoothError::NotFound))) - } - adapter - }, - None => return drop($sender.send(Err(BluetoothError::NotFound))), - } - ); -); - pub trait BluetoothThreadFactory { fn new() -> Self; } @@ -88,9 +72,9 @@ impl BluetoothThreadFactory for IpcSender<BluetoothRequest> { fn new() -> IpcSender<BluetoothRequest> { let (sender, receiver) = ipc::channel().unwrap(); let adapter = BluetoothAdapter::init().ok(); - spawn_named("BluetoothThread".to_owned(), move || { + thread::Builder::new().name("BluetoothThread".to_owned()).spawn(move || { BluetoothManager::new(receiver, adapter).start(); - }); + }).expect("Thread spawning failed"); sender } } @@ -237,49 +221,37 @@ impl BluetoothManager { while let Ok(msg) = self.receiver.recv() { match msg { BluetoothRequest::RequestDevice(options, sender) => { - self.request_device(options, sender) + let _ = sender.send(self.request_device(options)); }, BluetoothRequest::GATTServerConnect(device_id, sender) => { - self.gatt_server_connect(device_id, sender) + let _ = sender.send(self.gatt_server_connect(device_id)); }, BluetoothRequest::GATTServerDisconnect(device_id, sender) => { - self.gatt_server_disconnect(device_id, sender) - }, - BluetoothRequest::GetPrimaryService(device_id, uuid, sender) => { - self.get_primary_service(device_id, uuid, sender) - }, - BluetoothRequest::GetPrimaryServices(device_id, uuid, sender) => { - self.get_primary_services(device_id, uuid, sender) - }, - BluetoothRequest::GetIncludedService(service_id, uuid, sender) => { - self.get_included_service(service_id, uuid, sender) + let _ = sender.send(self.gatt_server_disconnect(device_id)); }, - BluetoothRequest::GetIncludedServices(service_id, uuid, sender) => { - self.get_included_services(service_id, uuid, sender) - }, - BluetoothRequest::GetCharacteristic(service_id, uuid, sender) => { - self.get_characteristic(service_id, uuid, sender) - }, - BluetoothRequest::GetCharacteristics(service_id, uuid, sender) => { - self.get_characteristics(service_id, uuid, sender) - }, - BluetoothRequest::GetDescriptor(characteristic_id, uuid, sender) => { - self.get_descriptor(characteristic_id, uuid, sender) - }, - BluetoothRequest::GetDescriptors(characteristic_id, uuid, sender) => { - self.get_descriptors(characteristic_id, uuid, sender) + BluetoothRequest::GetGATTChildren(id, uuid, single, child_type, sender) => { + let _ = sender.send(self.get_gatt_children(id, uuid, single, child_type)); }, BluetoothRequest::ReadValue(id, sender) => { - self.read_value(id, sender) + let _ = sender.send(self.read_value(id)); }, BluetoothRequest::WriteValue(id, value, sender) => { - self.write_value(id, value, sender) + let _ = sender.send(self.write_value(id, value)); }, BluetoothRequest::EnableNotification(id, enable, sender) => { - self.enable_notification(id, enable, sender) + let _ = sender.send(self.enable_notification(id, enable)); + }, + BluetoothRequest::WatchAdvertisements(id, sender) => { + let _ = sender.send(self.watch_advertisements(id)); }, BluetoothRequest::Test(data_set_name, sender) => { - self.test(data_set_name, sender) + let _ = sender.send(self.test(data_set_name)); + } + BluetoothRequest::SetRepresentedToNull(service_ids, characteristic_ids, descriptor_ids) => { + self.remove_ids_from_caches(service_ids, characteristic_ids, descriptor_ids) + } + BluetoothRequest::IsRepresentedDeviceNull(id, sender) => { + let _ = sender.send(!self.device_is_cached(&id)); } BluetoothRequest::Exit => { break @@ -290,7 +262,7 @@ impl BluetoothManager { // Test - fn test(&mut self, data_set_name: String, sender: IpcSender<BluetoothResult<()>>) { + fn test(&mut self, data_set_name: String) -> BluetoothResult<()> { self.address_to_id.clear(); self.service_to_device.clear(); self.characteristic_to_service.clear(); @@ -302,12 +274,28 @@ impl BluetoothManager { self.allowed_services.clear(); self.adapter = BluetoothAdapter::init_mock().ok(); match test::test(self, data_set_name) { - Ok(_) => { - let _ = sender.send(Ok(())); - }, - Err(error) => { - let _ = sender.send(Err(BluetoothError::Type(error.description().to_owned()))); - }, + Ok(_) => return Ok(()), + Err(error) => Err(BluetoothError::Type(error.description().to_owned())), + } + } + + fn remove_ids_from_caches(&mut self, + service_ids: Vec<String>, + characteristic_ids: Vec<String>, + descriptor_ids: Vec<String>) { + for id in service_ids { + self.cached_services.remove(&id); + self.service_to_device.remove(&id); + } + + for id in characteristic_ids { + self.cached_characteristics.remove(&id); + self.characteristic_to_service.remove(&id); + } + + for id in descriptor_ids { + self.cached_descriptors.remove(&id); + self.descriptor_to_characteristic.remove(&id); } } @@ -331,6 +319,18 @@ impl BluetoothManager { self.adapter.clone() } + fn get_adapter(&mut self) -> BluetoothResult<BluetoothAdapter> { + match self.get_or_create_adapter() { + Some(adapter) => { + if !adapter.is_powered().unwrap_or(false) { + return Err(BluetoothError::NotFound); + } + return Ok(adapter); + }, + None => return Err(BluetoothError::NotFound), + } + } + // Device fn get_and_cache_devices(&mut self, adapter: &mut BluetoothAdapter) -> Vec<BluetoothDevice> { @@ -418,6 +418,10 @@ impl BluetoothManager { } } + fn device_is_cached(&self, device_id: &str) -> bool { + self.cached_devices.contains_key(device_id) && self.address_to_id.values().any(|v| v == device_id) + } + // Service fn get_and_cache_gatt_services(&mut self, @@ -451,13 +455,8 @@ impl BluetoothManager { None } - fn get_gatt_services_by_uuid(&mut self, - adapter: &mut BluetoothAdapter, - device_id: &str, - service_uuid: &str) - -> Vec<BluetoothGATTService> { - let services = self.get_and_cache_gatt_services(adapter, device_id); - services.into_iter().filter(|s| s.get_uuid().ok() == Some(service_uuid.to_string())).collect() + fn service_is_cached(&self, service_id: &str) -> bool { + self.cached_services.contains_key(service_id) && self.service_to_device.contains_key(service_id) } // Characteristic @@ -493,17 +492,6 @@ impl BluetoothManager { None } - fn get_gatt_characteristics_by_uuid(&mut self, - adapter: &mut BluetoothAdapter, - service_id: &str, - characteristic_uuid: &str) - -> Vec<BluetoothGATTCharacteristic> { - let characteristics = self.get_and_cache_gatt_characteristics(adapter, service_id); - characteristics.into_iter() - .filter(|c| c.get_uuid().ok() == Some(characteristic_uuid.to_string())) - .collect() - } - fn get_characteristic_properties(&self, characteristic: &BluetoothGATTCharacteristic) -> Flags { let mut props: Flags = Flags::empty(); let flags = characteristic.get_flags().unwrap_or(vec!()); @@ -524,6 +512,11 @@ impl BluetoothManager { props } + fn characteristic_is_cached(&self, characteristic_id: &str) -> bool { + self.cached_characteristics.contains_key(characteristic_id) && + self.characteristic_to_service.contains_key(characteristic_id) + } + // Descriptor fn get_and_cache_gatt_descriptors(&mut self, @@ -557,25 +550,14 @@ impl BluetoothManager { None } - fn get_gatt_descriptors_by_uuid(&mut self, - adapter: &mut BluetoothAdapter, - characteristic_id: &str, - descriptor_uuid: &str) - -> Vec<BluetoothGATTDescriptor> { - let descriptors = self.get_and_cache_gatt_descriptors(adapter, characteristic_id); - descriptors.into_iter() - .filter(|d| d.get_uuid().ok() == Some(descriptor_uuid.to_string())) - .collect() - } - // Methods // https://webbluetoothcg.github.io/web-bluetooth/#request-bluetooth-devices fn request_device(&mut self, - options: RequestDeviceoptions, - sender: IpcSender<BluetoothResponseResult>) { + options: RequestDeviceoptions) + -> BluetoothResponseResult { // Step 6. - let mut adapter = get_adapter_or_return_error!(self, sender); + let mut adapter = try!(self.get_adapter()); if let Ok(ref session) = adapter.create_discovery_session() { if session.start_discovery().is_ok() { if !is_mock_adapter(&adapter) { @@ -602,7 +584,7 @@ impl BluetoothManager { if let Some(address) = self.select_device(matched_devices, &adapter) { let device_id = match self.address_to_id.get(&address) { Some(id) => id.clone(), - None => return drop(sender.send(Err(BluetoothError::NotFound))), + None => return Err(BluetoothError::NotFound), }; let mut services = options.get_services_set(); if let Some(services_set) = self.allowed_services.get(&device_id) { @@ -613,32 +595,33 @@ impl BluetoothManager { let message = BluetoothDeviceMsg { id: device_id, name: device.get_name().ok(), - appearance: device.get_appearance().ok(), - tx_power: device.get_tx_power().ok().map(|p| p as i8), - rssi: device.get_rssi().ok().map(|p| p as i8), }; - return drop(sender.send(Ok(BluetoothResponse::RequestDevice(message)))); + return Ok(BluetoothResponse::RequestDevice(message)); } } // TODO: Step 10 - 11: Implement the permission API. - return drop(sender.send(Err(BluetoothError::NotFound))); + return Err(BluetoothError::NotFound); // Step 12: Missing, because it is optional. } // https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetoothremotegattserver-connect - fn gatt_server_connect(&mut self, device_id: String, sender: IpcSender<BluetoothResponseResult>) { - let mut adapter = get_adapter_or_return_error!(self, sender); + fn gatt_server_connect(&mut self, device_id: String) -> BluetoothResponseResult { + // Step 2. + if !self.device_is_cached(&device_id) { + return Err(BluetoothError::Network); + } + let mut adapter = try!(self.get_adapter()); // Step 5.1.1. match self.get_device(&mut adapter, &device_id) { Some(d) => { if d.is_connected().unwrap_or(false) { - return drop(sender.send(Ok(BluetoothResponse::GATTServerConnect(true)))); + return Ok(BluetoothResponse::GATTServerConnect(true)); } let _ = d.connect(); for _ in 0..MAXIMUM_TRANSACTION_TIME { match d.is_connected().unwrap_or(false) { - true => return drop(sender.send(Ok(BluetoothResponse::GATTServerConnect(true)))), + true => return Ok(BluetoothResponse::GATTServerConnect(true)), false => { if is_mock_adapter(&adapter) { break; @@ -649,360 +632,194 @@ impl BluetoothManager { // TODO: Step 5.1.4: Use the exchange MTU procedure. } // Step 5.1.3. - return drop(sender.send(Err(BluetoothError::Network))); + return Err(BluetoothError::Network); }, - None => return drop(sender.send(Err(BluetoothError::NotFound))), + None => return Err(BluetoothError::NotFound), } } // https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetoothremotegattserver-disconnect - fn gatt_server_disconnect(&mut self, device_id: String, sender: IpcSender<BluetoothResult<bool>>) { - let mut adapter = get_adapter_or_return_error!(self, sender); - + fn gatt_server_disconnect(&mut self, device_id: String) -> BluetoothResult<()> { + let mut adapter = try!(self.get_adapter()); match self.get_device(&mut adapter, &device_id) { Some(d) => { // Step 2. if !d.is_connected().unwrap_or(true) { - return drop(sender.send(Ok(false))); + return Ok(()); } let _ = d.disconnect(); for _ in 0..MAXIMUM_TRANSACTION_TIME { match d.is_connected().unwrap_or(true) { true => thread::sleep(Duration::from_millis(CONNECTION_TIMEOUT_MS)), - false => return drop(sender.send(Ok(false))), + false => return Ok(()), } } - return drop(sender.send(Err(BluetoothError::Network))); + return Err(BluetoothError::Network); }, - None => return drop(sender.send(Err(BluetoothError::NotFound))), + None => return Err(BluetoothError::NotFound), } } - // https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetoothremotegattserver-getprimaryservice // https://webbluetoothcg.github.io/web-bluetooth/#getgattchildren - fn get_primary_service(&mut self, - device_id: String, - uuid: String, - sender: IpcSender<BluetoothResponseResult>) { - // Step 5. - if !self.cached_devices.contains_key(&device_id) { - return drop(sender.send(Err(BluetoothError::InvalidState))); - } - let mut adapter = get_adapter_or_return_error!(self, sender); - if !self.allowed_services.get(&device_id).map_or(false, |s| s.contains(&uuid)) { - return drop(sender.send(Err(BluetoothError::Security))); - } - let services = self.get_gatt_services_by_uuid(&mut adapter, &device_id, &uuid); + fn get_gatt_children(&mut self, + id: String, + uuid: Option<String>, + single: bool, + child_type: GATTType) + -> BluetoothResponseResult { + let mut adapter = try!(self.get_adapter()); + match child_type { + GATTType::PrimaryService => { + // Step 5. + if !self.device_is_cached(&id) { + return Err(BluetoothError::InvalidState); + } + // Step 6. + if let Some(ref uuid) = uuid { + if !self.allowed_services.get(&id).map_or(false, |s| s.contains(uuid)) { + return Err(BluetoothError::Security); + } + } + let mut services = self.get_and_cache_gatt_services(&mut adapter, &id); + if let Some(uuid) = uuid { + services.retain(|ref e| e.get_uuid().unwrap_or(String::new()) == uuid); + } + let mut services_vec = vec!(); + for service in services { + if service.is_primary().unwrap_or(false) { + if let Ok(uuid) = service.get_uuid() { + services_vec.push( + BluetoothServiceMsg { + uuid: uuid, + is_primary: true, + instance_id: service.get_id(), + } + ); + } + } + } + // Step 7. + if services_vec.is_empty() { + return Err(BluetoothError::NotFound); + } - // Step 6. - for service in services { - if service.is_primary().unwrap_or(false) { - if let Ok(uuid) = service.get_uuid() { - return drop(sender.send( - Ok(BluetoothResponse::GetPrimaryService( - BluetoothServiceMsg { + return Ok(BluetoothResponse::GetPrimaryServices(services_vec, single)); + }, + GATTType::Characteristic => { + // Step 5. + if !self.service_is_cached(&id) { + return Err(BluetoothError::InvalidState); + } + // Step 6. + let mut characteristics = self.get_and_cache_gatt_characteristics(&mut adapter, &id); + if let Some(uuid) = uuid { + characteristics.retain(|ref e| e.get_uuid().unwrap_or(String::new()) == uuid); + } + let mut characteristics_vec = vec!(); + for characteristic in characteristics { + if let Ok(uuid) = characteristic.get_uuid() { + let properties = self.get_characteristic_properties(&characteristic); + characteristics_vec.push( + BluetoothCharacteristicMsg { uuid: uuid, - is_primary: true, - instance_id: service.get_id(), + instance_id: characteristic.get_id(), + broadcast: properties.contains(BROADCAST), + read: properties.contains(READ), + write_without_response: properties.contains(WRITE_WITHOUT_RESPONSE), + write: properties.contains(WRITE), + notify: properties.contains(NOTIFY), + indicate: properties.contains(INDICATE), + authenticated_signed_writes: properties.contains(AUTHENTICATED_SIGNED_WRITES), + reliable_write: properties.contains(RELIABLE_WRITE), + writable_auxiliaries: properties.contains(WRITABLE_AUXILIARIES), } - )) - )); + ); + } } - } - } - // Step 7. - return drop(sender.send(Err(BluetoothError::NotFound))); - } - // https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetoothremotegattserver-getprimaryservices - // https://webbluetoothcg.github.io/web-bluetooth/#getgattchildren - fn get_primary_services(&mut self, - device_id: String, - uuid: Option<String>, - sender: IpcSender<BluetoothResponseResult>) { - // Step 5. - if !self.cached_devices.contains_key(&device_id) { - return drop(sender.send(Err(BluetoothError::InvalidState))); - } - let mut adapter = get_adapter_or_return_error!(self, sender); - let services = match uuid { - Some(ref id) => { - if !self.allowed_services.get(&device_id).map_or(false, |s| s.contains(id)) { - return drop(sender.send(Err(BluetoothError::Security))) + // Step 7. + if characteristics_vec.is_empty() { + return Err(BluetoothError::NotFound); } - self.get_gatt_services_by_uuid(&mut adapter, &device_id, id) - }, - None => self.get_and_cache_gatt_services(&mut adapter, &device_id), - }; - // Step 6. - let mut services_vec = vec!(); - for service in services { - if service.is_primary().unwrap_or(false) { - if let Ok(uuid) = service.get_uuid() { - services_vec.push( - BluetoothServiceMsg { - uuid: uuid, - is_primary: true, - instance_id: service.get_id(), - } - ); + return Ok(BluetoothResponse::GetCharacteristics(characteristics_vec, single)); + }, + GATTType::IncludedService => { + // Step 5. + if !self.service_is_cached(&id) { + return Err(BluetoothError::InvalidState); } - } - } - - // Step 7. - if services_vec.is_empty() { - return drop(sender.send(Err(BluetoothError::NotFound))); - } - - return drop(sender.send(Ok(BluetoothResponse::GetPrimaryServices(services_vec)))); - } - - // https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetoothremotegattservice-getincludedservice - // https://webbluetoothcg.github.io/web-bluetooth/#getgattchildren - fn get_included_service(&mut self, - service_id: String, - uuid: String, - sender: IpcSender<BluetoothResponseResult>) { - // Step 5. - if !self.cached_services.contains_key(&service_id) { - return drop(sender.send(Err(BluetoothError::InvalidState))); - } - let mut adapter = get_adapter_or_return_error!(self, sender); - let device = match self.device_from_service_id(&service_id) { - Some(device) => device, - None => return drop(sender.send(Err(BluetoothError::NotFound))), - }; - let primary_service = match self.get_gatt_service(&mut adapter, &service_id) { - Some(s) => s, - None => return drop(sender.send(Err(BluetoothError::NotFound))), - }; - let services = primary_service.get_includes(device).unwrap_or(vec!()); - - // Step 6. - for service in services { - if let Ok(service_uuid) = service.get_uuid() { - if uuid == service_uuid { - return drop(sender.send( - Ok(BluetoothResponse::GetIncludedService( + // Step 6. + let device = match self.device_from_service_id(&id) { + Some(device) => device, + None => return Err(BluetoothError::NotFound), + }; + let primary_service = match self.get_gatt_service(&mut adapter, &id) { + Some(s) => s, + None => return Err(BluetoothError::NotFound), + }; + let services = primary_service.get_includes(device).unwrap_or(vec!()); + let mut services_vec = vec!(); + for service in services { + if let Ok(service_uuid) = service.get_uuid() { + services_vec.push( BluetoothServiceMsg { - uuid: uuid, + uuid: service_uuid, is_primary: service.is_primary().unwrap_or(false), instance_id: service.get_id(), - } - )) - )); - } - } - } - // Step 7. - return drop(sender.send(Err(BluetoothError::NotFound))); - } - - // https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetoothremotegattservice-getincludedservices - // https://webbluetoothcg.github.io/web-bluetooth/#getgattchildren - fn get_included_services(&mut self, - service_id: String, - uuid: Option<String>, - sender: IpcSender<BluetoothResponseResult>) { - // Step 5. - if !self.cached_services.contains_key(&service_id) { - return drop(sender.send(Err(BluetoothError::InvalidState))); - } - let mut adapter = get_adapter_or_return_error!(self, sender); - let device = match self.device_from_service_id(&service_id) { - Some(device) => device, - None => return drop(sender.send(Err(BluetoothError::NotFound))), - }; - let primary_service = match self.get_gatt_service(&mut adapter, &service_id) { - Some(s) => s, - None => return drop(sender.send(Err(BluetoothError::NotFound))), - }; - let services = primary_service.get_includes(device).unwrap_or(vec!()); - - // Step 6. - let mut services_vec = vec!(); - for service in services { - if let Ok(service_uuid) = service.get_uuid() { - services_vec.push( - BluetoothServiceMsg { - uuid: service_uuid, - is_primary: service.is_primary().unwrap_or(false), - instance_id: service.get_id(), - } - ); - } - } - if let Some(uuid) = uuid { - services_vec.retain(|ref s| s.uuid == uuid); - } - services_vec.retain(|s| !uuid_is_blocklisted(&s.uuid, Blocklist::All)); - - // Step 7. - if services_vec.is_empty() { - return drop(sender.send(Err(BluetoothError::NotFound))); - } - - return drop(sender.send(Ok(BluetoothResponse::GetIncludedServices(services_vec)))); - } - - // https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetoothremotegattservice-getcharacteristic - // https://webbluetoothcg.github.io/web-bluetooth/#getgattchildren - fn get_characteristic(&mut self, - service_id: String, - uuid: String, - sender: IpcSender<BluetoothResponseResult>) { - // Step 5. - if !self.cached_services.contains_key(&service_id) { - return drop(sender.send(Err(BluetoothError::InvalidState))); - } - let mut adapter = get_adapter_or_return_error!(self, sender); - let characteristics = self.get_gatt_characteristics_by_uuid(&mut adapter, &service_id, &uuid); - - // Step 6. - for characteristic in characteristics { - if let Ok(uuid) = characteristic.get_uuid() { - let properties = self.get_characteristic_properties(&characteristic); - let message = BluetoothCharacteristicMsg { - uuid: uuid, - instance_id: characteristic.get_id(), - broadcast: properties.contains(BROADCAST), - read: properties.contains(READ), - write_without_response: properties.contains(WRITE_WITHOUT_RESPONSE), - write: properties.contains(WRITE), - notify: properties.contains(NOTIFY), - indicate: properties.contains(INDICATE), - authenticated_signed_writes: properties.contains(AUTHENTICATED_SIGNED_WRITES), - reliable_write: properties.contains(RELIABLE_WRITE), - writable_auxiliaries: properties.contains(WRITABLE_AUXILIARIES), - }; - return drop(sender.send(Ok(BluetoothResponse::GetCharacteristic(message)))); - } - } - // Step 7. - return drop(sender.send(Err(BluetoothError::NotFound))); - } - - // https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetoothremotegattservice-getcharacteristics - // https://webbluetoothcg.github.io/web-bluetooth/#getgattchildren - fn get_characteristics(&mut self, - service_id: String, - uuid: Option<String>, - sender: IpcSender<BluetoothResponseResult>) { - // Step 5. - if !self.cached_services.contains_key(&service_id) { - return drop(sender.send(Err(BluetoothError::InvalidState))); - } - let mut adapter = get_adapter_or_return_error!(self, sender); - let characteristics = match uuid { - Some(id) => self.get_gatt_characteristics_by_uuid(&mut adapter, &service_id, &id), - None => self.get_and_cache_gatt_characteristics(&mut adapter, &service_id), - }; - - // Step 6. - let mut characteristics_vec = vec!(); - for characteristic in characteristics { - if let Ok(uuid) = characteristic.get_uuid() { - let properties = self.get_characteristic_properties(&characteristic); - characteristics_vec.push( - BluetoothCharacteristicMsg { - uuid: uuid, - instance_id: characteristic.get_id(), - broadcast: properties.contains(BROADCAST), - read: properties.contains(READ), - write_without_response: properties.contains(WRITE_WITHOUT_RESPONSE), - write: properties.contains(WRITE), - notify: properties.contains(NOTIFY), - indicate: properties.contains(INDICATE), - authenticated_signed_writes: properties.contains(AUTHENTICATED_SIGNED_WRITES), - reliable_write: properties.contains(RELIABLE_WRITE), - writable_auxiliaries: properties.contains(WRITABLE_AUXILIARIES), + } + ); } - ); - } - } - - // Step 7. - if characteristics_vec.is_empty() { - return drop(sender.send(Err(BluetoothError::NotFound))); - } - - return drop(sender.send(Ok(BluetoothResponse::GetCharacteristics(characteristics_vec)))); - } - - // https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetoothremotegattcharacteristic-getdescriptor - // https://webbluetoothcg.github.io/web-bluetooth/#getgattchildren - fn get_descriptor(&mut self, - characteristic_id: String, - uuid: String, - sender: IpcSender<BluetoothResponseResult>) { - // Step 5. - if !self.cached_characteristics.contains_key(&characteristic_id) { - return drop(sender.send(Err(BluetoothError::InvalidState))); - } - let mut adapter = get_adapter_or_return_error!(self, sender); - let descriptors = self.get_gatt_descriptors_by_uuid(&mut adapter, &characteristic_id, &uuid); - - // Step 6. - for descriptor in descriptors { - if let Ok(uuid) = descriptor.get_uuid() { - return drop(sender.send( - Ok(BluetoothResponse::GetDescriptor( - BluetoothDescriptorMsg { - uuid: uuid, - instance_id: descriptor.get_id(), - } - )) - )); - } - } - // Step 7. - return drop(sender.send(Err(BluetoothError::NotFound))); - } + } + if let Some(uuid) = uuid { + services_vec.retain(|ref s| s.uuid == uuid); + } + services_vec.retain(|s| !uuid_is_blocklisted(&s.uuid, Blocklist::All)); - // https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetoothremotegattcharacteristic-getdescriptors - // https://webbluetoothcg.github.io/web-bluetooth/#getgattchildren - fn get_descriptors(&mut self, - characteristic_id: String, - uuid: Option<String>, - sender: IpcSender<BluetoothResponseResult>) { - // Step 5. - if !self.cached_characteristics.contains_key(&characteristic_id) { - return drop(sender.send(Err(BluetoothError::InvalidState))); - } - let mut adapter = get_adapter_or_return_error!(self, sender); - let descriptors = match uuid { - Some(id) => self.get_gatt_descriptors_by_uuid(&mut adapter, &characteristic_id, &id), - None => self.get_and_cache_gatt_descriptors(&mut adapter, &characteristic_id), - }; + // Step 7. + if services_vec.is_empty() { + return Err(BluetoothError::NotFound); + } - // Step 6. - let mut descriptors_vec = vec!(); - for descriptor in descriptors { - if let Ok(uuid) = descriptor.get_uuid() { - descriptors_vec.push( - BluetoothDescriptorMsg { - uuid: uuid, - instance_id: descriptor.get_id(), + return Ok(BluetoothResponse::GetIncludedServices(services_vec, single)); + }, + GATTType::Descriptor => { + // Step 5. + if !self.characteristic_is_cached(&id) { + return Err(BluetoothError::InvalidState); + } + // Step 6. + let mut descriptors = self.get_and_cache_gatt_descriptors(&mut adapter, &id); + if let Some(uuid) = uuid { + descriptors.retain(|ref e| e.get_uuid().unwrap_or(String::new()) == uuid); + } + let mut descriptors_vec = vec!(); + for descriptor in descriptors { + if let Ok(uuid) = descriptor.get_uuid() { + descriptors_vec.push( + BluetoothDescriptorMsg { + uuid: uuid, + instance_id: descriptor.get_id(), + } + ); } - ); - } - } + } - // Step 7. - if descriptors_vec.is_empty() { - return drop(sender.send(Err(BluetoothError::NotFound))); + // Step 7. + if descriptors_vec.is_empty() { + return Err(BluetoothError::NotFound); + } + return Ok(BluetoothResponse::GetDescriptors(descriptors_vec, single)); + }, } - return drop(sender.send(Ok(BluetoothResponse::GetDescriptors(descriptors_vec)))); } // https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetoothremotegattcharacteristic-readvalue // https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetoothremotegattdescriptor-readvalue - fn read_value(&mut self, id: String, sender: IpcSender<BluetoothResponseResult>) { + fn read_value(&mut self, id: String) -> BluetoothResponseResult { // (Characteristic) Step 5.2: Missing because it is optional. // (Descriptor) Step 5.1: Missing because it is optional. - let mut adapter = get_adapter_or_return_error!(self, sender); + let mut adapter = try!(self.get_adapter()); // (Characteristic) Step 5.3. let mut value = self.get_gatt_characteristic(&mut adapter, &id) @@ -1021,20 +838,20 @@ impl BluetoothManager { match value { // (Characteristic) Step 5.5.4. // (Descriptor) Step 5.4.3. - Some(v) => return drop(sender.send(Ok(BluetoothResponse::ReadValue(v)))), + Some(v) => return Ok(BluetoothResponse::ReadValue(v)), // (Characteristic) Step 4. // (Descriptor) Step 4. - None => return drop(sender.send(Err(BluetoothError::InvalidState))), + None => return Err(BluetoothError::InvalidState), } } // https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetoothremotegattcharacteristic-writevalue // https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetoothremotegattdescriptor-writevalue - fn write_value(&mut self, id: String, value: Vec<u8>, sender: IpcSender<BluetoothResponseResult>) { + fn write_value(&mut self, id: String, value: Vec<u8>) -> BluetoothResponseResult { // (Characteristic) Step 7.2: Missing because it is optional. // (Descriptor) Step 7.1: Missing because it is optional. - let mut adapter = get_adapter_or_return_error!(self, sender); + let mut adapter = try!(self.get_adapter()); // (Characteristic) Step 7.3. let mut result = self.get_gatt_characteristic(&mut adapter, &id) @@ -1054,23 +871,29 @@ impl BluetoothManager { Some(v) => match v { // (Characteristic) Step 7.5.3. // (Descriptor) Step 7.4.3. - Ok(_) => return drop(sender.send(Ok(BluetoothResponse::WriteValue(value)))), + Ok(_) => return Ok(BluetoothResponse::WriteValue(value)), // (Characteristic) Step 7.1. - Err(_) => return drop(sender.send(Err(BluetoothError::NotSupported))), + Err(_) => return Err(BluetoothError::NotSupported), }, // (Characteristic) Step 6. // (Descriptor) Step 6. - None => return drop(sender.send(Err(BluetoothError::InvalidState))), + None => return Err(BluetoothError::InvalidState), } } // https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetoothremotegattcharacteristic-startnotifications // https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetoothremotegattcharacteristic-stopnotifications - fn enable_notification(&mut self, id: String, enable: bool, sender: IpcSender<BluetoothResponseResult>) { + fn enable_notification(&mut self, id: String, enable: bool) -> BluetoothResponseResult { + // (StartNotifications) Step 2 - 3. + // (StopNotifications) Step 1 - 2. + if !self.characteristic_is_cached(&id) { + return Err(BluetoothError::InvalidState); + } + // (StartNotification) TODO: Step 7: Missing because it is optional. - let mut adapter = get_adapter_or_return_error!(self, sender); + let mut adapter = try!(self.get_adapter()); match self.get_gatt_characteristic(&mut adapter, &id) { Some(c) => { let result = match enable { @@ -1084,14 +907,21 @@ impl BluetoothManager { match result { // (StartNotification) Step 11. // (StopNotification) Step 5. - Ok(_) => return drop(sender.send(Ok(BluetoothResponse::EnableNotification(())))), + Ok(_) => return Ok(BluetoothResponse::EnableNotification(())), // (StartNotification) Step 4. - Err(_) => return drop(sender.send(Err(BluetoothError::NotSupported))), + Err(_) => return Err(BluetoothError::NotSupported), } }, // (StartNotification) Step 3. - None => return drop(sender.send(Err(BluetoothError::InvalidState))), + None => return Err(BluetoothError::InvalidState), } } + + // https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetoothdevice-watchadvertisements + fn watch_advertisements(&mut self, _device_id: String) -> BluetoothResponseResult { + // Step 2. + // TODO: Implement this when supported in lower level + return Err(BluetoothError::NotSupported); + } } diff --git a/components/bluetooth/test.rs b/components/bluetooth/test.rs index e2c6e639e82..b8f8a53750f 100644 --- a/components/bluetooth/test.rs +++ b/components/bluetooth/test.rs @@ -222,21 +222,23 @@ fn create_heart_rate_service(device: &BluetoothDevice, try!(create_characteristic_with_value(&heart_rate_service, HEART_RATE_MEASUREMENT_CHARACTERISTIC_UUID.to_owned(), vec![0])); - try!(heart_rate_measurement_characteristic.set_flags(vec![NOTIFY_FLAG.to_string()])); + try!(heart_rate_measurement_characteristic.set_flags(vec![NOTIFY_FLAG.to_string(), + READ_FLAG.to_string(), + WRITE_FLAG.to_string()])); // Body Sensor Location Characteristic 1 let body_sensor_location_characteristic_1 = try!(create_characteristic_with_value(&heart_rate_service, BODY_SENSOR_LOCATION_CHARACTERISTIC_UUID.to_owned(), vec![49])); - try!(body_sensor_location_characteristic_1.set_flags(vec![READ_FLAG.to_string()])); + try!(body_sensor_location_characteristic_1.set_flags(vec![READ_FLAG.to_string(), WRITE_FLAG.to_string()])); // Body Sensor Location Characteristic 2 let body_sensor_location_characteristic_2 = try!(create_characteristic_with_value(&heart_rate_service, BODY_SENSOR_LOCATION_CHARACTERISTIC_UUID.to_owned(), vec![50])); - try!(body_sensor_location_characteristic_2.set_flags(vec![READ_FLAG.to_string()])); + try!(body_sensor_location_characteristic_2.set_flags(vec![READ_FLAG.to_string(), WRITE_FLAG.to_string()])); Ok(heart_rate_service) } diff --git a/components/bluetooth_traits/Cargo.toml b/components/bluetooth_traits/Cargo.toml index 5ac8057c2b2..c2c5a632b2d 100644 --- a/components/bluetooth_traits/Cargo.toml +++ b/components/bluetooth_traits/Cargo.toml @@ -14,4 +14,4 @@ ipc-channel = "0.5" regex = "0.1.43" serde = "0.8" serde_derive = "0.8" -util = {path = "../util"} +servo_config = {path = "../config"} diff --git a/components/bluetooth_traits/blocklist.rs b/components/bluetooth_traits/blocklist.rs index f859def1379..26df3413c10 100644 --- a/components/bluetooth_traits/blocklist.rs +++ b/components/bluetooth_traits/blocklist.rs @@ -3,11 +3,11 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ use regex::Regex; +use servo_config::resource_files::read_resource_file; use std::cell::RefCell; use std::collections::HashMap; use std::io::BufRead; use std::string::String; -use util::resource_files::read_resource_file; const BLOCKLIST_FILE: &'static str = "gatt_blocklist.txt"; const BLOCKLIST_FILE_NOT_FOUND: &'static str = "Could not find gatt_blocklist.txt file"; diff --git a/components/bluetooth_traits/lib.rs b/components/bluetooth_traits/lib.rs index 761173eb32f..e38c122f72d 100644 --- a/components/bluetooth_traits/lib.rs +++ b/components/bluetooth_traits/lib.rs @@ -8,7 +8,7 @@ extern crate ipc_channel; extern crate regex; #[macro_use] extern crate serde_derive; -extern crate util; +extern crate servo_config; pub mod blocklist; pub mod scanfilter; @@ -27,14 +27,18 @@ pub enum BluetoothError { } #[derive(Deserialize, Serialize)] +pub enum GATTType { + PrimaryService, + Characteristic, + IncludedService, + Descriptor, +} + +#[derive(Deserialize, Serialize)] pub struct BluetoothDeviceMsg { // Bluetooth Device properties pub id: String, pub name: Option<String>, - // Advertising Data properties - pub appearance: Option<u16>, - pub tx_power: Option<i8>, - pub rssi: Option<i8>, } #[derive(Deserialize, Serialize)] @@ -81,18 +85,14 @@ pub type BluetoothResponseResult = Result<BluetoothResponse, BluetoothError>; pub enum BluetoothRequest { RequestDevice(RequestDeviceoptions, IpcSender<BluetoothResponseResult>), GATTServerConnect(String, IpcSender<BluetoothResponseResult>), - GATTServerDisconnect(String, IpcSender<BluetoothResult<bool>>), - GetPrimaryService(String, String, IpcSender<BluetoothResponseResult>), - GetPrimaryServices(String, Option<String>, IpcSender<BluetoothResponseResult>), - GetIncludedService(String, String, IpcSender<BluetoothResponseResult>), - GetIncludedServices(String, Option<String>, IpcSender<BluetoothResponseResult>), - GetCharacteristic(String, String, IpcSender<BluetoothResponseResult>), - GetCharacteristics(String, Option<String>, IpcSender<BluetoothResponseResult>), - GetDescriptor(String, String, IpcSender<BluetoothResponseResult>), - GetDescriptors(String, Option<String>, IpcSender<BluetoothResponseResult>), + GATTServerDisconnect(String, IpcSender<BluetoothResult<()>>), + GetGATTChildren(String, Option<String>, bool, GATTType, IpcSender<BluetoothResponseResult>), ReadValue(String, IpcSender<BluetoothResponseResult>), WriteValue(String, Vec<u8>, IpcSender<BluetoothResponseResult>), EnableNotification(String, bool, IpcSender<BluetoothResponseResult>), + WatchAdvertisements(String, IpcSender<BluetoothResponseResult>), + SetRepresentedToNull(Vec<String>, Vec<String>, Vec<String>), + IsRepresentedDeviceNull(String, IpcSender<bool>), Test(String, IpcSender<BluetoothResult<()>>), Exit, } @@ -101,19 +101,12 @@ pub enum BluetoothRequest { pub enum BluetoothResponse { RequestDevice(BluetoothDeviceMsg), GATTServerConnect(bool), - GetPrimaryService(BluetoothServiceMsg), - GetPrimaryServices(BluetoothServicesMsg), - GetIncludedService(BluetoothServiceMsg), - GetIncludedServices(BluetoothServicesMsg), - GetCharacteristic(BluetoothCharacteristicMsg), - GetCharacteristics(BluetoothCharacteristicsMsg), - GetDescriptor(BluetoothDescriptorMsg), - GetDescriptors(BluetoothDescriptorsMsg), + GetPrimaryServices(BluetoothServicesMsg, bool), + GetIncludedServices(BluetoothServicesMsg, bool), + GetCharacteristics(BluetoothCharacteristicsMsg, bool), + GetDescriptors(BluetoothDescriptorsMsg, bool), ReadValue(Vec<u8>), WriteValue(Vec<u8>), EnableNotification(()), -} - -pub trait BluetoothResponseListener { - fn response(&mut self, response: BluetoothResponseResult); + WatchAdvertisements(()), } diff --git a/components/canvas/Cargo.toml b/components/canvas/Cargo.toml index 41debc4a83a..4416e1cb0b3 100644 --- a/components/canvas/Cargo.toml +++ b/components/canvas/Cargo.toml @@ -12,6 +12,7 @@ path = "lib.rs" [dependencies] azure = {git = "https://github.com/servo/rust-azure", features = ["plugins"]} canvas_traits = {path = "../canvas_traits"} +cssparser = {version = "0.7", features = ["heap_size", "serde-serialization"]} euclid = "0.10.1" gleam = "0.2.8" ipc-channel = "0.5" @@ -19,7 +20,7 @@ log = "0.3.5" num-traits = "0.1.32" offscreen_gl_context = "0.5.0" plugins = {path = "../plugins"} -util = {path = "../util"} +servo_config = {path = "../config"} [dependencies.webrender_traits] git = "https://github.com/servo/webrender" diff --git a/components/canvas/canvas_paint_thread.rs b/components/canvas/canvas_paint_thread.rs index 26863482a99..f7c3fdfb6ae 100644 --- a/components/canvas/canvas_paint_thread.rs +++ b/components/canvas/canvas_paint_thread.rs @@ -6,7 +6,10 @@ use azure::azure::AzFloat; use azure::azure_hl::{AntialiasMode, CapStyle, CompositionOp, JoinStyle}; use azure::azure_hl::{BackendType, DrawOptions, DrawTarget, Pattern, StrokeOptions, SurfaceFormat}; use azure::azure_hl::{Color, ColorPattern, DrawSurfaceOptions, Filter, PathBuilder}; +use azure::azure_hl::{ExtendMode, GradientStop, LinearGradientPattern, RadialGradientPattern}; +use azure::azure_hl::SurfacePattern; use canvas_traits::*; +use cssparser::RGBA; use euclid::matrix2d::Matrix2D; use euclid::point::Point2D; use euclid::rect::Rect; @@ -15,7 +18,7 @@ use ipc_channel::ipc::{self, IpcSender}; use num_traits::ToPrimitive; use std::borrow::ToOwned; use std::mem; -use util::thread::spawn_named; +use std::thread; use webrender_traits; impl<'a> CanvasPaintThread<'a> { @@ -121,7 +124,7 @@ impl<'a> CanvasPaintThread<'a> { antialias: bool) -> IpcSender<CanvasMsg> { let (sender, receiver) = ipc::channel::<CanvasMsg>().unwrap(); - spawn_named("CanvasThread".to_owned(), move || { + thread::Builder::new().name("CanvasThread".to_owned()).spawn(move || { let mut painter = CanvasPaintThread::new(size, webrender_api_sender, antialias); loop { let msg = receiver.recv(); @@ -185,7 +188,7 @@ impl<'a> CanvasPaintThread<'a> { Canvas2dMsg::SetShadowOffsetX(value) => painter.set_shadow_offset_x(value), Canvas2dMsg::SetShadowOffsetY(value) => painter.set_shadow_offset_y(value), Canvas2dMsg::SetShadowBlur(value) => painter.set_shadow_blur(value), - Canvas2dMsg::SetShadowColor(ref color) => painter.set_shadow_color(color.to_azcolor()), + Canvas2dMsg::SetShadowColor(ref color) => painter.set_shadow_color(color.to_azure_style()), } }, CanvasMsg::Common(message) => { @@ -211,7 +214,7 @@ impl<'a> CanvasPaintThread<'a> { CanvasMsg::WebGL(_) => panic!("Wrong message sent to Canvas2D thread"), } } - }); + }).expect("Thread spawning failed"); sender } @@ -794,8 +797,8 @@ fn write_image(draw_target: &DrawTarget, let draw_options = DrawOptions::new(global_alpha, composition_op, AntialiasMode::None); draw_target.draw_surface(source_surface, - dest_rect.to_azfloat(), - image_rect.to_azfloat(), + dest_rect.to_azure_style(), + image_rect.to_azure_style(), draw_surface_options, draw_options); } @@ -854,13 +857,163 @@ impl RectToi32 for Rect<f64> { } -pub trait ToAzFloat { - fn to_azfloat(&self) -> Rect<AzFloat>; +pub trait ToAzureStyle { + type Target; + fn to_azure_style(self) -> Self::Target; } -impl ToAzFloat for Rect<f64> { - fn to_azfloat(&self) -> Rect<AzFloat> { +impl ToAzureStyle for Rect<f64> { + type Target = Rect<AzFloat>; + + fn to_azure_style(self) -> Rect<AzFloat> { Rect::new(Point2D::new(self.origin.x as AzFloat, self.origin.y as AzFloat), Size2D::new(self.size.width as AzFloat, self.size.height as AzFloat)) } } + + +impl ToAzureStyle for LineCapStyle { + type Target = CapStyle; + + fn to_azure_style(self) -> CapStyle { + match self { + LineCapStyle::Butt => CapStyle::Butt, + LineCapStyle::Round => CapStyle::Round, + LineCapStyle::Square => CapStyle::Square, + } + } +} + +impl ToAzureStyle for LineJoinStyle { + type Target = JoinStyle; + + fn to_azure_style(self) -> JoinStyle { + match self { + LineJoinStyle::Round => JoinStyle::Round, + LineJoinStyle::Bevel => JoinStyle::Bevel, + LineJoinStyle::Miter => JoinStyle::Miter, + } + } +} + +impl ToAzureStyle for CompositionStyle { + type Target = CompositionOp; + + fn to_azure_style(self) -> CompositionOp { + match self { + CompositionStyle::SrcIn => CompositionOp::In, + CompositionStyle::SrcOut => CompositionOp::Out, + CompositionStyle::SrcOver => CompositionOp::Over, + CompositionStyle::SrcAtop => CompositionOp::Atop, + CompositionStyle::DestIn => CompositionOp::DestIn, + CompositionStyle::DestOut => CompositionOp::DestOut, + CompositionStyle::DestOver => CompositionOp::DestOver, + CompositionStyle::DestAtop => CompositionOp::DestAtop, + CompositionStyle::Copy => CompositionOp::Source, + CompositionStyle::Lighter => CompositionOp::Add, + CompositionStyle::Xor => CompositionOp::Xor, + } + } +} + +impl ToAzureStyle for BlendingStyle { + type Target = CompositionOp; + + fn to_azure_style(self) -> CompositionOp { + match self { + BlendingStyle::Multiply => CompositionOp::Multiply, + BlendingStyle::Screen => CompositionOp::Screen, + BlendingStyle::Overlay => CompositionOp::Overlay, + BlendingStyle::Darken => CompositionOp::Darken, + BlendingStyle::Lighten => CompositionOp::Lighten, + BlendingStyle::ColorDodge => CompositionOp::ColorDodge, + BlendingStyle::ColorBurn => CompositionOp::ColorBurn, + BlendingStyle::HardLight => CompositionOp::HardLight, + BlendingStyle::SoftLight => CompositionOp::SoftLight, + BlendingStyle::Difference => CompositionOp::Difference, + BlendingStyle::Exclusion => CompositionOp::Exclusion, + BlendingStyle::Hue => CompositionOp::Hue, + BlendingStyle::Saturation => CompositionOp::Saturation, + BlendingStyle::Color => CompositionOp::Color, + BlendingStyle::Luminosity => CompositionOp::Luminosity, + } + } +} + +impl ToAzureStyle for CompositionOrBlending { + type Target = CompositionOp; + + fn to_azure_style(self) -> CompositionOp { + match self { + CompositionOrBlending::Composition(op) => op.to_azure_style(), + CompositionOrBlending::Blending(op) => op.to_azure_style(), + } + } +} + +pub trait ToAzurePattern { + fn to_azure_pattern(&self, drawtarget: &DrawTarget) -> Option<Pattern>; +} + +impl ToAzurePattern for FillOrStrokeStyle { + fn to_azure_pattern(&self, drawtarget: &DrawTarget) -> Option<Pattern> { + match *self { + FillOrStrokeStyle::Color(ref color) => { + Some(Pattern::Color(ColorPattern::new(color.to_azure_style()))) + }, + FillOrStrokeStyle::LinearGradient(ref linear_gradient_style) => { + let gradient_stops: Vec<GradientStop> = linear_gradient_style.stops.iter().map(|s| { + GradientStop { + offset: s.offset as AzFloat, + color: s.color.to_azure_style() + } + }).collect(); + + Some(Pattern::LinearGradient(LinearGradientPattern::new( + &Point2D::new(linear_gradient_style.x0 as AzFloat, linear_gradient_style.y0 as AzFloat), + &Point2D::new(linear_gradient_style.x1 as AzFloat, linear_gradient_style.y1 as AzFloat), + drawtarget.create_gradient_stops(&gradient_stops, ExtendMode::Clamp), + &Matrix2D::identity()))) + }, + FillOrStrokeStyle::RadialGradient(ref radial_gradient_style) => { + let gradient_stops: Vec<GradientStop> = radial_gradient_style.stops.iter().map(|s| { + GradientStop { + offset: s.offset as AzFloat, + color: s.color.to_azure_style() + } + }).collect(); + + Some(Pattern::RadialGradient(RadialGradientPattern::new( + &Point2D::new(radial_gradient_style.x0 as AzFloat, radial_gradient_style.y0 as AzFloat), + &Point2D::new(radial_gradient_style.x1 as AzFloat, radial_gradient_style.y1 as AzFloat), + radial_gradient_style.r0 as AzFloat, radial_gradient_style.r1 as AzFloat, + drawtarget.create_gradient_stops(&gradient_stops, ExtendMode::Clamp), + &Matrix2D::identity()))) + }, + FillOrStrokeStyle::Surface(ref surface_style) => { + drawtarget.create_source_surface_from_data(&surface_style.surface_data, + surface_style.surface_size, + surface_style.surface_size.width * 4, + SurfaceFormat::B8G8R8A8) + .map(|source_surface| { + Pattern::Surface(SurfacePattern::new( + source_surface.azure_source_surface, + surface_style.repeat_x, + surface_style.repeat_y, + &Matrix2D::identity())) + }) + } + } + } +} + +impl ToAzureStyle for RGBA { + type Target = Color; + + fn to_azure_style(self) -> Color { + Color::rgba(self.red as AzFloat, + self.green as AzFloat, + self.blue as AzFloat, + self.alpha as AzFloat) + } +} diff --git a/components/canvas/lib.rs b/components/canvas/lib.rs index 752207aa127..10470167372 100644 --- a/components/canvas/lib.rs +++ b/components/canvas/lib.rs @@ -10,6 +10,7 @@ extern crate azure; extern crate canvas_traits; extern crate core; +extern crate cssparser; extern crate euclid; extern crate gleam; extern crate ipc_channel; @@ -17,7 +18,7 @@ extern crate ipc_channel; extern crate log; extern crate num_traits; extern crate offscreen_gl_context; -extern crate util; +extern crate servo_config; extern crate webrender_traits; pub mod canvas_paint_thread; diff --git a/components/canvas/webgl_paint_thread.rs b/components/canvas/webgl_paint_thread.rs index 8a080aa639a..7de4fd67979 100644 --- a/components/canvas/webgl_paint_thread.rs +++ b/components/canvas/webgl_paint_thread.rs @@ -9,10 +9,10 @@ use gleam::gl; use ipc_channel::ipc::{self, IpcSender}; use offscreen_gl_context::{ColorAttachmentType, GLContext, GLLimits}; use offscreen_gl_context::{GLContextAttributes, NativeGLContext, OSMesaContext}; +use servo_config::opts; use std::borrow::ToOwned; use std::sync::mpsc::channel; -use util::opts; -use util::thread::spawn_named; +use std::thread; use webrender_traits; enum GLContextWrapper { @@ -116,7 +116,8 @@ impl WebGLPaintThread { webrender_api_sender: webrender_traits::RenderApiSender) -> Result<(WebGLPaintThread, GLLimits), String> { let wr_api = webrender_api_sender.create_api(); - match wr_api.request_webgl_context(&size, attrs) { + let device_size = webrender_traits::DeviceIntSize::from_untyped(&size); + match wr_api.request_webgl_context(&device_size, attrs) { Ok((id, limits)) => { let painter = WebGLPaintThread { data: WebGLPaintTaskData::WebRender(wr_api, id), @@ -151,7 +152,7 @@ impl WebGLPaintThread { -> Result<(IpcSender<CanvasMsg>, GLLimits), String> { let (sender, receiver) = ipc::channel::<CanvasMsg>().unwrap(); let (result_chan, result_port) = channel(); - spawn_named("WebGLThread".to_owned(), move || { + thread::Builder::new().name("WebGLThread".to_owned()).spawn(move || { let mut painter = match WebGLPaintThread::new(size, attrs, webrender_api_sender) { Ok((thread, limits)) => { result_chan.send(Ok(limits)).unwrap(); @@ -191,7 +192,7 @@ impl WebGLPaintThread { CanvasMsg::Canvas2d(_) => panic!("Wrong message sent to WebGLThread"), } } - }); + }).expect("Thread spawning failed"); result_port.recv().unwrap().map(|limits| (sender, limits)) } @@ -252,7 +253,8 @@ impl WebGLPaintThread { } } WebGLPaintTaskData::WebRender(ref api, id) => { - api.resize_webgl_context(id, &size); + let device_size = webrender_traits::DeviceIntSize::from_untyped(&size); + api.resize_webgl_context(id, &device_size); } } diff --git a/components/canvas_traits/Cargo.toml b/components/canvas_traits/Cargo.toml index 4f8a639c29c..0f28b2f29a3 100644 --- a/components/canvas_traits/Cargo.toml +++ b/components/canvas_traits/Cargo.toml @@ -10,7 +10,6 @@ name = "canvas_traits" path = "lib.rs" [dependencies] -azure = {git = "https://github.com/servo/rust-azure", features = ["plugins"]} cssparser = {version = "0.7", features = ["heap_size", "serde-serialization"]} euclid = "0.10.1" heapsize = "0.3.0" diff --git a/components/canvas_traits/lib.rs b/components/canvas_traits/lib.rs index 8269664cd46..b4b64e667ec 100644 --- a/components/canvas_traits/lib.rs +++ b/components/canvas_traits/lib.rs @@ -10,7 +10,6 @@ #![deny(unsafe_code)] -extern crate azure; extern crate core; extern crate cssparser; extern crate euclid; @@ -21,11 +20,6 @@ extern crate serde; #[macro_use] extern crate serde_derive; extern crate webrender_traits; -use azure::azure::AzFloat; -use azure::azure_hl::{CapStyle, CompositionOp, JoinStyle}; -use azure::azure_hl::{Color, ColorPattern, DrawTarget, Pattern}; -use azure::azure_hl::{ExtendMode, GradientStop, LinearGradientPattern, RadialGradientPattern}; -use azure::azure_hl::{SurfaceFormat, SurfacePattern}; use cssparser::RGBA; use euclid::matrix2d::Matrix2D; use euclid::point::Point2D; @@ -202,58 +196,6 @@ pub enum FillOrStrokeStyle { Surface(SurfaceStyle), } -impl FillOrStrokeStyle { - pub fn to_azure_pattern(&self, drawtarget: &DrawTarget) -> Option<Pattern> { - match *self { - FillOrStrokeStyle::Color(ref color) => { - Some(Pattern::Color(ColorPattern::new(color.to_azcolor()))) - }, - FillOrStrokeStyle::LinearGradient(ref linear_gradient_style) => { - let gradient_stops: Vec<GradientStop> = linear_gradient_style.stops.iter().map(|s| { - GradientStop { - offset: s.offset as AzFloat, - color: s.color.to_azcolor() - } - }).collect(); - - Some(Pattern::LinearGradient(LinearGradientPattern::new( - &Point2D::new(linear_gradient_style.x0 as AzFloat, linear_gradient_style.y0 as AzFloat), - &Point2D::new(linear_gradient_style.x1 as AzFloat, linear_gradient_style.y1 as AzFloat), - drawtarget.create_gradient_stops(&gradient_stops, ExtendMode::Clamp), - &Matrix2D::identity()))) - }, - FillOrStrokeStyle::RadialGradient(ref radial_gradient_style) => { - let gradient_stops: Vec<GradientStop> = radial_gradient_style.stops.iter().map(|s| { - GradientStop { - offset: s.offset as AzFloat, - color: s.color.to_azcolor() - } - }).collect(); - - Some(Pattern::RadialGradient(RadialGradientPattern::new( - &Point2D::new(radial_gradient_style.x0 as AzFloat, radial_gradient_style.y0 as AzFloat), - &Point2D::new(radial_gradient_style.x1 as AzFloat, radial_gradient_style.y1 as AzFloat), - radial_gradient_style.r0 as AzFloat, radial_gradient_style.r1 as AzFloat, - drawtarget.create_gradient_stops(&gradient_stops, ExtendMode::Clamp), - &Matrix2D::identity()))) - }, - FillOrStrokeStyle::Surface(ref surface_style) => { - drawtarget.create_source_surface_from_data(&surface_style.surface_data, - surface_style.surface_size, - surface_style.surface_size.width * 4, - SurfaceFormat::B8G8R8A8) - .map(|source_surface| { - Pattern::Surface(SurfacePattern::new( - source_surface.azure_source_surface, - surface_style.repeat_x, - surface_style.repeat_y, - &Matrix2D::identity())) - }) - } - } - } -} - #[derive(Copy, Clone, PartialEq, Deserialize, Serialize, HeapSizeOf)] pub enum LineCapStyle { Butt = 0, @@ -274,16 +216,6 @@ impl FromStr for LineCapStyle { } } -impl LineCapStyle { - pub fn to_azure_style(&self) -> CapStyle { - match *self { - LineCapStyle::Butt => CapStyle::Butt, - LineCapStyle::Round => CapStyle::Round, - LineCapStyle::Square => CapStyle::Square, - } - } -} - #[derive(Copy, Clone, PartialEq, Deserialize, Serialize, HeapSizeOf)] pub enum LineJoinStyle { Round = 0, @@ -304,16 +236,6 @@ impl FromStr for LineJoinStyle { } } -impl LineJoinStyle { - pub fn to_azure_style(&self) -> JoinStyle { - match *self { - LineJoinStyle::Round => JoinStyle::Round, - LineJoinStyle::Bevel => JoinStyle::Bevel, - LineJoinStyle::Miter => JoinStyle::Miter, - } - } -} - #[derive(Copy, Clone, PartialEq, Deserialize, Serialize)] pub enum RepetitionStyle { Repeat, @@ -373,22 +295,6 @@ impl FromStr for CompositionStyle { } impl CompositionStyle { - pub fn to_azure_style(&self) -> CompositionOp { - match *self { - CompositionStyle::SrcIn => CompositionOp::In, - CompositionStyle::SrcOut => CompositionOp::Out, - CompositionStyle::SrcOver => CompositionOp::Over, - CompositionStyle::SrcAtop => CompositionOp::Atop, - CompositionStyle::DestIn => CompositionOp::DestIn, - CompositionStyle::DestOut => CompositionOp::DestOut, - CompositionStyle::DestOver => CompositionOp::DestOver, - CompositionStyle::DestAtop => CompositionOp::DestAtop, - CompositionStyle::Copy => CompositionOp::Source, - CompositionStyle::Lighter => CompositionOp::Add, - CompositionStyle::Xor => CompositionOp::Xor, - } - } - pub fn to_str(&self) -> &str { match *self { CompositionStyle::SrcIn => "source-in", @@ -451,26 +357,6 @@ impl FromStr for BlendingStyle { } impl BlendingStyle { - pub fn to_azure_style(&self) -> CompositionOp { - match *self { - BlendingStyle::Multiply => CompositionOp::Multiply, - BlendingStyle::Screen => CompositionOp::Screen, - BlendingStyle::Overlay => CompositionOp::Overlay, - BlendingStyle::Darken => CompositionOp::Darken, - BlendingStyle::Lighten => CompositionOp::Lighten, - BlendingStyle::ColorDodge => CompositionOp::ColorDodge, - BlendingStyle::ColorBurn => CompositionOp::ColorBurn, - BlendingStyle::HardLight => CompositionOp::HardLight, - BlendingStyle::SoftLight => CompositionOp::SoftLight, - BlendingStyle::Difference => CompositionOp::Difference, - BlendingStyle::Exclusion => CompositionOp::Exclusion, - BlendingStyle::Hue => CompositionOp::Hue, - BlendingStyle::Saturation => CompositionOp::Saturation, - BlendingStyle::Color => CompositionOp::Color, - BlendingStyle::Luminosity => CompositionOp::Luminosity, - } - } - pub fn to_str(&self) -> &str { match *self { BlendingStyle::Multiply => "multiply", @@ -520,28 +406,6 @@ impl FromStr for CompositionOrBlending { } } -impl CompositionOrBlending { - pub fn to_azure_style(&self) -> CompositionOp { - match *self { - CompositionOrBlending::Composition(op) => op.to_azure_style(), - CompositionOrBlending::Blending(op) => op.to_azure_style(), - } - } -} - -pub trait ToAzColor { - fn to_azcolor(&self) -> Color; -} - -impl ToAzColor for RGBA { - fn to_azcolor(&self) -> Color { - Color::rgba(self.red as AzFloat, - self.green as AzFloat, - self.blue as AzFloat, - self.alpha as AzFloat) - } -} - // TODO(pcwalton): Speed up with SIMD, or better yet, find some way to not do this. pub fn byte_swap(data: &mut [u8]) { let length = data.len(); diff --git a/components/compositing/Cargo.toml b/components/compositing/Cargo.toml index 1ba3aa39eb8..37309714e50 100644 --- a/components/compositing/Cargo.toml +++ b/components/compositing/Cargo.toml @@ -23,10 +23,11 @@ profile_traits = {path = "../profile_traits"} script_traits = {path = "../script_traits"} serde = "0.8" serde_derive = "0.8" +servo_config = {path = "../config", features = ["servo"]} +servo_geometry = {path = "../geometry", features = ["servo"]} servo_url = {path = "../url", features = ["servo"]} style_traits = {path = "../style_traits"} time = "0.1.17" -util = {path = "../util"} [dependencies.webrender] git = "https://github.com/servo/webrender" diff --git a/components/compositing/compositor.rs b/components/compositing/compositor.rs index a721c2b19c8..4f667bfbef3 100644 --- a/components/compositing/compositor.rs +++ b/components/compositing/compositor.rs @@ -7,7 +7,7 @@ use SendableFrameTree; use compositor_thread::{CompositorProxy, CompositorReceiver}; use compositor_thread::{InitialCompositorState, Msg, RenderListener}; use delayed_composition::DelayedCompositionTimerProxy; -use euclid::{Point2D, Size2D}; +use euclid::Point2D; use euclid::point::TypedPoint2D; use euclid::scale_factor::ScaleFactor; use euclid::size::TypedSize2D; @@ -26,20 +26,21 @@ use script_traits::{ConstellationMsg, LayoutControlMsg, LoadData, MouseButton}; use script_traits::{MouseEventType, StackingContextScrollState}; use script_traits::{TouchpadPressurePhase, TouchEventType, TouchId, WindowSizeData, WindowSizeType}; use script_traits::CompositorEvent::{self, MouseMoveEvent, MouseButtonEvent, TouchEvent, TouchpadPressureEvent}; +use servo_config::opts; +use servo_config::prefs::PREFS; +use servo_geometry::ScreenPx; use servo_url::ServoUrl; use std::collections::HashMap; use std::fs::File; use std::rc::Rc; use std::sync::mpsc::Sender; +use std::time::{Duration, Instant}; use style_traits::{PagePx, ViewportPx}; use style_traits::viewport::ViewportConstraints; use time::{precise_time_ns, precise_time_s}; use touch::{TouchHandler, TouchAction}; -use util::geometry::ScreenPx; -use util::opts; -use util::prefs::PREFS; use webrender; -use webrender_traits::{self, ScrollEventPhase, ServoScrollRootId}; +use webrender_traits::{self, ScrollEventPhase, ServoScrollRootId, LayoutPoint}; use windowing::{self, MouseWindowEvent, WindowEvent, WindowMethods, WindowNavigateMsg}; #[derive(Debug, PartialEq)] @@ -198,6 +199,8 @@ pub struct IOCompositor<Window: WindowMethods> { /// Whether a scroll is in progress; i.e. whether the user's fingers are down. scroll_in_progress: bool, + in_scroll_transaction: Option<Instant>, + /// The webrender renderer. webrender: webrender::Renderer, @@ -333,11 +336,11 @@ impl webrender_traits::RenderNotifier for RenderNotifier { fn pipeline_size_changed(&mut self, pipeline_id: webrender_traits::PipelineId, - size: Option<Size2D<f32>>) { + size: Option<webrender_traits::LayoutSize>) { let pipeline_id = pipeline_id.from_webrender(); if let Some(size) = size { - let msg = ConstellationMsg::FrameSize(pipeline_id, size); + let msg = ConstellationMsg::FrameSize(pipeline_id, size.to_untyped()); if let Err(e) = self.constellation_chan.send(msg) { warn!("Compositor resize to constellation failed ({}).", e); } @@ -396,6 +399,7 @@ impl<Window: WindowMethods> IOCompositor<Window> { last_composite_time: 0, ready_to_save_state: ReadyState::Unknown, scroll_in_progress: false, + in_scroll_transaction: None, webrender: state.webrender, webrender_api: state.webrender_api_sender.create_api(), } @@ -769,7 +773,7 @@ impl<Window: WindowMethods> IOCompositor<Window> { scroll_root_id: ScrollRootId, point: Point2D<f32>) { self.webrender_api.scroll_layers_with_scroll_root_id( - point, + LayoutPoint::from_untyped(&point), pipeline_id.to_webrender(), ServoScrollRootId(scroll_root_id.0)); } @@ -1076,11 +1080,18 @@ impl<Window: WindowMethods> IOCompositor<Window> { fn on_scroll_window_event(&mut self, delta: TypedPoint2D<f32, DevicePixel>, cursor: TypedPoint2D<i32, DevicePixel>) { + let event_phase = match (self.scroll_in_progress, self.in_scroll_transaction) { + (false, None) => ScrollEventPhase::Start, + (false, Some(last_scroll)) if last_scroll.elapsed() > Duration::from_millis(80) => + ScrollEventPhase::Start, + (_, _) => ScrollEventPhase::Move(self.scroll_in_progress), + }; + self.in_scroll_transaction = Some(Instant::now()); self.pending_scroll_zoom_events.push(ScrollZoomEvent { magnification: 1.0, delta: delta, cursor: cursor, - phase: ScrollEventPhase::Move(self.scroll_in_progress), + phase: event_phase, event_count: 1, }); } @@ -1124,7 +1135,10 @@ impl<Window: WindowMethods> IOCompositor<Window> { let delta = (combined_event.delta / self.scale).to_untyped(); let cursor = (combined_event.cursor.to_f32() / self.scale).to_untyped(); - self.webrender_api.scroll(delta, cursor, combined_event.phase); + let delta = webrender_traits::LayerPoint::from_untyped(&delta); + let location = webrender_traits::ScrollLocation::Delta(delta); + let cursor = webrender_traits::WorldPoint::from_untyped(&cursor); + self.webrender_api.scroll(location, cursor, combined_event.phase); last_combined_event = None } } @@ -1164,8 +1178,11 @@ impl<Window: WindowMethods> IOCompositor<Window> { // TODO(gw): Support zoom (WR issue #28). if let Some(combined_event) = last_combined_event { let delta = (combined_event.delta / self.scale).to_untyped(); + let delta = webrender_traits::LayoutPoint::from_untyped(&delta); let cursor = (combined_event.cursor.to_f32() / self.scale).to_untyped(); - self.webrender_api.scroll(delta, cursor, combined_event.phase); + let location = webrender_traits::ScrollLocation::Delta(delta); + let cursor = webrender_traits::WorldPoint::from_untyped(&cursor); + self.webrender_api.scroll(location, cursor, combined_event.phase); self.waiting_for_results_of_scroll = true } @@ -1306,7 +1323,7 @@ impl<Window: WindowMethods> IOCompositor<Window> { for scroll_layer_state in self.webrender_api.get_scroll_layer_state() { let stacking_context_scroll_state = StackingContextScrollState { scroll_root_id: scroll_layer_state.scroll_root_id.from_webrender(), - scroll_offset: scroll_layer_state.scroll_offset, + scroll_offset: scroll_layer_state.scroll_offset.to_untyped(), }; let pipeline_id = scroll_layer_state.pipeline_id; stacking_context_scroll_states_per_pipeline @@ -1454,7 +1471,8 @@ impl<Window: WindowMethods> IOCompositor<Window> { debug!("compositor: compositing"); // Paint the scene. - self.webrender.render(self.window_size.to_untyped()); + let size = webrender_traits::DeviceUintSize::from_untyped(&self.window_size.to_untyped()); + self.webrender.render(size); }); let rv = match target { diff --git a/components/compositing/lib.rs b/components/compositing/lib.rs index c5b98a6e679..781f4c4f868 100644 --- a/components/compositing/lib.rs +++ b/components/compositing/lib.rs @@ -23,11 +23,11 @@ extern crate profile_traits; extern crate script_traits; #[macro_use] extern crate serde_derive; +extern crate servo_config; +extern crate servo_geometry; extern crate servo_url; extern crate style_traits; extern crate time; -#[macro_use] -extern crate util; extern crate webrender; extern crate webrender_traits; diff --git a/components/compositing/windowing.rs b/components/compositing/windowing.rs index 33eed7630cc..a6933ce92fd 100644 --- a/components/compositing/windowing.rs +++ b/components/compositing/windowing.rs @@ -13,10 +13,10 @@ use gfx_traits::DevicePixel; use msg::constellation_msg::{Key, KeyModifiers, KeyState}; use net_traits::net_error_list::NetError; use script_traits::{MouseButton, TouchEventType, TouchId, TouchpadPressurePhase}; +use servo_geometry::ScreenPx; use servo_url::ServoUrl; use std::fmt::{Debug, Error, Formatter}; use style_traits::cursor::Cursor; -use util::geometry::ScreenPx; #[derive(Clone)] pub enum MouseWindowEvent { diff --git a/components/util/Cargo.toml b/components/config/Cargo.toml index 2f9ee4486cf..1ef60b64382 100644 --- a/components/util/Cargo.toml +++ b/components/config/Cargo.toml @@ -1,31 +1,29 @@ [package] -name = "util" +name = "servo_config" version = "0.0.1" authors = ["The Servo Project Developers"] license = "MPL-2.0" publish = false [lib] -name = "util" +name = "servo_config" path = "lib.rs" [features] # servo as opposed to geckolib -servo = ["serde", "serde_derive", "app_units/plugins", - "euclid/unstable", "url/heap_size", "url/serde", "plugins"] +servo = ["serde", "serde_derive", "url/heap_size", "url/serde", "plugins"] [dependencies] -app_units = "0.3" bitflags = "0.7" euclid = "0.10.1" getopts = "0.2.11" -heapsize = "0.3.0" lazy_static = "0.2" log = "0.3.5" num_cpus = "1.1.0" rustc-serialize = "0.3" serde = {version = "0.8", optional = true} serde_derive = {version = "0.8", optional = true} +servo_geometry = {path = "../geometry"} servo_url = {path = "../url"} plugins = {path = "../plugins", optional = true} url = "1.2" diff --git a/components/util/basedir.rs b/components/config/basedir.rs index 5c7896a388b..5c7896a388b 100644 --- a/components/util/basedir.rs +++ b/components/config/basedir.rs diff --git a/components/util/lib.rs b/components/config/lib.rs index 3c72d90d257..e4df206f47a 100644 --- a/components/util/lib.rs +++ b/components/config/lib.rs @@ -2,37 +2,32 @@ * 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/. */ -#![cfg_attr(feature = "servo", feature(nonzero))] #![cfg_attr(feature = "servo", feature(plugin))] #![cfg_attr(feature = "servo", feature(proc_macro))] #![cfg_attr(feature = "servo", plugin(plugins))] #![deny(unsafe_code)] -extern crate app_units; #[allow(unused_extern_crates)] #[macro_use] extern crate bitflags; extern crate core; -#[macro_use] extern crate euclid; +extern crate euclid; extern crate getopts; -#[macro_use] extern crate heapsize; #[allow(unused_extern_crates)] #[macro_use] extern crate lazy_static; #[macro_use] extern crate log; extern crate num_cpus; extern crate rustc_serialize; #[cfg(feature = "servo")] extern crate serde; #[cfg(feature = "servo")] #[macro_use] extern crate serde_derive; +extern crate servo_geometry; extern crate servo_url; extern crate url; #[cfg(all(unix, not(target_os = "macos"), not(target_os = "ios"), not(target_os = "android")))] extern crate xdg; pub mod basedir; -pub mod geometry; #[allow(unsafe_code)] pub mod opts; pub mod prefs; -#[cfg(feature = "servo")] pub mod remutex; pub mod resource_files; -pub mod thread; pub fn servo_version() -> String { let cargo_version = env!("CARGO_PKG_VERSION"); @@ -42,13 +37,3 @@ pub fn servo_version() -> String { None => format!("Servo {}", cargo_version), } } - -pub fn clamp<T: Ord>(lo: T, mid: T, hi: T) -> T { - if mid < lo { - lo - } else if mid > hi { - hi - } else { - mid - } -} diff --git a/components/util/opts.rs b/components/config/opts.rs index 4f1db5d8c50..a59cd56f0d7 100644 --- a/components/util/opts.rs +++ b/components/config/opts.rs @@ -6,11 +6,11 @@ //! from command line arguments. use euclid::size::TypedSize2D; -use geometry::ScreenPx; use getopts::Options; use num_cpus; use prefs::{self, PrefValue, PREFS}; use resource_files::set_resources_path; +use servo_geometry::ScreenPx; use servo_url::ServoUrl; use std::borrow::Cow; use std::cmp; diff --git a/components/util/prefs.rs b/components/config/prefs.rs index c0ad11bfe0b..c0ad11bfe0b 100644 --- a/components/util/prefs.rs +++ b/components/config/prefs.rs diff --git a/components/util/resource_files.rs b/components/config/resource_files.rs index 4a155ecf51e..4a155ecf51e 100644 --- a/components/util/resource_files.rs +++ b/components/config/resource_files.rs diff --git a/components/constellation/Cargo.toml b/components/constellation/Cargo.toml index 1734ec27df8..d919cd63af3 100644 --- a/components/constellation/Cargo.toml +++ b/components/constellation/Cargo.toml @@ -33,8 +33,9 @@ script_traits = {path = "../script_traits"} serde = "0.8" serde_derive = "0.8" style_traits = {path = "../style_traits"} +servo_config = {path = "../config", features = ["servo"]} +servo_remutex = {path = "../remutex"} servo_url = {path = "../url", features = ["servo"]} -util = {path = "../util"} [dependencies.webrender_traits] git = "https://github.com/servo/webrender" diff --git a/components/constellation/constellation.rs b/components/constellation/constellation.rs index c34f9b1597c..12a641c3c08 100644 --- a/components/constellation/constellation.rs +++ b/components/constellation/constellation.rs @@ -4,10 +4,63 @@ //! The `Constellation`, Servo's Grand Central Station //! -//! The primary duty of a `Constellation` is to mediate between the -//! graphics compositor and the many `Pipeline`s in the browser's -//! navigation context, each `Pipeline` encompassing a `ScriptThread`, -//! `LayoutThread`, and `PaintThread`. +//! The constellation tracks all information kept globally by the +//! browser engine, which includes: +//! +//! * The set of all `EventLoop` objects. Each event loop is +//! the constellation's view of a script thread. The constellation +//! interacts with a script thread by message-passing. +//! +//! * The set of all `Pipeline` objects. Each pipeline gives the +//! constellation's view of a `Window`, with its script thread and +//! layout threads. Pipelines may share script threads, but not +//! layout threads. +//! +//! * The set of all `Frame` objects. Each frame gives the constellation's +//! view of a browsing context. Each browsing context stores an independent +//! session history, created by navigation of that frame. The session +//! history can be traversed, for example by the back and forwards UI, +//! so each session history maintains a list of past and future pipelines, +//! as well as the current active pipeline. +//! +//! There are two kinds of frames: top-level frames (for example tabs +//! in a browser UI), and nested frames (typically caused by `iframe` +//! elements). Frames have a hierarchy (typically caused by `iframe`s +//! containing `iframe`s), giving rise to a frame tree with a root frame. +//! The logical relationship between these types is: +//! +//! ``` +//! +---------+ +------------+ +-------------+ +//! | Frame | --parent?--> | Pipeline | --event_loop--> | EventLoop | +//! | | --current--> | | | | +//! | | --prev*----> | | <---pipeline*-- | | +//! | | --next*----> | | +-------------+ +//! | | | | +//! | | <----frame-- | | +//! +---------+ +------------+ +//! ``` +// +//! Complicating matters, there are also mozbrowser iframes, which are top-level +//! frames with a parent. +//! +//! The constellation also maintains channels to threads, including: +//! +//! * The script and layout threads. +//! * The graphics compositor. +//! * The font cache, image cache, and resource manager, which load +//! and cache shared fonts, images, or other resources. +//! * The service worker manager. +//! * The devtools, debugger and webdriver servers. +//! +//! The constellation passes messages between the threads, and updates its state +//! to track the evolving state of the frame tree. +//! +//! The constellation acts as a logger, tracking any `warn!` messages from threads, +//! and converting any `error!` or `panic!` into a crash report, which is filed +//! using an appropriate `mozbrowsererror` event. +//! +//! Since there is only one constellation, and its responsibilities include crash reporting, +//! it is very important that it does not panic. use backtrace::Backtrace; use bluetooth_traits::BluetoothRequest; @@ -21,6 +74,7 @@ use debugger; use devtools_traits::{ChromeToDevtoolsControlMsg, DevtoolsControlMsg}; use euclid::scale_factor::ScaleFactor; use euclid::size::{Size2D, TypedSize2D}; +use event_loop::EventLoop; use gfx::font_cache_thread::FontCacheThread; use gfx_traits::Epoch; use ipc_channel::ipc::{self, IpcSender}; @@ -32,10 +86,10 @@ use msg::constellation_msg::{Key, KeyModifiers, KeyState}; use msg::constellation_msg::{PipelineNamespace, PipelineNamespaceId, TraversalDirection}; use net_traits::{self, IpcSend, ResourceThreads}; use net_traits::image_cache_thread::ImageCacheThread; -use net_traits::pub_domains::reg_suffix; +use net_traits::pub_domains::reg_host; use net_traits::storage_thread::{StorageThreadMsg, StorageType}; use offscreen_gl_context::{GLContextAttributes, GLLimits}; -use pipeline::{ChildProcess, InitialPipelineState, Pipeline}; +use pipeline::{InitialPipelineState, Pipeline}; use profile_traits::mem; use profile_traits::time; use rand::{Rng, SeedableRng, StdRng, random}; @@ -47,6 +101,9 @@ use script_traits::{LayoutMsg as FromLayoutMsg, ScriptMsg as FromScriptMsg, Scri use script_traits::{LogEntry, ServiceWorkerMsg, webdriver_msg}; use script_traits::{MozBrowserErrorType, MozBrowserEvent, WebDriverCommandMsg, WindowSizeData}; use script_traits::{SWManagerMsg, ScopeThings, WindowSizeType}; +use servo_config::opts; +use servo_config::prefs::PREFS; +use servo_remutex::ReentrantMutex; use servo_url::ServoUrl; use std::borrow::ToOwned; use std::collections::{HashMap, VecDeque}; @@ -64,127 +121,152 @@ use style_traits::PagePx; use style_traits::cursor::Cursor; use style_traits::viewport::ViewportConstraints; use timer_scheduler::TimerScheduler; -use util::opts; -use util::prefs::PREFS; -use util::remutex::ReentrantMutex; -use util::thread::spawn_named; use webrender_traits; -#[derive(Debug, PartialEq)] -enum ReadyToSave { - NoRootFrame, - PendingFrames, - WebFontNotLoaded, - DocumentLoading, - EpochMismatch, - PipelineUnknown, - Ready, -} - -/// Maintains the pipelines and navigation context and grants permission to composite. +/// The `Constellation` itself. In the servo browser, there is one +/// constellation, which maintains all of the browser global data. +/// In embedded applications, there may be more than one constellation, +/// which are independent of each other. +/// +/// The constellation may be in a different process from the pipelines, +/// and communicates using IPC. /// /// It is parameterized over a `LayoutThreadFactory` and a /// `ScriptThreadFactory` (which in practice are implemented by /// `LayoutThread` in the `layout` crate, and `ScriptThread` in -/// the `script` crate). +/// the `script` crate). Script and layout communicate using a `Message` +/// type. pub struct Constellation<Message, LTF, STF> { - /// A channel through which script messages can be sent to this object. + /// An IPC channel for script threads to send messages to the constellation. + /// This is the script threads' view of `script_receiver`. script_sender: IpcSender<FromScriptMsg>, - /// A channel through which layout thread messages can be sent to this object. - layout_sender: IpcSender<FromLayoutMsg>, - - /// Receives messages from scripts. + /// A channel for the constellation to receive messages from script threads. + /// This is the constellation's view of `script_sender`. script_receiver: Receiver<FromScriptMsg>, - /// Receives messages from the compositor - compositor_receiver: Receiver<FromCompositorMsg>, + /// An IPC channel for layout threads to send messages to the constellation. + /// This is the layout threads' view of `layout_receiver`. + layout_sender: IpcSender<FromLayoutMsg>, - /// Receives messages from the layout thread + /// A channel for the constellation to receive messages from layout threads. + /// This is the constellation's view of `layout_sender`. layout_receiver: Receiver<FromLayoutMsg>, - /// A channel (the implementation of which is port-specific) through which messages can be sent - /// to the compositor. + /// A channel for the constellation to receive messages from the compositor thread. + compositor_receiver: Receiver<FromCompositorMsg>, + + /// A channel (the implementation of which is port-specific) for the + /// constellation to send messages to the compositor thread. compositor_proxy: Box<CompositorProxy>, - /// Channels through which messages can be sent to the resource-related threads. + /// Channels for the constellation to send messages to the public + /// resource-related threads. There are two groups of resource + /// threads: one for public browsing, and one for private + /// browsing. public_resource_threads: ResourceThreads, - /// Channels through which messages can be sent to the resource-related threads. + /// Channels for the constellation to send messages to the private + /// resource-related threads. There are two groups of resource + /// threads: one for public browsing, and one for private + /// browsing. private_resource_threads: ResourceThreads, - /// A channel through which messages can be sent to the image cache thread. + /// A channel for the constellation to send messages to the image + /// cache thread. image_cache_thread: ImageCacheThread, - /// A channel through which messages can be sent to the debugger. + /// A channel for the constellation to send messages to the font + /// cache thread. + font_cache_thread: FontCacheThread, + + /// A channel for the constellation to send messages to the + /// debugger thread. debugger_chan: Option<debugger::Sender>, - /// A channel through which messages can be sent to the developer tools. + /// A channel for the constellation to send messages to the + /// devtools thread. devtools_chan: Option<Sender<DevtoolsControlMsg>>, - /// A channel through which messages can be sent to the bluetooth thread. + /// An IPC channel for the constellation to send messages to the + /// bluetooth thread. bluetooth_thread: IpcSender<BluetoothRequest>, - /// Sender to Service Worker Manager thread + /// An IPC channel for the constellation to send messages to the + /// Service Worker Manager thread. swmanager_chan: Option<IpcSender<ServiceWorkerMsg>>, - /// to send messages to this object + /// An IPC channel for Service Worker Manager threads to send + /// messages to the constellation. This is the SW Manager thread's + /// view of `swmanager_receiver`. swmanager_sender: IpcSender<SWManagerMsg>, - /// to receive sw manager message + /// A channel for the constellation to receive messages from the + /// Service Worker Manager thread. This is the constellation's view of + /// `swmanager_sender`. swmanager_receiver: Receiver<SWManagerMsg>, - /// A map from top-level frame id and registered domain name to script channels. - /// This double indirection ensures that separate tabs do not share script threads, - /// even if the same domain is loaded in each. - script_channels: HashMap<FrameId, HashMap<String, Weak<ScriptChan>>>, - - /// A list of all the pipelines. (See the `pipeline` module for more details.) - pipelines: HashMap<PipelineId, Pipeline>, + /// A channel for the constellation to send messages to the + /// time profiler thread. + time_profiler_chan: time::ProfilerChan, - /// A list of all the frames - frames: HashMap<FrameId, Frame>, + /// A channel for the constellation to send messages to the + /// memory profiler thread. + mem_profiler_chan: mem::ProfilerChan, - /// A channel through which messages can be sent to the font cache. - font_cache_thread: FontCacheThread, + /// A channel for the constellation to send messages to the + /// timer thread. + scheduler_chan: IpcSender<TimerEventRequest>, - /// ID of the root frame. - root_frame_id: FrameId, + /// A channel for the constellation to send messages to the + /// Webrender thread. + webrender_api_sender: webrender_traits::RenderApiSender, - /// The next free ID to assign to a pipeline ID namespace. - next_pipeline_namespace_id: PipelineNamespaceId, + /// The set of all event loops in the browser. We generate a new + /// event loop for each registered domain name (aka eTLD+1) in + /// each top-level frame. We store the event loops in a map + /// indexed by top-level frame id (as a `FrameId`) and registered + /// domain name (as a `String`) to event loops. This double + /// indirection ensures that separate tabs do not share event + /// loops, even if the same domain is loaded in each. + /// It is important that scripts with the same eTLD+1 + /// share an event loop, since they can use `document.domain` + /// to become same-origin, at which point they can share DOM objects. + event_loops: HashMap<FrameId, HashMap<String, Weak<EventLoop>>>, + + /// The set of all the pipelines in the browser. + /// (See the `pipeline` module for more details.) + pipelines: HashMap<PipelineId, Pipeline>, - /// Pipeline ID that has currently focused element for key events. - focus_pipeline_id: Option<PipelineId>, + /// The set of all the frames in the browser. + frames: HashMap<FrameId, Frame>, - /// Navigation operations that are in progress. + /// When a navigation is performed, we do not immediately update + /// the frame tree, instead we ask the event loop to begin loading + /// the new document, and do not update the frame tree until the + /// document is active. Between starting the load and it activating, + /// we store a `FrameChange` object for the navigation in progress. pending_frames: Vec<FrameChange>, - /// A channel through which messages can be sent to the time profiler. - time_profiler_chan: time::ProfilerChan, + /// The root frame. + root_frame_id: FrameId, - /// A channel through which messages can be sent to the memory profiler. - mem_profiler_chan: mem::ProfilerChan, + /// The currently focused pipeline for key events. + focus_pipeline_id: Option<PipelineId>, - phantom: PhantomData<(Message, LTF, STF)>, + /// Pipeline IDs are namespaced in order to avoid name collisions, + /// and the namespaces are allocated by the constellation. + next_pipeline_namespace_id: PipelineNamespaceId, + /// The size of the top-level window. window_size: WindowSizeData, /// Bits of state used to interact with the webdriver implementation webdriver: WebDriverData, - scheduler_chan: IpcSender<TimerEventRequest>, - - /// A list of child content processes. - #[cfg_attr(target_os = "windows", allow(dead_code))] - child_processes: Vec<ChildProcess>, - /// Document states for loaded pipelines (used only when writing screenshots). document_states: HashMap<PipelineId, DocumentState>, - // Webrender interface. - webrender_api_sender: webrender_traits::RenderApiSender, - /// Are we shutting down? shutting_down: bool, @@ -195,62 +277,77 @@ pub struct Constellation<Message, LTF, STF> { /// The random number generator and probability for closing pipelines. /// This is for testing the hardening of the constellation. random_pipeline_closure: Option<(StdRng, f32)>, + + /// Phantom data that keeps the Rust type system happy. + phantom: PhantomData<(Message, LTF, STF)>, } /// State needed to construct a constellation. pub struct InitialConstellationState { /// A channel through which messages can be sent to the compositor. pub compositor_proxy: Box<CompositorProxy + Send>, + /// A channel to the debugger, if applicable. pub debugger_chan: Option<debugger::Sender>, + /// A channel to the developer tools, if applicable. pub devtools_chan: Option<Sender<DevtoolsControlMsg>>, + /// A channel to the bluetooth thread. pub bluetooth_thread: IpcSender<BluetoothRequest>, + /// A channel to the image cache thread. pub image_cache_thread: ImageCacheThread, + /// A channel to the font cache thread. pub font_cache_thread: FontCacheThread, + /// A channel to the resource thread. pub public_resource_threads: ResourceThreads, + /// A channel to the resource thread. pub private_resource_threads: ResourceThreads, + /// A channel to the time profiler thread. pub time_profiler_chan: time::ProfilerChan, + /// A channel to the memory profiler thread. pub mem_profiler_chan: mem::ProfilerChan, - /// Whether the constellation supports the clipboard. - pub supports_clipboard: bool, + /// Webrender API. pub webrender_api_sender: webrender_traits::RenderApiSender, -} - -#[derive(Debug, Clone)] -struct FrameState { - instant: Instant, - pipeline_id: PipelineId, - frame_id: FrameId, -} -impl FrameState { - fn new(pipeline_id: PipelineId, frame_id: FrameId) -> FrameState { - FrameState { - instant: Instant::now(), - pipeline_id: pipeline_id, - frame_id: frame_id, - } - } + /// Whether the constellation supports the clipboard. + /// TODO: this field is not used, remove it? + pub supports_clipboard: bool, } -/// Stores the navigation context for a single frame in the frame tree. +/// A frame in the frame tree. +/// Each frame is the constrellation's view of a browsing context. +/// Each browsing context has a session history, caused by +/// navigation and traversing the history. Each frame has its +/// current entry, plus past and future entries. The past is sorted +/// chronologically, the future is sorted reverse chronoogically: +/// in partiucular prev.pop() is the latest past entry, and +/// next.pop() is the earliest future entry. +#[derive(Debug, Clone)] struct Frame { + /// The frame id. id: FrameId, + + /// The past session history, ordered chronologically. prev: Vec<FrameState>, + + /// The currently active session history entry. current: FrameState, + + /// The future session history, ordered reverse chronologically. next: Vec<FrameState>, } impl Frame { + /// Create a new frame. + /// Note this just creates the frame, it doesn't add it to the frame tree. fn new(id: FrameId, pipeline_id: PipelineId) -> Frame { Frame { id: id, @@ -260,36 +357,80 @@ impl Frame { } } + /// Set the current frame entry, and push the current frame entry into the past. fn load(&mut self, pipeline_id: PipelineId) { self.prev.push(self.current.clone()); self.current = FrameState::new(pipeline_id, self.id); } + /// Set the future to be empty. fn remove_forward_entries(&mut self) -> Vec<FrameState> { replace(&mut self.next, vec!()) } + /// Set the current frame entry, and drop the current frame entry. fn replace_current(&mut self, pipeline_id: PipelineId) -> FrameState { replace(&mut self.current, FrameState::new(pipeline_id, self.id)) } } +/// An entry in a frame's session history. +/// Each entry stores the pipeline id for a document in the session history. +/// When we operate on the joint session history, entries are sorted chronologically, +/// so we timestamp the entries by when the entry was added to the session history. +#[derive(Debug, Clone)] +struct FrameState { + /// The timestamp for when the session history entry was created + instant: Instant, + /// The pipeline for the document in the session history + pipeline_id: PipelineId, + /// The frame that this session history entry is part of + frame_id: FrameId, +} + +impl FrameState { + /// Create a new session history entry. + fn new(pipeline_id: PipelineId, frame_id: FrameId) -> FrameState { + FrameState { + instant: Instant::now(), + pipeline_id: pipeline_id, + frame_id: frame_id, + } + } +} + /// Represents a pending change in the frame tree, that will be applied /// once the new pipeline has loaded and completed initial layout / paint. struct FrameChange { + /// The frame to change. frame_id: FrameId, + + /// The pipeline that was currently active at the time the change started. + /// TODO: can this field be removed? old_pipeline_id: Option<PipelineId>, + + /// The pipeline for the document being loaded. new_pipeline_id: PipelineId, - document_ready: bool, + + /// Is the new document replacing the current document (e.g. a reload) + /// or pushing it into the session history (e.g. a navigation)? replace: bool, } -/// An iterator over a frame tree, returning nodes in depth-first order. -/// Note that this iterator should _not_ be used to mutate nodes _during_ -/// iteration. Mutating nodes once the iterator is out of scope is OK. +/// An iterator over a frame tree, returning the fully active frames in +/// depth-first order. Note that this iterator only returns the fully +/// active frames, that is ones where every ancestor frame is +/// in the currently active pipeline of its parent frame. struct FrameTreeIterator<'a> { + /// The frames still to iterate over. stack: Vec<FrameId>, + + /// The set of all frames. frames: &'a HashMap<FrameId, Frame>, + + /// The set of all pipelines. We use this to find the active + /// children of a frame, which are the iframes in the currently + /// active document. pipelines: &'a HashMap<PipelineId, Pipeline>, } @@ -321,9 +462,19 @@ impl<'a> Iterator for FrameTreeIterator<'a> { } } +/// An iterator over a frame tree, returning all frames in depth-first +/// order. Note that this iterator returns all frames, not just the +/// fully active ones. struct FullFrameTreeIterator<'a> { + /// The frames still to iterate over. stack: Vec<FrameId>, + + /// The set of all frames. frames: &'a HashMap<FrameId, Frame>, + + /// The set of all pipelines. We use this to find the + /// children of a frame, which are the iframes in all documents + /// in the session history. pipelines: &'a HashMap<PipelineId, Pipeline>, } @@ -352,6 +503,7 @@ impl<'a> Iterator for FullFrameTreeIterator<'a> { } } +/// Data needed for webdriver struct WebDriverData { load_channel: Option<(PipelineId, IpcSender<webdriver_msg::LoadStatus>)>, resize_channel: Option<IpcSender<WindowSizeData>>, @@ -366,35 +518,32 @@ impl WebDriverData { } } +/// When we are running reftests, we save an image to compare against a reference. +/// This enum gives the possible states of preparing such an image. +#[derive(Debug, PartialEq)] +enum ReadyToSave { + NoRootFrame, + PendingFrames, + WebFontNotLoaded, + DocumentLoading, + EpochMismatch, + PipelineUnknown, + Ready, +} + +/// When we are exiting a pipeline, we can either force exiting or not. +/// A normal exit waits for the compositor to update its state before +/// exiting, and delegates layout exit to script. A forced exit does +/// not notify the compositor, and exits layout without involving script. #[derive(Clone, Copy)] enum ExitPipelineMode { Normal, Force, } -/// A script channel, that closes the script thread down when it is dropped -pub struct ScriptChan { - chan: IpcSender<ConstellationControlMsg>, - dont_send_or_sync: PhantomData<Rc<()>>, -} - -impl Drop for ScriptChan { - fn drop(&mut self) { - let _ = self.chan.send(ConstellationControlMsg::ExitScriptThread); - } -} - -impl ScriptChan { - pub fn send(&self, msg: ConstellationControlMsg) -> Result<(), IOError> { - self.chan.send(msg) - } - pub fn new(chan: IpcSender<ConstellationControlMsg>) -> Rc<ScriptChan> { - Rc::new(ScriptChan { chan: chan, dont_send_or_sync: PhantomData }) - } - pub fn sender(&self) -> IpcSender<ConstellationControlMsg> { - self.chan.clone() - } -} +/// The constellation uses logging to perform crash reporting. +/// The constellation receives all `warn!`, `error!` and `panic!` messages, +/// and generates a crash report when it receives a panic. /// A logger directed at the constellation from content processes #[derive(Clone)] @@ -472,6 +621,10 @@ impl Log for FromCompositorLogger { } } +/// Rust uses `LogRecord` for storing logging, but servo converts that to +/// a `LogEntry`. We do this so that we can record panics as well as log +/// messages, and because `LogRecord` does not implement serde (de)serialization, +/// so cannot be used over an IPC channel. fn log_entry(record: &LogRecord) -> Option<LogEntry> { match record.level() { LogLevel::Error if thread::panicking() => Some(LogEntry::Panic( @@ -488,20 +641,14 @@ fn log_entry(record: &LogRecord) -> Option<LogEntry> { } } +/// The number of warnings to include in each crash report. const WARNINGS_BUFFER_SIZE: usize = 32; -/// The registered domain name (aka eTLD+1) for a URL. -/// Returns None if the URL has no host name. -/// Returns the registered suffix for the host name if it is a domain. -/// Leaves the host name alone if it is an IP address. -fn reg_host<'a>(url: &'a ServoUrl) -> Option<&'a str> { - url.domain().map(reg_suffix).or(url.host_str()) -} - impl<Message, LTF, STF> Constellation<Message, LTF, STF> where LTF: LayoutThreadFactory<Message=Message>, STF: ScriptThreadFactory<Message=Message> { + /// Create a new constellation thread. pub fn start(state: InitialConstellationState) -> (Sender<FromCompositorMsg>, IpcSender<SWManagerMsg>) { let (compositor_sender, compositor_receiver) = channel(); @@ -509,7 +656,7 @@ impl<Message, LTF, STF> Constellation<Message, LTF, STF> let (swmanager_sender, swmanager_receiver) = ipc::channel().expect("ipc channel failure"); let sw_mgr_clone = swmanager_sender.clone(); - spawn_named("Constellation".to_owned(), move || { + thread::Builder::new().name("Constellation".to_owned()).spawn(move || { let (ipc_script_sender, ipc_script_receiver) = ipc::channel().expect("ipc channel failure"); let script_receiver = ROUTER.route_ipc_receiver_to_new_mpsc_receiver(ipc_script_receiver); @@ -537,7 +684,7 @@ impl<Message, LTF, STF> Constellation<Message, LTF, STF> swmanager_chan: None, swmanager_receiver: swmanager_receiver, swmanager_sender: sw_mgr_clone, - script_channels: HashMap::new(), + event_loops: HashMap::new(), pipelines: HashMap::new(), frames: HashMap::new(), pending_frames: vec!(), @@ -558,7 +705,6 @@ impl<Message, LTF, STF> Constellation<Message, LTF, STF> phantom: PhantomData, webdriver: WebDriverData::new(), scheduler_chan: TimerScheduler::start(), - child_processes: Vec::new(), document_states: HashMap::new(), webrender_api_sender: state.webrender_api_sender, shutting_down: false, @@ -573,10 +719,12 @@ impl<Message, LTF, STF> Constellation<Message, LTF, STF> }; constellation.run(); - }); + }).expect("Thread spawning failed"); + (compositor_sender, swmanager_sender) } + /// The main event loop for the constellation. fn run(&mut self) { while !self.shutting_down || !self.pipelines.is_empty() { // Randomly close a pipeline if --random-pipeline-closure-probability is set @@ -587,6 +735,7 @@ impl<Message, LTF, STF> Constellation<Message, LTF, STF> self.handle_shutdown(); } + /// Generate a new pipeline id namespace. fn next_pipeline_namespace_id(&mut self) -> PipelineNamespaceId { let namespace_id = self.next_pipeline_namespace_id; let PipelineNamespaceId(ref mut i) = self.next_pipeline_namespace_id; @@ -613,17 +762,17 @@ impl<Message, LTF, STF> Constellation<Message, LTF, STF> None => self.root_frame_id, }; - let (script_channel, host) = match sandbox { + let (event_loop, host) = match sandbox { IFrameSandboxState::IFrameSandboxed => (None, None), IFrameSandboxState::IFrameUnsandboxed => match reg_host(&load_data.url) { None => (None, None), Some(host) => { - let script_channel = self.script_channels.get(&top_level_frame_id) + let event_loop = self.event_loops.get(&top_level_frame_id) .and_then(|map| map.get(host)) .and_then(|weak| weak.upgrade()); - match script_channel { + match event_loop { None => (None, Some(String::from(host))), - Some(script_channel) => (Some(script_channel.clone()), None), + Some(event_loop) => (Some(event_loop.clone()), None), } }, }, @@ -670,7 +819,7 @@ impl<Message, LTF, STF> Constellation<Message, LTF, STF> time_profiler_chan: self.time_profiler_chan.clone(), mem_profiler_chan: self.mem_profiler_chan.clone(), window_size: initial_window_size, - script_chan: script_channel, + event_loop: event_loop, load_data: load_data, device_pixel_ratio: self.window_size.device_pixel_ratio, pipeline_namespace_id: self.next_pipeline_namespace_id(), @@ -679,27 +828,24 @@ impl<Message, LTF, STF> Constellation<Message, LTF, STF> is_private: is_private, }); - let (pipeline, child_process) = match result { + let pipeline = match result { Ok(result) => result, Err(e) => return self.handle_send_error(pipeline_id, e), }; - if let Some(child_process) = child_process { - self.child_processes.push(child_process); - } - if let Some(host) = host { - self.script_channels.entry(top_level_frame_id) + self.event_loops.entry(top_level_frame_id) .or_insert_with(HashMap::new) - .insert(host, Rc::downgrade(&pipeline.script_chan)); + .insert(host, Rc::downgrade(&pipeline.event_loop)); } assert!(!self.pipelines.contains_key(&pipeline_id)); self.pipelines.insert(pipeline_id, pipeline); } - // Get an iterator for the current frame tree. Specify self.root_frame_id to - // iterate the entire tree, or a specific frame id to iterate only that sub-tree. + /// Get an iterator for the current frame tree. Specify self.root_frame_id to + /// iterate the entire tree, or a specific frame id to iterate only that sub-tree. + /// Iterates over the fully active frames in the tree. fn current_frame_tree_iter(&self, frame_id_root: FrameId) -> FrameTreeIterator { FrameTreeIterator { stack: vec!(frame_id_root), @@ -708,6 +854,9 @@ impl<Message, LTF, STF> Constellation<Message, LTF, STF> } } + /// Get an iterator for the current frame tree. Specify self.root_frame_id to + /// iterate the entire tree, or a specific frame id to iterate only that sub-tree. + /// Iterates over all frames in the tree. fn full_frame_tree_iter(&self, frame_id_root: FrameId) -> FullFrameTreeIterator { FullFrameTreeIterator { stack: vec!(frame_id_root), @@ -716,6 +865,8 @@ impl<Message, LTF, STF> Constellation<Message, LTF, STF> } } + /// The joint session future is the merge of the session future of every + /// frame in the frame tree, sorted reverse chronologically. fn joint_session_future(&self, frame_id_root: FrameId) -> Vec<(Instant, FrameId, PipelineId)> { let mut future = vec!(); for frame in self.full_frame_tree_iter(frame_id_root) { @@ -727,11 +878,14 @@ impl<Message, LTF, STF> Constellation<Message, LTF, STF> future } + /// Is the joint session future empty? fn joint_session_future_is_empty(&self, frame_id_root: FrameId) -> bool { self.full_frame_tree_iter(frame_id_root) .all(|frame| frame.next.is_empty()) } + /// The joint session past is the merge of the session past of every + /// frame in the frame tree, sorted chronologically. fn joint_session_past(&self, frame_id_root: FrameId) -> Vec<(Instant, FrameId, PipelineId)> { let mut past = vec!(); for frame in self.full_frame_tree_iter(frame_id_root) { @@ -746,12 +900,13 @@ impl<Message, LTF, STF> Constellation<Message, LTF, STF> past } + /// Is the joint session past empty? fn joint_session_past_is_empty(&self, frame_id_root: FrameId) -> bool { self.full_frame_tree_iter(frame_id_root) .all(|frame| frame.prev.is_empty()) } - // Create a new frame and update the internal bookkeeping. + /// Create a new frame and update the internal bookkeeping. fn new_frame(&mut self, frame_id: FrameId, pipeline_id: PipelineId) { let frame = Frame::new(frame_id, pipeline_id); self.frames.insert(frame_id, frame); @@ -979,7 +1134,7 @@ impl<Message, LTF, STF> Constellation<Message, LTF, STF> let msg = ConstellationControlMsg::SendEvent(pipeline_id, event); let result = match self.pipelines.get(&pipeline_id) { None => { debug!("Pipeline {:?} got event after closure.", pipeline_id); return; } - Some(pipeline) => pipeline.script_chan.send(msg), + Some(pipeline) => pipeline.event_loop.send(msg), }; if let Err(e) = result { self.handle_send_error(pipeline_id, e); @@ -1127,7 +1282,7 @@ impl<Message, LTF, STF> Constellation<Message, LTF, STF> let msg = ConstellationControlMsg::DispatchStorageEvent( pipeline.id, storage, url.clone(), key.clone(), old_value.clone(), new_value.clone() ); - if let Err(err) = pipeline.script_chan.send(msg) { + if let Err(err) = pipeline.event_loop.send(msg) { warn!("Failed to broadcast storage event to pipeline {} ({:?}).", pipeline.id, err); } } @@ -1279,7 +1434,6 @@ impl<Message, LTF, STF> Constellation<Message, LTF, STF> frame_id: top_level_frame_id, old_pipeline_id: pipeline_id, new_pipeline_id: new_pipeline_id, - document_ready: false, replace: false, }); } @@ -1313,7 +1467,6 @@ impl<Message, LTF, STF> Constellation<Message, LTF, STF> frame_id: self.root_frame_id, old_pipeline_id: None, new_pipeline_id: root_pipeline_id, - document_ready: false, replace: false, }); self.compositor_proxy.send(ToCompositorMsg::ChangePageUrl(root_pipeline_id, url)); @@ -1336,7 +1489,7 @@ impl<Message, LTF, STF> Constellation<Message, LTF, STF> match self.pipelines.get_mut(&pipeline_id) { Some(pipeline) => { pipeline.size = Some(*size); - pipeline.script_chan.send(msg) + pipeline.event_loop.send(msg) } None => return, } @@ -1361,7 +1514,7 @@ impl<Message, LTF, STF> Constellation<Message, LTF, STF> child: pipeline_id, }; let result = match self.pipelines.get(&parent_id) { - Some(parent) => parent.script_chan.send(msg), + Some(parent) => parent.event_loop.send(msg), None => return warn!("Parent {} frame loaded after closure.", parent_id), }; if let Err(e) = result { @@ -1418,7 +1571,6 @@ impl<Message, LTF, STF> Constellation<Message, LTF, STF> frame_id: load_info.info.frame_id, old_pipeline_id: load_info.old_pipeline_id, new_pipeline_id: load_info.info.new_pipeline_id, - document_ready: false, replace: load_info.info.replace, }); } @@ -1441,7 +1593,7 @@ impl<Message, LTF, STF> Constellation<Message, LTF, STF> None => return warn!("Script loaded url in closed iframe {}.", parent_pipeline_id), }; - let script_sender = parent_pipeline.script_chan.clone(); + let script_sender = parent_pipeline.event_loop.clone(); let url = ServoUrl::parse("about:blank").expect("infallible"); Pipeline::new(new_pipeline_id, @@ -1463,7 +1615,6 @@ impl<Message, LTF, STF> Constellation<Message, LTF, STF> frame_id: frame_id, old_pipeline_id: None, new_pipeline_id: new_pipeline_id, - document_ready: false, replace: replace, }); } @@ -1484,7 +1635,7 @@ impl<Message, LTF, STF> Constellation<Message, LTF, STF> AnimationTickType::Script => { let msg = ConstellationControlMsg::TickAllAnimations(pipeline_id); match self.pipelines.get(&pipeline_id) { - Some(pipeline) => pipeline.script_chan.send(msg), + Some(pipeline) => pipeline.event_loop.send(msg), None => return warn!("Pipeline {:?} got script tick after closure.", pipeline_id), } } @@ -1557,7 +1708,7 @@ impl<Message, LTF, STF> Constellation<Message, LTF, STF> // and issue an iframe load through there. let msg = ConstellationControlMsg::Navigate(parent_pipeline_id, frame_id, load_data, replace); let result = match self.pipelines.get(&parent_pipeline_id) { - Some(parent_pipeline) => parent_pipeline.script_chan.send(msg), + Some(parent_pipeline) => parent_pipeline.event_loop.send(msg), None => { warn!("Pipeline {:?} child loaded after closure", parent_pipeline_id); return None; @@ -1599,7 +1750,6 @@ impl<Message, LTF, STF> Constellation<Message, LTF, STF> frame_id: root_frame_id, old_pipeline_id: Some(source_id), new_pipeline_id: new_pipeline_id, - document_ready: false, replace: replace, }); @@ -1703,7 +1853,7 @@ impl<Message, LTF, STF> Constellation<Message, LTF, STF> let event = CompositorEvent::KeyEvent(ch, key, state, mods); let msg = ConstellationControlMsg::SendEvent(pipeline_id, event); let result = match self.pipelines.get(&pipeline_id) { - Some(pipeline) => pipeline.script_chan.send(msg), + Some(pipeline) => pipeline.event_loop.send(msg), None => return debug!("Pipeline {:?} got key event after closure.", pipeline_id), }; if let Err(e) = result { @@ -1725,7 +1875,7 @@ impl<Message, LTF, STF> Constellation<Message, LTF, STF> if let Some(pipeline_id) = root_pipeline_id { let msg = ConstellationControlMsg::Reload(pipeline_id); let result = match self.pipelines.get(&pipeline_id) { - Some(pipeline) => pipeline.script_chan.send(msg), + Some(pipeline) => pipeline.event_loop.send(msg), None => return debug!("Pipeline {:?} got reload event after closure.", pipeline_id), }; if let Err(e) = result { @@ -1737,7 +1887,7 @@ impl<Message, LTF, STF> Constellation<Message, LTF, STF> fn handle_get_pipeline_title_msg(&mut self, pipeline_id: PipelineId) { let result = match self.pipelines.get(&pipeline_id) { None => return self.compositor_proxy.send(ToCompositorMsg::ChangePageTitle(pipeline_id, None)), - Some(pipeline) => pipeline.script_chan.send(ConstellationControlMsg::GetTitle(pipeline_id)), + Some(pipeline) => pipeline.event_loop.send(ConstellationControlMsg::GetTitle(pipeline_id)), }; if let Err(e) = result { self.handle_send_error(pipeline_id, e); @@ -1762,15 +1912,15 @@ impl<Message, LTF, STF> Constellation<Message, LTF, STF> } fn handle_get_pipeline(&mut self, frame_id: Option<FrameId>, - resp_chan: IpcSender<Option<(PipelineId, bool)>>) { + resp_chan: IpcSender<Option<PipelineId>>) { let frame_id = frame_id.unwrap_or(self.root_frame_id); let current_pipeline_id = self.frames.get(&frame_id) .map(|frame| frame.current.pipeline_id); let current_pipeline_id_loaded = current_pipeline_id - .map(|id| (id, true)); + .map(|id| id); let pipeline_id_loaded = self.pending_frames.iter().rev() .find(|x| x.old_pipeline_id == current_pipeline_id) - .map(|x| (x.new_pipeline_id, x.document_ready)) + .map(|x| x.new_pipeline_id) .or(current_pipeline_id_loaded); if let Err(e) = resp_chan.send(pipeline_id_loaded) { warn!("Failed get_pipeline response ({}).", e); @@ -1800,7 +1950,7 @@ impl<Message, LTF, STF> Constellation<Message, LTF, STF> // telling it to mark the iframe element as focused. let msg = ConstellationControlMsg::FocusIFrame(parent_pipeline_id, frame_id); let result = match self.pipelines.get(&parent_pipeline_id) { - Some(pipeline) => pipeline.script_chan.send(msg), + Some(pipeline) => pipeline.event_loop.send(msg), None => return warn!("Pipeline {:?} focus after closure.", parent_pipeline_id), }; if let Err(e) = result { @@ -1862,7 +2012,7 @@ impl<Message, LTF, STF> Constellation<Message, LTF, STF> visibility); let result = match self.pipelines.get(&parent_pipeline_id) { None => return warn!("Parent pipeline {:?} closed", parent_pipeline_id), - Some(parent_pipeline) => parent_pipeline.script_chan.send(visibility_msg), + Some(parent_pipeline) => parent_pipeline.event_loop.send(visibility_msg), }; if let Err(e) = result { @@ -1920,7 +2070,7 @@ impl<Message, LTF, STF> Constellation<Message, LTF, STF> WebDriverCommandMsg::ScriptCommand(pipeline_id, cmd) => { let control_msg = ConstellationControlMsg::WebDriverScriptCommand(pipeline_id, cmd); let result = match self.pipelines.get(&pipeline_id) { - Some(pipeline) => pipeline.script_chan.send(control_msg), + Some(pipeline) => pipeline.event_loop.send(control_msg), None => return warn!("Pipeline {:?} ScriptCommand after closure.", pipeline_id), }; if let Err(e) = result { @@ -1928,14 +2078,14 @@ impl<Message, LTF, STF> Constellation<Message, LTF, STF> } }, WebDriverCommandMsg::SendKeys(pipeline_id, cmd) => { - let script_channel = match self.pipelines.get(&pipeline_id) { - Some(pipeline) => pipeline.script_chan.clone(), + let event_loop = match self.pipelines.get(&pipeline_id) { + Some(pipeline) => pipeline.event_loop.clone(), None => return warn!("Pipeline {:?} SendKeys after closure.", pipeline_id), }; for (key, mods, state) in cmd { let event = CompositorEvent::KeyEvent(None, key, state, mods); let control_msg = ConstellationControlMsg::SendEvent(pipeline_id, event); - if let Err(e) = script_channel.send(control_msg) { + if let Err(e) = event_loop.send(control_msg) { return self.handle_send_error(pipeline_id, e); } } @@ -2024,7 +2174,7 @@ impl<Message, LTF, STF> Constellation<Message, LTF, STF> next_pipeline_id); let result = match self.pipelines.get(&parent_pipeline_id) { None => return warn!("Pipeline {:?} child traversed after closure.", parent_pipeline_id), - Some(pipeline) => pipeline.script_chan.send(msg), + Some(pipeline) => pipeline.event_loop.send(msg), }; if let Err(e) = result { self.handle_send_error(parent_pipeline_id, e); @@ -2121,7 +2271,7 @@ impl<Message, LTF, STF> Constellation<Message, LTF, STF> if let Some((parent_pipeline_id, _)) = pipeline.parent_info { if let Some(parent_pipeline) = self.pipelines.get(&parent_pipeline_id) { let msg = ConstellationControlMsg::FramedContentChanged(parent_pipeline_id, pipeline.frame_id); - let _ = parent_pipeline.script_chan.send(msg); + let _ = parent_pipeline.event_loop.send(msg); } } } @@ -2152,7 +2302,7 @@ impl<Message, LTF, STF> Constellation<Message, LTF, STF> None => return warn!("Pipeline {:?} resized after closing.", pipeline_id), Some(pipeline) => pipeline, }; - let _ = pipeline.script_chan.send(ConstellationControlMsg::Resize( + let _ = pipeline.event_loop.send(ConstellationControlMsg::Resize( pipeline.id, new_size, size_type @@ -2165,7 +2315,7 @@ impl<Message, LTF, STF> Constellation<Message, LTF, STF> }, Some(pipeline) => pipeline, }; - let _ = pipeline.script_chan.send(ConstellationControlMsg::ResizeInactive( + let _ = pipeline.event_loop.send(ConstellationControlMsg::ResizeInactive( pipeline.id, new_size )); @@ -2180,7 +2330,7 @@ impl<Message, LTF, STF> Constellation<Message, LTF, STF> Some(pipeline) => pipeline, }; if pipeline.parent_info.is_none() { - let _ = pipeline.script_chan.send(ConstellationControlMsg::Resize( + let _ = pipeline.event_loop.send(ConstellationControlMsg::Resize( pipeline.id, new_size, size_type @@ -2349,7 +2499,7 @@ impl<Message, LTF, STF> Constellation<Message, LTF, STF> self.close_frame_children(frame_id, exit_mode); - self.script_channels.remove(&frame_id); + self.event_loops.remove(&frame_id); if self.frames.remove(&frame_id).is_none() { warn!("Closing frame {:?} twice.", frame_id); } diff --git a/components/constellation/event_loop.rs b/components/constellation/event_loop.rs new file mode 100644 index 00000000000..476df9e91ae --- /dev/null +++ b/components/constellation/event_loop.rs @@ -0,0 +1,46 @@ +/* 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/. */ + +//! This module contains the `EventLoop` type, which is the constellation's +//! view of a script thread. When an `EventLoop` is dropped, an `ExitScriptThread` +//! message is sent to the script thread, asking it to shut down. + +use ipc_channel::ipc::IpcSender; +use script_traits::ConstellationControlMsg; +use std::io::Error as IOError; +use std::marker::PhantomData; +use std::rc::Rc; + +/// https://html.spec.whatwg.org/multipage/#event-loop +pub struct EventLoop { + script_chan: IpcSender<ConstellationControlMsg>, + dont_send_or_sync: PhantomData<Rc<()>>, +} + +impl Drop for EventLoop { + fn drop(&mut self) { + let _ = self.script_chan.send(ConstellationControlMsg::ExitScriptThread); + } +} + +impl EventLoop { + /// Create a new event loop from the channel to its script thread. + pub fn new(script_chan: IpcSender<ConstellationControlMsg>) -> Rc<EventLoop> { + Rc::new(EventLoop { + script_chan: script_chan, + dont_send_or_sync: PhantomData, + }) + } + + /// Send a message to the event loop. + pub fn send(&self, msg: ConstellationControlMsg) -> Result<(), IOError> { + self.script_chan.send(msg) + } + + /// The underlying channel to the script thread. + pub fn sender(&self) -> IpcSender<ConstellationControlMsg> { + self.script_chan.clone() + } +} + diff --git a/components/constellation/lib.rs b/components/constellation/lib.rs index 7d455d954b2..b4e6bda940e 100644 --- a/components/constellation/lib.rs +++ b/components/constellation/lib.rs @@ -36,13 +36,14 @@ extern crate script_traits; extern crate serde; #[macro_use] extern crate serde_derive; +extern crate servo_config; +extern crate servo_remutex; extern crate servo_url; extern crate style_traits; -#[macro_use] -extern crate util; extern crate webrender_traits; mod constellation; +mod event_loop; mod pipeline; #[cfg(not(target_os = "windows"))] mod sandboxing; diff --git a/components/constellation/pipeline.rs b/components/constellation/pipeline.rs index 890476e5010..10aed362427 100644 --- a/components/constellation/pipeline.rs +++ b/components/constellation/pipeline.rs @@ -6,12 +6,10 @@ use bluetooth_traits::BluetoothRequest; use compositing::CompositionPipeline; use compositing::CompositorProxy; use compositing::compositor_thread::Msg as CompositorMsg; -use constellation::ScriptChan; use devtools_traits::{DevtoolsControlMsg, ScriptToDevtoolsControlMsg}; use euclid::scale_factor::ScaleFactor; use euclid::size::TypedSize2D; -#[cfg(not(target_os = "windows"))] -use gaol; +use event_loop::EventLoop; use gfx::font_cache_thread::FontCacheThread; use gfx_traits::DevicePixel; use ipc_channel::ipc::{self, IpcReceiver, IpcSender}; @@ -26,6 +24,8 @@ use script_traits::{ConstellationControlMsg, InitialScriptState}; use script_traits::{LayoutControlMsg, LayoutMsg, LoadData, MozBrowserEvent}; use script_traits::{NewLayoutInfo, SWManagerMsg, SWManagerSenders, ScriptMsg}; use script_traits::{ScriptThreadFactory, TimerEventRequest, WindowSizeData}; +use servo_config::opts::{self, Opts}; +use servo_config::prefs::{PREFS, Pref}; use servo_url::ServoUrl; use std::collections::HashMap; use std::env; @@ -35,39 +35,58 @@ use std::process; use std::rc::Rc; use std::sync::mpsc::Sender; use style_traits::{PagePx, ViewportPx}; -use util::opts::{self, Opts}; -use util::prefs::{PREFS, Pref}; use webrender_traits; -pub enum ChildProcess { - #[cfg(not(target_os = "windows"))] - Sandboxed(gaol::platform::process::Process), - #[cfg(not(target_os = "windows"))] - Unsandboxed(process::Child), -} - -/// A uniquely-identifiable pipeline of script thread, layout thread, and paint thread. +/// A `Pipeline` is the constellation's view of a `Document`. Each pipeline has an +/// event loop (executed by a script thread) and a layout thread. A script thread +/// may be responsible for many pipelines, but a layout thread is only responsible +/// for one. pub struct Pipeline { + /// The ID of the pipeline. pub id: PipelineId, + /// The ID of the frame that contains this Pipeline. pub frame_id: FrameId, + + /// The parent pipeline of this one. `None` if this is a root pipeline. + /// Note that because of mozbrowser iframes, even top-level pipelines + /// may have a parent (in which case the frame type will be + /// `MozbrowserIFrame`). + /// TODO: move this field to `Frame`. pub parent_info: Option<(PipelineId, FrameType)>, - pub script_chan: Rc<ScriptChan>, + + /// The event loop handling this pipeline. + pub event_loop: Rc<EventLoop>, + /// A channel to layout, for performing reflows and shutdown. pub layout_chan: IpcSender<LayoutControlMsg>, + /// A channel to the compositor. pub compositor_proxy: Box<CompositorProxy + 'static + Send>, - /// URL corresponding to the most recently-loaded page. + + /// The most recently loaded URL in this pipeline. + /// Note that this URL can change, for example if the page navigates + /// to a hash URL. pub url: ServoUrl, + /// The title of the most recently-loaded page. pub title: Option<String>, + + /// The size of the frame. + /// TODO: move this field to `Frame`. pub size: Option<TypedSize2D<f32, PagePx>>, + /// Whether this pipeline is currently running animations. Pipelines that are running /// animations cause composites to be continually scheduled. pub running_animations: bool, + + /// The child frames of this pipeline (these are iframes in the document). pub children: Vec<FrameId>, - /// Whether this pipeline is considered distinct from public pipelines. + + /// Whether this pipeline is in private browsing mode. + /// TODO: move this field to `Frame`. pub is_private: bool, + /// Whether this pipeline should be treated as visible for the purposes of scheduling and /// resource management. pub visible: bool, @@ -80,69 +99,89 @@ pub struct Pipeline { pub struct InitialPipelineState { /// The ID of the pipeline to create. pub id: PipelineId, + /// The ID of the frame that contains this Pipeline. pub frame_id: FrameId, + /// The ID of the top-level frame that contains this Pipeline. pub top_level_frame_id: FrameId, + /// The ID of the parent pipeline and frame type, if any. /// If `None`, this is the root. pub parent_info: Option<(PipelineId, FrameType)>, + /// A channel to the associated constellation. pub constellation_chan: IpcSender<ScriptMsg>, + /// A channel for the layout thread to send messages to the constellation. pub layout_to_constellation_chan: IpcSender<LayoutMsg>, + /// A channel to schedule timer events. pub scheduler_chan: IpcSender<TimerEventRequest>, + /// A channel to the compositor. pub compositor_proxy: Box<CompositorProxy + 'static + Send>, + /// A channel to the developer tools, if applicable. pub devtools_chan: Option<Sender<DevtoolsControlMsg>>, + /// A channel to the bluetooth thread. pub bluetooth_thread: IpcSender<BluetoothRequest>, + /// A channel to the service worker manager thread pub swmanager_thread: IpcSender<SWManagerMsg>, + /// A channel to the image cache thread. pub image_cache_thread: ImageCacheThread, + /// A channel to the font cache thread. pub font_cache_thread: FontCacheThread, + /// Channels to the resource-related threads. pub resource_threads: ResourceThreads, + /// A channel to the time profiler thread. pub time_profiler_chan: time::ProfilerChan, + /// A channel to the memory profiler thread. pub mem_profiler_chan: profile_mem::ProfilerChan, + /// Information about the initial window size. pub window_size: Option<TypedSize2D<f32, PagePx>>, + /// Information about the device pixel ratio. pub device_pixel_ratio: ScaleFactor<f32, ViewportPx, DevicePixel>, - /// A channel to the script thread, if applicable. - /// If this is `None`, create a new script thread. - /// If this is `Some`, then reuse an existing script thread. - pub script_chan: Option<Rc<ScriptChan>>, + + /// The event loop to run in, if applicable. + pub event_loop: Option<Rc<EventLoop>>, + /// Information about the page to load. pub load_data: LoadData, + /// The ID of the pipeline namespace for this script thread. pub pipeline_namespace_id: PipelineNamespaceId, + /// Pipeline visibility to be inherited pub prev_visibility: Option<bool>, + /// Webrender api. pub webrender_api_sender: webrender_traits::RenderApiSender, + /// Whether this pipeline is considered private. pub is_private: bool, } impl Pipeline { - /// Starts a paint thread, layout thread, and possibly a script thread, in + /// Starts a layout thread, and possibly a script thread, in /// a new process if requested. - pub fn spawn<Message, LTF, STF>(state: InitialPipelineState) - -> Result<(Pipeline, Option<ChildProcess>), IOError> + pub fn spawn<Message, LTF, STF>(state: InitialPipelineState) -> Result<Pipeline, IOError> where LTF: LayoutThreadFactory<Message=Message>, STF: ScriptThreadFactory<Message=Message> { // Note: we allow channel creation to panic, since recovering from this // probably requires a general low-memory strategy. let (pipeline_chan, pipeline_port) = ipc::channel() - .expect("Pipeline main chan");; + .expect("Pipeline main chan"); let (layout_content_process_shutdown_chan, layout_content_process_shutdown_port) = ipc::channel().expect("Pipeline layout content shutdown chan"); @@ -156,7 +195,7 @@ impl Pipeline { } }); - let (script_chan, content_ports) = match state.script_chan { + let (script_chan, content_ports) = match state.event_loop { Some(script_chan) => { let new_layout_info = NewLayoutInfo { parent_info: state.parent_info, @@ -176,11 +215,10 @@ impl Pipeline { } None => { let (script_chan, script_port) = ipc::channel().expect("Pipeline script chan"); - (ScriptChan::new(script_chan), Some((script_port, pipeline_port))) + (EventLoop::new(script_chan), Some((script_port, pipeline_port))) } }; - let mut child_process = None; if let Some((script_port, pipeline_port)) = content_ports { // Route messages coming from content to devtools as appropriate. let script_to_devtools_chan = state.devtools_chan.as_ref().map(|devtools_chan| { @@ -236,24 +274,22 @@ impl Pipeline { // // Yes, that's all there is to it! if opts::multiprocess() { - child_process = Some(try!(unprivileged_pipeline_content.spawn_multiprocess())); + let _ = try!(unprivileged_pipeline_content.spawn_multiprocess()); } else { unprivileged_pipeline_content.start_all::<Message, LTF, STF>(false); } } - let pipeline = Pipeline::new(state.id, - state.frame_id, - state.parent_info, - script_chan, - pipeline_chan, - state.compositor_proxy, - state.is_private, - state.load_data.url, - state.window_size, - state.prev_visibility.unwrap_or(true)); - - Ok((pipeline, child_process)) + Ok(Pipeline::new(state.id, + state.frame_id, + state.parent_info, + script_chan, + pipeline_chan, + state.compositor_proxy, + state.is_private, + state.load_data.url, + state.window_size, + state.prev_visibility.unwrap_or(true))) } /// Creates a new `Pipeline`, after the script and layout threads have been @@ -261,7 +297,7 @@ impl Pipeline { pub fn new(id: PipelineId, frame_id: FrameId, parent_info: Option<(PipelineId, FrameType)>, - script_chan: Rc<ScriptChan>, + event_loop: Rc<EventLoop>, layout_chan: IpcSender<LayoutControlMsg>, compositor_proxy: Box<CompositorProxy + 'static + Send>, is_private: bool, @@ -273,7 +309,7 @@ impl Pipeline { id: id, frame_id: frame_id, parent_info: parent_info, - script_chan: script_chan, + event_loop: event_loop, layout_chan: layout_chan, compositor_proxy: compositor_proxy, url: url, @@ -290,6 +326,8 @@ impl Pipeline { pipeline } + /// A normal exit of the pipeline, which waits for the compositor, + /// and delegates layout shutdown to the script thread. pub fn exit(&self) { debug!("pipeline {:?} exiting", self.id); @@ -307,44 +345,51 @@ impl Pipeline { // Script thread handles shutting down layout, and layout handles shutting down the painter. // For now, if the script thread has failed, we give up on clean shutdown. - if let Err(e) = self.script_chan.send(ConstellationControlMsg::ExitPipeline(self.id)) { + if let Err(e) = self.event_loop.send(ConstellationControlMsg::ExitPipeline(self.id)) { warn!("Sending script exit message failed ({}).", e); } } - pub fn freeze(&self) { - if let Err(e) = self.script_chan.send(ConstellationControlMsg::Freeze(self.id)) { - warn!("Sending freeze message failed ({}).", e); + /// A forced exit of the shutdown, which does not wait for the compositor, + /// or for the script thread to shut down layout. + pub fn force_exit(&self) { + if let Err(e) = self.event_loop.send(ConstellationControlMsg::ExitPipeline(self.id)) { + warn!("Sending script exit message failed ({}).", e); + } + if let Err(e) = self.layout_chan.send(LayoutControlMsg::ExitNow) { + warn!("Sending layout exit message failed ({}).", e); } } - pub fn thaw(&self) { - if let Err(e) = self.script_chan.send(ConstellationControlMsg::Thaw(self.id)) { + /// Notify this pipeline that it is no longer fully active. + pub fn freeze(&self) { + if let Err(e) = self.event_loop.send(ConstellationControlMsg::Freeze(self.id)) { warn!("Sending freeze message failed ({}).", e); } } - pub fn force_exit(&self) { - if let Err(e) = self.script_chan.send(ConstellationControlMsg::ExitPipeline(self.id)) { - warn!("Sending script exit message failed ({}).", e); - } - if let Err(e) = self.layout_chan.send(LayoutControlMsg::ExitNow) { - warn!("Sending layout exit message failed ({}).", e); + /// Notify this pipeline that it is fully active. + pub fn thaw(&self) { + if let Err(e) = self.event_loop.send(ConstellationControlMsg::Thaw(self.id)) { + warn!("Sending freeze message failed ({}).", e); } } + /// The compositor's view of a pipeline. pub fn to_sendable(&self) -> CompositionPipeline { CompositionPipeline { id: self.id.clone(), - script_chan: self.script_chan.sender(), + script_chan: self.event_loop.sender(), layout_chan: self.layout_chan.clone(), } } + /// Add a new child frame. pub fn add_child(&mut self, frame_id: FrameId) { self.children.push(frame_id); } + /// Remove a child frame. pub fn remove_child(&mut self, frame_id: FrameId) { match self.children.iter().position(|id| *id == frame_id) { None => return warn!("Pipeline remove child already removed ({:?}).", frame_id), @@ -352,6 +397,9 @@ impl Pipeline { }; } + /// Send a mozbrowser event to the script thread for this pipeline. + /// This will cause an event to be fired on an iframe in the document, + /// or on the `Window` if no frame is given. pub fn trigger_mozbrowser_event(&self, child_id: Option<FrameId>, event: MozBrowserEvent) { @@ -360,18 +408,23 @@ impl Pipeline { let event = ConstellationControlMsg::MozBrowserEvent(self.id, child_id, event); - if let Err(e) = self.script_chan.send(event) { + if let Err(e) = self.event_loop.send(event) { warn!("Sending mozbrowser event to script failed ({}).", e); } } + /// Notify the script thread that this pipeline is visible. fn notify_visibility(&self) { - self.script_chan.send(ConstellationControlMsg::ChangeFrameVisibilityStatus(self.id, self.visible)) - .expect("Pipeline script chan"); - - self.compositor_proxy.send(CompositorMsg::PipelineVisibilityChanged(self.id, self.visible)); + let script_msg = ConstellationControlMsg::ChangeFrameVisibilityStatus(self.id, self.visible); + let compositor_msg = CompositorMsg::PipelineVisibilityChanged(self.id, self.visible); + let err = self.event_loop.send(script_msg); + if let Err(e) = err { + warn!("Sending visibility change failed ({}).", e); + } + self.compositor_proxy.send(compositor_msg); } + /// Change the visibility of this pipeline. pub fn change_visibility(&mut self, visible: bool) { if visible == self.visible { return; @@ -382,6 +435,9 @@ impl Pipeline { } +/// Creating a new pipeline may require creating a new event loop. +/// This is the data used to initialize the event loop. +/// TODO: simplify this, and unify it with `InitialPipelineState` if possible. #[derive(Deserialize, Serialize)] pub struct UnprivilegedPipelineContent { id: PipelineId, @@ -464,7 +520,7 @@ impl UnprivilegedPipelineContent { } #[cfg(not(target_os = "windows"))] - pub fn spawn_multiprocess(self) -> Result<ChildProcess, IOError> { + pub fn spawn_multiprocess(self) -> Result<(), IOError> { use gaol::sandbox::{self, Sandbox, SandboxMethods}; use ipc_channel::ipc::IpcOneShotServer; use sandboxing::content_process_sandbox_profile; @@ -489,31 +545,30 @@ impl UnprivilegedPipelineContent { .expect("Failed to create IPC one-shot server."); // If there is a sandbox, use the `gaol` API to create the child process. - let child_process = if opts::get().sandbox { + if opts::get().sandbox { let mut command = sandbox::Command::me().expect("Failed to get current sandbox."); self.setup_common(&mut command, token); let profile = content_process_sandbox_profile(); - ChildProcess::Sandboxed(Sandbox::new(profile).start(&mut command) - .expect("Failed to start sandboxed child process!")) + let _ = Sandbox::new(profile) + .start(&mut command) + .expect("Failed to start sandboxed child process!"); } else { let path_to_self = env::current_exe() .expect("Failed to get current executor."); let mut child_process = process::Command::new(path_to_self); self.setup_common(&mut child_process, token); - - ChildProcess::Unsandboxed(child_process.spawn() - .expect("Failed to start unsandboxed child process!")) - }; + let _ = child_process.spawn().expect("Failed to start unsandboxed child process!"); + } let (_receiver, sender) = server.accept().expect("Server failed to accept."); try!(sender.send(self)); - Ok(child_process) + Ok(()) } #[cfg(target_os = "windows")] - pub fn spawn_multiprocess(self) -> Result<ChildProcess, IOError> { + pub fn spawn_multiprocess(self) -> Result<(), IOError> { error!("Multiprocess is not supported on Windows."); process::exit(1); } @@ -552,10 +607,13 @@ impl UnprivilegedPipelineContent { } } +/// A trait to unify commands launched as multiprocess with or without a sandbox. trait CommandMethods { + /// A command line argument. fn arg<T>(&mut self, arg: T) where T: AsRef<OsStr>; + /// An environment variable. fn env<T, U>(&mut self, key: T, val: U) where T: AsRef<OsStr>, U: AsRef<OsStr>; } diff --git a/components/constellation/sandboxing.rs b/components/constellation/sandboxing.rs index 380155b562f..a51fd4b8ef1 100644 --- a/components/constellation/sandboxing.rs +++ b/components/constellation/sandboxing.rs @@ -3,8 +3,8 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ use gaol::profile::{Operation, PathPattern, Profile}; +use servo_config::resource_files; use std::path::PathBuf; -use util::resource_files; /// Our content process sandbox profile on Mac. As restrictive as possible. #[cfg(target_os = "macos")] diff --git a/components/debugger/Cargo.toml b/components/debugger/Cargo.toml index e9b097e5963..b9385d80e1e 100644 --- a/components/debugger/Cargo.toml +++ b/components/debugger/Cargo.toml @@ -12,7 +12,6 @@ crate_type = ["rlib"] [dependencies] log = "0.3.5" -util = {path = "../util"} [target.'cfg(not(target_os = "android"))'.dependencies] ws = "0.5.3" diff --git a/components/debugger/lib.rs b/components/debugger/lib.rs index 25983561d5d..25b3c4890a6 100644 --- a/components/debugger/lib.rs +++ b/components/debugger/lib.rs @@ -4,13 +4,12 @@ #[macro_use] extern crate log; -extern crate util; #[cfg(not(target_os = "android"))] extern crate ws; use std::sync::mpsc; use std::sync::mpsc::channel; -use util::thread::spawn_named; +use std::thread; #[cfg(not(target_os = "android"))] use ws::{Builder, CloseCode, Handler, Handshake}; @@ -45,14 +44,14 @@ impl Handler for Connection { pub fn start_server(port: u16) -> Sender { debug!("Starting server."); let (sender, receiver) = channel(); - spawn_named("debugger".to_owned(), move || { + thread::Builder::new().name("debugger".to_owned()).spawn(move || { let socket = Builder::new().build(|sender: ws::Sender| { Connection { sender: sender } }).unwrap(); let sender = socket.broadcaster(); - spawn_named("debugger-websocket".to_owned(), move || { + thread::Builder::new().name("debugger-websocket".to_owned()).spawn(move || { socket.listen(("127.0.0.1", port)).unwrap(); - }); + }).expect("Thread spawning failed"); while let Ok(message) = receiver.recv() { match message { Message::ShutdownServer => { @@ -61,7 +60,7 @@ pub fn start_server(port: u16) -> Sender { } } sender.shutdown().unwrap(); - }); + }).expect("Thread spawning failed"); Sender(sender) } diff --git a/components/devtools/Cargo.toml b/components/devtools/Cargo.toml index caa5f1755b3..e6b877f1e6d 100644 --- a/components/devtools/Cargo.toml +++ b/components/devtools/Cargo.toml @@ -22,4 +22,3 @@ serde = "0.8" serde_json = "0.8" serde_derive = "0.8" time = "0.1" -util = {path = "../util"} diff --git a/components/devtools/actors/timeline.rs b/components/devtools/actors/timeline.rs index 0d495faf7c2..6285faafabf 100644 --- a/components/devtools/actors/timeline.rs +++ b/components/devtools/actors/timeline.rs @@ -19,7 +19,6 @@ use std::net::TcpStream; use std::sync::{Arc, Mutex}; use std::thread; use std::time::Duration; -use util::thread::spawn_named; pub struct TimelineActor { name: String, @@ -150,7 +149,7 @@ impl TimelineActor { return; } - spawn_named("PullTimelineMarkers".to_owned(), move || { + thread::Builder::new().name("PullTimelineMarkers".to_owned()).spawn(move || { loop { if !*is_recording.lock().unwrap() { break; @@ -164,7 +163,7 @@ impl TimelineActor { thread::sleep(Duration::from_millis(DEFAULT_TIMELINE_DATA_PULL_TIMEOUT)); } - }); + }).expect("Thread spawning failed"); } } diff --git a/components/devtools/lib.rs b/components/devtools/lib.rs index 815bee12a88..c98bb270333 100644 --- a/components/devtools/lib.rs +++ b/components/devtools/lib.rs @@ -30,7 +30,6 @@ extern crate serde; extern crate serde_derive; extern crate serde_json; extern crate time; -extern crate util; use actor::{Actor, ActorRegistry}; use actors::console::ConsoleActor; @@ -57,8 +56,8 @@ use std::collections::hash_map::Entry::{Occupied, Vacant}; use std::net::{Shutdown, TcpListener, TcpStream}; use std::sync::{Arc, Mutex}; use std::sync::mpsc::{Receiver, Sender, channel}; +use std::thread; use time::precise_time_ns; -use util::thread::spawn_named; mod actor; /// Corresponds to http://mxr.mozilla.org/mozilla-central/source/toolkit/devtools/server/actors/ @@ -137,9 +136,9 @@ pub fn start_server(port: u16) -> Sender<DevtoolsControlMsg> { let (sender, receiver) = channel(); { let sender = sender.clone(); - spawn_named("Devtools".to_owned(), move || { + thread::Builder::new().name("Devtools".to_owned()).spawn(move || { run_server(sender, receiver, port) - }); + }).expect("Thread spawning failed"); } sender } @@ -485,23 +484,23 @@ fn run_server(sender: Sender<DevtoolsControlMsg>, } let sender_clone = sender.clone(); - spawn_named("DevtoolsClientAcceptor".to_owned(), move || { + thread::Builder::new().name("DevtoolsClientAcceptor".to_owned()).spawn(move || { // accept connections and process them, spawning a new thread for each one for stream in listener.incoming() { // connection succeeded sender_clone.send(DevtoolsControlMsg::FromChrome( ChromeToDevtoolsControlMsg::AddClient(stream.unwrap()))).unwrap(); } - }); + }).expect("Thread spawning failed"); while let Ok(msg) = receiver.recv() { match msg { DevtoolsControlMsg::FromChrome(ChromeToDevtoolsControlMsg::AddClient(stream)) => { let actors = actors.clone(); accepted_connections.push(stream.try_clone().unwrap()); - spawn_named("DevtoolsClientHandler".to_owned(), move || { + thread::Builder::new().name("DevtoolsClientHandler".to_owned()).spawn(move || { handle_client(actors, stream.try_clone().unwrap()) - }) + }).expect("Thread spawning failed"); } DevtoolsControlMsg::FromScript(ScriptToDevtoolsControlMsg::FramerateTick( actor_name, tick)) => diff --git a/components/geometry/Cargo.toml b/components/geometry/Cargo.toml new file mode 100644 index 00000000000..28480439060 --- /dev/null +++ b/components/geometry/Cargo.toml @@ -0,0 +1,19 @@ +[package] +name = "servo_geometry" +version = "0.0.1" +authors = ["The Servo Project Developers"] +license = "MPL-2.0" +publish = false + +[lib] +name = "servo_geometry" +path = "lib.rs" + +[features] +# servo as opposed to geckolib +servo = ["app_units/plugins", "euclid/unstable"] + +[dependencies] +app_units = "0.3" +euclid = "0.10.1" +heapsize = "0.3.0" diff --git a/components/util/geometry.rs b/components/geometry/lib.rs index 2d102d2d0dc..52fcd420c0e 100644 --- a/components/util/geometry.rs +++ b/components/geometry/lib.rs @@ -2,6 +2,10 @@ * 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/. */ +extern crate app_units; +#[macro_use] extern crate euclid; +#[macro_use] extern crate heapsize; + use app_units::{Au, MAX_AU}; use euclid::point::Point2D; use euclid::rect::Rect; diff --git a/components/gfx/Cargo.toml b/components/gfx/Cargo.toml index c61b2072f15..79b6f86916f 100644 --- a/components/gfx/Cargo.toml +++ b/components/gfx/Cargo.toml @@ -32,6 +32,7 @@ range = {path = "../range"} rustc-serialize = "0.3" serde = "0.8" servo_atoms = {path = "../atoms"} +servo_geometry = {path = "../geometry"} servo_url = {path = "../url"} serde_derive = "0.8" smallvec = "0.1" @@ -39,7 +40,6 @@ style = {path = "../style"} style_traits = {path = "../style_traits"} time = "0.1.12" unicode-script = {version = "0.1", features = ["harfbuzz"]} -util = {path = "../util"} xi-unicode = "0.0.1" [dependencies.webrender_traits] @@ -54,7 +54,7 @@ core-graphics = "0.4" core-text = "2.0" [target.'cfg(any(target_os = "linux", target_os = "android"))'.dependencies] -freetype = {git = "https://github.com/servo/rust-freetype"} +freetype = "0.1.3" servo-fontconfig = "0.2.1" [target.'cfg(any(target_arch = "x86_64", target_arch = "aarch64"))'.dependencies] diff --git a/components/gfx/display_list/mod.rs b/components/gfx/display_list/mod.rs index ab8f1ba7a8f..eeb78f9f9e7 100644 --- a/components/gfx/display_list/mod.rs +++ b/components/gfx/display_list/mod.rs @@ -25,6 +25,7 @@ use ipc_channel::ipc::IpcSharedMemory; use msg::constellation_msg::PipelineId; use net_traits::image::base::{Image, PixelFormat}; use range::Range; +use servo_geometry::{au_rect_to_f32_rect, f32_rect_to_au_rect, max_rect}; use std::cmp::{self, Ordering}; use std::collections::HashMap; use std::fmt; @@ -33,7 +34,6 @@ use style::computed_values::{border_style, filter, image_rendering, mix_blend_mo use style_traits::cursor::Cursor; use text::TextRun; use text::glyph::ByteIndex; -use util::geometry::{self, max_rect}; use webrender_traits::{self, ColorF, GradientStop, WebGLContextId}; pub use style::dom::OpaqueNode; @@ -397,9 +397,9 @@ impl StackingContext { .pre_mul(&self.transform); let transform_2d = transform.to_2d(); - let overflow = geometry::au_rect_to_f32_rect(self.overflow); + let overflow = au_rect_to_f32_rect(self.overflow); let overflow = transform_2d.transform_rect(&overflow); - geometry::f32_rect_to_au_rect(overflow) + f32_rect_to_au_rect(overflow) } pub fn print_with_tree(&self, print_tree: &mut PrintTree) { diff --git a/components/gfx/font_cache_thread.rs b/components/gfx/font_cache_thread.rs index edad5aa56d1..a365ef47c5e 100644 --- a/components/gfx/font_cache_thread.rs +++ b/components/gfx/font_cache_thread.rs @@ -18,13 +18,14 @@ use servo_atoms::Atom; use servo_url::ServoUrl; use std::borrow::ToOwned; use std::collections::HashMap; +use std::fmt; use std::mem; use std::ops::Deref; use std::sync::{Arc, Mutex}; +use std::thread; use std::u32; use style::font_face::{EffectiveSources, Source}; use style::properties::longhands::font_family::computed_value::FontFamily; -use util::thread::spawn_named; use webrender_traits; /// A list of font templates that make up a given font family. @@ -222,31 +223,36 @@ impl FontCache { let channel_to_self = self.channel_to_self.clone(); let bytes = Mutex::new(Vec::new()); let response_valid = Mutex::new(false); + debug!("Loading @font-face {} from {}", family_name, url); fetch_async(request, &self.core_resource_thread, move |response| { match response { FetchResponseMsg::ProcessRequestBody | FetchResponseMsg::ProcessRequestEOF => (), FetchResponseMsg::ProcessResponse(meta_result) => { + trace!("@font-face {} metadata ok={:?}", family_name, meta_result.is_ok()); *response_valid.lock().unwrap() = meta_result.is_ok(); } FetchResponseMsg::ProcessResponseChunk(new_bytes) => { + trace!("@font-face {} chunk={:?}", family_name, new_bytes); if *response_valid.lock().unwrap() { bytes.lock().unwrap().extend(new_bytes.into_iter()) } } FetchResponseMsg::ProcessResponseEOF(response) => { + trace!("@font-face {} EOF={:?}", family_name, response); if response.is_err() || !*response_valid.lock().unwrap() { let msg = Command::AddWebFont(family_name.clone(), sources.clone(), sender.clone()); channel_to_self.send(msg).unwrap(); return; } let bytes = mem::replace(&mut *bytes.lock().unwrap(), vec![]); + trace!("@font-face {} data={:?}", family_name, bytes); let bytes = match fontsan::process(&bytes) { Ok(san) => san, Err(_) => { // FIXME(servo/fontsan#1): get an error message debug!("Sanitiser rejected web font: \ - family={:?} url={:?}", family_name, url); + family={} url={:?}", family_name, url); let msg = Command::AddWebFont(family_name.clone(), sources.clone(), sender.clone()); channel_to_self.send(msg).unwrap(); return; @@ -396,7 +402,7 @@ impl FontCacheThread { let (chan, port) = ipc::channel().unwrap(); let channel_to_self = chan.clone(); - spawn_named("FontCacheThread".to_owned(), move || { + thread::Builder::new().name("FontCacheThread".to_owned()).spawn(move || { // TODO: Allow users to specify these. let generic_fonts = populate_generic_fonts(); @@ -414,7 +420,7 @@ impl FontCacheThread { cache.refresh_local_families(); cache.run(); - }); + }).expect("Thread spawning failed"); FontCacheThread { chan: chan, @@ -488,3 +494,9 @@ impl Deref for LowercaseString { &*self.inner } } + +impl fmt::Display for LowercaseString { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + self.inner.fmt(f) + } +} diff --git a/components/gfx/lib.rs b/components/gfx/lib.rs index 32fd79875ea..3095074b126 100644 --- a/components/gfx/lib.rs +++ b/components/gfx/lib.rs @@ -63,6 +63,7 @@ extern crate rustc_serialize; extern crate serde; #[macro_use] extern crate serde_derive; +extern crate servo_geometry; extern crate servo_url; #[macro_use] extern crate servo_atoms; #[cfg(any(target_arch = "x86_64", target_arch = "aarch64"))] @@ -72,7 +73,6 @@ extern crate style; extern crate style_traits; extern crate time; extern crate unicode_script; -extern crate util; extern crate webrender_traits; extern crate xi_unicode; diff --git a/components/gfx/platform/macos/font_template.rs b/components/gfx/platform/macos/font_template.rs index a98f60a95b2..cba1738b926 100644 --- a/components/gfx/platform/macos/font_template.rs +++ b/components/gfx/platform/macos/font_template.rs @@ -81,9 +81,8 @@ impl FontTemplateData { /// operation (depending on the platform) which performs synchronous disk I/O /// and should never be done lightly. pub fn bytes(&self) -> Vec<u8> { - match self.bytes_if_in_memory() { - Some(font_data) => return font_data, - None => {} + if let Some(font_data) = self.bytes_if_in_memory() { + return font_data; } let path = ServoUrl::parse(&*self.ctfont(0.0) diff --git a/components/layout/Cargo.toml b/components/layout/Cargo.toml index 6443c4a6aa3..d3da21bf1a6 100644 --- a/components/layout/Cargo.toml +++ b/components/layout/Cargo.toml @@ -31,7 +31,7 @@ parking_lot = "0.3.3" plugins = {path = "../plugins"} profile_traits = {path = "../profile_traits"} range = {path = "../range"} -rayon = "0.5" +rayon = "0.6" script_layout_interface = {path = "../script_layout_interface"} script_traits = {path = "../script_traits"} selectors = "0.15" @@ -39,13 +39,13 @@ serde = "0.8" serde_derive = "0.8" serde_json = "0.8" servo_atoms = {path = "../atoms"} +servo_config = {path = "../config"} servo_url = {path = "../url"} smallvec = "0.1" style = {path = "../style"} style_traits = {path = "../style_traits"} unicode-bidi = "0.2" unicode-script = {version = "0.1", features = ["harfbuzz"]} -util = {path = "../util"} [dependencies.webrender_traits] git = "https://github.com/servo/webrender" diff --git a/components/layout/animation.rs b/components/layout/animation.rs index b14771e5de9..7fdc452ccc3 100644 --- a/components/layout/animation.rs +++ b/components/layout/animation.rs @@ -13,7 +13,6 @@ use script_traits::{AnimationState, ConstellationControlMsg, LayoutMsg as Conste use std::collections::HashMap; use std::sync::mpsc::Receiver; use style::animation::{Animation, update_style_for_animation}; -use style::dom::TRestyleDamage; use style::selector_parser::RestyleDamage; use style::timer::Timer; diff --git a/components/layout/block.rs b/components/layout/block.rs index 45de8786778..f7370e00a4e 100644 --- a/components/layout/block.rs +++ b/components/layout/block.rs @@ -42,12 +42,11 @@ use flow::IS_ABSOLUTELY_POSITIONED; use flow_list::FlowList; use fragment::{CoordinateSystem, Fragment, FragmentBorderBoxIterator, Overflow}; use fragment::{IS_INLINE_FLEX_ITEM, IS_BLOCK_FLEX_ITEM}; -use fragment::SpecificFragmentInfo; use gfx::display_list::{ClippingRegion, StackingContext}; use gfx_traits::ScrollRootId; use gfx_traits::print_tree::PrintTree; use layout_debug; -use model::{CollapsibleMargins, IntrinsicISizes, MarginCollapseInfo, MaybeAuto}; +use model::{AdjoiningMargins, CollapsibleMargins, IntrinsicISizes, MarginCollapseInfo, MaybeAuto}; use model::{specified, specified_or_none}; use sequential; use serde::{Serialize, Serializer}; @@ -56,13 +55,12 @@ use std::fmt; use std::sync::Arc; use style::computed_values::{border_collapse, box_sizing, display, float, overflow_x, overflow_y}; use style::computed_values::{position, text_align}; -use style::context::{SharedStyleContext, StyleContext}; +use style::context::SharedStyleContext; use style::logical_geometry::{LogicalPoint, LogicalRect, LogicalSize, WritingMode}; use style::properties::ServoComputedValues; use style::servo::restyle_damage::{BUBBLE_ISIZES, REFLOW, REFLOW_OUT_OF_FLOW, REPOSITION}; use style::values::computed::{LengthOrPercentageOrNone, LengthOrPercentage}; use style::values::computed::LengthOrPercentageOrAuto; -use util::clamp; /// Information specific to floated blocks. #[derive(Clone, Serialize)] @@ -555,7 +553,7 @@ impl BlockFlow { /// relevant margins for this Block. pub fn block_type(&self) -> BlockType { if self.base.flags.contains(IS_ABSOLUTELY_POSITIONED) { - if self.is_replaced_content() { + if self.fragment.is_replaced() { BlockType::AbsoluteReplaced } else { BlockType::AbsoluteNonReplaced @@ -563,19 +561,19 @@ impl BlockFlow { } else if self.is_inline_flex_item() { BlockType::InlineFlexItem } else if self.base.flags.is_float() { - if self.is_replaced_content() { + if self.fragment.is_replaced() { BlockType::FloatReplaced } else { BlockType::FloatNonReplaced } } else if self.is_inline_block() { - if self.is_replaced_content() { + if self.fragment.is_replaced() { BlockType::InlineBlockReplaced } else { BlockType::InlineBlockNonReplaced } } else { - if self.is_replaced_content() { + if self.fragment.is_replaced() { BlockType::Replaced } else { BlockType::NonReplaced @@ -668,22 +666,6 @@ impl BlockFlow { } } - /// Return true if this has a replaced fragment. - /// - /// Text, Images, Inline Block and Canvas - /// (https://html.spec.whatwg.org/multipage/#replaced-elements) fragments are considered as - /// replaced fragments. - fn is_replaced_content(&self) -> bool { - match self.fragment.specific { - SpecificFragmentInfo::ScannedText(_) | - SpecificFragmentInfo::Svg(_) | - SpecificFragmentInfo::Image(_) | - SpecificFragmentInfo::Canvas(_) | - SpecificFragmentInfo::InlineBlock(_) => true, - _ => false, - } - } - /// Return shrink-to-fit inline-size. /// /// This is where we use the preferred inline-sizes and minimum inline-sizes @@ -1267,11 +1249,11 @@ impl BlockFlow { let available_block_size = containing_block_block_size - self.fragment.border_padding.block_start_end(); - if self.is_replaced_content() { + if self.fragment.is_replaced() { // Calculate used value of block-size just like we do for inline replaced elements. // TODO: Pass in the containing block block-size when Fragment's // assign-block-size can handle it correctly. - self.fragment.assign_replaced_block_size_if_necessary(Some(containing_block_block_size)); + self.fragment.assign_replaced_block_size_if_necessary(); // TODO: Right now, this content block-size value includes the // margin because of erroneous block-size calculation in fragment. // Check this when that has been fixed. @@ -1551,7 +1533,7 @@ impl BlockFlow { size + self.fragment.border_padding.inline_start_end(), } } else { - clamp(min_inline_size, available_inline_size, max_inline_size) + max(min_inline_size, min(available_inline_size, max_inline_size)) }; self.base.position.size.inline = inline_size + self.fragment.margin.inline_start_end(); @@ -1896,16 +1878,22 @@ impl Flow for BlockFlow { fn fragment(&mut self, layout_context: &LayoutContext, fragmentation_context: Option<FragmentationContext>) -> Option<Arc<Flow>> { - if self.is_replaced_content() { + if self.fragment.is_replaced() { let _scope = layout_debug_scope!("assign_replaced_block_size_if_necessary {:x}", self.base.debug_id()); // Assign block-size for fragment if it is an image fragment. - let containing_block_block_size = - self.base.block_container_explicit_block_size; - self.fragment.assign_replaced_block_size_if_necessary(containing_block_block_size); + self.fragment.assign_replaced_block_size_if_necessary(); if !self.base.flags.contains(IS_ABSOLUTELY_POSITIONED) { self.base.position.size.block = self.fragment.border_box.size.block; + let mut block_start = AdjoiningMargins::from_margin(self.fragment.margin.block_start); + let block_end = AdjoiningMargins::from_margin(self.fragment.margin.block_end); + if self.fragment.border_box.size.block == Au(0) { + block_start.union(block_end); + self.base.collapsible_margins = CollapsibleMargins::CollapseThrough(block_start); + } else { + self.base.collapsible_margins = CollapsibleMargins::Collapse(block_start, block_end); + } self.base.restyle_damage.remove(REFLOW_OUT_OF_FLOW | REFLOW); self.fragment.restyle_damage.remove(REFLOW_OUT_OF_FLOW | REFLOW); } @@ -2870,7 +2858,7 @@ impl ISizeAndMarginsComputer for AbsoluteReplaced { fragment.assign_replaced_inline_size_if_necessary(containing_block_inline_size, container_block_size); // For replaced absolute flow, the rest of the constraint solving will // take inline-size to be specified as the value computed here. - MaybeAuto::Specified(fragment.content_inline_size()) + MaybeAuto::Specified(fragment.content_box().size.inline) } fn containing_block_inline_size(&self, @@ -2929,7 +2917,7 @@ impl ISizeAndMarginsComputer for BlockReplaced { fragment.assign_replaced_inline_size_if_necessary(parent_flow_inline_size, container_block_size); // For replaced block flow, the rest of the constraint solving will // take inline-size to be specified as the value computed here. - MaybeAuto::Specified(fragment.content_inline_size()) + MaybeAuto::Specified(fragment.content_box().size.inline) } } @@ -2987,7 +2975,7 @@ impl ISizeAndMarginsComputer for FloatReplaced { fragment.assign_replaced_inline_size_if_necessary(parent_flow_inline_size, container_block_size); // For replaced block flow, the rest of the constraint solving will // take inline-size to be specified as the value computed here. - MaybeAuto::Specified(fragment.content_inline_size()) + MaybeAuto::Specified(fragment.content_box().size.inline) } } @@ -3075,7 +3063,7 @@ impl ISizeAndMarginsComputer for InlineBlockReplaced { fragment.assign_replaced_inline_size_if_necessary(parent_flow_inline_size, container_block_size); // For replaced block flow, the rest of the constraint solving will // take inline-size to be specified as the value computed here. - MaybeAuto::Specified(fragment.content_inline_size()) + MaybeAuto::Specified(fragment.content_box().size.inline) } } diff --git a/components/layout/construct.rs b/components/layout/construct.rs index f3309b97b75..660d4f64834 100644 --- a/components/layout/construct.rs +++ b/components/layout/construct.rs @@ -38,6 +38,7 @@ use multicol::{MulticolColumnFlow, MulticolFlow}; use parallel; use script_layout_interface::{LayoutElementType, LayoutNodeType, is_image_data}; use script_layout_interface::wrapper_traits::{PseudoElementType, ThreadSafeLayoutElement, ThreadSafeLayoutNode}; +use servo_config::opts; use servo_url::ServoUrl; use std::borrow::ToOwned; use std::collections::LinkedList; @@ -64,7 +65,6 @@ use table_rowgroup::TableRowGroupFlow; use table_wrapper::TableWrapperFlow; use text::TextRunScanner; use traversal::PostorderNodeMutTraversal; -use util::opts; use wrapper::{LayoutNodeLayoutData, TextContent, ThreadSafeLayoutNodeHelpers}; /// The results of flow construction for a DOM node. @@ -141,17 +141,22 @@ pub struct InlineFragmentsConstructionResult { /// The resulting `ConstructionItem` for the outer `span` will be: /// /// ```ignore -/// ConstructionItem::InlineFragments(Some(~[ -/// InlineBlockSplit { -/// predecessor_fragments: ~[ -/// A +/// ConstructionItem::InlineFragments( +/// InlineFragmentsConstructionResult{ +/// splits: linked_list![ +/// InlineBlockSplit{ +/// predecessors: IntermediateInlineFragments{ +/// fragments: linked_list![A], +/// absolute_descendents: AbsoluteDescendents{ +/// descendant_links: vec![] +/// } +/// }, +/// flow: B +/// } /// ], -/// block: ~BlockFlow { -/// B -/// }, -/// }),~[ -/// C -/// ]) +/// fragments: linked_list![C], +/// } +/// ) /// ``` #[derive(Clone)] pub struct InlineBlockSplit { @@ -346,14 +351,12 @@ impl<'a, ConcreteThreadSafeLayoutNode: ThreadSafeLayoutNode> SpecificFragmentInfo::Iframe(IframeFragmentInfo::new(node)) } Some(LayoutNodeType::Element(LayoutElementType::HTMLImageElement)) => { - let image_info = box ImageFragmentInfo::new(node, - node.image_url(), + let image_info = box ImageFragmentInfo::new(node.image_url(), &self.layout_context.shared); SpecificFragmentInfo::Image(image_info) } Some(LayoutNodeType::Element(LayoutElementType::HTMLObjectElement)) => { - let image_info = box ImageFragmentInfo::new(node, - node.object_data(), + let image_info = box ImageFragmentInfo::new(node.object_data(), &self.layout_context.shared); SpecificFragmentInfo::Image(image_info) } @@ -372,11 +375,11 @@ impl<'a, ConcreteThreadSafeLayoutNode: ThreadSafeLayoutNode> } Some(LayoutNodeType::Element(LayoutElementType::HTMLCanvasElement)) => { let data = node.canvas_data().unwrap(); - SpecificFragmentInfo::Canvas(box CanvasFragmentInfo::new(node, data, self.style_context())) + SpecificFragmentInfo::Canvas(box CanvasFragmentInfo::new(data)) } Some(LayoutNodeType::Element(LayoutElementType::SVGSVGElement)) => { let data = node.svg_data().unwrap(); - SpecificFragmentInfo::Svg(box SvgFragmentInfo::new(node, data, self.style_context())) + SpecificFragmentInfo::Svg(box SvgFragmentInfo::new(data)) } _ => { // This includes pseudo-elements. @@ -1207,8 +1210,7 @@ impl<'a, ConcreteThreadSafeLayoutNode: ThreadSafeLayoutNode> let flotation = FloatKind::from_property(flotation); let marker_fragments = match node.style(self.style_context()).get_list().list_style_image { Either::First(ref url_value) => { - let image_info = box ImageFragmentInfo::new(node, - url_value.url().map(|u| u.clone()), + let image_info = box ImageFragmentInfo::new(url_value.url().map(|u| u.clone()), &self.layout_context.shared); vec![Fragment::new(node, SpecificFragmentInfo::Image(image_info), self.layout_context)] } diff --git a/components/layout/context.rs b/components/layout/context.rs index cb5b9efb0ef..e2d1fa7831c 100644 --- a/components/layout/context.rs +++ b/components/layout/context.rs @@ -17,57 +17,74 @@ use net_traits::image::base::Image; use net_traits::image_cache_thread::{ImageCacheChan, ImageCacheThread, ImageResponse, ImageState}; use net_traits::image_cache_thread::{ImageOrMetadataAvailable, UsePlaceholder}; use parking_lot::RwLock; +use servo_config::opts; use servo_url::ServoUrl; use std::cell::{RefCell, RefMut}; use std::collections::HashMap; use std::hash::BuildHasherDefault; use std::rc::Rc; use std::sync::{Arc, Mutex}; -use style::context::{LocalStyleContext, StyleContext, SharedStyleContext}; -use util::opts; +use style::context::{SharedStyleContext, ThreadLocalStyleContext}; +use style::dom::TElement; -struct LocalLayoutContext { - style_context: LocalStyleContext, +/// TLS data scoped to the traversal. +pub struct ScopedThreadLocalLayoutContext<E: TElement> { + pub style_context: ThreadLocalStyleContext<E>, +} + +impl<E: TElement> ScopedThreadLocalLayoutContext<E> { + pub fn new(shared: &SharedLayoutContext) -> Self { + ScopedThreadLocalLayoutContext { + style_context: ThreadLocalStyleContext::new(&shared.style_context), + } + } +} + +/// TLS data that persists across traversals. +pub struct PersistentThreadLocalLayoutContext { + // FontContext uses Rc all over the place and so isn't Send, which means we + // can't use ScopedTLS for it. There's also no reason to scope it to the + // traversal, and performance is probably better if we don't. + pub font_context: RefCell<FontContext>, +} - font_context: RefCell<FontContext>, +impl PersistentThreadLocalLayoutContext { + pub fn new(shared: &SharedLayoutContext) -> Rc<Self> { + let font_cache_thread = shared.font_cache_thread.lock().unwrap().clone(); + Rc::new(PersistentThreadLocalLayoutContext { + font_context: RefCell::new(FontContext::new(font_cache_thread)), + }) + } } -impl HeapSizeOf for LocalLayoutContext { - // FIXME(njn): measure other fields eventually. +impl HeapSizeOf for PersistentThreadLocalLayoutContext { fn heap_size_of_children(&self) -> usize { self.font_context.heap_size_of_children() } } -thread_local!(static LOCAL_CONTEXT_KEY: RefCell<Option<Rc<LocalLayoutContext>>> = RefCell::new(None)); +thread_local!(static LOCAL_CONTEXT_KEY: RefCell<Option<Rc<PersistentThreadLocalLayoutContext>>> = RefCell::new(None)); -pub fn heap_size_of_local_context() -> usize { - LOCAL_CONTEXT_KEY.with(|r| { - r.borrow().clone().map_or(0, |context| context.heap_size_of_children()) - }) -} - -// Keep this implementation in sync with the one in ports/geckolib/traversal.rs. -fn create_or_get_local_context(shared_layout_context: &SharedLayoutContext) - -> Rc<LocalLayoutContext> { +fn create_or_get_persistent_context(shared: &SharedLayoutContext) + -> Rc<PersistentThreadLocalLayoutContext> { LOCAL_CONTEXT_KEY.with(|r| { let mut r = r.borrow_mut(); if let Some(context) = r.clone() { context } else { - let font_cache_thread = shared_layout_context.font_cache_thread.lock().unwrap().clone(); - let local_style_data = shared_layout_context.style_context.local_context_creation_data.lock().unwrap(); - - let context = Rc::new(LocalLayoutContext { - style_context: LocalStyleContext::new(&local_style_data), - font_context: RefCell::new(FontContext::new(font_cache_thread)), - }); + let context = PersistentThreadLocalLayoutContext::new(shared); *r = Some(context.clone()); context } }) } +pub fn heap_size_of_persistent_local_context() -> usize { + LOCAL_CONTEXT_KEY.with(|r| { + r.borrow().clone().map_or(0, |context| context.heap_size_of_children()) + }) +} + /// Layout information shared among all workers. This must be thread-safe. pub struct SharedLayoutContext { /// Bits shared by the layout and style system. @@ -90,27 +107,26 @@ pub struct SharedLayoutContext { pub struct LayoutContext<'a> { pub shared: &'a SharedLayoutContext, - cached_local_layout_context: Rc<LocalLayoutContext>, + pub persistent: Rc<PersistentThreadLocalLayoutContext>, } -impl<'a> StyleContext<'a> for LayoutContext<'a> { - fn shared_context(&self) -> &'a SharedStyleContext { - &self.shared.style_context - } - - fn local_context(&self) -> &LocalStyleContext { - &self.cached_local_layout_context.style_context +impl<'a> LayoutContext<'a> { + pub fn new(shared: &'a SharedLayoutContext) -> Self + { + LayoutContext { + shared: shared, + persistent: create_or_get_persistent_context(shared), + } } } impl<'a> LayoutContext<'a> { - pub fn new(shared_layout_context: &'a SharedLayoutContext) -> LayoutContext<'a> { - let local_context = create_or_get_local_context(shared_layout_context); - - LayoutContext { - shared: shared_layout_context, - cached_local_layout_context: local_context, - } + // FIXME(bholley): The following two methods are identical and should be merged. + // shared_context() is the appropriate name, but it involves renaming a lot of + // calls. + #[inline(always)] + pub fn shared_context(&self) -> &SharedStyleContext { + &self.shared.style_context } #[inline(always)] @@ -120,7 +136,7 @@ impl<'a> LayoutContext<'a> { #[inline(always)] pub fn font_context(&self) -> RefMut<FontContext> { - self.cached_local_layout_context.font_context.borrow_mut() + self.persistent.font_context.borrow_mut() } } diff --git a/components/layout/display_list_builder.rs b/components/layout/display_list_builder.rs index 0c34a147655..be11ba66edd 100644 --- a/components/layout/display_list_builder.rs +++ b/components/layout/display_list_builder.rs @@ -35,6 +35,7 @@ use model::{self, MaybeAuto, ToGfxMatrix}; use net_traits::image::base::PixelFormat; use net_traits::image_cache_thread::UsePlaceholder; use range::Range; +use servo_config::opts; use servo_url::ServoUrl; use std::{cmp, f32}; use std::collections::HashMap; @@ -53,11 +54,10 @@ use style::properties::{self, ServoComputedValues}; use style::properties::style_structs; use style::servo::restyle_damage::REPAINT; use style::values::{self, Either, RGBA, computed}; -use style::values::computed::{Gradient, GradientKind, LengthOrPercentage, LengthOrPercentageOrAuto}; -use style::values::specified::{AngleOrCorner, HorizontalDirection, VerticalDirection}; +use style::values::computed::{AngleOrCorner, Gradient, GradientKind, LengthOrPercentage, LengthOrPercentageOrAuto}; +use style::values::specified::{HorizontalDirection, VerticalDirection}; use style_traits::cursor::Cursor; use table_cell::CollapsedBordersForCell; -use util::opts; use webrender_traits::{ColorF, GradientStop}; trait RgbColor { @@ -755,11 +755,12 @@ impl FragmentDisplayListBuilding for Fragment { } }; - let position = *get_cyclic(&background.background_position.0, index); + let horiz_position = *get_cyclic(&background.background_position_x.0, index); + let vert_position = *get_cyclic(&background.background_position_y.0, index); // Use `background-position` to get the offset. - let horizontal_position = model::specified(position.horizontal, + let horizontal_position = model::specified(horiz_position.0, bounds.size.width - image_size.width); - let vertical_position = model::specified(position.vertical, + let vertical_position = model::specified(vert_position.0, bounds.size.height - image_size.height); // The anchor position for this background, based on both the background-attachment @@ -1489,57 +1490,51 @@ impl FragmentDisplayListBuilding for Fragment { } } SpecificFragmentInfo::Canvas(ref canvas_fragment_info) => { - let width = canvas_fragment_info.replaced_image_fragment_info - .computed_inline_size.map_or(0, |w| w.to_px() as usize); - let height = canvas_fragment_info.replaced_image_fragment_info - .computed_block_size.map_or(0, |h| h.to_px() as usize); - if width > 0 && height > 0 { - let computed_width = canvas_fragment_info.canvas_inline_size().to_px(); - let computed_height = canvas_fragment_info.canvas_block_size().to_px(); - - let canvas_data = match canvas_fragment_info.ipc_renderer { - Some(ref ipc_renderer) => { - let ipc_renderer = ipc_renderer.lock().unwrap(); - let (sender, receiver) = ipc::channel().unwrap(); - ipc_renderer.send(CanvasMsg::FromLayout( - FromLayoutMsg::SendData(sender))).unwrap(); - receiver.recv().unwrap() - }, - None => return, - }; + let computed_width = canvas_fragment_info.dom_width.to_px(); + let computed_height = canvas_fragment_info.dom_height.to_px(); + + let canvas_data = match canvas_fragment_info.ipc_renderer { + Some(ref ipc_renderer) => { + let ipc_renderer = ipc_renderer.lock().unwrap(); + let (sender, receiver) = ipc::channel().unwrap(); + ipc_renderer.send(CanvasMsg::FromLayout( + FromLayoutMsg::SendData(sender))).unwrap(); + receiver.recv().unwrap() + }, + None => return, + }; + + let base = state.create_base_display_item( + &stacking_relative_content_box, + clip, + self.node, + self.style.get_cursor(Cursor::Default), + DisplayListSection::Content); + let display_item = match canvas_data { + CanvasData::Image(canvas_data) => { + DisplayItem::Image(box ImageDisplayItem { + base: base, + webrender_image: WebRenderImageInfo { + width: computed_width as u32, + height: computed_height as u32, + format: PixelFormat::RGBA8, + key: Some(canvas_data.image_key), + }, + image_data: None, + stretch_size: stacking_relative_content_box.size, + tile_spacing: Size2D::zero(), + image_rendering: image_rendering::T::auto, + }) + } + CanvasData::WebGL(context_id) => { + DisplayItem::WebGL(box WebGLDisplayItem { + base: base, + context_id: context_id, + }) + } + }; - let base = state.create_base_display_item( - &stacking_relative_content_box, - clip, - self.node, - self.style.get_cursor(Cursor::Default), - DisplayListSection::Content); - let display_item = match canvas_data { - CanvasData::Image(canvas_data) => { - DisplayItem::Image(box ImageDisplayItem { - base: base, - webrender_image: WebRenderImageInfo { - width: computed_width as u32, - height: computed_height as u32, - format: PixelFormat::RGBA8, - key: Some(canvas_data.image_key), - }, - image_data: None, - stretch_size: stacking_relative_content_box.size, - tile_spacing: Size2D::zero(), - image_rendering: image_rendering::T::auto, - }) - } - CanvasData::WebGL(context_id) => { - DisplayItem::WebGL(box WebGLDisplayItem { - base: base, - context_id: context_id, - }) - } - }; - - state.add_display_item(display_item); - } + state.add_display_item(display_item); } SpecificFragmentInfo::UnscannedText(_) => { panic!("Shouldn't see unscanned fragments here.") diff --git a/components/layout/flex.rs b/components/layout/flex.rs index d84373a7c21..7b8d694494c 100644 --- a/components/layout/flex.rs +++ b/components/layout/flex.rs @@ -19,14 +19,14 @@ use fragment::{Fragment, FragmentBorderBoxIterator, Overflow}; use gfx::display_list::StackingContext; use gfx_traits::ScrollRootId; use layout_debug; -use model::{IntrinsicISizes, MaybeAuto, MinMaxConstraint}; +use model::{IntrinsicISizes, MaybeAuto, SizeConstraint}; use model::{specified, specified_or_none}; use std::cmp::{max, min}; use std::ops::Range; use std::sync::Arc; use style::computed_values::{align_content, align_self, flex_direction, flex_wrap, justify_content}; use style::computed_values::border_collapse; -use style::context::{SharedStyleContext, StyleContext}; +use style::context::SharedStyleContext; use style::logical_geometry::{Direction, LogicalSize}; use style::properties::ServoComputedValues; use style::servo::restyle_damage::{REFLOW, REFLOW_OUT_OF_FLOW}; @@ -38,7 +38,7 @@ use style::values::computed::{LengthOrPercentageOrAutoOrContent, LengthOrPercent #[derive(Debug)] enum AxisSize { Definite(Au), - MinMax(MinMaxConstraint), + MinMax(SizeConstraint), Infinite, } @@ -62,7 +62,7 @@ impl AxisSize { } } LengthOrPercentageOrAuto::Auto => { - AxisSize::MinMax(MinMaxConstraint::new(content_size, min, max)) + AxisSize::MinMax(SizeConstraint::new(content_size, min, max, None)) } } } diff --git a/components/layout/flow.rs b/components/layout/flow.rs index df7a6510ff2..34fcd3bf300 100644 --- a/components/layout/flow.rs +++ b/components/layout/flow.rs @@ -50,7 +50,6 @@ use std::sync::Arc; use std::sync::atomic::Ordering; use style::computed_values::{clear, float, overflow_x, position, text_align}; use style::context::SharedStyleContext; -use style::dom::TRestyleDamage; use style::logical_geometry::{LogicalRect, LogicalSize, WritingMode}; use style::properties::ServoComputedValues; use style::selector_parser::RestyleDamage; diff --git a/components/layout/fragment.rs b/components/layout/fragment.rs index 104c45fd918..e5d86e78ed5 100644 --- a/components/layout/fragment.rs +++ b/components/layout/fragment.rs @@ -23,7 +23,8 @@ use inline::{InlineMetrics, LAST_FRAGMENT_OF_ELEMENT, LineMetrics}; use ipc_channel::ipc::IpcSender; #[cfg(debug_assertions)] use layout_debug; -use model::{self, IntrinsicISizes, IntrinsicISizesContribution, MaybeAuto}; +use model::{self, IntrinsicISizes, IntrinsicISizesContribution, MaybeAuto, SizeConstraint}; +use model::style_length; use msg::constellation_msg::PipelineId; use net_traits::image::base::{Image, ImageMetadata}; use net_traits::image_cache_thread::{ImageOrMetadataAvailable, UsePlaceholder}; @@ -34,7 +35,7 @@ use script_layout_interface::wrapper_traits::{PseudoElementType, ThreadSafeLayou use serde::{Serialize, Serializer}; use servo_url::ServoUrl; use std::borrow::ToOwned; -use std::cmp::{max, min}; +use std::cmp::{Ordering, max, min}; use std::collections::LinkedList; use std::fmt; use std::sync::{Arc, Mutex}; @@ -43,8 +44,6 @@ use style::computed_values::{border_collapse, box_sizing, clear, color, display, use style::computed_values::{overflow_wrap, overflow_x, position, text_decoration}; use style::computed_values::{transform_style, vertical_align, white_space, word_break, z_index}; use style::computed_values::content::ContentItem; -use style::context::SharedStyleContext; -use style::dom::TRestyleDamage; use style::logical_geometry::{Direction, LogicalMargin, LogicalRect, LogicalSize, WritingMode}; use style::properties::ServoComputedValues; use style::selector_parser::RestyleDamage; @@ -52,7 +51,6 @@ use style::servo::restyle_damage::RECONSTRUCT_FLOW; use style::str::char_is_whitespace; use style::values::Either; use style::values::computed::{LengthOrPercentage, LengthOrPercentageOrAuto}; -use style::values::computed::LengthOrPercentageOrNone; use text; use text::TextRunScanner; @@ -60,6 +58,10 @@ use text::TextRunScanner; static FONT_SUBSCRIPT_OFFSET_RATIO: f32 = 0.20; static FONT_SUPERSCRIPT_OFFSET_RATIO: f32 = 0.34; +// https://drafts.csswg.org/css-images/#default-object-size +static DEFAULT_REPLACED_WIDTH: i32 = 300; +static DEFAULT_REPLACED_HEIGHT: i32 = 150; + /// Fragments (`struct Fragment`) are the leaves of the layout tree. They cannot position /// themselves. In general, fragments do not have a simple correspondence with CSS fragments in the /// specification: @@ -248,21 +250,6 @@ impl fmt::Debug for SpecificFragmentInfo { } } -/// Clamp a value obtained from style_length, based on min / max lengths. -fn clamp_size(size: Au, - min_size: LengthOrPercentage, - max_size: LengthOrPercentageOrNone, - container_size: Au) - -> Au { - let min_size = model::specified(min_size, container_size); - let max_size = model::specified_or_none(max_size, container_size); - - max(min_size, match max_size { - None => size, - Some(max_size) => min(size, max_size), - }) -} - /// Information for generated content. #[derive(Clone)] pub enum GeneratedContentInfo { @@ -327,89 +314,41 @@ impl InlineAbsoluteFragmentInfo { #[derive(Clone)] pub struct CanvasFragmentInfo { - pub replaced_image_fragment_info: ReplacedImageFragmentInfo, pub ipc_renderer: Option<Arc<Mutex<IpcSender<CanvasMsg>>>>, pub dom_width: Au, pub dom_height: Au, } impl CanvasFragmentInfo { - pub fn new<N: ThreadSafeLayoutNode>(node: &N, - data: HTMLCanvasData, - ctx: &SharedStyleContext) - -> CanvasFragmentInfo { + pub fn new(data: HTMLCanvasData) -> CanvasFragmentInfo { CanvasFragmentInfo { - replaced_image_fragment_info: ReplacedImageFragmentInfo::new(node, ctx), ipc_renderer: data.ipc_renderer .map(|renderer| Arc::new(Mutex::new(renderer))), dom_width: Au::from_px(data.width as i32), dom_height: Au::from_px(data.height as i32), } } - - /// Returns the original inline-size of the canvas. - pub fn canvas_inline_size(&self) -> Au { - if self.replaced_image_fragment_info.writing_mode_is_vertical { - self.dom_height - } else { - self.dom_width - } - } - - /// Returns the original block-size of the canvas. - pub fn canvas_block_size(&self) -> Au { - if self.replaced_image_fragment_info.writing_mode_is_vertical { - self.dom_width - } else { - self.dom_height - } - } } #[derive(Clone)] pub struct SvgFragmentInfo { - pub replaced_image_fragment_info: ReplacedImageFragmentInfo, pub dom_width: Au, pub dom_height: Au, } impl SvgFragmentInfo { - pub fn new<N: ThreadSafeLayoutNode>(node: &N, - data: SVGSVGData, - ctx: &SharedStyleContext) - -> SvgFragmentInfo { + pub fn new(data: SVGSVGData) -> SvgFragmentInfo { SvgFragmentInfo { - replaced_image_fragment_info: ReplacedImageFragmentInfo::new(node, ctx), dom_width: Au::from_px(data.width as i32), dom_height: Au::from_px(data.height as i32), } } - - /// Returns the original inline-size of the SVG element. - pub fn svg_inline_size(&self) -> Au { - if self.replaced_image_fragment_info.writing_mode_is_vertical { - self.dom_height - } else { - self.dom_width - } - } - - /// Returns the original block-size of the SVG element. - pub fn svg_block_size(&self) -> Au { - if self.replaced_image_fragment_info.writing_mode_is_vertical { - self.dom_width - } else { - self.dom_height - } - } } /// A fragment that represents a replaced content image and its accompanying borders, shadows, etc. #[derive(Clone)] pub struct ImageFragmentInfo { - /// The image held within this fragment. - pub replaced_image_fragment_info: ReplacedImageFragmentInfo, pub image: Option<Arc<Image>>, pub metadata: Option<ImageMetadata>, } @@ -419,9 +358,9 @@ impl ImageFragmentInfo { /// /// FIXME(pcwalton): The fact that image fragments store the cache in the fragment makes little /// sense to me. - pub fn new<N: ThreadSafeLayoutNode>(node: &N, url: Option<ServoUrl>, - shared_layout_context: &SharedLayoutContext) - -> ImageFragmentInfo { + pub fn new(url: Option<ServoUrl>, + shared_layout_context: &SharedLayoutContext) + -> ImageFragmentInfo { let image_or_metadata = url.and_then(|url| { shared_layout_context.get_or_request_image_or_meta(url, UsePlaceholder::Yes) }); @@ -439,40 +378,11 @@ impl ImageFragmentInfo { }; ImageFragmentInfo { - replaced_image_fragment_info: ReplacedImageFragmentInfo::new(node, &shared_layout_context.style_context), image: image, metadata: metadata, } } - /// Returns the original inline-size of the image. - pub fn image_inline_size(&mut self) -> Au { - match self.metadata { - Some(ref metadata) => { - Au::from_px(if self.replaced_image_fragment_info.writing_mode_is_vertical { - metadata.height - } else { - metadata.width - } as i32) - } - None => Au(0) - } - } - - /// Returns the original block-size of the image. - pub fn image_block_size(&mut self) -> Au { - match self.metadata { - Some(ref metadata) => { - Au::from_px(if self.replaced_image_fragment_info.writing_mode_is_vertical { - metadata.width - } else { - metadata.height - } as i32) - } - None => Au(0) - } - } - pub fn tile_image_round(position: &mut Au, size: &mut Au, absolute_anchor_origin: Au, @@ -545,149 +455,6 @@ impl ImageFragmentInfo { } } -#[derive(Clone)] -pub struct ReplacedImageFragmentInfo { - pub computed_inline_size: Option<Au>, - pub computed_block_size: Option<Au>, - pub writing_mode_is_vertical: bool, -} - -impl ReplacedImageFragmentInfo { - pub fn new<N>(node: &N, ctx: &SharedStyleContext) -> ReplacedImageFragmentInfo - where N: ThreadSafeLayoutNode { - let is_vertical = node.style(ctx).writing_mode.is_vertical(); - ReplacedImageFragmentInfo { - computed_inline_size: None, - computed_block_size: None, - writing_mode_is_vertical: is_vertical, - } - } - - /// Returns the calculated inline-size of the image, accounting for the inline-size attribute. - pub fn computed_inline_size(&self) -> Au { - self.computed_inline_size.expect("image inline_size is not computed yet!") - } - - /// Returns the calculated block-size of the image, accounting for the block-size attribute. - pub fn computed_block_size(&self) -> Au { - self.computed_block_size.expect("image block_size is not computed yet!") - } - - // Return used value for inline-size or block-size. - // - // `dom_length`: inline-size or block-size as specified in the `img` tag. - // `style_length`: inline-size as given in the CSS - pub fn style_length(style_length: LengthOrPercentageOrAuto, - container_size: Option<Au>) -> MaybeAuto { - match (style_length, container_size) { - (LengthOrPercentageOrAuto::Length(length), _) => MaybeAuto::Specified(length), - (LengthOrPercentageOrAuto::Percentage(pc), Some(container_size)) => { - MaybeAuto::Specified(container_size.scale_by(pc)) - } - (LengthOrPercentageOrAuto::Percentage(_), None) => MaybeAuto::Auto, - (LengthOrPercentageOrAuto::Calc(calc), Some(container_size)) => { - MaybeAuto::Specified(calc.length() + container_size.scale_by(calc.percentage())) - } - (LengthOrPercentageOrAuto::Calc(_), None) => MaybeAuto::Auto, - (LengthOrPercentageOrAuto::Auto, _) => MaybeAuto::Auto, - } - } - - pub fn calculate_replaced_inline_size(&mut self, - style: &ServoComputedValues, - noncontent_inline_size: Au, - container_inline_size: Au, - container_block_size: Option<Au>, - fragment_inline_size: Au, - fragment_block_size: Au) - -> Au { - let style_inline_size = style.content_inline_size(); - let style_block_size = style.content_block_size(); - let style_min_inline_size = style.min_inline_size(); - let style_max_inline_size = style.max_inline_size(); - let style_min_block_size = style.min_block_size(); - let style_max_block_size = style.max_block_size(); - - // TODO(ksh8281): compute border,margin - let inline_size = ReplacedImageFragmentInfo::style_length( - style_inline_size, - Some(container_inline_size)); - - let inline_size = match inline_size { - MaybeAuto::Auto => { - let intrinsic_width = fragment_inline_size; - let intrinsic_height = fragment_block_size; - if intrinsic_height == Au(0) { - intrinsic_width - } else { - let ratio = intrinsic_width.to_f32_px() / - intrinsic_height.to_f32_px(); - - let specified_height = ReplacedImageFragmentInfo::style_length( - style_block_size, - container_block_size); - let specified_height = match specified_height { - MaybeAuto::Auto => intrinsic_height, - MaybeAuto::Specified(h) => h, - }; - let specified_height = clamp_size(specified_height, - style_min_block_size, - style_max_block_size, - Au(0)); - Au::from_f32_px(specified_height.to_f32_px() * ratio) - } - }, - MaybeAuto::Specified(w) => w, - }; - - let inline_size = clamp_size(inline_size, - style_min_inline_size, - style_max_inline_size, - container_inline_size); - - self.computed_inline_size = Some(inline_size); - inline_size + noncontent_inline_size - } - - /// Here, `noncontent_block_size` represents the sum of border and padding, but not margin. - pub fn calculate_replaced_block_size(&mut self, - style: &ServoComputedValues, - noncontent_block_size: Au, - containing_block_block_size: Option<Au>, - fragment_inline_size: Au, - fragment_block_size: Au) - -> Au { - let style_block_size = style.content_block_size(); - let style_min_block_size = style.min_block_size(); - let style_max_block_size = style.max_block_size(); - - let inline_size = self.computed_inline_size(); - let block_size = ReplacedImageFragmentInfo::style_length( - style_block_size, - containing_block_block_size); - - let block_size = match block_size { - MaybeAuto::Auto => { - let intrinsic_width = fragment_inline_size; - let intrinsic_height = fragment_block_size; - let scale = intrinsic_width.to_f32_px() / inline_size.to_f32_px(); - Au::from_f32_px(intrinsic_height.to_f32_px() / scale) - }, - MaybeAuto::Specified(h) => { - h - } - }; - - let block_size = clamp_size(block_size, - style_min_block_size, - style_max_block_size, - Au(0)); - - self.computed_block_size = Some(block_size); - block_size + noncontent_block_size - } -} - /// A fragment that represents an inline frame (iframe). This stores the pipeline ID so that the /// size of this iframe can be communicated via the constellation to the iframe's own layout thread. #[derive(Clone)] @@ -704,52 +471,6 @@ impl IframeFragmentInfo { pipeline_id: pipeline_id, } } - - #[inline] - pub fn calculate_replaced_inline_size(&self, style: &ServoComputedValues, containing_size: Au) - -> Au { - // Calculate the replaced inline size (or default) as per CSS 2.1 § 10.3.2 - IframeFragmentInfo::calculate_replaced_size(style.content_inline_size(), - style.min_inline_size(), - style.max_inline_size(), - Some(containing_size), - Au::from_px(300)) - } - - #[inline] - pub fn calculate_replaced_block_size(&self, style: &ServoComputedValues, containing_size: Option<Au>) - -> Au { - // Calculate the replaced block size (or default) as per CSS 2.1 § 10.3.2 - IframeFragmentInfo::calculate_replaced_size(style.content_block_size(), - style.min_block_size(), - style.max_block_size(), - containing_size, - Au::from_px(150)) - - } - - fn calculate_replaced_size(content_size: LengthOrPercentageOrAuto, - style_min_size: LengthOrPercentage, - style_max_size: LengthOrPercentageOrNone, - containing_size: Option<Au>, - default_size: Au) -> Au { - let computed_size = match (content_size, containing_size) { - (LengthOrPercentageOrAuto::Length(length), _) => length, - (LengthOrPercentageOrAuto::Percentage(pc), Some(container_size)) => container_size.scale_by(pc), - (LengthOrPercentageOrAuto::Calc(calc), Some(container_size)) => { - container_size.scale_by(calc.percentage()) + calc.length() - }, - (LengthOrPercentageOrAuto::Calc(calc), None) => calc.length(), - (LengthOrPercentageOrAuto::Percentage(_), None) => default_size, - (LengthOrPercentageOrAuto::Auto, _) => default_size, - }; - - let containing_size = containing_size.unwrap_or(Au(0)); - clamp_size(computed_size, - style_min_size, - style_max_size, - containing_size) - } } /// A scanned text fragment represents a single run of text with a distinct style. A `TextFragment` @@ -1203,6 +924,198 @@ impl Fragment { } } + /// intrinsic width of this replaced element. + #[inline] + pub fn intrinsic_width(&self) -> Au { + match self.specific { + SpecificFragmentInfo::Image(ref info) => { + if let Some(ref data) = info.metadata { + Au::from_px(data.width as i32) + } else { + Au(0) + } + } + SpecificFragmentInfo::Canvas(ref info) => info.dom_width, + SpecificFragmentInfo::Svg(ref info) => info.dom_width, + // Note: Currently for replaced element with no intrinsic size, + // this function simply returns the default object size. As long as + // these elements do not have intrinsic aspect ratio this should be + // sufficient, but we may need to investigate if this is enough for + // use cases like SVG. + SpecificFragmentInfo::Iframe(_) => Au::from_px(DEFAULT_REPLACED_WIDTH), + _ => panic!("Trying to get intrinsic width on non-replaced element!") + } + } + + /// intrinsic width of this replaced element. + #[inline] + pub fn intrinsic_height(&self) -> Au { + match self.specific { + SpecificFragmentInfo::Image(ref info) => { + if let Some(ref data) = info.metadata { + Au::from_px(data.height as i32) + } else { + Au(0) + } + } + SpecificFragmentInfo::Canvas(ref info) => info.dom_height, + SpecificFragmentInfo::Svg(ref info) => info.dom_height, + SpecificFragmentInfo::Iframe(_) => Au::from_px(DEFAULT_REPLACED_HEIGHT), + _ => panic!("Trying to get intrinsic height on non-replaced element!") + } + } + + /// Whether this replace element has intrinsic aspect ratio. + pub fn has_intrinsic_ratio(&self) -> bool { + match self.specific { + SpecificFragmentInfo::Image(_) | + SpecificFragmentInfo::Canvas(_) | + // TODO(stshine): According to the SVG spec, whether a SVG element has intrinsic + // aspect ratio is determined by the `preserveAspectRatio` attribute. Since for + // now SVG is far from implemented, we simply choose the default behavior that + // the intrinsic aspect ratio is preserved. + // https://svgwg.org/svg2-draft/coords.html#PreserveAspectRatioAttribute + SpecificFragmentInfo::Svg(_) => + self.intrinsic_width() != Au(0) && self.intrinsic_height() != Au(0), + _ => false + } + } + + /// CSS 2.1 § 10.3.2 & 10.6.2 Calculate the used width and height of a replaced element. + /// When a parameter is `None` it means the specified size in certain direction + /// is unconstrained. The inline containing size can also be `None` since this + /// method is also used for calculating intrinsic inline size contribution. + pub fn calculate_replaced_sizes(&self, + containing_inline_size: Option<Au>, + containing_block_size: Option<Au>) + -> (Au, Au) { + let (intrinsic_inline_size, intrinsic_block_size) = if self.style.writing_mode.is_vertical() { + (self.intrinsic_height(), self.intrinsic_width()) + } else { + (self.intrinsic_width(), self.intrinsic_height()) + }; + + // Make sure the size we used here is for content box since they may be + // transferred by the intrinsic aspect ratio. + let inline_size = style_length(self.style.content_inline_size(), containing_inline_size) + .map(|x| x - self.box_sizing_boundary(Direction::Inline)); + let block_size = style_length(self.style.content_block_size(), containing_block_size) + .map(|x| x - self.box_sizing_boundary(Direction::Block)); + let inline_constraint = self.size_constraint(containing_inline_size, Direction::Inline); + let block_constraint = self.size_constraint(containing_block_size, Direction::Block); + + // https://drafts.csswg.org/css-images-3/#default-sizing + match (inline_size, block_size) { + // If the specified size is a definite width and height, the concrete + // object size is given that width and height. + (MaybeAuto::Specified(inline_size), MaybeAuto::Specified(block_size)) => + (inline_constraint.clamp(inline_size), block_constraint.clamp(block_size)), + + // If the specified size is only a width or height (but not both) + // then the concrete object size is given that specified width or + // height. The other dimension is calculated as follows: + // + // If the object has an intrinsic aspect ratio, the missing dimension + // of the concrete object size is calculated using the intrinsic + // aspect ratio and the present dimension. + // + // Otherwise, if the missing dimension is present in the object’s intrinsic + // dimensions, the missing dimension is taken from the object’s intrinsic + // dimensions. Otherwise it is taken from the default object size. + (MaybeAuto::Specified(inline_size), MaybeAuto::Auto) => { + let inline_size = inline_constraint.clamp(inline_size); + let block_size = if self.has_intrinsic_ratio() { + // Note: We can not precompute the ratio and store it as a float, because + // doing so may result one pixel difference in calculation for certain + // images, thus make some tests fail. + inline_size * intrinsic_block_size.0 / intrinsic_inline_size.0 + } else { + intrinsic_block_size + }; + (inline_size, block_constraint.clamp(block_size)) + } + (MaybeAuto::Auto, MaybeAuto::Specified(block_size)) => { + let block_size = block_constraint.clamp(block_size); + let inline_size = if self.has_intrinsic_ratio() { + block_size * intrinsic_inline_size.0 / intrinsic_block_size.0 + } else { + intrinsic_inline_size + }; + (inline_constraint.clamp(inline_size), block_size) + } + // https://drafts.csswg.org/css2/visudet.html#min-max-widths + (MaybeAuto::Auto, MaybeAuto::Auto) => { + if self.has_intrinsic_ratio() { + // This approch follows the spirit of cover and contain constraint. + // https://drafts.csswg.org/css-images-3/#cover-contain + + // First, create two rectangles that keep aspect ratio while may be clamped + // by the contraints; + let first_isize = inline_constraint.clamp(intrinsic_inline_size); + let first_bsize = first_isize * intrinsic_block_size.0 / intrinsic_inline_size.0; + let second_bsize = block_constraint.clamp(intrinsic_block_size); + let second_isize = second_bsize * intrinsic_inline_size.0 / intrinsic_block_size.0; + + let (inline_size, block_size) = match (first_isize.cmp(&intrinsic_inline_size) , + second_isize.cmp(&intrinsic_inline_size)) { + (Ordering::Equal, Ordering::Equal) => + (first_isize, first_bsize), + // When only one rectangle is clamped, use it; + (Ordering::Equal, _) => + (second_isize, second_bsize), + (_, Ordering::Equal) => + (first_isize, first_bsize), + // When both rectangles grow (smaller than min sizes), + // Choose the larger one; + (Ordering::Greater, Ordering::Greater) => + if first_isize > second_isize { + (first_isize, first_bsize) + } else { + (second_isize, second_bsize) + }, + // When both rectangles shrink (larger than max sizes), + // Choose the smaller one; + (Ordering::Less, Ordering::Less) => + if first_isize > second_isize { + (second_isize, second_bsize) + } else { + (first_isize, first_bsize) + }, + // It does not matter which we choose here, because both sizes + // will be clamped to constraint; + (Ordering::Less, Ordering::Greater) | (Ordering::Greater, Ordering::Less) => + (first_isize, first_bsize) + }; + // Clamp the result and we are done :-) + (inline_constraint.clamp(inline_size), block_constraint.clamp(block_size)) + } else { + (inline_constraint.clamp(intrinsic_inline_size), + block_constraint.clamp(intrinsic_block_size)) + } + } + } + } + + /// Return a size constraint that can be used the clamp size in given direction. + /// To take `box-sizing: border-box` into account, the `border_padding` field + /// must be initialized first. + /// + /// TODO(stshine): Maybe there is a more convenient way. + pub fn size_constraint(&self, containing_size: Option<Au>, direction: Direction) -> SizeConstraint { + let (style_min_size, style_max_size) = match direction { + Direction::Inline => (self.style.min_inline_size(), self.style.max_inline_size()), + Direction::Block => (self.style.min_block_size(), self.style.max_block_size()) + }; + + let border = if self.style().get_position().box_sizing == box_sizing::T::border_box { + Some(self.border_padding.start_end(direction)) + } else { + None + }; + + SizeConstraint::new(containing_size, style_min_size, style_max_size, border) + } + /// Returns a guess as to the distances from the margin edge of this fragment to its content /// in the inline direction. This will generally be correct unless percentages are involved. /// @@ -1255,7 +1168,7 @@ impl Fragment { } /// Returns the border width in given direction if this fragment has property - /// 'box-sizing: border-box'. The `border_padding` field should have been initialized. + /// 'box-sizing: border-box'. The `border_padding` field must have been initialized. pub fn box_sizing_boundary(&self, direction: Direction) -> Au { match (self.style().get_position().box_sizing, direction) { (box_sizing::T::border_box, Direction::Inline) => { @@ -1532,7 +1445,6 @@ impl Fragment { match self.specific { SpecificFragmentInfo::Generic | SpecificFragmentInfo::GeneratedContent(_) | - SpecificFragmentInfo::Iframe(_) | SpecificFragmentInfo::Table | SpecificFragmentInfo::TableCell | SpecificFragmentInfo::TableColumn(_) | @@ -1549,66 +1461,42 @@ impl Fragment { let block_flow = info.flow_ref.as_block(); result.union_block(&block_flow.base.intrinsic_inline_sizes) } - SpecificFragmentInfo::Image(ref mut image_fragment_info) => { - let mut image_inline_size = match self.style.content_inline_size() { - LengthOrPercentageOrAuto::Auto | - LengthOrPercentageOrAuto::Percentage(_) => { - image_fragment_info.image_inline_size() - } - LengthOrPercentageOrAuto::Length(length) => length, - LengthOrPercentageOrAuto::Calc(calc) => calc.length(), - }; - - image_inline_size = max(model::specified(self.style.min_inline_size(), Au(0)), image_inline_size); - if let Some(max) = model::specified_or_none(self.style.max_inline_size(), Au(0)) { - image_inline_size = min(image_inline_size, max) - } - - result.union_block(&IntrinsicISizes { - minimum_inline_size: image_inline_size, - preferred_inline_size: image_inline_size, - }); - } - SpecificFragmentInfo::Canvas(ref mut canvas_fragment_info) => { - let mut canvas_inline_size = match self.style.content_inline_size() { + SpecificFragmentInfo::Image(_) | + SpecificFragmentInfo::Canvas(_) | + SpecificFragmentInfo::Iframe(_) | + SpecificFragmentInfo::Svg(_) => { + let mut inline_size = match self.style.content_inline_size() { LengthOrPercentageOrAuto::Auto | LengthOrPercentageOrAuto::Percentage(_) => { - canvas_fragment_info.canvas_inline_size() + // We have to initialize the `border_padding` field first to make + // the size constraints work properly. + // TODO(stshine): Find a cleaner way to do this. + let padding = self.style.logical_padding(); + self.border_padding.inline_start = model::specified(padding.inline_start, Au(0)); + self.border_padding.inline_end = model::specified(padding.inline_end, Au(0)); + self.border_padding.block_start = model::specified(padding.block_start, Au(0)); + self.border_padding.block_end = model::specified(padding.block_end, Au(0)); + let border = self.border_width(); + self.border_padding.inline_start += border.inline_start; + self.border_padding.inline_end += border.inline_end; + self.border_padding.block_start += border.block_start; + self.border_padding.block_end += border.block_end; + let (result_inline, _) = self.calculate_replaced_sizes(None, None); + result_inline } LengthOrPercentageOrAuto::Length(length) => length, LengthOrPercentageOrAuto::Calc(calc) => calc.length(), }; - canvas_inline_size = max(model::specified(self.style.min_inline_size(), Au(0)), canvas_inline_size); - if let Some(max) = model::specified_or_none(self.style.max_inline_size(), Au(0)) { - canvas_inline_size = min(canvas_inline_size, max) - } + let size_constraint = self.size_constraint(None, Direction::Inline); + inline_size = size_constraint.clamp(inline_size); result.union_block(&IntrinsicISizes { - minimum_inline_size: canvas_inline_size, - preferred_inline_size: canvas_inline_size, + minimum_inline_size: inline_size, + preferred_inline_size: inline_size, }); } - SpecificFragmentInfo::Svg(ref mut svg_fragment_info) => { - let mut svg_inline_size = match self.style.content_inline_size() { - LengthOrPercentageOrAuto::Auto | - LengthOrPercentageOrAuto::Percentage(_) => { - svg_fragment_info.svg_inline_size() - } - LengthOrPercentageOrAuto::Length(length) => length, - LengthOrPercentageOrAuto::Calc(calc) => calc.length(), - }; - - svg_inline_size = max(model::specified(self.style.min_inline_size(), Au(0)), svg_inline_size); - if let Some(max) = model::specified_or_none(self.style.max_inline_size(), Au(0)) { - svg_inline_size = min(svg_inline_size, max) - } - result.union_block(&IntrinsicISizes { - minimum_inline_size: svg_inline_size, - preferred_inline_size: svg_inline_size, - }); - } SpecificFragmentInfo::ScannedText(ref text_fragment_info) => { let range = &text_fragment_info.range; @@ -1677,45 +1565,6 @@ impl Fragment { } } - /// TODO: What exactly does this function return? Why is it Au(0) for - /// `SpecificFragmentInfo::Generic`? - pub fn content_inline_size(&self) -> Au { - match self.specific { - SpecificFragmentInfo::Generic | - SpecificFragmentInfo::GeneratedContent(_) | - SpecificFragmentInfo::Iframe(_) | - SpecificFragmentInfo::Table | - SpecificFragmentInfo::TableCell | - SpecificFragmentInfo::TableRow | - SpecificFragmentInfo::TableWrapper | - SpecificFragmentInfo::Multicol | - SpecificFragmentInfo::MulticolColumn | - SpecificFragmentInfo::InlineBlock(_) | - SpecificFragmentInfo::InlineAbsoluteHypothetical(_) | - SpecificFragmentInfo::InlineAbsolute(_) => Au(0), - SpecificFragmentInfo::Canvas(ref canvas_fragment_info) => { - canvas_fragment_info.replaced_image_fragment_info.computed_inline_size() - } - SpecificFragmentInfo::Svg(ref svg_fragment_info) => { - svg_fragment_info.replaced_image_fragment_info.computed_inline_size() - } - SpecificFragmentInfo::Image(ref image_fragment_info) => { - image_fragment_info.replaced_image_fragment_info.computed_inline_size() - } - SpecificFragmentInfo::ScannedText(ref text_fragment_info) => { - let (range, run) = (&text_fragment_info.range, &text_fragment_info.run); - let text_bounds = run.metrics_for_range(range).bounding_box; - text_bounds.size.width - } - SpecificFragmentInfo::TableColumn(_) => { - panic!("Table column fragments do not have inline_size") - } - SpecificFragmentInfo::UnscannedText(_) => { - panic!("Unscanned text fragments should have been scanned by now!") - } - } - } - /// Returns the dimensions of the content box. /// /// This is marked `#[inline]` because it is frequently called when only one or two of the @@ -1992,10 +1841,8 @@ impl Fragment { SpecificFragmentInfo::Svg(_) => {} }; - let style = &*self.style; - let noncontent_inline_size = self.border_padding.inline_start_end(); - match self.specific { + // Inline blocks SpecificFragmentInfo::InlineAbsoluteHypothetical(ref mut info) => { let block_flow = FlowRef::deref_mut(&mut info.flow_ref).as_mut_block(); block_flow.base.position.size.inline = @@ -2020,54 +1867,24 @@ impl Fragment { block_flow.base.block_container_inline_size = self.border_box.size.inline; block_flow.base.block_container_writing_mode = self.style.writing_mode; } + + // Text SpecificFragmentInfo::ScannedText(ref info) => { // Scanned text fragments will have already had their content inline-sizes assigned // by this point. - self.border_box.size.inline = info.content_size.inline + noncontent_inline_size + self.border_box.size.inline = info.content_size.inline + + self.border_padding.inline_start_end(); } - SpecificFragmentInfo::Image(ref mut image_fragment_info) => { - let fragment_inline_size = image_fragment_info.image_inline_size(); - let fragment_block_size = image_fragment_info.image_block_size(); - self.border_box.size.inline = - image_fragment_info.replaced_image_fragment_info - .calculate_replaced_inline_size(style, - noncontent_inline_size, - container_inline_size, - container_block_size, - fragment_inline_size, - fragment_block_size); - } - SpecificFragmentInfo::Canvas(ref mut canvas_fragment_info) => { - let fragment_inline_size = canvas_fragment_info.canvas_inline_size(); - let fragment_block_size = canvas_fragment_info.canvas_block_size(); - self.border_box.size.inline = - canvas_fragment_info.replaced_image_fragment_info - .calculate_replaced_inline_size(style, - noncontent_inline_size, - container_inline_size, - container_block_size, - fragment_inline_size, - fragment_block_size); - } - SpecificFragmentInfo::Svg(ref mut svg_fragment_info) => { - let fragment_inline_size = svg_fragment_info.svg_inline_size(); - let fragment_block_size = svg_fragment_info.svg_block_size(); - self.border_box.size.inline = - svg_fragment_info.replaced_image_fragment_info - .calculate_replaced_inline_size(style, - noncontent_inline_size, - container_inline_size, - container_block_size, - fragment_inline_size, - fragment_block_size); - } - SpecificFragmentInfo::Iframe(ref iframe_fragment_info) => { - self.border_box.size.inline = - iframe_fragment_info.calculate_replaced_inline_size(style, - container_inline_size) + - noncontent_inline_size; + + // Replaced elements + _ if self.is_replaced() => { + let (inline_size, block_size) = + self.calculate_replaced_sizes(Some(container_inline_size), container_block_size); + self.border_box.size.inline = inline_size + self.border_padding.inline_start_end(); + self.border_box.size.block = block_size + self.border_padding.block_start_end(); } - _ => panic!("this case should have been handled above"), + + ref unhandled @ _ => panic!("this case should have been handled above: {:?}", unhandled), } } @@ -2075,7 +1892,7 @@ impl Fragment { /// been assigned first. /// /// Ideally, this should follow CSS 2.1 § 10.6.2. - pub fn assign_replaced_block_size_if_necessary(&mut self, containing_block_block_size: Option<Au>) { + pub fn assign_replaced_block_size_if_necessary(&mut self) { match self.specific { SpecificFragmentInfo::Generic | SpecificFragmentInfo::GeneratedContent(_) | @@ -2101,48 +1918,16 @@ impl Fragment { SpecificFragmentInfo::Svg(_) => {} } - let style = &*self.style; - let noncontent_block_size = self.border_padding.block_start_end(); - match self.specific { - SpecificFragmentInfo::Image(ref mut image_fragment_info) => { - let fragment_inline_size = image_fragment_info.image_inline_size(); - let fragment_block_size = image_fragment_info.image_block_size(); - self.border_box.size.block = - image_fragment_info.replaced_image_fragment_info - .calculate_replaced_block_size(style, - noncontent_block_size, - containing_block_block_size, - fragment_inline_size, - fragment_block_size); - } - SpecificFragmentInfo::Canvas(ref mut canvas_fragment_info) => { - let fragment_inline_size = canvas_fragment_info.canvas_inline_size(); - let fragment_block_size = canvas_fragment_info.canvas_block_size(); - self.border_box.size.block = - canvas_fragment_info.replaced_image_fragment_info - .calculate_replaced_block_size(style, - noncontent_block_size, - containing_block_block_size, - fragment_inline_size, - fragment_block_size); - } - SpecificFragmentInfo::Svg(ref mut svg_fragment_info) => { - let fragment_inline_size = svg_fragment_info.svg_inline_size(); - let fragment_block_size = svg_fragment_info.svg_block_size(); - self.border_box.size.block = - svg_fragment_info.replaced_image_fragment_info - .calculate_replaced_block_size(style, - noncontent_block_size, - containing_block_block_size, - fragment_inline_size, - fragment_block_size); - } + // Text SpecificFragmentInfo::ScannedText(ref info) => { // Scanned text fragments' content block-sizes are calculated by the text run // scanner during flow construction. - self.border_box.size.block = info.content_size.block + noncontent_block_size + self.border_box.size.block = info.content_size.block + + self.border_padding.block_start_end(); } + + // Inline blocks SpecificFragmentInfo::InlineBlock(ref mut info) => { // Not the primary fragment, so we do not take the noncontent size into account. let block_flow = FlowRef::deref_mut(&mut info.flow_ref).as_block(); @@ -2160,36 +1945,31 @@ impl Fragment { self.border_box.size.block = block_flow.base.position.size.block + block_flow.fragment.margin.block_start_end() } - SpecificFragmentInfo::Iframe(ref info) => { - self.border_box.size.block = - info.calculate_replaced_block_size(style, containing_block_block_size) + - noncontent_block_size; - } - _ => panic!("should have been handled above"), + + // Replaced elements + _ if self.is_replaced() => {}, + + ref unhandled @ _ => panic!("should have been handled above: {:?}", unhandled), } } - /// Returns true if this fragment is replaced content or an inline-block or false otherwise. - pub fn is_replaced_or_inline_block(&self) -> bool { + /// Returns true if this fragment is replaced content. + pub fn is_replaced(&self) -> bool { match self.specific { - SpecificFragmentInfo::Canvas(_) | SpecificFragmentInfo::Iframe(_) | + SpecificFragmentInfo::Canvas(_) | SpecificFragmentInfo::Image(_) | - SpecificFragmentInfo::InlineAbsoluteHypothetical(_) | - SpecificFragmentInfo::InlineBlock(_) | SpecificFragmentInfo::Svg(_) => true, - SpecificFragmentInfo::Generic | - SpecificFragmentInfo::GeneratedContent(_) | - SpecificFragmentInfo::InlineAbsolute(_) | - SpecificFragmentInfo::Table | - SpecificFragmentInfo::TableCell | - SpecificFragmentInfo::TableColumn(_) | - SpecificFragmentInfo::TableRow | - SpecificFragmentInfo::TableWrapper | - SpecificFragmentInfo::Multicol | - SpecificFragmentInfo::MulticolColumn | - SpecificFragmentInfo::ScannedText(_) | - SpecificFragmentInfo::UnscannedText(_) => false, + _ => false + } + } + + /// Returns true if this fragment is replaced content or an inline-block or false otherwise. + pub fn is_replaced_or_inline_block(&self) -> bool { + match self.specific { + SpecificFragmentInfo::InlineAbsoluteHypothetical(_) | + SpecificFragmentInfo::InlineBlock(_) => true, + _ => self.is_replaced(), } } @@ -2210,10 +1990,10 @@ impl Fragment { SpecificFragmentInfo::Canvas(_) | SpecificFragmentInfo::Iframe(_) | SpecificFragmentInfo::Image(_) | SpecificFragmentInfo::Svg(_) | SpecificFragmentInfo::Generic | SpecificFragmentInfo::GeneratedContent(_) => { - let ascent = self.border_box.size.block + self.margin.block_start; + let ascent = self.border_box.size.block + self.margin.block_end; InlineMetrics { - space_above_baseline: ascent, - space_below_baseline: self.margin.block_end, + space_above_baseline: ascent + self.margin.block_start, + space_below_baseline: Au(0), ascent: ascent, } } diff --git a/components/layout/generated_content.rs b/components/layout/generated_content.rs index d3eed080a8f..fe5ca470506 100644 --- a/components/layout/generated_content.rs +++ b/components/layout/generated_content.rs @@ -19,7 +19,6 @@ use std::collections::{HashMap, LinkedList}; use std::sync::Arc; use style::computed_values::{display, list_style_type}; use style::computed_values::content::ContentItem; -use style::dom::TRestyleDamage; use style::properties::ServoComputedValues; use style::selector_parser::RestyleDamage; use style::servo::restyle_damage::RESOLVE_GENERATED_CONTENT; diff --git a/components/layout/incremental.rs b/components/layout/incremental.rs index e38f55bec08..d24cda3307b 100644 --- a/components/layout/incremental.rs +++ b/components/layout/incremental.rs @@ -4,7 +4,6 @@ use flow::{self, AFFECTS_COUNTERS, Flow, HAS_COUNTER_AFFECTING_CHILDREN, IS_ABSOLUTELY_POSITIONED}; use style::computed_values::float; -use style::dom::TRestyleDamage; use style::selector_parser::RestyleDamage; use style::servo::restyle_damage::{REFLOW, RECONSTRUCT_FLOW}; diff --git a/components/layout/inline.rs b/components/layout/inline.rs index 57eb16f1b84..372aa2ea088 100644 --- a/components/layout/inline.rs +++ b/components/layout/inline.rs @@ -32,7 +32,7 @@ use std::sync::Arc; use style::arc_ptr_eq; use style::computed_values::{display, overflow_x, position, text_align, text_justify}; use style::computed_values::{vertical_align, white_space}; -use style::context::{SharedStyleContext, StyleContext}; +use style::context::SharedStyleContext; use style::logical_geometry::{LogicalRect, LogicalSize, WritingMode}; use style::properties::{longhands, ServoComputedValues}; use style::servo::restyle_damage::{BUBBLE_ISIZES, REFLOW, REFLOW_OUT_OF_FLOW, REPOSITION, RESOLVE_GENERATED_CONTENT}; @@ -1394,11 +1394,9 @@ impl Flow for InlineFlow { debug!("assign_block_size_inline: floats in: {:?}", self.base.floats); // Assign the block-size and late-computed inline-sizes for the inline fragments. - let containing_block_block_size = - self.base.block_container_explicit_block_size; for fragment in &mut self.fragments.fragments { fragment.update_late_computed_replaced_inline_size_if_necessary(); - fragment.assign_replaced_block_size_if_necessary(containing_block_block_size); + fragment.assign_replaced_block_size_if_necessary(); } // Reset our state, so that we handle incremental reflow correctly. diff --git a/components/layout/layout_debug.rs b/components/layout/layout_debug.rs index f98f253881f..3a8a1171287 100644 --- a/components/layout/layout_debug.rs +++ b/components/layout/layout_debug.rs @@ -65,13 +65,10 @@ struct State { impl Scope { pub fn new(name: String) -> Scope { STATE_KEY.with(|ref r| { - match *r.borrow_mut() { - Some(ref mut state) => { - let flow_trace = to_value(&flow::base(&*state.flow_root)); - let data = box ScopeData::new(name.clone(), flow_trace); - state.scope_stack.push(data); - } - None => {} + if let Some(ref mut state) = *r.borrow_mut() { + let flow_trace = to_value(&flow::base(&*state.flow_root)); + let data = box ScopeData::new(name.clone(), flow_trace); + state.scope_stack.push(data); } }); Scope @@ -82,14 +79,11 @@ impl Scope { impl Drop for Scope { fn drop(&mut self) { STATE_KEY.with(|ref r| { - match *r.borrow_mut() { - Some(ref mut state) => { - let mut current_scope = state.scope_stack.pop().unwrap(); - current_scope.post = to_value(&flow::base(&*state.flow_root)); - let previous_scope = state.scope_stack.last_mut().unwrap(); - previous_scope.children.push(current_scope); - } - None => {} + if let Some(ref mut state) = *r.borrow_mut() { + let mut current_scope = state.scope_stack.pop().unwrap(); + current_scope.post = to_value(&flow::base(&*state.flow_root)); + let previous_scope = state.scope_stack.last_mut().unwrap(); + previous_scope.children.push(current_scope); } }); } diff --git a/components/layout/lib.rs b/components/layout/lib.rs index a74bea33431..b2aaa006a2a 100644 --- a/components/layout/lib.rs +++ b/components/layout/lib.rs @@ -49,13 +49,13 @@ extern crate serde; extern crate serde_derive; extern crate serde_json; #[macro_use] extern crate servo_atoms; +extern crate servo_config; extern crate servo_url; extern crate smallvec; extern crate style; extern crate style_traits; extern crate unicode_bidi; extern crate unicode_script; -extern crate util; extern crate webrender_traits; #[macro_use] diff --git a/components/layout/list_item.rs b/components/layout/list_item.rs index b3f8df9752d..20cc7bfa850 100644 --- a/components/layout/list_item.rs +++ b/components/layout/list_item.rs @@ -111,9 +111,7 @@ impl Flow for ListItemFlow { &mut layout_context.font_context(), &*self.block_flow.fragment.style); for marker in &mut self.marker_fragments { - let containing_block_block_size = - self.block_flow.base.block_container_explicit_block_size; - marker.assign_replaced_block_size_if_necessary(containing_block_block_size); + marker.assign_replaced_block_size_if_necessary(); let marker_inline_metrics = marker.aligned_inline_metrics(layout_context, &marker_line_metrics, Some(&marker_line_metrics)); diff --git a/components/layout/model.rs b/components/layout/model.rs index a0693e0d8f8..89847e0190b 100644 --- a/components/layout/model.rs +++ b/components/layout/model.rs @@ -436,6 +436,21 @@ impl MaybeAuto { } } +/// Receive an optional container size and return used value for width or height. +/// +/// `style_length`: content size as given in the CSS. +pub fn style_length(style_length: LengthOrPercentageOrAuto, + container_size: Option<Au>) -> MaybeAuto { + match container_size { + Some(length) => MaybeAuto::from_style(style_length, length), + None => if let LengthOrPercentageOrAuto::Length(length) = style_length { + MaybeAuto::Specified(length) + } else { + MaybeAuto::Auto + } + } +} + pub fn specified_or_none(length: LengthOrPercentageOrNone, containing_length: Au) -> Option<Au> { match length { LengthOrPercentageOrNone::None => None, @@ -504,64 +519,60 @@ impl ToGfxMatrix for ComputedMatrix { } } -// https://drafts.csswg.org/css2/visudet.html#min-max-widths -// https://drafts.csswg.org/css2/visudet.html#min-max-heights -/// A min or max constraint -/// -/// A `max` of `None` is equivalent to no limmit for the size in the given -/// dimension. The `min` is >= 0, as negative values are illegal and by -/// default `min` is 0. -#[derive(Debug)] -pub struct MinMaxConstraint { - min: Au, - max: Option<Au> +/// A min-size and max-size constraint. The constructor has a optional `border` +/// parameter, and when it is present the constraint will be subtracted. This is +/// used to adjust the constraint for `box-sizing: border-box`, and when you do so +/// make sure the size you want to clamp is intended to be used for content box. +#[derive(Clone, Copy, Debug)] +pub struct SizeConstraint { + min_size: Au, + max_size: Option<Au>, } -impl MinMaxConstraint { - /// Create a `MinMaxConstraint` for a dimension given the min, max, and content box size for - /// an axis - pub fn new(content_size: Option<Au>, min: LengthOrPercentage, - max: LengthOrPercentageOrNone) -> MinMaxConstraint { - let min = match min { - LengthOrPercentage::Length(length) => length, - LengthOrPercentage::Percentage(percent) => { - match content_size { - Some(size) => size.scale_by(percent), - None => Au(0), - } - }, - LengthOrPercentage::Calc(calc) => { - match content_size { - Some(size) => size.scale_by(calc.percentage()), - None => Au(0), - } +impl SizeConstraint { + /// Create a `SizeConstraint` for an axis. + pub fn new(container_size: Option<Au>, + min_size: LengthOrPercentage, + max_size: LengthOrPercentageOrNone, + border: Option<Au>) -> SizeConstraint { + let mut min_size = match container_size { + Some(container_size) => specified(min_size, container_size), + None => if let LengthOrPercentage::Length(length) = min_size { + length + } else { + Au(0) } }; - let max = match max { - LengthOrPercentageOrNone::Length(length) => Some(length), - LengthOrPercentageOrNone::Percentage(percent) => { - content_size.map(|size| size.scale_by(percent)) - }, - LengthOrPercentageOrNone::Calc(calc) => { - content_size.map(|size| size.scale_by(calc.percentage())) + let mut max_size = match container_size { + Some(container_size) => specified_or_none(max_size, container_size), + None => if let LengthOrPercentageOrNone::Length(length) = max_size { + Some(length) + } else { + None } - LengthOrPercentageOrNone::None => None, }; + // Make sure max size is not smaller than min size. + max_size = max_size.map(|x| max(x, min_size)); + + if let Some(border) = border { + min_size = max((min_size - border), Au(0)); + max_size = max_size.map(|x| max(x - border, Au(0))); + } - MinMaxConstraint { - min: min, - max: max + SizeConstraint { + min_size: min_size, + max_size: max_size } } - /// Clamp the given size by the given `min` and `max` constraints. + /// Clamp the given size by the given min size and max size constraint. pub fn clamp(&self, other: Au) -> Au { - if other < self.min { - self.min + if other < self.min_size { + self.min_size } else { - match self.max { - Some(max) if max < other => max, + match self.max_size { + Some(max_size) if max_size < other => max_size, _ => other } } diff --git a/components/layout/multicol.rs b/components/layout/multicol.rs index c1773fc0c63..b5651369ebf 100644 --- a/components/layout/multicol.rs +++ b/components/layout/multicol.rs @@ -21,7 +21,7 @@ use gfx_traits::print_tree::PrintTree; use std::cmp::{min, max}; use std::fmt; use std::sync::Arc; -use style::context::{StyleContext, SharedStyleContext}; +use style::context::SharedStyleContext; use style::logical_geometry::LogicalSize; use style::properties::ServoComputedValues; use style::values::Either; @@ -99,9 +99,11 @@ impl Flow for MulticolFlow { { let column_style = self.block_flow.fragment.style.get_column(); - // `None` is 'normal': "UA-specified length. A value of 1em is suggested." - let column_gap = column_style.column_gap.0.unwrap_or_else(|| - self.block_flow.fragment.style.get_font().font_size); + let column_gap = match column_style.column_gap { + Either::First(len) => len, + Either::Second(_normal) => self.block_flow.fragment.style.get_font().font_size, + }; + let mut column_count; if let Either::First(column_width) = column_style.column_width { column_count = diff --git a/components/layout/parallel.rs b/components/layout/parallel.rs index 03aaa512d3e..a51f585eb3c 100644 --- a/components/layout/parallel.rs +++ b/components/layout/parallel.rs @@ -13,13 +13,13 @@ use flow::{self, Flow, MutableFlowUtils, PostorderFlowTraversal, PreorderFlowTra use flow_ref::FlowRef; use profile_traits::time::{self, TimerMetadata, profile}; use rayon; +use servo_config::opts; use std::mem; use std::sync::atomic::{AtomicIsize, Ordering}; use style::dom::UnsafeNode; use style::parallel::CHUNK_SIZE; use traversal::{AssignISizes, BubbleISizes}; use traversal::AssignBSizes; -use util::opts; pub use style::parallel::traverse_dom; @@ -50,9 +50,9 @@ pub fn borrowed_flow_to_unsafe_flow(flow: &Flow) -> UnsafeFlow { } pub type ChunkedFlowTraversalFunction<'scope> = - extern "Rust" fn(Box<[UnsafeFlow]>, &'scope SharedLayoutContext, &rayon::Scope<'scope>); + extern "Rust" fn(Box<[UnsafeFlow]>, &rayon::Scope<'scope>, &'scope SharedLayoutContext); -pub type FlowTraversalFunction = extern "Rust" fn(UnsafeFlow, &SharedLayoutContext); +pub type FlowTraversalFunction = extern "Rust" fn(UnsafeFlow, &LayoutContext); /// Information that we need stored in each flow. pub struct FlowParallelInfo { @@ -132,20 +132,22 @@ trait ParallelPostorderFlowTraversal : PostorderFlowTraversal { trait ParallelPreorderFlowTraversal : PreorderFlowTraversal { fn run_parallel<'scope>(&self, unsafe_flows: &[UnsafeFlow], - layout_context: &'scope SharedLayoutContext, - scope: &rayon::Scope<'scope>); + scope: &rayon::Scope<'scope>, + shared: &'scope SharedLayoutContext); fn should_record_thread_ids(&self) -> bool; #[inline(always)] fn run_parallel_helper<'scope>(&self, unsafe_flows: &[UnsafeFlow], - layout_context: &'scope SharedLayoutContext, scope: &rayon::Scope<'scope>, + shared: &'scope SharedLayoutContext, top_down_func: ChunkedFlowTraversalFunction<'scope>, bottom_up_func: FlowTraversalFunction) { let mut discovered_child_flows = vec![]; + let context = LayoutContext::new(&shared); + for unsafe_flow in unsafe_flows { let mut had_children = false; unsafe { @@ -175,7 +177,7 @@ trait ParallelPreorderFlowTraversal : PreorderFlowTraversal { // If there were no more children, start assigning block-sizes. if !had_children { - bottom_up_func(*unsafe_flow, layout_context) + bottom_up_func(*unsafe_flow, &context) } } @@ -183,7 +185,7 @@ trait ParallelPreorderFlowTraversal : PreorderFlowTraversal { let nodes = chunk.iter().cloned().collect::<Vec<_>>().into_boxed_slice(); scope.spawn(move |scope| { - top_down_func(nodes, layout_context, scope); + top_down_func(nodes, scope, shared); }); } } @@ -192,12 +194,12 @@ trait ParallelPreorderFlowTraversal : PreorderFlowTraversal { impl<'a> ParallelPreorderFlowTraversal for AssignISizes<'a> { fn run_parallel<'scope>(&self, unsafe_flows: &[UnsafeFlow], - layout_context: &'scope SharedLayoutContext, - scope: &rayon::Scope<'scope>) + scope: &rayon::Scope<'scope>, + shared: &'scope SharedLayoutContext) { self.run_parallel_helper(unsafe_flows, - layout_context, scope, + shared, assign_inline_sizes, assign_block_sizes_and_store_overflow) } @@ -210,20 +212,19 @@ impl<'a> ParallelPreorderFlowTraversal for AssignISizes<'a> { impl<'a> ParallelPostorderFlowTraversal for AssignBSizes<'a> {} fn assign_inline_sizes<'scope>(unsafe_flows: Box<[UnsafeFlow]>, - shared_layout_context: &'scope SharedLayoutContext, - scope: &rayon::Scope<'scope>) { + scope: &rayon::Scope<'scope>, + shared: &'scope SharedLayoutContext) { let assign_inline_sizes_traversal = AssignISizes { - shared_context: &shared_layout_context.style_context, + shared_context: &shared.style_context, }; - assign_inline_sizes_traversal.run_parallel(&unsafe_flows, shared_layout_context, scope) + assign_inline_sizes_traversal.run_parallel(&unsafe_flows, scope, shared) } fn assign_block_sizes_and_store_overflow( unsafe_flow: UnsafeFlow, - shared_layout_context: &SharedLayoutContext) { - let layout_context = LayoutContext::new(shared_layout_context); + context: &LayoutContext) { let assign_block_sizes_traversal = AssignBSizes { - layout_context: &layout_context, + layout_context: context, }; assign_block_sizes_traversal.run_parallel(unsafe_flow) } @@ -232,11 +233,11 @@ pub fn traverse_flow_tree_preorder( root: &mut Flow, profiler_metadata: Option<TimerMetadata>, time_profiler_chan: time::ProfilerChan, - shared_layout_context: &SharedLayoutContext, + shared: &SharedLayoutContext, queue: &rayon::ThreadPool) { if opts::get().bubble_inline_sizes_separately { - let layout_context = LayoutContext::new(shared_layout_context); - let bubble_inline_sizes = BubbleISizes { layout_context: &layout_context }; + let context = LayoutContext::new(shared); + let bubble_inline_sizes = BubbleISizes { layout_context: &context }; root.traverse_postorder(&bubble_inline_sizes); } @@ -246,7 +247,7 @@ pub fn traverse_flow_tree_preorder( rayon::scope(move |scope| { profile(time::ProfilerCategory::LayoutParallelWarmup, profiler_metadata, time_profiler_chan, move || { - assign_inline_sizes(nodes, &shared_layout_context, scope); + assign_inline_sizes(nodes, scope, &shared); }); }); }); diff --git a/components/layout/query.rs b/components/layout/query.rs index 765cd2bdab4..0a44a9b1b49 100644 --- a/components/layout/query.rs +++ b/components/layout/query.rs @@ -6,6 +6,7 @@ use app_units::Au; use construct::ConstructionResult; +use context::{ScopedThreadLocalLayoutContext, SharedLayoutContext}; use euclid::point::Point2D; use euclid::rect::Rect; use euclid::size::Size2D; @@ -24,7 +25,6 @@ use script_layout_interface::wrapper_traits::{LayoutNode, ThreadSafeLayoutElemen use script_traits::LayoutMsg as ConstellationMsg; use script_traits::UntrustedNodeAddress; use sequential; -use servo_atoms::Atom; use std::cmp::{min, max}; use std::ops::Deref; use std::sync::{Arc, Mutex}; @@ -32,8 +32,8 @@ use style::computed_values; use style::context::StyleContext; use style::dom::TElement; use style::logical_geometry::{WritingMode, BlockFlowDirection, InlineBaseDirection}; +use style::properties::{style_structs, PropertyId, PropertyDeclarationId, LonghandId}; use style::properties::longhands::{display, position}; -use style::properties::style_structs; use style::selector_parser::PseudoElement; use style::stylist::Stylist; use style_traits::ToCss; @@ -75,7 +75,7 @@ pub struct LayoutThreadData { pub scroll_area_response: Rect<i32>, /// A queued response for the resolved style property of an element. - pub resolved_style_response: Option<String>, + pub resolved_style_response: String, /// A queued response for the offset parent/rect of a node. pub offset_parent_response: OffsetParentResponse, @@ -625,13 +625,12 @@ pub fn process_node_scroll_area_request< N: LayoutNode>(requested_node: N, layou /// Return the resolved value of property for a given (pseudo)element. /// https://drafts.csswg.org/cssom/#resolved-value -pub fn process_resolved_style_request<'a, N, C>(requested_node: N, - style_context: &'a C, - pseudo: &Option<PseudoElement>, - property: &Atom, - layout_root: &mut Flow) -> Option<String> +pub fn process_resolved_style_request<'a, N>(shared: &SharedLayoutContext, + requested_node: N, + pseudo: &Option<PseudoElement>, + property: &PropertyId, + layout_root: &mut Flow) -> String where N: LayoutNode, - C: StyleContext<'a> { use style::traversal::{clear_descendant_data, style_element_in_display_none_subtree}; let element = requested_node.as_element().unwrap(); @@ -646,8 +645,14 @@ pub fn process_resolved_style_request<'a, N, C>(requested_node: N, // we'd need a mechanism to prevent detect when it's stale (since we don't // traverse display:none subtrees during restyle). let display_none_root = if element.get_data().is_none() { - Some(style_element_in_display_none_subtree(element, &|e| e.as_node().initialize_data(), - style_context)) + let mut tlc = ScopedThreadLocalLayoutContext::new(shared); + let context = StyleContext { + shared: &shared.style_context, + thread_local: &mut tlc.style_context, + }; + + Some(style_element_in_display_none_subtree(&context, element, + &|e| e.as_node().initialize_data())) } else { None }; @@ -667,13 +672,25 @@ pub fn process_resolved_style_request<'a, N, C>(requested_node: N, // The pseudo doesn't exist, return nothing. Chrome seems to query // the element itself in this case, Firefox uses the resolved value. // https://www.w3.org/Bugs/Public/show_bug.cgi?id=29006 - return None; + return String::new(); } Some(layout_el) => layout_el }; let style = &*layout_el.resolved_style(); + let longhand_id = match *property { + PropertyId::Longhand(id) => id, + + // Firefox returns blank strings for the computed value of shorthands, + // so this should be web-compatible. + PropertyId::Shorthand(_) => return String::new(), + + PropertyId::Custom(ref name) => { + return style.computed_value_to_string(PropertyDeclarationId::Custom(name)) + } + }; + // Clear any temporarily-resolved data to maintain our invariants. See the comment // at the top of this function. display_none_root.map(|r| clear_descendant_data(r, &|e| e.as_node().clear_data())); @@ -697,7 +714,7 @@ pub fn process_resolved_style_request<'a, N, C>(requested_node: N, layout_el: <N::ConcreteThreadSafeLayoutNode as ThreadSafeLayoutNode>::ConcreteThreadSafeLayoutElement, layout_root: &mut Flow, requested_node: N, - property: &Atom) -> Option<String> { + longhand_id: LonghandId) -> String { let maybe_data = layout_el.borrow_layout_data(); let position = maybe_data.map_or(Point2D::zero(), |data| { match (*data).flow_construction_result { @@ -708,13 +725,13 @@ pub fn process_resolved_style_request<'a, N, C>(requested_node: N, _ => Point2D::zero() } }); - let property = match *property { - atom!("bottom") => PositionProperty::Bottom, - atom!("top") => PositionProperty::Top, - atom!("left") => PositionProperty::Left, - atom!("right") => PositionProperty::Right, - atom!("width") => PositionProperty::Width, - atom!("height") => PositionProperty::Height, + let property = match longhand_id { + LonghandId::Bottom => PositionProperty::Bottom, + LonghandId::Top => PositionProperty::Top, + LonghandId::Left => PositionProperty::Left, + LonghandId::Right => PositionProperty::Right, + LonghandId::Width => PositionProperty::Width, + LonghandId::Height => PositionProperty::Height, _ => unreachable!() }; let mut iterator = @@ -723,27 +740,25 @@ pub fn process_resolved_style_request<'a, N, C>(requested_node: N, position); sequential::iterate_through_flow_tree_fragment_border_boxes(layout_root, &mut iterator); - iterator.result.map(|r| r.to_css_string()) + iterator.result.map(|r| r.to_css_string()).unwrap_or(String::new()) } // TODO: we will return neither the computed nor used value for margin and padding. - // Firefox returns blank strings for the computed value of shorthands, - // so this should be web-compatible. - match *property { - atom!("margin-bottom") | atom!("margin-top") | - atom!("margin-left") | atom!("margin-right") | - atom!("padding-bottom") | atom!("padding-top") | - atom!("padding-left") | atom!("padding-right") + match longhand_id { + LonghandId::MarginBottom | LonghandId::MarginTop | + LonghandId::MarginLeft | LonghandId::MarginRight | + LonghandId::PaddingBottom | LonghandId::PaddingTop | + LonghandId::PaddingLeft | LonghandId::PaddingRight if applies && style.get_box().display != display::computed_value::T::none => { - let (margin_padding, side) = match *property { - atom!("margin-bottom") => (MarginPadding::Margin, Side::Bottom), - atom!("margin-top") => (MarginPadding::Margin, Side::Top), - atom!("margin-left") => (MarginPadding::Margin, Side::Left), - atom!("margin-right") => (MarginPadding::Margin, Side::Right), - atom!("padding-bottom") => (MarginPadding::Padding, Side::Bottom), - atom!("padding-top") => (MarginPadding::Padding, Side::Top), - atom!("padding-left") => (MarginPadding::Padding, Side::Left), - atom!("padding-right") => (MarginPadding::Padding, Side::Right), + let (margin_padding, side) = match longhand_id { + LonghandId::MarginBottom => (MarginPadding::Margin, Side::Bottom), + LonghandId::MarginTop => (MarginPadding::Margin, Side::Top), + LonghandId::MarginLeft => (MarginPadding::Margin, Side::Left), + LonghandId::MarginRight => (MarginPadding::Margin, Side::Right), + LonghandId::PaddingBottom => (MarginPadding::Padding, Side::Bottom), + LonghandId::PaddingTop => (MarginPadding::Padding, Side::Top), + LonghandId::PaddingLeft => (MarginPadding::Padding, Side::Left), + LonghandId::PaddingRight => (MarginPadding::Padding, Side::Right), _ => unreachable!() }; let mut iterator = @@ -753,23 +768,22 @@ pub fn process_resolved_style_request<'a, N, C>(requested_node: N, style.writing_mode); sequential::iterate_through_flow_tree_fragment_border_boxes(layout_root, &mut iterator); - iterator.result.map(|r| r.to_css_string()) + iterator.result.map(|r| r.to_css_string()).unwrap_or(String::new()) }, - atom!("bottom") | atom!("top") | atom!("right") | - atom!("left") + LonghandId::Bottom | LonghandId::Top | LonghandId::Right | LonghandId::Left if applies && positioned && style.get_box().display != display::computed_value::T::none => { - used_value_for_position_property(layout_el, layout_root, requested_node, property) + used_value_for_position_property(layout_el, layout_root, requested_node, longhand_id) } - atom!("width") | atom!("height") + LonghandId::Width | LonghandId::Height if applies && style.get_box().display != display::computed_value::T::none => { - used_value_for_position_property(layout_el, layout_root, requested_node, property) + used_value_for_position_property(layout_el, layout_root, requested_node, longhand_id) } // FIXME: implement used value computation for line-height - ref property => { - style.computed_value_to_string(&*property).ok() + _ => { + style.computed_value_to_string(PropertyDeclarationId::Longhand(longhand_id)) } } } diff --git a/components/layout/sequential.rs b/components/layout/sequential.rs index 71626243206..b8c62aaafb0 100644 --- a/components/layout/sequential.rs +++ b/components/layout/sequential.rs @@ -15,14 +15,13 @@ use flow::IS_ABSOLUTELY_POSITIONED; use fragment::FragmentBorderBoxIterator; use generated_content::ResolveGeneratedContent; use gfx_traits::ScrollRootId; -use style::context::StyleContext; +use servo_config::opts; use style::servo::restyle_damage::{REFLOW, STORE_OVERFLOW}; use traversal::{AssignBSizes, AssignISizes, BubbleISizes, BuildDisplayList}; -use util::opts; pub use style::sequential::traverse_dom; -pub fn resolve_generated_content(root: &mut Flow, shared_layout_context: &SharedLayoutContext) { +pub fn resolve_generated_content(root: &mut Flow, shared: &SharedLayoutContext) { fn doit(flow: &mut Flow, level: u32, traversal: &mut ResolveGeneratedContent) { if !traversal.should_process(flow) { return @@ -35,13 +34,13 @@ pub fn resolve_generated_content(root: &mut Flow, shared_layout_context: &Shared } } - let layout_context = LayoutContext::new(shared_layout_context); + let layout_context = LayoutContext::new(shared); let mut traversal = ResolveGeneratedContent::new(&layout_context); doit(root, 0, &mut traversal) } pub fn traverse_flow_tree_preorder(root: &mut Flow, - shared_layout_context: &SharedLayoutContext) { + shared: &SharedLayoutContext) { fn doit(flow: &mut Flow, assign_inline_sizes: AssignISizes, assign_block_sizes: AssignBSizes) { @@ -58,7 +57,7 @@ pub fn traverse_flow_tree_preorder(root: &mut Flow, } } - let layout_context = LayoutContext::new(shared_layout_context); + let layout_context = LayoutContext::new(shared); if opts::get().bubble_inline_sizes_separately { let bubble_inline_sizes = BubbleISizes { layout_context: &layout_context }; diff --git a/components/layout/traversal.rs b/components/layout/traversal.rs index e20d3ab98ef..b3672ecf32c 100644 --- a/components/layout/traversal.rs +++ b/components/layout/traversal.rs @@ -5,102 +5,83 @@ //! Traversals over the DOM and flow trees, running the layout computations. use construct::FlowConstructor; -use context::{LayoutContext, SharedLayoutContext}; +use context::{LayoutContext, ScopedThreadLocalLayoutContext, SharedLayoutContext}; use display_list_builder::DisplayListBuildState; use flow::{self, PreorderFlowTraversal}; use flow::{CAN_BE_FRAGMENTED, Flow, ImmutableFlowUtils, PostorderFlowTraversal}; -use gfx::display_list::OpaqueNode; use script_layout_interface::wrapper_traits::{LayoutNode, ThreadSafeLayoutNode}; -use std::mem; +use servo_config::opts; use style::atomic_refcell::AtomicRefCell; -use style::context::{LocalStyleContext, SharedStyleContext, StyleContext}; +use style::context::{SharedStyleContext, StyleContext}; use style::data::ElementData; -use style::dom::{StylingMode, TElement, TNode}; +use style::dom::{TElement, TNode}; use style::selector_parser::RestyleDamage; use style::servo::restyle_damage::{BUBBLE_ISIZES, REFLOW, REFLOW_OUT_OF_FLOW, REPAINT}; -use style::traversal::{DomTraversalContext, recalc_style_at, remove_from_bloom_filter}; +use style::traversal::{DomTraversal, recalc_style_at}; use style::traversal::PerLevelTraversalData; -use util::opts; use wrapper::{GetRawData, LayoutNodeHelpers, LayoutNodeLayoutData}; -pub struct RecalcStyleAndConstructFlows<'lc> { - context: LayoutContext<'lc>, - root: OpaqueNode, +pub struct RecalcStyleAndConstructFlows { + shared: SharedLayoutContext, } -#[allow(unsafe_code)] -impl<'lc, N> DomTraversalContext<N> for RecalcStyleAndConstructFlows<'lc> - where N: LayoutNode + TNode, - N::ConcreteElement: TElement +impl RecalcStyleAndConstructFlows { + pub fn shared_layout_context(&self) -> &SharedLayoutContext { + &self.shared + } +} -{ - type SharedContext = SharedLayoutContext; - #[allow(unsafe_code)] - fn new<'a>(shared: &'a Self::SharedContext, root: OpaqueNode) -> Self { - // FIXME(bholley): This transmutation from &'a to &'lc is very unfortunate, but I haven't - // found a way to avoid it despite spending several days on it (and consulting Manishearth, - // brson, and nmatsakis). - // - // The crux of the problem is that parameterizing DomTraversalContext on the lifetime of - // the SharedContext doesn't work for a variety of reasons [1]. However, the code in - // parallel.rs needs to be able to use the DomTraversalContext trait (or something similar) - // to stack-allocate a struct (a generalized LayoutContext<'a>) that holds a borrowed - // SharedContext, which means that the struct needs to be parameterized on a lifetime. - // Given the aforementioned constraint, the only way to accomplish this is to avoid - // propagating the borrow lifetime from the struct to the trait, but that means that the - // new() method on the trait cannot require the lifetime of its argument to match the - // lifetime of the Self object it creates. - // - // This could be solved with an associated type with an unbound lifetime parameter, but - // that would require higher-kinded types, which don't exist yet and probably aren't coming - // for a while. - // - // So we transmute. :-( This is safe because the DomTravesalContext is stack-allocated on - // the worker thread while processing a WorkUnit, whereas the borrowed SharedContext is - // live for the entire duration of the restyle. This really could _almost_ compile: all - // we'd need to do is change the signature to to |new<'a: 'lc>|, and everything would - // work great. But we can't do that, because that would cause a mismatch with the signature - // in the trait we're implementing, and we can't mention 'lc in that trait at all for the - // reasons described above. - // - // [1] For example, the WorkQueue type needs to be parameterized on the concrete type of - // DomTraversalContext::SharedContext, and the WorkQueue lifetime is similar to that of the - // LayoutThread, generally much longer than that of a given SharedLayoutContext borrow. - let shared_lc: &'lc SharedLayoutContext = unsafe { mem::transmute(shared) }; +impl RecalcStyleAndConstructFlows { + /// Creates a traversal context, taking ownership of the shared layout context. + pub fn new(shared: SharedLayoutContext) -> Self { RecalcStyleAndConstructFlows { - context: LayoutContext::new(shared_lc), - root: root, + shared: shared, } } - fn process_preorder(&self, node: N, data: &mut PerLevelTraversalData) { + /// Consumes this traversal context, returning ownership of the shared layout + /// context to the caller. + pub fn destroy(self) -> SharedLayoutContext { + self.shared + } +} + +#[allow(unsafe_code)] +impl<N> DomTraversal<N> for RecalcStyleAndConstructFlows + where N: LayoutNode + TNode, + N::ConcreteElement: TElement +{ + type ThreadLocalContext = ScopedThreadLocalLayoutContext<N::ConcreteElement>; + + fn process_preorder(&self, traversal_data: &mut PerLevelTraversalData, + thread_local: &mut Self::ThreadLocalContext, node: N) { // FIXME(pcwalton): Stop allocating here. Ideally this should just be // done by the HTML parser. node.initialize_data(); if !node.is_text_node() { let el = node.as_element().unwrap(); - recalc_style_at::<_, _, Self>(&self.context, data, el); + let mut data = el.mutate_data().unwrap(); + let mut context = StyleContext { + shared: &self.shared.style_context, + thread_local: &mut thread_local.style_context, + }; + recalc_style_at(self, traversal_data, &mut context, el, &mut data); } } - fn process_postorder(&self, node: N) { - construct_flows_at(&self.context, self.root, node); + fn process_postorder(&self, thread_local: &mut Self::ThreadLocalContext, node: N) { + let context = LayoutContext::new(&self.shared); + construct_flows_at(&context, thread_local, node); } - fn should_traverse_child(child: N) -> bool { - match child.as_element() { - // Elements should be traversed if they need styling or flow construction. - Some(el) => el.styling_mode() != StylingMode::Stop || - el.as_node().to_threadsafe().restyle_damage() != RestyleDamage::empty(), - - // Text nodes never need styling. However, there are two cases they may need - // flow construction: - // (1) They child doesn't yet have layout data (preorder traversal initializes it). - // (2) The parent element has restyle damage (so the text flow also needs fixup). - None => child.get_raw_data().is_none() || - child.parent_node().unwrap().to_threadsafe().restyle_damage() != RestyleDamage::empty(), - } + fn text_node_needs_traversal(node: N) -> bool { + // Text nodes never need styling. However, there are two cases they may need + // flow construction: + // (1) They child doesn't yet have layout data (preorder traversal initializes it). + // (2) The parent element has restyle damage (so the text flow also needs fixup). + node.get_raw_data().is_none() || + node.parent_node().unwrap().to_threadsafe().restyle_damage() != RestyleDamage::empty() } unsafe fn ensure_element_data(element: &N::ConcreteElement) -> &AtomicRefCell<ElementData> { @@ -112,8 +93,12 @@ impl<'lc, N> DomTraversalContext<N> for RecalcStyleAndConstructFlows<'lc> element.as_node().clear_data(); } - fn local_context(&self) -> &LocalStyleContext { - self.context.local_context() + fn shared_context(&self) -> &SharedStyleContext { + &self.shared.style_context + } + + fn create_thread_local_context(&self) -> Self::ThreadLocalContext { + ScopedThreadLocalLayoutContext::new(&self.shared) } } @@ -126,7 +111,11 @@ pub trait PostorderNodeMutTraversal<ConcreteThreadSafeLayoutNode: ThreadSafeLayo /// The flow construction traversal, which builds flows for styled nodes. #[inline] #[allow(unsafe_code)] -fn construct_flows_at<'a, N: LayoutNode>(context: &'a LayoutContext<'a>, root: OpaqueNode, node: N) { +fn construct_flows_at<'a, N>(context: &LayoutContext<'a>, + _thread_local: &mut ScopedThreadLocalLayoutContext<N::ConcreteElement>, + node: N) + where N: LayoutNode, +{ debug!("construct_flows_at: {:?}", node); // Construct flows for this node. @@ -150,8 +139,6 @@ fn construct_flows_at<'a, N: LayoutNode>(context: &'a LayoutContext<'a>, root: O if let Some(el) = node.as_element() { el.mutate_data().unwrap().persist(); unsafe { el.unset_dirty_descendants(); } - - remove_from_bloom_filter(context, root, el); } } diff --git a/components/layout/webrender_helpers.rs b/components/layout/webrender_helpers.rs index 69d3de29e72..0887e7d4b0c 100644 --- a/components/layout/webrender_helpers.rs +++ b/components/layout/webrender_helpers.rs @@ -16,7 +16,7 @@ use msg::constellation_msg::PipelineId; use style::computed_values::{image_rendering, mix_blend_mode}; use style::computed_values::filter::{self, Filter}; use style::values::computed::BorderStyle; -use webrender_traits::{self, DisplayListBuilder}; +use webrender_traits::{self, DisplayListBuilder, LayoutTransform}; pub trait WebRenderDisplayListConverter { fn convert_to_webrender(&self, pipeline_id: PipelineId) -> DisplayListBuilder; @@ -61,36 +61,38 @@ impl ToBoxShadowClipMode for BoxShadowClipMode { } trait ToSizeF { - fn to_sizef(&self) -> Size2D<f32>; + fn to_sizef(&self) -> webrender_traits::LayoutSize; } trait ToPointF { - fn to_pointf(&self) -> Point2D<f32>; + fn to_pointf(&self) -> webrender_traits::LayoutPoint; } impl ToPointF for Point2D<Au> { - fn to_pointf(&self) -> Point2D<f32> { - Point2D::new(self.x.to_f32_px(), self.y.to_f32_px()) + fn to_pointf(&self) -> webrender_traits::LayoutPoint { + webrender_traits::LayoutPoint::new(self.x.to_f32_px(), self.y.to_f32_px()) } } impl ToSizeF for Size2D<Au> { - fn to_sizef(&self) -> Size2D<f32> { - Size2D::new(self.width.to_f32_px(), self.height.to_f32_px()) + fn to_sizef(&self) -> webrender_traits::LayoutSize { + webrender_traits::LayoutSize::new(self.width.to_f32_px(), self.height.to_f32_px()) } } trait ToRectF { - fn to_rectf(&self) -> Rect<f32>; + fn to_rectf(&self) -> webrender_traits::LayoutRect; } impl ToRectF for Rect<Au> { - fn to_rectf(&self) -> Rect<f32> { + fn to_rectf(&self) -> webrender_traits::LayoutRect { let x = self.origin.x.to_f32_px(); let y = self.origin.y.to_f32_px(); let w = self.size.width.to_f32_px(); let h = self.size.height.to_f32_px(); - Rect::new(Point2D::new(x, y), Size2D::new(w, h)) + let point = webrender_traits::LayoutPoint::new(x, y); + let size = webrender_traits::LayoutSize::new(w, h); + webrender_traits::LayoutRect::new(point, size) } } @@ -340,12 +342,16 @@ impl WebRenderDisplayItemConverter for DisplayItem { ScrollPolicy::FixedPosition => webrender_traits::ScrollPolicy::Fixed, }; + let clip = builder.new_clip_region(&stacking_context.overflow.to_rectf(), + vec![], + None); + builder.push_stacking_context(webrender_scroll_policy, stacking_context.bounds.to_rectf(), - stacking_context.overflow.to_rectf(), + clip, stacking_context.z_index, - &stacking_context.transform, - &stacking_context.perspective, + &LayoutTransform::from_untyped(&stacking_context.transform), + &LayoutTransform::from_untyped(&stacking_context.perspective), stacking_context.blend_mode.to_blend_mode(), stacking_context.filters.to_filter_ops()); } diff --git a/components/layout_thread/Cargo.toml b/components/layout_thread/Cargo.toml index 3f750cf70fa..d99a52061fb 100644 --- a/components/layout_thread/Cargo.toml +++ b/components/layout_thread/Cargo.toml @@ -27,16 +27,17 @@ net_traits = {path = "../net_traits"} parking_lot = {version = "0.3.3", features = ["nightly"]} plugins = {path = "../plugins"} profile_traits = {path = "../profile_traits"} -rayon = "0.5" +rayon = "0.6" script = {path = "../script"} script_layout_interface = {path = "../script_layout_interface"} script_traits = {path = "../script_traits"} selectors = "0.15" serde_derive = "0.8" serde_json = "0.8" +servo_config = {path = "../config"} +servo_geometry = {path = "../geometry"} servo_url = {path = "../url"} style = {path = "../style"} -util = {path = "../util"} [dependencies.webrender_traits] git = "https://github.com/servo/webrender" diff --git a/components/layout_thread/lib.rs b/components/layout_thread/lib.rs index 04f35183ff4..f9f4c371a94 100644 --- a/components/layout_thread/lib.rs +++ b/components/layout_thread/lib.rs @@ -40,9 +40,10 @@ extern crate script_layout_interface; extern crate script_traits; extern crate selectors; extern crate serde_json; +extern crate servo_config; +extern crate servo_geometry; extern crate servo_url; extern crate style; -extern crate util; extern crate webrender_traits; use app_units::Au; @@ -62,7 +63,8 @@ use ipc_channel::ipc::{self, IpcReceiver, IpcSender}; use ipc_channel::router::ROUTER; use layout::animation; use layout::construct::ConstructionResult; -use layout::context::{LayoutContext, SharedLayoutContext, heap_size_of_local_context}; +use layout::context::{LayoutContext, SharedLayoutContext}; +use layout::context::heap_size_of_persistent_local_context; use layout::display_list_builder::ToGfxColor; use layout::flow::{self, Flow, ImmutableFlowUtils, MutableFlowUtils, MutableOwnedFlowUtils}; use layout::flow_ref::FlowRef; @@ -94,6 +96,10 @@ use script_layout_interface::wrapper_traits::LayoutNode; use script_traits::{ConstellationControlMsg, LayoutControlMsg, LayoutMsg as ConstellationMsg}; use script_traits::{StackingContextScrollState, UntrustedNodeAddress}; use selectors::Element; +use servo_config::opts; +use servo_config::prefs::PREFS; +use servo_config::resource_files::read_resource_file; +use servo_geometry::max_rect; use servo_url::ServoUrl; use std::borrow::ToOwned; use std::collections::HashMap; @@ -103,10 +109,11 @@ use std::process; use std::sync::{Arc, Mutex, MutexGuard}; use std::sync::atomic::{AtomicUsize, Ordering}; use std::sync::mpsc::{Receiver, Sender, channel}; +use std::thread; use style::animation::Animation; -use style::context::{LocalStyleContextCreationInfo, ReflowGoal, SharedStyleContext}; +use style::context::{QuirksMode, ReflowGoal, SharedStyleContext, ThreadLocalStyleContextCreationInfo}; use style::data::StoredRestyleHint; -use style::dom::{StylingMode, TElement, TNode}; +use style::dom::{ShowSubtree, ShowSubtreeDataAndPrimaryValues, TElement, TNode}; use style::error_reporting::{ParseErrorReporter, StdoutErrorReporter}; use style::logical_geometry::LogicalPoint; use style::media_queries::{Device, MediaType}; @@ -116,11 +123,7 @@ use style::stylesheets::{Origin, Stylesheet, UserAgentStylesheets}; use style::stylist::Stylist; use style::thread_state; use style::timer::Timer; -use util::geometry::max_rect; -use util::opts; -use util::prefs::PREFS; -use util::resource_files::read_resource_file; -use util::thread; +use style::traversal::DomTraversal; /// Information needed by the layout thread. pub struct LayoutThread { @@ -228,9 +231,12 @@ pub struct LayoutThread { /// only be a test-mode timer during testing for animations. timer: Timer, - // Number of layout threads. This is copied from `util::opts`, but we'd + // Number of layout threads. This is copied from `servo_config::opts`, but we'd // rather limit the dependency on that module here. layout_threads: usize, + + /// Which quirks mode are we rendering the document in? + quirks_mode: Option<QuirksMode> } impl LayoutThreadFactory for LayoutThread { @@ -252,8 +258,7 @@ impl LayoutThreadFactory for LayoutThread { content_process_shutdown_chan: Option<IpcSender<()>>, webrender_api_sender: webrender_traits::RenderApiSender, layout_threads: usize) { - thread::spawn_named(format!("LayoutThread {:?}", id), - move || { + thread::Builder::new().name(format!("LayoutThread {:?}", id)).spawn(move || { thread_state::initialize(thread_state::LAYOUT); if let Some(top_level_frame_id) = top_level_frame_id { @@ -284,7 +289,7 @@ impl LayoutThreadFactory for LayoutThread { if let Some(content_process_shutdown_chan) = content_process_shutdown_chan { let _ = content_process_shutdown_chan.send(()); } - }); + }).expect("Thread spawning failed"); } } @@ -465,7 +470,7 @@ impl LayoutThread { scroll_root_id_response: None, scroll_area_response: Rect::zero(), overflow_response: NodeOverflowResponse(None), - resolved_style_response: None, + resolved_style_response: String::new(), offset_parent_response: OffsetParentResponse::empty(), margin_style_response: MarginStyleResponse::empty(), stacking_context_scroll_offsets: HashMap::new(), @@ -484,6 +489,7 @@ impl LayoutThread { Timer::new() }, layout_threads: layout_threads, + quirks_mode: None, } } @@ -506,20 +512,21 @@ impl LayoutThread { screen_size_changed: bool, goal: ReflowGoal) -> SharedLayoutContext { - let local_style_context_creation_data = LocalStyleContextCreationInfo::new(self.new_animations_sender.clone()); + let thread_local_style_context_creation_data = + ThreadLocalStyleContextCreationInfo::new(self.new_animations_sender.clone()); SharedLayoutContext { style_context: SharedStyleContext { viewport_size: self.viewport_size.clone(), screen_size_changed: screen_size_changed, stylist: rw_data.stylist.clone(), - generation: self.generation, goal: goal, running_animations: self.running_animations.clone(), expired_animations: self.expired_animations.clone(), error_reporter: self.error_reporter.clone(), - local_context_creation_data: Mutex::new(local_style_context_creation_data), + local_context_creation_data: Mutex::new(thread_local_style_context_creation_data), timer: self.timer.clone(), + quirks_mode: self.quirks_mode.unwrap(), }, image_cache_thread: Mutex::new(self.image_cache_thread.clone()), image_cache_sender: Mutex::new(self.image_cache_sender.clone()), @@ -716,11 +723,11 @@ impl LayoutThread { size: stylist.heap_size_of_children(), }); - // The LayoutThread has a context in TLS... + // The LayoutThread has data in Persistent TLS... reports.push(Report { path: path![formatted_url, "layout-thread", "local-context"], kind: ReportKind::ExplicitJemallocHeapSize, - size: heap_size_of_local_context(), + size: heap_size_of_persistent_local_context(), }); reports_chan.send(reports); @@ -960,8 +967,9 @@ impl LayoutThread { self.epoch.next(); let Epoch(epoch_number) = self.epoch; + let viewport_size = webrender_traits::LayoutSize::from_untyped(&viewport_size); self.webrender_api.set_root_display_list( - get_root_flow_background_color(layout_root), + Some(get_root_flow_background_color(layout_root)), webrender_traits::Epoch(epoch_number), viewport_size, builder); @@ -974,6 +982,7 @@ impl LayoutThread { possibly_locked_rw_data: &mut RwData<'a, 'b>) { let document = unsafe { ServoLayoutNode::new(&data.document) }; let document = document.as_document().unwrap(); + self.quirks_mode = Some(document.quirks_mode()); // FIXME(pcwalton): Combine `ReflowGoal` and `ReflowQueryType`. Then remove this assert. debug_assert!((data.reflow_info.goal == ReflowGoal::ForDisplay && @@ -1017,7 +1026,7 @@ impl LayoutThread { rw_data.scroll_root_id_response = None; }, ReflowQueryType::ResolvedStyleQuery(_, _, _) => { - rw_data.resolved_style_response = None; + rw_data.resolved_style_response = String::new(); }, ReflowQueryType::OffsetParentQuery(_) => { rw_data.offset_parent_response = OffsetParentResponse::empty(); @@ -1034,9 +1043,7 @@ impl LayoutThread { debug!("layout: processing reflow request for: {:?} ({}) (query={:?})", element, self.url, data.query_type); - if log_enabled!(log::LogLevel::Debug) { - element.as_node().dump(); - } + debug!("{:?}", ShowSubtree(element.as_node())); let initial_viewport = data.window_size.initial_viewport; let old_viewport_size = self.viewport_size; @@ -1122,7 +1129,7 @@ impl LayoutThread { None => continue, }; let mut style_data = &mut data.base.style_data; - debug_assert!(!style_data.is_restyle()); + debug_assert!(style_data.has_current_styles()); let mut restyle_data = match style_data.restyle() { Some(d) => d, None => continue, @@ -1131,7 +1138,9 @@ impl LayoutThread { // Stash the data on the element for processing by the style system. restyle_data.hint = restyle.hint.into(); restyle_data.damage = restyle.damage; - restyle_data.snapshot = restyle.snapshot; + if let Some(s) = restyle.snapshot { + restyle_data.snapshot.ensure(move || s); + } debug!("Noting restyle for {:?}: {:?}", el, restyle_data); } } @@ -1141,22 +1150,31 @@ impl LayoutThread { viewport_size_changed, data.reflow_info.goal); + // NB: Type inference falls apart here for some reason, so we need to be very verbose. :-( + let traversal = RecalcStyleAndConstructFlows::new(shared_layout_context); let dom_depth = Some(0); // This is always the root node. - if element.styling_mode() != StylingMode::Stop { + let token = { + let stylist = &<RecalcStyleAndConstructFlows as + DomTraversal<ServoLayoutNode>>::shared_context(&traversal).stylist; + <RecalcStyleAndConstructFlows as + DomTraversal<ServoLayoutNode>>::pre_traverse(element, stylist, /* skip_root = */ false) + }; + + if token.should_traverse() { // Recalculate CSS styles and rebuild flows and fragments. profile(time::ProfilerCategory::LayoutStyleRecalc, self.profiler_metadata(), self.time_profiler_chan.clone(), || { // Perform CSS selector matching and flow construction. - if let (true, Some(traversal)) = (self.parallel_flag, self.parallel_traversal.as_mut()) { + if let (true, Some(pool)) = (self.parallel_flag, self.parallel_traversal.as_mut()) { // Parallel mode parallel::traverse_dom::<ServoLayoutNode, RecalcStyleAndConstructFlows>( - element.as_node(), dom_depth, &shared_layout_context, traversal); + &traversal, element, dom_depth, token, pool); } else { // Sequential mode sequential::traverse_dom::<ServoLayoutNode, RecalcStyleAndConstructFlows>( - element.as_node(), &shared_layout_context); + &traversal, element, token); } }); // TODO(pcwalton): Measure energy usage of text shaping, perhaps? @@ -1175,8 +1193,10 @@ impl LayoutThread { self.root_flow = self.try_get_layout_root(element.as_node()); } + shared_layout_context = traversal.destroy(); + if opts::get().dump_style_tree { - element.as_node().dump_style(); + println!("{:?}", ShowSubtreeDataAndPrimaryValues(element.as_node())); } if opts::get().dump_rule_tree { @@ -1201,7 +1221,7 @@ impl LayoutThread { fn respond_to_query_if_necessary(&mut self, query_type: &ReflowQueryType, rw_data: &mut LayoutThreadData, - shared_layout_context: &mut SharedLayoutContext) { + shared: &mut SharedLayoutContext) { let mut root_flow = match self.root_flow.clone() { Some(root_flow) => root_flow, None => return, @@ -1249,10 +1269,9 @@ impl LayoutThread { }, ReflowQueryType::ResolvedStyleQuery(node, ref pseudo, ref property) => { let node = unsafe { ServoLayoutNode::new(&node) }; - let layout_context = LayoutContext::new(&shared_layout_context); rw_data.resolved_style_response = - process_resolved_style_request(node, - &layout_context, + process_resolved_style_request(shared, + node, pseudo, property, root_flow); @@ -1361,7 +1380,7 @@ impl LayoutThread { query_type: Option<&ReflowQueryType>, document: Option<&ServoLayoutDocument>, rw_data: &mut LayoutThreadData, - layout_context: &mut SharedLayoutContext) { + shared: &mut SharedLayoutContext) { if let Some(mut root_flow) = self.root_flow.clone() { // Kick off animations if any were triggered, expire completed ones. animation::update_animation_state(&self.constellation_chan, @@ -1393,7 +1412,7 @@ impl LayoutThread { profile(time::ProfilerCategory::LayoutGeneratedContent, self.profiler_metadata(), self.time_profiler_chan.clone(), - || sequential::resolve_generated_content(FlowRef::deref_mut(&mut root_flow), &layout_context)); + || sequential::resolve_generated_content(FlowRef::deref_mut(&mut root_flow), &shared)); // Guess float placement. profile(time::ProfilerCategory::LayoutFloatPlacementSpeculation, @@ -1416,10 +1435,10 @@ impl LayoutThread { FlowRef::deref_mut(&mut root_flow), profiler_metadata, self.time_profiler_chan.clone(), - &*layout_context); + &*shared); } else { //Sequential mode - LayoutThread::solve_constraints(FlowRef::deref_mut(&mut root_flow), &layout_context) + LayoutThread::solve_constraints(FlowRef::deref_mut(&mut root_flow), &shared) } }); } @@ -1428,8 +1447,8 @@ impl LayoutThread { self.profiler_metadata(), self.time_profiler_chan.clone(), || { - let layout_context = LayoutContext::new(&*layout_context); - sequential::store_overflow(&layout_context, + let context = LayoutContext::new(&shared); + sequential::store_overflow(&context, FlowRef::deref_mut(&mut root_flow) as &mut Flow); }); @@ -1437,7 +1456,7 @@ impl LayoutThread { query_type, document, rw_data, - layout_context); + shared); } } @@ -1538,6 +1557,7 @@ fn get_ua_stylesheets() -> Result<UserAgentStylesheets, &'static str> { None, Origin::UserAgent, Default::default(), + None, Box::new(StdoutErrorReporter), ParserContextExtraData::default())) } @@ -1551,7 +1571,8 @@ fn get_ua_stylesheets() -> Result<UserAgentStylesheets, &'static str> { for &(ref contents, ref url) in &opts::get().user_stylesheets { user_or_user_agent_stylesheets.push(Stylesheet::from_bytes( &contents, url.clone(), None, None, Origin::User, Default::default(), - Box::new(StdoutErrorReporter), ParserContextExtraData::default())); + None, Box::new(StdoutErrorReporter), + ParserContextExtraData::default())); } let quirks_mode_stylesheet = try!(parse_ua_stylesheet("quirks-mode.css")); diff --git a/components/net/Cargo.toml b/components/net/Cargo.toml index 758f9b3aa20..a6949734bf3 100644 --- a/components/net/Cargo.toml +++ b/components/net/Cargo.toml @@ -34,12 +34,12 @@ profile_traits = {path = "../profile_traits"} rustc-serialize = "0.3" serde = "0.8" serde_derive = "0.8" +servo_config = {path = "../config"} servo_url = {path = "../url"} threadpool = "1.0" time = "0.1.17" unicase = "1.4.0" url = {version = "1.2", features = ["heap_size", "rustc-serialize"]} -util = {path = "../util"} uuid = {version = "0.3.1", features = ["v4"]} websocket = "0.17" diff --git a/components/net/chrome_loader.rs b/components/net/chrome_loader.rs index 6ddb096548a..83b5b59da4a 100644 --- a/components/net/chrome_loader.rs +++ b/components/net/chrome_loader.rs @@ -2,10 +2,10 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ +use servo_config::resource_files::resources_dir_path; use servo_url::ServoUrl; use std::fs::canonicalize; use url::percent_encoding::percent_decode; -use util::resource_files::resources_dir_path; pub fn resolve_chrome_url(url: &ServoUrl) -> Result<ServoUrl, ()> { assert_eq!(url.scheme(), "chrome"); diff --git a/components/net/connector.rs b/components/net/connector.rs index 4040c929dc5..3e4a8071f28 100644 --- a/components/net/connector.rs +++ b/components/net/connector.rs @@ -6,8 +6,8 @@ use hyper::client::Pool; use hyper::net::{HttpStream, HttpsConnector, SslClient}; use openssl::ssl::{SSL_OP_NO_COMPRESSION, SSL_OP_NO_SSLV2, SSL_OP_NO_SSLV3, SSL_VERIFY_PEER}; use openssl::ssl::{Ssl, SslContext, SslMethod, SslStream}; +use servo_config::resource_files::resources_dir_path; use std::sync::Arc; -use util::resource_files::resources_dir_path; pub type Connector = HttpsConnector<ServoSslClient>; diff --git a/components/net/content_blocker.rs b/components/net/content_blocker.rs index c30961263dc..eb7f8e1a130 100644 --- a/components/net/content_blocker.rs +++ b/components/net/content_blocker.rs @@ -3,9 +3,9 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ use content_blocker_parser::{RuleList, parse_list}; +use servo_config::resource_files::read_resource_file; use std::str; use std::sync::Arc; -use util::resource_files::read_resource_file; lazy_static! { pub static ref BLOCKED_CONTENT_RULES: Arc<Option<RuleList>> = Arc::new(create_rule_list()); diff --git a/components/net/cookie.rs b/components/net/cookie.rs index 768017ec6f6..42a49a4ac0a 100644 --- a/components/net/cookie.rs +++ b/components/net/cookie.rs @@ -75,7 +75,7 @@ impl Cookie { // Step 10 - if cookie.httponly && source != CookieSource::HTTP { + if cookie.httponly && source == CookieSource::NonHTTP { return None; } @@ -132,16 +132,11 @@ impl Cookie { // http://tools.ietf.org/html/rfc6265#section-5.1.3 pub fn domain_match(string: &str, domain_string: &str) -> bool { - if string == domain_string { - return true; - } - if string.ends_with(domain_string) && - string.as_bytes()[string.len()-domain_string.len()-1] == b'.' && - string.parse::<Ipv4Addr>().is_err() && - string.parse::<Ipv6Addr>().is_err() { - return true; - } - false + string == domain_string || + (string.ends_with(domain_string) && + string.as_bytes()[string.len()-domain_string.len()-1] == b'.' && + string.parse::<Ipv4Addr>().is_err() && + string.parse::<Ipv6Addr>().is_err()) } // http://tools.ietf.org/html/rfc6265#section-5.4 step 1 @@ -165,7 +160,7 @@ impl Cookie { } } - if self.cookie.secure && url.scheme() != "https" { + if self.cookie.secure && !url.is_secure_scheme() { return false; } if self.cookie.httponly && source == CookieSource::NonHTTP { diff --git a/components/net/cookie_storage.rs b/components/net/cookie_storage.rs index 21c47e1f17b..8d39334263c 100644 --- a/components/net/cookie_storage.rs +++ b/components/net/cookie_storage.rs @@ -33,11 +33,32 @@ impl CookieStorage { } // http://tools.ietf.org/html/rfc6265#section-5.3 - pub fn remove(&mut self, cookie: &Cookie, source: CookieSource) -> Result<Option<Cookie>, ()> { + pub fn remove(&mut self, cookie: &Cookie, url: &ServoUrl, source: CookieSource) -> Result<Option<Cookie>, ()> { let domain = reg_host(cookie.cookie.domain.as_ref().unwrap_or(&"".to_string())); let cookies = self.cookies_map.entry(domain).or_insert(vec![]); - // Step 1 + // https://www.ietf.org/id/draft-ietf-httpbis-cookie-alone-01.txt Step 2 + if !cookie.cookie.secure && !url.is_secure_scheme() { + let new_domain = cookie.cookie.domain.as_ref().unwrap(); + let new_path = cookie.cookie.path.as_ref().unwrap(); + + let any_overlapping = cookies.iter().any(|c| { + let existing_domain = c.cookie.domain.as_ref().unwrap(); + let existing_path = c.cookie.path.as_ref().unwrap(); + + c.cookie.name == cookie.cookie.name && + c.cookie.secure && + (Cookie::domain_match(new_domain, existing_domain) || + Cookie::domain_match(existing_domain, new_domain)) && + Cookie::path_match(new_path, existing_path) + }); + + if any_overlapping { + return Err(()); + } + } + + // Step 11.1 let position = cookies.iter().position(|c| { c.cookie.domain == cookie.cookie.domain && c.cookie.path == cookie.cookie.path && @@ -45,15 +66,16 @@ impl CookieStorage { }); if let Some(ind) = position { + // Step 11.4 let c = cookies.remove(ind); // http://tools.ietf.org/html/rfc6265#section-5.3 step 11.2 - if !c.cookie.httponly || source == CookieSource::HTTP { - Ok(Some(c)) - } else { + if c.cookie.httponly && source == CookieSource::NonHTTP { // Undo the removal. cookies.push(c); Err(()) + } else { + Ok(Some(c)) } } else { Ok(None) @@ -61,8 +83,13 @@ impl CookieStorage { } // http://tools.ietf.org/html/rfc6265#section-5.3 - pub fn push(&mut self, mut cookie: Cookie, source: CookieSource) { - let old_cookie = self.remove(&cookie, source); + pub fn push(&mut self, mut cookie: Cookie, url: &ServoUrl, source: CookieSource) { + // https://www.ietf.org/id/draft-ietf-httpbis-cookie-alone-01.txt Step 1 + if cookie.cookie.secure && !url.is_secure_scheme() { + return; + } + + let old_cookie = self.remove(&cookie, url, source); if old_cookie.is_err() { // This new cookie is not allowed to overwrite an existing one. return; @@ -83,7 +110,7 @@ impl CookieStorage { cookies.retain(|c| !is_cookie_expired(&c)); let new_len = cookies.len(); - // https://datatracker.ietf.org/doc/draft-ietf-httpbis-cookie-alone + // https://www.ietf.org/id/draft-ietf-httpbis-cookie-alone-01.txt if new_len == old_len && !evict_one_cookie(cookie.cookie.secure, cookies) { return; } @@ -119,7 +146,6 @@ impl CookieStorage { // Step 1 c.appropriate_for_url(url, source) }; - // Step 2 let domain = reg_host(url.host_str().unwrap_or("")); let cookies = self.cookies_map.entry(domain).or_insert(vec![]); @@ -159,6 +185,7 @@ impl CookieStorage { })) } } + fn reg_host<'a>(url: &'a str) -> String { reg_suffix(url).to_string() } diff --git a/components/net/fetch/methods.rs b/components/net/fetch/methods.rs index ebff48a80ba..de41bfa202a 100644 --- a/components/net/fetch/methods.rs +++ b/components/net/fetch/methods.rs @@ -25,7 +25,7 @@ use std::mem; use std::rc::Rc; use std::sync::mpsc::{Sender, Receiver}; -pub type Target = Option<Box<FetchTaskTarget + Send>>; +pub type Target<'a> = &'a mut (FetchTaskTarget + Send); pub enum Data { Payload(Vec<u8>), @@ -43,17 +43,15 @@ pub type DoneChannel = Option<(Sender<Data>, Receiver<Data>)>; /// [Fetch](https://fetch.spec.whatwg.org#concept-fetch) pub fn fetch(request: Rc<Request>, - target: &mut Target, - context: &FetchContext) - -> Response { - fetch_with_cors_cache(request, &mut CorsCache::new(), target, context) + target: Target, + context: &FetchContext) { + fetch_with_cors_cache(request, &mut CorsCache::new(), target, context); } pub fn fetch_with_cors_cache(request: Rc<Request>, cache: &mut CorsCache, - target: &mut Target, - context: &FetchContext) - -> Response { + target: Target, + context: &FetchContext) { // Step 1 if request.window.get() == Window::Client { // TODO: Set window to request's client object if client is a Window object @@ -112,7 +110,7 @@ pub fn fetch_with_cors_cache(request: Rc<Request>, } // Step 7 - main_fetch(request, cache, false, false, target, &mut None, &context) + main_fetch(request, cache, false, false, target, &mut None, &context); } /// [Main fetch](https://fetch.spec.whatwg.org/#concept-main-fetch) @@ -120,7 +118,7 @@ pub fn main_fetch(request: Rc<Request>, cache: &mut CorsCache, cors_flag: bool, recursive_flag: bool, - target: &mut Target, + target: Target, done_chan: &mut DoneChannel, context: &FetchContext) -> Response { @@ -145,6 +143,18 @@ pub fn main_fetch(request: Rc<Request>, // Step 5 // TODO this step (CSP port/content blocking) + if let Some(port) = request.url().port() { + let is_ftp = request.url().scheme() == "ftp" && (port == 20 || port == 21); + static BAD_PORTS: [u16; 64] = [1, 7, 9, 11, 13, 15, 17, 19, 20, 21, 22, 23, 25, 37, 42, + 43, 53, 77, 79, 87, 95, 101, 102, 103, 104, 109, 110, 111, + 113, 115, 117, 119, 123, 135, 139, 143, 179, 389, 465, 512, + 513, 514, 515, 526, 530, 531, 532, 540, 556, 563, 587, 601, + 636, 993, 995, 2049, 3659, 4045, 6000, 6665, 6666, 6667, + 6668, 6669]; + if !is_ftp && BAD_PORTS.binary_search(&port).is_ok() { + response = Some(Response::network_error(NetworkError::Internal("Request attempted on bad port".into()))); + } + } // Step 6 // TODO this step (referrer policy) @@ -297,20 +307,16 @@ pub fn main_fetch(request: Rc<Request>, // Step 19 if request.synchronous { - if let Some(ref mut target) = *target { - // process_response is not supposed to be used - // by sync fetch, but we overload it here for simplicity - target.process_response(&response); - } + // process_response is not supposed to be used + // by sync fetch, but we overload it here for simplicity + target.process_response(&response); if let Some(ref ch) = *done_chan { loop { match ch.1.recv() .expect("fetch worker should always send Done before terminating") { Data::Payload(vec) => { - if let Some(ref mut target) = *target { - target.process_response_chunk(vec); - } + target.process_response_chunk(vec); } Data::Done => break, } @@ -321,37 +327,29 @@ pub fn main_fetch(request: Rc<Request>, // in case there was no channel to wait for, the body was // obtained synchronously via basic_fetch for data/file/about/etc // We should still send the body across as a chunk - if let Some(ref mut target) = *target { - target.process_response_chunk(vec.clone()); - } + target.process_response_chunk(vec.clone()); } else { assert!(*body == ResponseBody::Empty) } } // overloaded similarly to process_response - if let Some(ref mut target) = *target { - target.process_response_eof(&response); - } + target.process_response_eof(&response); return response; } // Step 20 if request.body.borrow().is_some() && matches!(request.current_url().scheme(), "http" | "https") { - if let Some(ref mut target) = *target { - // XXXManishearth: We actually should be calling process_request - // in http_network_fetch. However, we can't yet follow the request - // upload progress, so I'm keeping it here for now and pretending - // the body got sent in one chunk - target.process_request_body(&request); - target.process_request_eof(&request); - } + // XXXManishearth: We actually should be calling process_request + // in http_network_fetch. However, we can't yet follow the request + // upload progress, so I'm keeping it here for now and pretending + // the body got sent in one chunk + target.process_request_body(&request); + target.process_request_eof(&request); } // Step 21 - if let Some(ref mut target) = *target { - target.process_response(&response); - } + target.process_response(&response); // Step 22 if let Some(ref ch) = *done_chan { @@ -359,14 +357,12 @@ pub fn main_fetch(request: Rc<Request>, match ch.1.recv() .expect("fetch worker should always send Done before terminating") { Data::Payload(vec) => { - if let Some(ref mut target) = *target { - target.process_response_chunk(vec); - } + target.process_response_chunk(vec); } Data::Done => break, } } - } else if let Some(ref mut target) = *target { + } else { let body = response.body.lock().unwrap(); if let ResponseBody::Done(ref vec) = *body { // in case there was no channel to wait for, the body was @@ -378,13 +374,8 @@ pub fn main_fetch(request: Rc<Request>, } } - // Step 23 - request.done.set(true); - // Step 24 - if let Some(ref mut target) = *target { - target.process_response_eof(&response); - } + target.process_response_eof(&response); // TODO remove this line when only asynchronous fetches are used return response; @@ -393,7 +384,7 @@ pub fn main_fetch(request: Rc<Request>, /// [Basic fetch](https://fetch.spec.whatwg.org#basic-fetch) fn basic_fetch(request: Rc<Request>, cache: &mut CorsCache, - target: &mut Target, + target: Target, done_chan: &mut DoneChannel, context: &FetchContext) -> Response { diff --git a/components/net/filemanager_thread.rs b/components/net/filemanager_thread.rs index 641b1394539..0fa1aeeca9c 100644 --- a/components/net/filemanager_thread.rs +++ b/components/net/filemanager_thread.rs @@ -7,6 +7,7 @@ use mime_guess::guess_mime_type_opt; use net_traits::blob_url_store::{BlobBuf, BlobURLStoreError}; use net_traits::filemanager_thread::{FileManagerResult, FileManagerThreadMsg, FileOrigin, FilterPattern}; use net_traits::filemanager_thread::{FileManagerThreadError, ReadFileProgress, RelativePos, SelectedFile}; +use servo_config::prefs::PREFS; use std::collections::HashMap; use std::fs::File; use std::io::{Read, Seek, SeekFrom}; @@ -14,11 +15,10 @@ use std::ops::Index; use std::path::{Path, PathBuf}; use std::sync::{Arc, RwLock}; use std::sync::atomic::{self, AtomicBool, AtomicUsize, Ordering}; +use std::thread; #[cfg(any(target_os = "macos", target_os = "linux", target_os = "windows"))] use tinyfiledialogs; use url::Url; -use util::prefs::PREFS; -use util::thread::spawn_named; use uuid::Uuid; /// The provider of file-dialog UI should implement this trait. @@ -129,12 +129,12 @@ impl FileManager { check_url_validity: bool, origin: FileOrigin) { let store = self.store.clone(); - spawn_named("read file".to_owned(), move || { + thread::Builder::new().name("read file".to_owned()).spawn(move || { if let Err(e) = store.try_read_file(&sender, id, check_url_validity, origin) { let _ = sender.send(Err(FileManagerThreadError::BlobURLStoreError(e))); } - }) + }).expect("Thread spawning failed"); } pub fn promote_memory(&self, @@ -143,9 +143,9 @@ impl FileManager { sender: IpcSender<Result<Uuid, BlobURLStoreError>>, origin: FileOrigin) { let store = self.store.clone(); - spawn_named("transfer memory".to_owned(), move || { + thread::Builder::new().name("transfer memory".to_owned()).spawn(move || { store.promote_memory(blob_buf, set_valid, sender, origin); - }) + }).expect("Thread spawning failed"); } /// Message handler @@ -157,15 +157,15 @@ impl FileManager { match msg { FileManagerThreadMsg::SelectFile(filter, sender, origin, opt_test_path) => { let store = self.store.clone(); - spawn_named("select file".to_owned(), move || { + thread::Builder::new().name("select file".to_owned()).spawn(move || { store.select_file(filter, sender, origin, opt_test_path, ui); - }); + }).expect("Thread spawning failed"); } FileManagerThreadMsg::SelectFiles(filter, sender, origin, opt_test_paths) => { let store = self.store.clone(); - spawn_named("select files".to_owned(), move || { + thread::Builder::new().name("select files".to_owned()).spawn(move || { store.select_files(filter, sender, origin, opt_test_paths, ui); - }) + }).expect("Thread spawning failed"); } FileManagerThreadMsg::ReadFile(sender, id, check_url_validity, origin) => { self.read_file(sender, id, check_url_validity, origin); diff --git a/components/net/hsts.rs b/components/net/hsts.rs index 662ec7b8088..6b8665bd2e5 100644 --- a/components/net/hsts.rs +++ b/components/net/hsts.rs @@ -4,11 +4,11 @@ use net_traits::IncludeSubdomains; use rustc_serialize::json::decode; +use servo_config::resource_files::read_resource_file; use std::net::{Ipv4Addr, Ipv6Addr}; use std::str::from_utf8; use time; use url::Url; -use util::resource_files::read_resource_file; #[derive(RustcDecodable, RustcEncodable, Clone)] pub struct HstsEntry { diff --git a/components/net/http_loader.rs b/components/net/http_loader.rs index 6199c45209f..4091486597b 100644 --- a/components/net/http_loader.rs +++ b/components/net/http_loader.rs @@ -42,16 +42,16 @@ use std::collections::HashSet; use std::error::Error; use std::io::{self, Read, Write}; use std::iter::FromIterator; -use std::mem::swap; +use std::mem; use std::ops::Deref; use std::rc::Rc; use std::sync::{Arc, RwLock}; use std::sync::mpsc::{channel, Sender}; +use std::thread; use time; use time::Tm; use unicase::UniCase; use url::Origin as UrlOrigin; -use util::thread::spawn_named; use uuid; fn read_block<R: Read>(reader: &mut R) -> Result<Data, ()> { @@ -281,7 +281,7 @@ fn set_cookie_for_url(cookie_jar: &Arc<RwLock<CookieStorage>>, if let Ok(SetCookie(cookies)) = header { for bare_cookie in cookies { if let Some(cookie) = cookie::Cookie::new_wrapped(bare_cookie, request, source) { - cookie_jar.push(cookie, source); + cookie_jar.push(cookie, request, source); } } } @@ -533,7 +533,7 @@ pub fn http_fetch(request: Rc<Request>, cors_flag: bool, cors_preflight_flag: bool, authentication_fetch_flag: bool, - target: &mut Target, + target: Target, done_chan: &mut DoneChannel, context: &FetchContext) -> Response { @@ -707,7 +707,7 @@ fn http_redirect_fetch(request: Rc<Request>, cache: &mut CorsCache, response: Response, cors_flag: bool, - target: &mut Target, + target: Target, done_chan: &mut DoneChannel, context: &FetchContext) -> Response { @@ -1071,7 +1071,7 @@ fn http_network_fetch(request: Rc<Request>, let devtools_sender = context.devtools_chan.clone(); let meta_status = meta.status.clone(); let meta_headers = meta.headers.clone(); - spawn_named(format!("fetch worker thread"), move || { + thread::Builder::new().name(format!("fetch worker thread")).spawn(move || { match StreamedResponse::from_http_response(res) { Ok(mut res) => { *res_body.lock().unwrap() = ResponseBody::Receiving(vec![]); @@ -1101,16 +1101,14 @@ fn http_network_fetch(request: Rc<Request>, } }, Ok(Data::Done) | Err(_) => { - let mut empty_vec = Vec::new(); - let completed_body = match *res_body.lock().unwrap() { + let mut body = res_body.lock().unwrap(); + let completed_body = match *body { ResponseBody::Receiving(ref mut body) => { - // avoid cloning the body - swap(body, &mut empty_vec); - empty_vec + mem::replace(body, vec![]) }, - _ => empty_vec, + _ => vec![], }; - *res_body.lock().unwrap() = ResponseBody::Done(completed_body); + *body = ResponseBody::Done(completed_body); let _ = done_sender.send(Data::Done); break; } @@ -1123,7 +1121,7 @@ fn http_network_fetch(request: Rc<Request>, let _ = done_sender.send(Data::Done); } } - }); + }).expect("Thread spawning failed"); // TODO these substeps aren't possible yet // Substep 1 diff --git a/components/net/image_cache_thread.rs b/components/net/image_cache_thread.rs index 5976ec50885..2df54b8e30c 100644 --- a/components/net/image_cache_thread.rs +++ b/components/net/image_cache_thread.rs @@ -5,12 +5,13 @@ use immeta::load_from_buf; use ipc_channel::ipc::{self, IpcReceiver, IpcSender}; use ipc_channel::router::ROUTER; -use net_traits::{CoreResourceThread, NetworkError, fetch_async, FetchResponseMsg, FetchMetadata, Metadata}; +use net_traits::{CoreResourceThread, NetworkError, fetch_async, FetchResponseMsg}; use net_traits::image::base::{Image, ImageMetadata, PixelFormat, load_from_memory}; use net_traits::image_cache_thread::{ImageCacheChan, ImageCacheCommand, ImageCacheThread, ImageState}; use net_traits::image_cache_thread::{ImageCacheResult, ImageOrMetadataAvailable, ImageResponse, UsePlaceholder}; use net_traits::image_cache_thread::ImageResponder; use net_traits::request::{Destination, RequestInit, Type as RequestType}; +use servo_config::resource_files::resources_dir_path; use servo_url::ServoUrl; use std::borrow::ToOwned; use std::collections::HashMap; @@ -20,9 +21,8 @@ use std::io::{self, Read}; use std::mem; use std::sync::Arc; use std::sync::mpsc::{Receiver, Sender, channel}; +use std::thread; use threadpool::ThreadPool; -use util::resource_files::resources_dir_path; -use util::thread::spawn_named; use webrender_traits; /// @@ -225,17 +225,8 @@ impl ImageListener { } } -/// A legacy type that's mostly redundant with FetchResponseMsg. -// FIXME(#13717): remove this type. -#[derive(Deserialize, Serialize)] -enum ResponseAction { - HeadersAvailable(Result<Metadata, NetworkError>), - DataAvailable(Vec<u8>), - ResponseComplete(Result<(), NetworkError>) -} - struct ResourceLoadInfo { - action: ResponseAction, + action: FetchResponseMsg, key: LoadKey, } @@ -417,8 +408,10 @@ impl ImageCache { // Handle progress messages from the resource thread fn handle_progress(&mut self, msg: ResourceLoadInfo) { match (msg.action, msg.key) { - (ResponseAction::HeadersAvailable(_), _) => {} - (ResponseAction::DataAvailable(data), _) => { + (FetchResponseMsg::ProcessRequestBody, _) | + (FetchResponseMsg::ProcessRequestEOF, _) => return, + (FetchResponseMsg::ProcessResponse(_), _) => {} + (FetchResponseMsg::ProcessResponseChunk(data), _) => { let pending_load = self.pending_loads.get_by_key_mut(&msg.key).unwrap(); pending_load.bytes.extend_from_slice(&data); //jmr0 TODO: possibly move to another task? @@ -434,7 +427,7 @@ impl ImageCache { } } } - (ResponseAction::ResponseComplete(result), key) => { + (FetchResponseMsg::ProcessResponseEOF(result), key) => { match result { Ok(()) => { let pending_load = self.pending_loads.get_by_key_mut(&msg.key).unwrap(); @@ -550,20 +543,7 @@ impl ImageCache { let action = match action { FetchResponseMsg::ProcessRequestBody | FetchResponseMsg::ProcessRequestEOF => return, - FetchResponseMsg::ProcessResponse(meta_result) => { - ResponseAction::HeadersAvailable(meta_result.map(|m| { - match m { - FetchMetadata::Unfiltered(m) => m, - FetchMetadata::Filtered { unsafe_, .. } => unsafe_ - } - })) - } - FetchResponseMsg::ProcessResponseChunk(new_bytes) => { - ResponseAction::DataAvailable(new_bytes) - } - FetchResponseMsg::ProcessResponseEOF(response) => { - ResponseAction::ResponseComplete(response) - } + a => a }; progress_sender.send(ResourceLoadInfo { action: action, @@ -630,12 +610,12 @@ impl ImageCache { loaded_bytes: Vec<u8>) { let (cache_result, load_key, _) = self.pending_loads.get_cached(ref_url.clone()); assert!(cache_result == CacheResult::Miss); - let action = ResponseAction::DataAvailable(loaded_bytes); + let action = FetchResponseMsg::ProcessResponseChunk(loaded_bytes); let _ = self.progress_sender.send(ResourceLoadInfo { action: action, key: load_key, }); - let action = ResponseAction::ResponseComplete(Ok(())); + let action = FetchResponseMsg::ProcessResponseEOF(Ok(())); let _ = self.progress_sender.send(ResourceLoadInfo { action: action, key: load_key, @@ -648,9 +628,9 @@ pub fn new_image_cache_thread(core_resource_thread: CoreResourceThread, webrender_api: webrender_traits::RenderApi) -> ImageCacheThread { let (ipc_command_sender, ipc_command_receiver) = ipc::channel().unwrap(); - spawn_named("ImageCacheThread".to_owned(), move || { + thread::Builder::new().name("ImageCacheThread".to_owned()).spawn(move || { ImageCache::run(core_resource_thread, webrender_api, ipc_command_receiver) - }); + }).expect("Thread spawning failed"); ImageCacheThread::new(ipc_command_sender) } diff --git a/components/net/lib.rs b/components/net/lib.rs index e5f3951d542..c1925df8616 100644 --- a/components/net/lib.rs +++ b/components/net/lib.rs @@ -35,6 +35,7 @@ extern crate profile_traits; extern crate rustc_serialize; #[macro_use] extern crate serde_derive; +extern crate servo_config; extern crate servo_url; extern crate threadpool; extern crate time; @@ -42,7 +43,6 @@ extern crate time; extern crate tinyfiledialogs; extern crate unicase; extern crate url; -extern crate util; extern crate uuid; extern crate webrender_traits; extern crate websocket; diff --git a/components/net/resource_thread.rs b/components/net/resource_thread.rs index 0a4cc89d806..108bc01d8cf 100644 --- a/components/net/resource_thread.rs +++ b/components/net/resource_thread.rs @@ -14,17 +14,12 @@ use filemanager_thread::{FileManager, TFDProvider}; use hsts::HstsList; use http_loader::HttpState; use hyper::client::pool::Pool; -use hyper::header::{ContentType, Header, SetCookie}; -use hyper::mime::{Mime, SubLevel, TopLevel}; use hyper_serde::Serde; use ipc_channel::ipc::{self, IpcReceiver, IpcReceiverSet, IpcSender}; -use mime_classifier::{ApacheBugFlag, MimeClassifier, NoSniffFlag}; -use net_traits::{CookieSource, CoreResourceThread, Metadata, ProgressMsg}; -use net_traits::{CoreResourceMsg, FetchResponseMsg, FetchTaskTarget, LoadConsumer}; -use net_traits::{CustomResponseMediator, LoadResponse, NetworkError, ResourceId}; +use net_traits::{CookieSource, CoreResourceThread}; +use net_traits::{CoreResourceMsg, FetchResponseMsg}; +use net_traits::{CustomResponseMediator, ResourceId}; use net_traits::{ResourceThreads, WebSocketCommunicate, WebSocketConnectData}; -use net_traits::LoadContext; -use net_traits::ProgressMsg::Done; use net_traits::request::{Request, RequestInit}; use net_traits::storage_thread::StorageThreadMsg; use profile_traits::time::ProfilerChan; @@ -41,17 +36,12 @@ use std::path::{Path, PathBuf}; use std::rc::Rc; use std::sync::{Arc, RwLock}; use std::sync::mpsc::Sender; +use std::thread; use storage_thread::StorageThreadFactory; -use util::prefs::PREFS; -use util::thread::spawn_named; use websocket_loader; const TFD_PROVIDER: &'static TFDProvider = &TFDProvider; -pub enum ProgressSender { - Channel(IpcSender<ProgressMsg>), -} - #[derive(Clone)] pub struct ResourceGroup { cookie_jar: Arc<RwLock<CookieStorage>>, @@ -60,82 +50,6 @@ pub struct ResourceGroup { connector: Arc<Pool<Connector>>, } -impl ProgressSender { - //XXXjdm return actual error - pub fn send(&self, msg: ProgressMsg) -> Result<(), ()> { - match *self { - ProgressSender::Channel(ref c) => c.send(msg).map_err(|_| ()), - } - } -} - -pub fn send_error(url: ServoUrl, err: NetworkError, start_chan: LoadConsumer) { - let mut metadata: Metadata = Metadata::default(url); - metadata.status = None; - - if let Ok(p) = start_sending_opt(start_chan, metadata) { - p.send(Done(Err(err))).unwrap(); - } -} - -/// For use by loaders in responding to a Load message that allows content sniffing. -pub fn start_sending_sniffed_opt(start_chan: LoadConsumer, mut metadata: Metadata, - classifier: Arc<MimeClassifier>, partial_body: &[u8], - context: LoadContext) - -> Result<ProgressSender, ()> { - if PREFS.get("network.mime.sniff").as_boolean().unwrap_or(false) { - // TODO: should be calculated in the resource loader, from pull requeset #4094 - let mut no_sniff = NoSniffFlag::Off; - let mut check_for_apache_bug = ApacheBugFlag::Off; - - if let Some(ref headers) = metadata.headers { - if let Some(ref content_type) = headers.get_raw("content-type").and_then(|c| c.last()) { - check_for_apache_bug = ApacheBugFlag::from_content_type(content_type) - } - if let Some(ref raw_content_type_options) = headers.get_raw("X-content-type-options") { - if raw_content_type_options.iter().any(|ref opt| *opt == b"nosniff") { - no_sniff = NoSniffFlag::On - } - } - } - - let supplied_type = - metadata.content_type.as_ref().map(|&Serde(ContentType(Mime(ref toplevel, ref sublevel, _)))| { - (toplevel.to_owned(), format!("{}", sublevel)) - }); - let (toplevel, sublevel) = classifier.classify(context, - no_sniff, - check_for_apache_bug, - &supplied_type, - &partial_body); - let mime_tp: TopLevel = toplevel.into(); - let mime_sb: SubLevel = sublevel.parse().unwrap(); - metadata.content_type = - Some(Serde(ContentType(Mime(mime_tp, mime_sb, vec![])))); - } - - start_sending_opt(start_chan, metadata) -} - -/// For use by loaders in responding to a Load message. -/// It takes an optional NetworkError, so that we can extract the SSL Validation errors -/// and take it to the HTML parser -fn start_sending_opt(start_chan: LoadConsumer, metadata: Metadata) -> Result<ProgressSender, ()> { - match start_chan { - LoadConsumer::Channel(start_chan) => { - let (progress_chan, progress_port) = ipc::channel().unwrap(); - let result = start_chan.send(LoadResponse { - metadata: metadata, - progress_port: progress_port, - }); - match result { - Ok(_) => Ok(ProgressSender::Channel(progress_chan)), - Err(_) => Err(()) - } - } - } -} - /// Returns a tuple of (public, private) senders to the new threads. pub fn new_resource_threads(user_agent: Cow<'static, str>, devtools_chan: Option<Sender<DevtoolsControlMsg>>, @@ -161,7 +75,7 @@ pub fn new_core_resource_thread(user_agent: Cow<'static, str>, -> (CoreResourceThread, CoreResourceThread) { let (public_setup_chan, public_setup_port) = ipc::channel().unwrap(); let (private_setup_chan, private_setup_port) = ipc::channel().unwrap(); - spawn_named("ResourceManager".to_owned(), move || { + thread::Builder::new().name("ResourceManager".to_owned()).spawn(move || { let resource_manager = CoreResourceManager::new( user_agent, devtools_chan, profiler_chan ); @@ -172,7 +86,7 @@ pub fn new_core_resource_thread(user_agent: Cow<'static, str>, }; channel_manager.start(public_setup_port, private_setup_port); - }); + }).expect("Thread spawning failed"); (public_setup_chan, private_setup_chan) } @@ -244,10 +158,13 @@ impl ResourceChannelManager { self.resource_manager.fetch(init, sender, group), CoreResourceMsg::WebsocketConnect(connect, connect_data) => self.resource_manager.websocket_connect(connect, connect_data, group), - CoreResourceMsg::SetCookiesForUrl(request, cookie_list, source) => - self.resource_manager.set_cookies_for_url(request, cookie_list, source, group), - CoreResourceMsg::SetCookiesForUrlWithData(request, cookie, source) => - self.resource_manager.set_cookies_for_url_with_data(request, cookie, source, group), + CoreResourceMsg::SetCookieForUrl(request, cookie, source) => + self.resource_manager.set_cookie_for_url(&request, cookie, source, group), + CoreResourceMsg::SetCookiesForUrl(request, cookies, source) => { + for cookie in cookies { + self.resource_manager.set_cookie_for_url(&request, cookie.0, source, group); + } + } CoreResourceMsg::GetCookiesForUrl(url, consumer, source) => { let mut cookie_jar = group.cookie_jar.write().unwrap(); consumer.send(cookie_jar.cookies_for_url(&url, source)).unwrap(); @@ -391,33 +308,17 @@ impl CoreResourceManager { } } - fn set_cookies_for_url(&mut self, - request: ServoUrl, - cookie_list: String, - source: CookieSource, - resource_group: &ResourceGroup) { - let header = Header::parse_header(&[cookie_list.into_bytes()]); - if let Ok(SetCookie(cookies)) = header { - for bare_cookie in cookies { - if let Some(cookie) = cookie::Cookie::new_wrapped(bare_cookie, &request, source) { - let mut cookie_jar = resource_group.cookie_jar.write().unwrap(); - cookie_jar.push(cookie, source); - } - } - } - } - - fn set_cookies_for_url_with_data(&mut self, request: ServoUrl, cookie: cookie_rs::Cookie, source: CookieSource, - resource_group: &ResourceGroup) { + fn set_cookie_for_url(&mut self, request: &ServoUrl, cookie: cookie_rs::Cookie, source: CookieSource, + resource_group: &ResourceGroup) { if let Some(cookie) = cookie::Cookie::new_wrapped(cookie, &request, source) { let mut cookie_jar = resource_group.cookie_jar.write().unwrap(); - cookie_jar.push(cookie, source) + cookie_jar.push(cookie, request, source) } } fn fetch(&self, init: RequestInit, - sender: IpcSender<FetchResponseMsg>, + mut sender: IpcSender<FetchResponseMsg>, group: &ResourceGroup) { let http_state = HttpState { hsts_list: group.hsts_list.clone(), @@ -428,21 +329,20 @@ impl CoreResourceManager { let ua = self.user_agent.clone(); let dc = self.devtools_chan.clone(); let filemanager = self.filemanager.clone(); - spawn_named(format!("fetch thread for {}", init.url), move || { + thread::Builder::new().name(format!("fetch thread for {}", init.url)).spawn(move || { let request = Request::from_init(init); // XXXManishearth: Check origin against pipeline id (also ensure that the mode is allowed) // todo load context / mimesniff in fetch // todo referrer policy? // todo service worker stuff - let mut target = Some(Box::new(sender) as Box<FetchTaskTarget + Send + 'static>); let context = FetchContext { state: http_state, user_agent: ua, devtools_chan: dc, filemanager: filemanager, }; - fetch(Rc::new(request), &mut target, &context); - }) + fetch(Rc::new(request), &mut sender, &context); + }).expect("Thread spawning failed"); } fn websocket_connect(&self, diff --git a/components/net/storage_thread.rs b/components/net/storage_thread.rs index cdf70aa6b3b..88726d5702b 100644 --- a/components/net/storage_thread.rs +++ b/components/net/storage_thread.rs @@ -10,7 +10,7 @@ use std::borrow::ToOwned; use std::collections::BTreeMap; use std::collections::HashMap; use std::path::PathBuf; -use util::thread::spawn_named; +use std::thread; const QUOTA_SIZE_LIMIT: usize = 5 * 1024 * 1024; @@ -22,9 +22,9 @@ impl StorageThreadFactory for IpcSender<StorageThreadMsg> { /// Create a storage thread fn new(config_dir: Option<PathBuf>) -> IpcSender<StorageThreadMsg> { let (chan, port) = ipc::channel().unwrap(); - spawn_named("StorageManager".to_owned(), move || { + thread::Builder::new().name("StorageManager".to_owned()).spawn(move || { StorageManager::new(port, config_dir).start(); - }); + }).expect("Thread spawning failed"); chan } } diff --git a/components/net/websocket_loader.rs b/components/net/websocket_loader.rs index c9b67dc7f0f..d0ce7d61836 100644 --- a/components/net/websocket_loader.rs +++ b/components/net/websocket_loader.rs @@ -14,7 +14,6 @@ use std::ascii::AsciiExt; use std::sync::{Arc, Mutex, RwLock}; use std::sync::atomic::{AtomicBool, Ordering}; use std::thread; -use util::thread::spawn_named; use websocket::{Client, Message}; use websocket::header::{Headers, Origin, WebSocketProtocol}; use websocket::message::Type; @@ -64,7 +63,7 @@ fn establish_a_websocket_connection(resource_url: &ServoUrl, net_url: (Host, Str } pub fn init(connect: WebSocketCommunicate, connect_data: WebSocketConnectData, cookie_jar: Arc<RwLock<CookieStorage>>) { - spawn_named(format!("WebSocket connection to {}", connect_data.resource_url), move || { + thread::Builder::new().name(format!("WebSocket connection to {}", connect_data.resource_url)).spawn(move || { // Step 8: Protocols. // Step 9. @@ -162,5 +161,5 @@ pub fn init(connect: WebSocketCommunicate, connect_data: WebSocketConnectData, c } } }); - }); + }).expect("Thread spawning failed"); } diff --git a/components/net_traits/Cargo.toml b/components/net_traits/Cargo.toml index 71cd286f863..a43158bb9ea 100644 --- a/components/net_traits/Cargo.toml +++ b/components/net_traits/Cargo.toml @@ -10,8 +10,6 @@ name = "net_traits" path = "lib.rs" [dependencies] -bluetooth_traits = {path = "../bluetooth_traits"} -util = {path = "../util"} msg = {path = "../msg"} ipc-channel = "0.5" heapsize = "0.3.0" @@ -24,6 +22,7 @@ log = "0.3.5" num-traits = "0.1.32" serde = "0.8" serde_derive = "0.8" +servo_config = {path = "../config", features = ["servo"]} servo_url = {path = "../url", features = ["servo"]} url = {version = "1.2", features = ["heap_size"]} websocket = "0.17" diff --git a/components/net_traits/lib.rs b/components/net_traits/lib.rs index bd0fae8d777..eb8983f9d10 100644 --- a/components/net_traits/lib.rs +++ b/components/net_traits/lib.rs @@ -9,7 +9,6 @@ #![deny(unsafe_code)] -extern crate bluetooth_traits; extern crate cookie as cookie_rs; extern crate heapsize; #[macro_use] extern crate heapsize_derive; @@ -27,14 +26,13 @@ extern crate num_traits; extern crate serde; #[macro_use] extern crate serde_derive; +extern crate servo_config; extern crate servo_url; extern crate url; -extern crate util; extern crate uuid; extern crate webrender_traits; extern crate websocket; -use bluetooth_traits::{BluetoothResponseListener, BluetoothResponseResult}; use cookie_rs::Cookie; use filemanager_thread::FileManagerThreadMsg; use heapsize::HeapSizeOf; @@ -44,7 +42,6 @@ use hyper::mime::{Attr, Mime}; use hyper_serde::Serde; use ipc_channel::ipc::{self, IpcReceiver, IpcSender}; use ipc_channel::router::ROUTER; -use msg::constellation_msg::PipelineId; use request::{Request, RequestInit}; use response::{HttpsState, Response}; use servo_url::ServoUrl; @@ -238,19 +235,6 @@ impl<T: FetchResponseListener> Action<T> for FetchResponseMsg { } } -impl<T: BluetoothResponseListener> Action<T> for BluetoothResponseResult { - /// Execute the default action on a provided listener. - fn process(self, listener: &mut T) { - listener.response(self) - } -} - -/// A wrapper for a network load that can either be channel or event-based. -#[derive(Deserialize, Serialize)] -pub enum LoadConsumer { - Channel(IpcSender<LoadResponse>), -} - /// Handle to a resource thread pub type CoreResourceThread = IpcSender<CoreResourceMsg>; @@ -361,16 +345,16 @@ pub enum CoreResourceMsg { Fetch(RequestInit, IpcSender<FetchResponseMsg>), /// Try to make a websocket connection to a URL. WebsocketConnect(WebSocketCommunicate, WebSocketConnectData), - /// Store a set of cookies for a given originating URL - SetCookiesForUrl(ServoUrl, String, CookieSource), - /// Store a set of cookies for a given originating URL - SetCookiesForUrlWithData( + /// Store a cookie for a given originating URL + SetCookieForUrl( ServoUrl, #[serde(deserialize_with = "::hyper_serde::deserialize", serialize_with = "::hyper_serde::serialize")] Cookie, CookieSource ), + /// Store cookies for a given originating URL + SetCookiesForUrl(ServoUrl, Vec<Serde<Cookie>>, CookieSource), /// Retrieve the stored cookies for a given URL GetCookiesForUrl(ServoUrl, IpcSender<Option<String>>, CookieSource), /// Get a cookie by name for a given originating URL @@ -401,19 +385,6 @@ pub fn fetch_async<F>(request: RequestInit, core_resource_thread.send(CoreResourceMsg::Fetch(request, action_sender)).unwrap(); } -/// Message sent in response to `Load`. Contains metadata, and a port -/// for receiving the data. -/// -/// Even if loading fails immediately, we send one of these and the -/// progress_port will provide the error. -#[derive(Serialize, Deserialize)] -pub struct LoadResponse { - /// Metadata, such as from HTTP headers. - pub metadata: Metadata, - /// Port for reading data. - pub progress_port: IpcReceiver<ProgressMsg>, -} - #[derive(Clone, Deserialize, Serialize, HeapSizeOf)] pub struct ResourceCorsData { /// CORS Preflight flag @@ -466,24 +437,17 @@ impl Metadata { /// Extract the parts of a Mime that we care about. pub fn set_content_type(&mut self, content_type: Option<&Mime>) { - match self.headers { - None => self.headers = Some(Serde(Headers::new())), - Some(_) => (), + if self.headers.is_none() { + self.headers = Some(Serde(Headers::new())); } - match content_type { - None => (), - Some(mime) => { - if let Some(headers) = self.headers.as_mut() { - headers.set(ContentType(mime.clone())); - } - - self.content_type = Some(Serde(ContentType(mime.clone()))); - let &Mime(_, _, ref parameters) = mime; - for &(ref k, ref v) in parameters { - if &Attr::Charset == k { - self.charset = Some(v.to_string()); - } + if let Some(mime) = content_type { + self.headers.as_mut().unwrap().set(ContentType(mime.clone())); + self.content_type = Some(Serde(ContentType(mime.clone()))); + let Mime(_, _, ref parameters) = *mime; + for &(ref k, ref v) in parameters { + if Attr::Charset == *k { + self.charset = Some(v.to_string()); } } } @@ -499,15 +463,6 @@ pub enum CookieSource { NonHTTP, } -/// Messages sent in response to a `Load` message -#[derive(PartialEq, Debug, Deserialize, Serialize)] -pub enum ProgressMsg { - /// Binary data - there may be multiple of these - Payload(Vec<u8>), - /// Indicates loading is complete, either successfully or not - Done(Result<(), NetworkError>), -} - /// Convenience function for synchronously loading a whole resource. pub fn load_whole_resource(request: RequestInit, core_resource_thread: &CoreResourceThread) @@ -544,12 +499,6 @@ pub fn unwrap_websocket_protocol(wsp: Option<&header::WebSocketProtocol>) -> Opt #[derive(Clone, PartialEq, Eq, Copy, Hash, Debug, Deserialize, Serialize, HeapSizeOf)] pub struct ResourceId(pub u32); -#[derive(Deserialize, Serialize)] -pub enum ConstellationMsg { - /// Queries whether a pipeline or its ancestors are private - IsPrivate(PipelineId, IpcSender<bool>), -} - /// Network errors that have to be exported out of the loaders #[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize, HeapSizeOf)] pub enum NetworkError { diff --git a/components/net_traits/pub_domains.rs b/components/net_traits/pub_domains.rs index f40815e100e..664c39fb09b 100644 --- a/components/net_traits/pub_domains.rs +++ b/components/net_traits/pub_domains.rs @@ -14,10 +14,11 @@ //! we don't need to make the code more complex for it. The `mach` update command makes sure that //! those cases are not present. +use servo_config::resource_files::read_resource_file; +use servo_url::ServoUrl; use std::collections::HashSet; use std::iter::FromIterator; use std::str::from_utf8; -use util::resource_files::read_resource_file; #[derive(Clone,Debug)] pub struct PubDomainRules { @@ -138,3 +139,11 @@ pub fn is_pub_domain(domain: &str) -> bool { pub fn is_reg_domain(domain: &str) -> bool { PUB_DOMAINS.is_registrable_suffix(domain) } + +/// The registered domain name (aka eTLD+1) for a URL. +/// Returns None if the URL has no host name. +/// Returns the registered suffix for the host name if it is a domain. +/// Leaves the host name alone if it is an IP address. +pub fn reg_host<'a>(url: &'a ServoUrl) -> Option<&'a str> { + url.domain().map(reg_suffix).or(url.host_str()) +} diff --git a/components/net_traits/request.rs b/components/net_traits/request.rs index 3c780a2c5d5..05f802ea183 100644 --- a/components/net_traits/request.rs +++ b/components/net_traits/request.rs @@ -208,7 +208,6 @@ pub struct Request { pub url_list: RefCell<Vec<ServoUrl>>, pub redirect_count: Cell<u32>, pub response_tainting: Cell<ResponseTainting>, - pub done: Cell<bool>, } impl Request { @@ -246,7 +245,6 @@ impl Request { url_list: RefCell::new(vec![url]), redirect_count: Cell::new(0), response_tainting: Cell::new(ResponseTainting::Basic), - done: Cell::new(false) } } diff --git a/components/plugins/jstraceable.rs b/components/plugins/jstraceable.rs index f1e0ed496b6..233f90b3bb7 100644 --- a/components/plugins/jstraceable.rs +++ b/components/plugins/jstraceable.rs @@ -12,6 +12,7 @@ pub fn expand_dom_struct(cx: &mut ExtCtxt, sp: Span, _: &MetaItem, anno: Annotat let mut item2 = (*item).clone(); item2.attrs.push(quote_attr!(cx, #[must_root])); item2.attrs.push(quote_attr!(cx, #[privatize])); + item2.attrs.push(quote_attr!(cx, #[repr(C)])); item2.attrs.push(quote_attr!(cx, #[derive(JSTraceable)])); item2.attrs.push(quote_attr!(cx, #[derive(HeapSizeOf)])); diff --git a/components/plugins/lints/ban.rs b/components/plugins/lints/ban.rs index 0e1ebc94721..bd152dfe313 100644 --- a/components/plugins/lints/ban.rs +++ b/components/plugins/lints/ban.rs @@ -29,19 +29,19 @@ impl EarlyLintPass for BanPass { .and_then(|t| t.get(0)) .and_then(|t| match_ty_unwrap(&**t, &["dom", "bindings", "js", "JS"])) .is_some() { - cx.span_lint(BANNED_TYPE, ty.span, "Banned type Cell<JS<T>> detected. Use MutHeap<JS<T>> instead") + cx.span_lint(BANNED_TYPE, ty.span, "Banned type Cell<JS<T>> detected. Use MutJS<JS<T>> instead") } if match_ty_unwrap(ty, &["std", "cell", "Cell"]) .and_then(|t| t.get(0)) .and_then(|t| match_ty_unwrap(&**t, &["js", "jsval", "JSVal"])) .is_some() { - cx.span_lint(BANNED_TYPE, ty.span, "Banned type Cell<JSVal> detected. Use MutHeap<JSVal> instead") + cx.span_lint(BANNED_TYPE, ty.span, "Banned type Cell<JSVal> detected. Use MutJS<JSVal> instead") } if match_ty_unwrap(ty, &["dom", "bindings", "cell", "DOMRefCell"]) .and_then(|t| t.get(0)) .and_then(|t| match_ty_unwrap(&**t, &["dom", "bindings", "js", "JS"])) .is_some() { - cx.span_lint(BANNED_TYPE, ty.span, "Banned type DOMRefCell<JS<T>> detected. Use MutHeap<JS<T>> instead") + cx.span_lint(BANNED_TYPE, ty.span, "Banned type DOMRefCell<JS<T>> detected. Use MutJS<JS<T>> instead") } } } diff --git a/components/plugins/lints/inheritance_integrity.rs b/components/plugins/lints/inheritance_integrity.rs index a47b6313db0..0c70a949c15 100644 --- a/components/plugins/lints/inheritance_integrity.rs +++ b/components/plugins/lints/inheritance_integrity.rs @@ -22,7 +22,7 @@ impl LintPass for InheritancePass { } } -impl LateLintPass for InheritancePass { +impl<'a, 'tcx> LateLintPass<'a, 'tcx> for InheritancePass { fn check_struct_def(&mut self, cx: &LateContext, def: &hir::VariantData, _n: ast::Name, _gen: &hir::Generics, id: ast::NodeId) { // Lints are run post expansion, so it's fine to use diff --git a/components/plugins/lints/privatize.rs b/components/plugins/lints/privatize.rs index f3f56a0cdc4..0eec1ad1596 100644 --- a/components/plugins/lints/privatize.rs +++ b/components/plugins/lints/privatize.rs @@ -21,7 +21,7 @@ impl LintPass for PrivatizePass { } } -impl LateLintPass for PrivatizePass { +impl<'a, 'tcx> LateLintPass<'a, 'tcx> for PrivatizePass { fn check_struct_def(&mut self, cx: &LateContext, def: &hir::VariantData, diff --git a/components/plugins/lints/transmute_type.rs b/components/plugins/lints/transmute_type.rs index 6cc1b3818a6..1488aaa9a74 100644 --- a/components/plugins/lints/transmute_type.rs +++ b/components/plugins/lints/transmute_type.rs @@ -20,7 +20,7 @@ impl LintPass for TransmutePass { } } -impl LateLintPass for TransmutePass { +impl<'a, 'tcx> LateLintPass<'a, 'tcx> for TransmutePass { fn check_expr(&mut self, cx: &LateContext, ex: &hir::Expr) { match ex.node { hir::ExprCall(ref expr, ref args) => { diff --git a/components/plugins/lints/unrooted_must_root.rs b/components/plugins/lints/unrooted_must_root.rs index a2ce68c522b..328b143593b 100644 --- a/components/plugins/lints/unrooted_must_root.rs +++ b/components/plugins/lints/unrooted_must_root.rs @@ -76,7 +76,7 @@ impl LintPass for UnrootedPass { } } -impl LateLintPass for UnrootedPass { +impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnrootedPass { /// All structs containing #[must_root] types must be #[must_root] themselves fn check_struct_def(&mut self, cx: &LateContext, @@ -119,8 +119,13 @@ impl LateLintPass for UnrootedPass { } } /// Function arguments that are #[must_root] types are not allowed - fn check_fn(&mut self, cx: &LateContext, kind: visit::FnKind, decl: &hir::FnDecl, - body: &hir::Expr, span: codemap::Span, id: ast::NodeId) { + fn check_fn(&mut self, + cx: &LateContext<'a, 'tcx>, + kind: visit::FnKind, + decl: &'tcx hir::FnDecl, + body: &'tcx hir::Expr, + span: codemap::Span, + id: ast::NodeId) { let in_new_function = match kind { visit::FnKind::ItemFn(n, _, _, _, _, _, _) | visit::FnKind::Method(n, _, _, _) => { @@ -159,8 +164,8 @@ struct FnDefVisitor<'a, 'b: 'a, 'tcx: 'a+'b> { in_new_function: bool, } -impl<'a, 'b: 'a, 'tcx: 'a+'b> visit::Visitor<'a> for FnDefVisitor<'a, 'b, 'tcx> { - fn visit_expr(&mut self, expr: &'a hir::Expr) { +impl<'a, 'b, 'tcx> visit::Visitor<'tcx> for FnDefVisitor<'a, 'b, 'tcx> { + fn visit_expr(&mut self, expr: &'tcx hir::Expr) { let cx = self.cx; fn require_rooted(cx: &LateContext, in_new_function: bool, subexpr: &hir::Expr) { @@ -194,7 +199,7 @@ impl<'a, 'b: 'a, 'tcx: 'a+'b> visit::Visitor<'a> for FnDefVisitor<'a, 'b, 'tcx> visit::walk_expr(self, expr); } - fn visit_pat(&mut self, pat: &'a hir::Pat) { + fn visit_pat(&mut self, pat: &'tcx hir::Pat) { let cx = self.cx; if let hir::PatKind::Binding(hir::BindingMode::BindByValue(_), _, _, _) = pat.node { @@ -209,13 +214,16 @@ impl<'a, 'b: 'a, 'tcx: 'a+'b> visit::Visitor<'a> for FnDefVisitor<'a, 'b, 'tcx> visit::walk_pat(self, pat); } - fn visit_fn(&mut self, kind: visit::FnKind<'a>, decl: &'a hir::FnDecl, - body: &'a hir::Expr, span: codemap::Span, id: ast::NodeId) { + fn visit_fn(&mut self, kind: visit::FnKind<'tcx>, decl: &'tcx hir::FnDecl, + body: hir::ExprId, span: codemap::Span, id: ast::NodeId) { if let visit::FnKind::Closure(_) = kind { visit::walk_fn(self, kind, decl, body, span, id); } } - fn visit_foreign_item(&mut self, _: &'a hir::ForeignItem) {} - fn visit_ty(&mut self, _: &'a hir::Ty) { } + fn visit_foreign_item(&mut self, _: &'tcx hir::ForeignItem) {} + fn visit_ty(&mut self, _: &'tcx hir::Ty) { } + fn nested_visit_map<'this>(&'this mut self) -> hir::intravisit::NestedVisitorMap<'this, 'tcx> { + hir::intravisit::NestedVisitorMap::OnlyBodies(&self.cx.tcx.map) + } } diff --git a/components/profile/Cargo.toml b/components/profile/Cargo.toml index f542c5a3f03..7ca08bccd6a 100644 --- a/components/profile/Cargo.toml +++ b/components/profile/Cargo.toml @@ -12,13 +12,13 @@ path = "lib.rs" [dependencies] profile_traits = {path = "../profile_traits"} plugins = {path = "../plugins"} -util = {path = "../util", features = ["servo"]} ipc-channel = "0.5" heartbeats-simple = "0.3" log = "0.3.5" serde = "0.8" serde_derive = "0.8" serde_json = "0.8" +servo_config = {path = "../config", features = ["servo"]} time = "0.1.12" [target.'cfg(target_os = "macos")'.dependencies] diff --git a/components/profile/heartbeats.rs b/components/profile/heartbeats.rs index 7579e6f3a39..b05cbf74b71 100644 --- a/components/profile/heartbeats.rs +++ b/components/profile/heartbeats.rs @@ -6,13 +6,13 @@ use heartbeats_simple::HeartbeatPow as Heartbeat; use heartbeats_simple::HeartbeatPowContext as HeartbeatContext; use profile_traits::time::ProfilerCategory; +use servo_config::opts; use std::collections::HashMap; use std::env::var_os; use std::error::Error; use std::fs::File; use std::mem; use std::path::Path; -use util::opts; static mut HBS: Option<*mut HashMap<ProfilerCategory, Heartbeat>> = None; diff --git a/components/profile/lib.rs b/components/profile/lib.rs index 5e1c4804dc9..df5e6706024 100644 --- a/components/profile/lib.rs +++ b/components/profile/lib.rs @@ -27,10 +27,10 @@ extern crate serde; #[macro_use] extern crate serde_derive; extern crate serde_json; +extern crate servo_config; #[cfg(target_os = "macos")] extern crate task_info; extern crate time as std_time; -extern crate util; #[allow(unsafe_code)] mod heartbeats; diff --git a/components/profile/mem.rs b/components/profile/mem.rs index b27ceeb898f..002cd4d1cb7 100644 --- a/components/profile/mem.rs +++ b/components/profile/mem.rs @@ -13,7 +13,6 @@ use std::cmp::Ordering; use std::collections::HashMap; use std::thread; use time::duration_from_seconds; -use util::thread::spawn_named; pub struct Profiler { /// The port through which messages are received. @@ -33,22 +32,22 @@ impl Profiler { // Create the timer thread if a period was provided. if let Some(period) = period { let chan = chan.clone(); - spawn_named("Memory profiler timer".to_owned(), move || { + thread::Builder::new().name("Memory profiler timer".to_owned()).spawn(move || { loop { thread::sleep(duration_from_seconds(period)); if chan.send(ProfilerMsg::Print).is_err() { break; } } - }); + }).expect("Thread spawning failed"); } // Always spawn the memory profiler. If there is no timer thread it won't receive regular // `Print` events, but it will still receive the other events. - spawn_named("Memory profiler".to_owned(), move || { + thread::Builder::new().name("Memory profiler".to_owned()).spawn(move || { let mut mem_profiler = Profiler::new(port); mem_profiler.start(); - }); + }).expect("Thread spawning failed"); let mem_profiler_chan = ProfilerChan(chan); diff --git a/components/profile/time.rs b/components/profile/time.rs index 648c31f83d6..c246aabee1b 100644 --- a/components/profile/time.rs +++ b/components/profile/time.rs @@ -9,6 +9,7 @@ use ipc_channel::ipc::{self, IpcReceiver}; use profile_traits::energy::{energy_interval_ms, read_energy_uj}; use profile_traits::time::{ProfilerCategory, ProfilerChan, ProfilerMsg, TimerMetadata}; use profile_traits::time::{TimerMetadataFrameType, TimerMetadataReflowType}; +use servo_config::opts::OutputOptions; use std::{f64, thread, u32, u64}; use std::borrow::ToOwned; use std::cmp::Ordering; @@ -22,8 +23,6 @@ use std::path::Path; use std::time::Duration; use std_time::precise_time_ns; use trace_dump::TraceDump; -use util::opts::OutputOptions; -use util::thread::spawn_named; pub trait Formattable { fn format(&self, output: &Option<OutputOptions>) -> String; @@ -176,28 +175,28 @@ impl Profiler { Some(ref option) => { // Spawn the time profiler thread let outputoption = option.clone(); - spawn_named("Time profiler".to_owned(), move || { + thread::Builder::new().name("Time profiler".to_owned()).spawn(move || { let trace = file_path.as_ref() .map(path::Path::new) .map(fs::File::create) .map(|res| TraceDump::new(res.unwrap())); let mut profiler = Profiler::new(port, trace, Some(outputoption)); profiler.start(); - }); + }).expect("Thread spawning failed"); // decide if we need to spawn the timer thread match option { &OutputOptions::FileName(_) => { /* no timer thread needed */ }, &OutputOptions::Stdout(period) => { // Spawn a timer thread let chan = chan.clone(); - spawn_named("Time profiler timer".to_owned(), move || { + thread::Builder::new().name("Time profiler timer".to_owned()).spawn(move || { loop { thread::sleep(duration_from_seconds(period)); if chan.send(ProfilerMsg::Print).is_err() { break; } } - }); + }).expect("Thread spawning failed"); }, } }, @@ -205,17 +204,17 @@ impl Profiler { // this is when the -p option hasn't been specified if file_path.is_some() { // Spawn the time profiler - spawn_named("Time profiler".to_owned(), move || { + thread::Builder::new().name("Time profiler".to_owned()).spawn(move || { let trace = file_path.as_ref() .map(path::Path::new) .map(fs::File::create) .map(|res| TraceDump::new(res.unwrap())); let mut profiler = Profiler::new(port, trace, None); profiler.start(); - }); + }).expect("Thread spawning failed"); } else { // No-op to handle messages when the time profiler is not printing: - spawn_named("Time profiler".to_owned(), move || { + thread::Builder::new().name("Time profiler".to_owned()).spawn(move || { loop { match port.recv() { Err(_) => break, @@ -226,7 +225,7 @@ impl Profiler { _ => {} } } - }); + }).expect("Thread spawning failed"); } } } @@ -247,7 +246,7 @@ impl Profiler { const MAX_ENERGY_INTERVAL_MS: u32 = 1000; let interval_ms = enforce_range(MIN_ENERGY_INTERVAL_MS, MAX_ENERGY_INTERVAL_MS, energy_interval_ms()); let loop_count: u32 = (interval_ms as f32 / SLEEP_MS as f32).ceil() as u32; - spawn_named("Application heartbeat profiler".to_owned(), move || { + thread::Builder::new().name("Application heartbeat profiler".to_owned()).spawn(move || { let mut start_time = precise_time_ns(); let mut start_energy = read_energy_uj(); loop { @@ -272,7 +271,7 @@ impl Profiler { start_time = end_time; start_energy = end_energy; } - }); + }).expect("Thread spawning failed"); } profiler_chan @@ -297,12 +296,7 @@ impl Profiler { } fn find_or_insert(&mut self, k: (ProfilerCategory, Option<TimerMetadata>), t: f64) { - match self.buckets.get_mut(&k) { - None => {}, - Some(v) => { v.push(t); return; }, - } - - self.buckets.insert(k, vec!(t)); + self.buckets.entry(k).or_insert_with(Vec::new).push(t); } fn handle_msg(&mut self, msg: ProfilerMsg) -> bool { diff --git a/components/profile_traits/Cargo.toml b/components/profile_traits/Cargo.toml index bf765fa45f2..954fb2907a1 100644 --- a/components/profile_traits/Cargo.toml +++ b/components/profile_traits/Cargo.toml @@ -20,7 +20,7 @@ log = "0.3.5" plugins = {path = "../plugins"} serde = "0.8" serde_derive = "0.8" +servo_config = {path = "../config"} signpost = {git = "https://github.com/pcwalton/signpost.git"} time = "0.1.12" -util = {path = "../util"} diff --git a/components/profile_traits/lib.rs b/components/profile_traits/lib.rs index 7f67575f6cb..ab53e33c4de 100644 --- a/components/profile_traits/lib.rs +++ b/components/profile_traits/lib.rs @@ -18,8 +18,8 @@ extern crate log; extern crate serde; #[macro_use] extern crate serde_derive; +extern crate servo_config; extern crate signpost; -extern crate util; #[allow(unsafe_code)] pub mod energy; diff --git a/components/profile_traits/time.rs b/components/profile_traits/time.rs index ae114f98bc0..f7b62e17139 100644 --- a/components/profile_traits/time.rs +++ b/components/profile_traits/time.rs @@ -7,8 +7,8 @@ extern crate time as std_time; use energy::read_energy_uj; use ipc_channel::ipc::IpcSender; use self::std_time::precise_time_ns; +use servo_config::opts; use signpost; -use util::opts; #[derive(PartialEq, Clone, PartialOrd, Eq, Ord, Debug, Deserialize, Serialize)] pub struct TimerMetadata { diff --git a/components/remutex/Cargo.toml b/components/remutex/Cargo.toml new file mode 100644 index 00000000000..8bb165d40df --- /dev/null +++ b/components/remutex/Cargo.toml @@ -0,0 +1,14 @@ +[package] +name = "servo_remutex" +version = "0.0.1" +authors = ["The Servo Project Developers"] +license = "MPL-2.0" +publish = false + +[lib] +name = "servo_remutex" +path = "lib.rs" + +[dependencies] +lazy_static = "0.2" +log = "0.3.5" diff --git a/components/util/remutex.rs b/components/remutex/lib.rs index a574de9cfb3..b2ea30d11a4 100644 --- a/components/util/remutex.rs +++ b/components/remutex/lib.rs @@ -10,6 +10,12 @@ //! It provides the same interface as https://github.com/rust-lang/rust/blob/master/src/libstd/sys/common/remutex.rs //! so if those types are ever exported, we should be able to replace this implemtation. +#![feature(nonzero)] + +extern crate core; +#[macro_use] extern crate lazy_static; +#[macro_use] extern crate log; + use core::nonzero::NonZero; use std::cell::{Cell, UnsafeCell}; use std::ops::Deref; diff --git a/components/script/Cargo.toml b/components/script/Cargo.toml index 293c2aefe02..05af21f1dc1 100644 --- a/components/script/Cargo.toml +++ b/components/script/Cargo.toml @@ -70,13 +70,14 @@ script_traits = {path = "../script_traits"} selectors = "0.15" serde = "0.8" servo_atoms = {path = "../atoms"} +servo_config = {path = "../config", features = ["servo"] } +servo_geometry = {path = "../geometry" } servo_url = {path = "../url", features = ["servo"] } smallvec = "0.1" style = {path = "../style"} style_traits = {path = "../style_traits"} time = "0.1.12" url = {version = "1.2", features = ["heap_size", "query_encoding"]} -util = {path = "../util"} uuid = {version = "0.3.1", features = ["v4"]} websocket = "0.17" xml5ever = {version = "0.2", features = ["unstable"]} diff --git a/components/script/dom/abstractworker.rs b/components/script/dom/abstractworker.rs index ee8ee31abc0..8d92680fbed 100644 --- a/components/script/dom/abstractworker.rs +++ b/components/script/dom/abstractworker.rs @@ -31,7 +31,7 @@ impl<T: DomObject> SimpleWorkerErrorHandler<T> { #[derive(Copy, Clone)] pub struct SharedRt { - pub rt: *mut JSRuntime + rt: *mut JSRuntime } impl SharedRt { @@ -47,10 +47,6 @@ impl SharedRt { JS_RequestInterruptCallback(self.rt); } } - - pub fn rt(&self) -> *mut JSRuntime { - self.rt - } } #[allow(unsafe_code)] unsafe impl Send for SharedRt {} diff --git a/components/script/dom/attr.rs b/components/script/dom/attr.rs index 8b9587c9151..c44cfd4367d 100644 --- a/components/script/dom/attr.rs +++ b/components/script/dom/attr.rs @@ -6,8 +6,7 @@ use devtools_traits::AttrInfo; use dom::bindings::cell::DOMRefCell; use dom::bindings::codegen::Bindings::AttrBinding::{self, AttrMethods}; use dom::bindings::inheritance::Castable; -use dom::bindings::js::{JS, MutNullableHeap}; -use dom::bindings::js::{LayoutJS, Root, RootedReference}; +use dom::bindings::js::{LayoutJS, MutNullableJS, Root, RootedReference}; use dom::bindings::reflector::{Reflector, reflect_dom_object}; use dom::bindings::str::DOMString; use dom::element::{AttributeMutation, Element}; @@ -28,7 +27,7 @@ pub struct Attr { value: DOMRefCell<AttrValue>, /// the element that owns this attribute. - owner: MutNullableHeap<JS<Element>>, + owner: MutNullableJS<Element>, } impl Attr { @@ -48,7 +47,7 @@ impl Attr { prefix: prefix, }, value: DOMRefCell::new(value), - owner: MutNullableHeap::new(owner), + owner: MutNullableJS::new(owner), } } diff --git a/components/script/dom/beforeunloadevent.rs b/components/script/dom/beforeunloadevent.rs index c79ca70c28e..d9162002016 100644 --- a/components/script/dom/beforeunloadevent.rs +++ b/components/script/dom/beforeunloadevent.rs @@ -2,6 +2,8 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ +#![allow(dead_code)] + use dom::bindings::cell::DOMRefCell; use dom::bindings::codegen::Bindings::BeforeUnloadEventBinding; use dom::bindings::codegen::Bindings::BeforeUnloadEventBinding::BeforeUnloadEventMethods; diff --git a/components/script/dom/bindings/codegen/CodegenRust.py b/components/script/dom/bindings/codegen/CodegenRust.py index dc39048ab40..d68b1adf33e 100644 --- a/components/script/dom/bindings/codegen/CodegenRust.py +++ b/components/script/dom/bindings/codegen/CodegenRust.py @@ -4260,7 +4260,9 @@ class CGUnionConversionStruct(CGThing): return CGWrapper( CGIndenter(jsConversion, 4), - pre="unsafe fn TryConvertTo%s(cx: *mut JSContext, value: HandleValue) -> %s {\n" % (t.name, returnType), + # TryConvertToObject is unused, but not generating it while generating others is tricky. + pre="#[allow(dead_code)] unsafe fn TryConvertTo%s(cx: *mut JSContext, value: HandleValue) -> %s {\n" + % (t.name, returnType), post="\n}") def define(self): @@ -5603,7 +5605,7 @@ def generate_imports(config, cgthings, descriptors, callbacks=None, dictionaries 'dom::globalscope::GlobalScope', 'mem::heap_size_of_raw_self_and_children', 'libc', - 'util::prefs::PREFS', + 'servo_config::prefs::PREFS', 'std::borrow::ToOwned', 'std::cmp', 'std::mem', diff --git a/components/script/dom/bindings/constant.rs b/components/script/dom/bindings/constant.rs index 7d453a1fd09..42f10055080 100644 --- a/components/script/dom/bindings/constant.rs +++ b/components/script/dom/bindings/constant.rs @@ -20,6 +20,7 @@ pub struct ConstantSpec { /// Representation of an IDL constant value. #[derive(Clone)] +#[allow(dead_code)] pub enum ConstantVal { /// `long` constant. IntVal(i32), diff --git a/components/script/dom/bindings/conversions.rs b/components/script/dom/bindings/conversions.rs index adfe242b5f8..18a2deb8f0f 100644 --- a/components/script/dom/bindings/conversions.rs +++ b/components/script/dom/bindings/conversions.rs @@ -56,8 +56,8 @@ use js::jsval::{ObjectValue, StringValue}; use js::rust::{ToString, get_object_class, is_dom_class, is_dom_object, maybe_wrap_value}; use libc; use num_traits::Float; +use servo_config::opts; use std::{char, mem, ptr, slice}; -use util::opts; /// A trait to check whether a given `JSObject` implements an IDL interface. pub trait IDLInterface { diff --git a/components/script/dom/bindings/guard.rs b/components/script/dom/bindings/guard.rs index 114045a62e8..25a52fbe84c 100644 --- a/components/script/dom/bindings/guard.rs +++ b/components/script/dom/bindings/guard.rs @@ -5,7 +5,7 @@ //! Machinery to conditionally expose things. use js::jsapi::{HandleObject, JSContext}; -use util::prefs::PREFS; +use servo_config::prefs::PREFS; /// A container with a condition. pub struct Guard<T: Clone + Copy> { diff --git a/components/script/dom/bindings/js.rs b/components/script/dom/bindings/js.rs index fa7999ebcb1..bdd2b81ce37 100644 --- a/components/script/dom/bindings/js.rs +++ b/components/script/dom/bindings/js.rs @@ -229,20 +229,6 @@ impl LayoutJS<Node> { } } - -/// A trait to be implemented for JS-managed types that can be stored in -/// mutable member fields. -/// -/// Do not implement this trait yourself. -pub trait HeapGCValue: JSTraceable { -} - -impl HeapGCValue for Heap<JSVal> { -} - -impl<T: DomObject> HeapGCValue for JS<T> { -} - /// A holder that provides interior mutability for GC-managed JSVals. /// /// Must be used in place of traditional interior mutability to ensure proper @@ -293,20 +279,20 @@ impl MutHeapJSVal { /// on `JS<T>`. #[must_root] #[derive(JSTraceable)] -pub struct MutHeap<T: HeapGCValue> { - val: UnsafeCell<T>, +pub struct MutJS<T: DomObject> { + val: UnsafeCell<JS<T>>, } -impl<T: DomObject> MutHeap<JS<T>> { - /// Create a new `MutHeap`. - pub fn new(initial: &T) -> MutHeap<JS<T>> { +impl<T: DomObject> MutJS<T> { + /// Create a new `MutJS`. + pub fn new(initial: &T) -> MutJS<T> { debug_assert!(thread_state::get().is_script()); - MutHeap { + MutJS { val: UnsafeCell::new(JS::from_ref(initial)), } } - /// Set this `MutHeap` to the given value. + /// Set this `MutJS` to the given value. pub fn set(&self, val: &T) { debug_assert!(thread_state::get().is_script()); unsafe { @@ -314,7 +300,7 @@ impl<T: DomObject> MutHeap<JS<T>> { } } - /// Get the value in this `MutHeap`. + /// Get the value in this `MutJS`. pub fn get(&self) -> Root<T> { debug_assert!(thread_state::get().is_script()); unsafe { @@ -323,14 +309,14 @@ impl<T: DomObject> MutHeap<JS<T>> { } } -impl<T: HeapGCValue> HeapSizeOf for MutHeap<T> { +impl<T: DomObject> HeapSizeOf for MutJS<T> { fn heap_size_of_children(&self) -> usize { // See comment on HeapSizeOf for JS<T>. 0 } } -impl<T: DomObject> PartialEq for MutHeap<JS<T>> { +impl<T: DomObject> PartialEq for MutJS<T> { fn eq(&self, other: &Self) -> bool { unsafe { *self.val.get() == *other.val.get() @@ -338,7 +324,7 @@ impl<T: DomObject> PartialEq for MutHeap<JS<T>> { } } -impl<T: DomObject + PartialEq> PartialEq<T> for MutHeap<JS<T>> { +impl<T: DomObject + PartialEq> PartialEq<T> for MutJS<T> { fn eq(&self, other: &T) -> bool { unsafe { **self.val.get() == *other @@ -354,15 +340,15 @@ impl<T: DomObject + PartialEq> PartialEq<T> for MutHeap<JS<T>> { /// on `JS<T>`. #[must_root] #[derive(JSTraceable)] -pub struct MutNullableHeap<T: HeapGCValue> { - ptr: UnsafeCell<Option<T>>, +pub struct MutNullableJS<T: DomObject> { + ptr: UnsafeCell<Option<JS<T>>>, } -impl<T: DomObject> MutNullableHeap<JS<T>> { - /// Create a new `MutNullableHeap`. - pub fn new(initial: Option<&T>) -> MutNullableHeap<JS<T>> { +impl<T: DomObject> MutNullableJS<T> { + /// Create a new `MutNullableJS`. + pub fn new(initial: Option<&T>) -> MutNullableJS<T> { debug_assert!(thread_state::get().is_script()); - MutNullableHeap { + MutNullableJS { ptr: UnsafeCell::new(initial.map(JS::from_ref)), } } @@ -400,7 +386,7 @@ impl<T: DomObject> MutNullableHeap<JS<T>> { } } - /// Set this `MutNullableHeap` to the given value. + /// Set this `MutNullableJS` to the given value. pub fn set(&self, val: Option<&T>) { debug_assert!(thread_state::get().is_script()); unsafe { @@ -416,7 +402,7 @@ impl<T: DomObject> MutNullableHeap<JS<T>> { } } -impl<T: DomObject> PartialEq for MutNullableHeap<JS<T>> { +impl<T: DomObject> PartialEq for MutNullableJS<T> { fn eq(&self, other: &Self) -> bool { unsafe { *self.ptr.get() == *other.ptr.get() @@ -424,7 +410,7 @@ impl<T: DomObject> PartialEq for MutNullableHeap<JS<T>> { } } -impl<'a, T: DomObject> PartialEq<Option<&'a T>> for MutNullableHeap<JS<T>> { +impl<'a, T: DomObject> PartialEq<Option<&'a T>> for MutNullableJS<T> { fn eq(&self, other: &Option<&T>) -> bool { unsafe { *self.ptr.get() == other.map(JS::from_ref) @@ -432,17 +418,17 @@ impl<'a, T: DomObject> PartialEq<Option<&'a T>> for MutNullableHeap<JS<T>> { } } -impl<T: HeapGCValue> Default for MutNullableHeap<T> { +impl<T: DomObject> Default for MutNullableJS<T> { #[allow(unrooted_must_root)] - fn default() -> MutNullableHeap<T> { + fn default() -> MutNullableJS<T> { debug_assert!(thread_state::get().is_script()); - MutNullableHeap { + MutNullableJS { ptr: UnsafeCell::new(None), } } } -impl<T: HeapGCValue> HeapSizeOf for MutNullableHeap<T> { +impl<T: DomObject> HeapSizeOf for MutNullableJS<T> { fn heap_size_of_children(&self) -> usize { // See comment on HeapSizeOf for JS<T>. 0 diff --git a/components/script/dom/bindings/mod.rs b/components/script/dom/bindings/mod.rs index 27504efda7c..4e7920828dd 100644 --- a/components/script/dom/bindings/mod.rs +++ b/components/script/dom/bindings/mod.rs @@ -129,6 +129,10 @@ //! return `Err()` from the method with the appropriate [error value] //! (error/enum.Error.html). +#![allow(unsafe_code)] +#![deny(missing_docs)] +#![deny(non_snake_case)] + pub mod callback; pub mod cell; pub mod constant; @@ -153,7 +157,7 @@ pub mod weakref; pub mod xmlname; /// Generated JS-Rust bindings. -#[allow(missing_docs, non_snake_case)] +#[allow(dead_code, missing_docs, non_snake_case)] pub mod codegen { #[allow(unrooted_must_root)] pub mod Bindings { diff --git a/components/script/dom/bindings/str.rs b/components/script/dom/bindings/str.rs index d7984939e28..896c2af5b24 100644 --- a/components/script/dom/bindings/str.rs +++ b/components/script/dom/bindings/str.rs @@ -286,6 +286,12 @@ impl Into<Vec<u8>> for DOMString { } } +impl<'a> Into<Cow<'a, str>> for DOMString { + fn into(self) -> Cow<'a, str> { + self.0.into() + } +} + impl Extend<char> for DOMString { fn extend<I>(&mut self, iterable: I) where I: IntoIterator<Item=char> { self.0.extend(iterable) diff --git a/components/script/dom/bindings/trace.rs b/components/script/dom/bindings/trace.rs index 4c650719bff..850bef189c7 100644 --- a/components/script/dom/bindings/trace.rs +++ b/components/script/dom/bindings/trace.rs @@ -48,7 +48,6 @@ use euclid::length::Length as EuclidLength; use euclid::rect::Rect; use euclid::size::Size2D; use html5ever::tokenizer::buffer_queue::BufferQueue; -use html5ever::tree_builder::QuirksMode; use html5ever_atoms::{Prefix, LocalName, Namespace, QualName}; use hyper::header::Headers; use hyper::method::Method; @@ -59,7 +58,6 @@ use js::glue::{CallObjectTracer, CallUnbarrieredObjectTracer, CallValueTracer}; use js::jsapi::{GCTraceKindToAscii, Heap, JSObject, JSTracer, TraceKind}; use js::jsval::JSVal; use js::rust::Runtime; -use libc; use msg::constellation_msg::{FrameId, FrameType, PipelineId}; use net_traits::{Metadata, NetworkError, ReferrerPolicy, ResourceThreads}; use net_traits::filemanager_thread::RelativePos; @@ -82,7 +80,7 @@ use serde::{Deserialize, Serialize}; use servo_atoms::Atom; use servo_url::ServoUrl; use smallvec::SmallVec; -use std::cell::{Cell, UnsafeCell}; +use std::cell::{Cell, RefCell, UnsafeCell}; use std::collections::{BTreeMap, HashMap, HashSet, VecDeque}; use std::hash::{BuildHasher, Hash}; use std::ops::{Deref, DerefMut}; @@ -93,13 +91,14 @@ use std::sync::atomic::{AtomicBool, AtomicUsize}; use std::sync::mpsc::{Receiver, Sender}; use std::time::{SystemTime, Instant}; use style::attr::{AttrIdentifier, AttrValue, LengthOrPercentageOrAuto}; +use style::context::QuirksMode; use style::element_state::*; use style::font_face::FontFaceRule; use style::keyframes::Keyframe; use style::media_queries::MediaList; use style::properties::PropertyDeclarationBlock; use style::selector_parser::{PseudoElement, Snapshot}; -use style::stylesheets::{CssRules, KeyframesRule, MediaRule, NamespaceRule, StyleRule}; +use style::stylesheets::{CssRules, KeyframesRule, MediaRule, NamespaceRule, StyleRule, ImportRule}; use style::values::specified::Length; use style::viewport::ViewportRule; use time::Duration; @@ -526,6 +525,12 @@ unsafe impl JSTraceable for RwLock<KeyframesRule> { } } +unsafe impl JSTraceable for RwLock<ImportRule> { + unsafe fn trace(&self, _trc: *mut JSTracer) { + // Do nothing. + } +} + unsafe impl JSTraceable for RwLock<MediaRule> { unsafe fn trace(&self, _trc: *mut JSTracer) { // Do nothing. @@ -568,27 +573,16 @@ unsafe impl JSTraceable for RwLock<MediaList> { } } -/// Homemade trait object for JSTraceable things -struct TraceableInfo { - pub ptr: *const libc::c_void, - pub trace: unsafe fn(obj: *const libc::c_void, tracer: *mut JSTracer), -} - /// Holds a set of JSTraceables that need to be rooted pub struct RootedTraceableSet { - set: Vec<TraceableInfo>, + set: Vec<*const JSTraceable>, } -#[allow(missing_docs)] // FIXME -mod dummy { // Attributes don’t apply through the macro. - use std::cell::RefCell; - use std::rc::Rc; - use super::RootedTraceableSet; +thread_local!( /// TLV Holds a set of JSTraceables that need to be rooted - thread_local!(pub static ROOTED_TRACEABLES: Rc<RefCell<RootedTraceableSet>> = - Rc::new(RefCell::new(RootedTraceableSet::new()))); -} -pub use self::dummy::ROOTED_TRACEABLES; + static ROOTED_TRACEABLES: RefCell<RootedTraceableSet> = + RefCell::new(RootedTraceableSet::new()); +); impl RootedTraceableSet { fn new() -> RootedTraceableSet { @@ -597,12 +591,12 @@ impl RootedTraceableSet { } } - unsafe fn remove<T: JSTraceable>(traceable: &T) { + unsafe fn remove(traceable: *const JSTraceable) { ROOTED_TRACEABLES.with(|ref traceables| { let mut traceables = traceables.borrow_mut(); let idx = match traceables.set.iter() - .rposition(|x| x.ptr == traceable as *const T as *const _) { + .rposition(|x| *x == traceable) { Some(idx) => idx, None => unreachable!(), }; @@ -610,25 +604,15 @@ impl RootedTraceableSet { }); } - unsafe fn add<T: JSTraceable>(traceable: &T) { + unsafe fn add(traceable: *const JSTraceable) { ROOTED_TRACEABLES.with(|ref traceables| { - unsafe fn trace<T: JSTraceable>(obj: *const libc::c_void, tracer: *mut JSTracer) { - let obj: &T = &*(obj as *const T); - obj.trace(tracer); - } - - let mut traceables = traceables.borrow_mut(); - let info = TraceableInfo { - ptr: traceable as *const T as *const libc::c_void, - trace: trace::<T>, - }; - traceables.set.push(info); + traceables.borrow_mut().set.push(traceable); }) } unsafe fn trace(&self, tracer: *mut JSTracer) { - for info in &self.set { - (info.trace)(info.ptr, tracer); + for traceable in &self.set { + (**traceable).trace(tracer); } } } @@ -640,11 +624,11 @@ impl RootedTraceableSet { /// If you have an arbitrary number of DomObjects to root, use rooted_vec!. /// If you know what you're doing, use this. #[derive(JSTraceable)] -pub struct RootedTraceable<'a, T: 'a + JSTraceable> { +pub struct RootedTraceable<'a, T: 'static + JSTraceable> { ptr: &'a T, } -impl<'a, T: JSTraceable> RootedTraceable<'a, T> { +impl<'a, T: JSTraceable + 'static> RootedTraceable<'a, T> { /// Root a JSTraceable thing for the life of this RootedTraceable pub fn new(traceable: &'a T) -> RootedTraceable<'a, T> { unsafe { @@ -656,7 +640,7 @@ impl<'a, T: JSTraceable> RootedTraceable<'a, T> { } } -impl<'a, T: JSTraceable> Drop for RootedTraceable<'a, T> { +impl<'a, T: JSTraceable + 'static> Drop for RootedTraceable<'a, T> { fn drop(&mut self) { unsafe { RootedTraceableSet::remove(self.ptr); @@ -686,15 +670,29 @@ impl<T: JSTraceable> RootableVec<T> { /// A vector of items that are rooted for the lifetime 'a. #[allow_unrooted_interior] -pub struct RootedVec<'a, T: 'a + JSTraceable> { +pub struct RootedVec<'a, T: 'static + JSTraceable> { root: &'a mut RootableVec<T>, } -impl<'a, T: JSTraceable + DomObject> RootedVec<'a, JS<T>> { +impl<'a, T: 'static + JSTraceable> RootedVec<'a, T> { /// Create a vector of items of type T that is rooted for /// the lifetime of this struct - pub fn new<I: Iterator<Item = Root<T>>>(root: &'a mut RootableVec<JS<T>>, iter: I) - -> RootedVec<'a, JS<T>> { + pub fn new(root: &'a mut RootableVec<T>) -> Self { + unsafe { + RootedTraceableSet::add(root); + } + RootedVec { + root: root, + } + } +} + +impl<'a, T: 'static + JSTraceable + DomObject> RootedVec<'a, JS<T>> { + /// Create a vector of items of type JS<T> that is rooted for + /// the lifetime of this struct + pub fn from_iter<I>(root: &'a mut RootableVec<JS<T>>, iter: I) -> Self + where I: Iterator<Item = Root<T>> + { unsafe { RootedTraceableSet::add(root); } @@ -705,7 +703,7 @@ impl<'a, T: JSTraceable + DomObject> RootedVec<'a, JS<T>> { } } -impl<'a, T: JSTraceable> Drop for RootedVec<'a, T> { +impl<'a, T: JSTraceable + 'static> Drop for RootedVec<'a, T> { fn drop(&mut self) { self.clear(); unsafe { diff --git a/components/script/dom/bluetooth.rs b/components/script/dom/bluetooth.rs index 5a657eb6459..dcbb398a4ee 100644 --- a/components/script/dom/bluetooth.rs +++ b/components/script/dom/bluetooth.rs @@ -2,8 +2,8 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -use bluetooth_traits::{BluetoothError, BluetoothRequest}; -use bluetooth_traits::{BluetoothResponse, BluetoothResponseListener, BluetoothResponseResult}; +use bluetooth_traits::{BluetoothError, BluetoothRequest, GATTType}; +use bluetooth_traits::{BluetoothResponse, BluetoothResponseResult}; use bluetooth_traits::blocklist::{Blocklist, uuid_is_blocklisted}; use bluetooth_traits::scanfilter::{BluetoothScanfilter, BluetoothScanfilterSequence}; use bluetooth_traits::scanfilter::{RequestDeviceoptions, ServiceUUIDSequence}; @@ -13,22 +13,21 @@ use dom::bindings::codegen::Bindings::BluetoothBinding::{self, BluetoothDataFilt use dom::bindings::codegen::Bindings::BluetoothBinding::{BluetoothMethods, RequestDeviceOptions}; use dom::bindings::codegen::Bindings::EventHandlerBinding::EventHandlerNonNull; use dom::bindings::codegen::UnionTypes::StringOrUnsignedLong; -use dom::bindings::error::Error::{self, NotFound, Security, Type}; +use dom::bindings::error::Error::{self, Network, NotFound, Security, Type}; use dom::bindings::error::Fallible; -use dom::bindings::js::{JS, MutHeap, Root}; +use dom::bindings::js::{MutJS, Root}; use dom::bindings::refcounted::{Trusted, TrustedPromise}; use dom::bindings::reflector::{DomObject, reflect_dom_object}; use dom::bindings::str::DOMString; -use dom::bluetoothadvertisingdata::BluetoothAdvertisingData; use dom::bluetoothdevice::BluetoothDevice; -use dom::bluetoothuuid::{BluetoothServiceUUID, BluetoothUUID}; +use dom::bluetoothuuid::{BluetoothServiceUUID, BluetoothUUID, UUID}; use dom::eventtarget::EventTarget; use dom::globalscope::GlobalScope; use dom::promise::Promise; use ipc_channel::ipc::{self, IpcSender}; use ipc_channel::router::ROUTER; use js::jsapi::{JSAutoCompartment, JSContext}; -use network_listener::{NetworkListener, PreInvoke}; +use script_thread::Runnable; use std::collections::HashMap; use std::rc::Rc; use std::str::FromStr; @@ -62,9 +61,7 @@ pub trait AsyncBluetoothListener { fn handle_response(&self, result: BluetoothResponse, cx: *mut JSContext, promise: &Rc<Promise>); } -impl<Listener: AsyncBluetoothListener + DomObject> PreInvoke for BluetoothContext<Listener> {} - -impl<Listener: AsyncBluetoothListener + DomObject> BluetoothResponseListener for BluetoothContext<Listener> { +impl<T: AsyncBluetoothListener + DomObject> BluetoothContext<T> { #[allow(unrooted_must_root)] fn response(&mut self, response: BluetoothResponseResult) { let promise = self.promise.take().expect("bt promise is missing").root(); @@ -86,7 +83,7 @@ impl<Listener: AsyncBluetoothListener + DomObject> BluetoothResponseListener for #[dom_struct] pub struct Bluetooth { eventtarget: EventTarget, - device_instance_map: DOMRefCell<HashMap<String, MutHeap<JS<BluetoothDevice>>>>, + device_instance_map: DOMRefCell<HashMap<String, MutJS<BluetoothDevice>>>, } impl Bluetooth { @@ -107,6 +104,10 @@ impl Bluetooth { self.global().as_window().bluetooth_thread() } + pub fn get_device_map(&self) -> &DOMRefCell<HashMap<String, MutJS<BluetoothDevice>>> { + &self.device_instance_map + } + // https://webbluetoothcg.github.io/web-bluetooth/#request-bluetooth-devices fn request_bluetooth_devices(&self, p: &Rc<Promise>, @@ -183,17 +184,84 @@ pub fn response_async<T: AsyncBluetoothListener + DomObject + 'static>( promise: Some(TrustedPromise::new(promise.clone())), receiver: Trusted::new(receiver), })); - let listener = NetworkListener { - context: context, - task_source: task_source, - wrapper: None, - }; ROUTER.add_route(action_receiver.to_opaque(), box move |message| { - listener.notify_response(message.to().unwrap()); + struct ListenerRunnable<T: AsyncBluetoothListener + DomObject> { + context: Arc<Mutex<BluetoothContext<T>>>, + action: BluetoothResponseResult, + } + + impl<T: AsyncBluetoothListener + DomObject> Runnable for ListenerRunnable<T> { + fn handler(self: Box<Self>) { + let this = *self; + let mut context = this.context.lock().unwrap(); + context.response(this.action); + } + } + + let runnable = box ListenerRunnable { + context: context.clone(), + action: message.to().unwrap(), + }; + + let result = task_source.queue_wrapperless(runnable); + if let Err(err) = result { + warn!("failed to deliver network data: {:?}", err); + } }); action_sender } +#[allow(unrooted_must_root)] +// https://webbluetoothcg.github.io/web-bluetooth/#getgattchildren +pub fn get_gatt_children<T, F> ( + attribute: &T, + single: bool, + uuid_canonicalizer: F, + uuid: Option<StringOrUnsignedLong>, + instance_id: String, + connected: bool, + child_type: GATTType) + -> Rc<Promise> + where T: AsyncBluetoothListener + DomObject + 'static, + F: FnOnce(StringOrUnsignedLong) -> Fallible<UUID> { + let p = Promise::new(&attribute.global()); + let p_cx = p.global().get_cx(); + + let result_uuid = if let Some(u) = uuid { + // Step 1. + let canonicalized = match uuid_canonicalizer(u) { + Ok(canonicalized_uuid) => canonicalized_uuid.to_string(), + Err(e) => { + p.reject_error(p_cx, e); + return p; + } + }; + // Step 2. + if uuid_is_blocklisted(canonicalized.as_ref(), Blocklist::All) { + p.reject_error(p_cx, Security); + return p; + } + Some(canonicalized) + } else { + None + }; + + // Step 3 - 4. + if !connected { + p.reject_error(p_cx, Network); + return p; + } + + // TODO: Step 5: Implement representedDevice internal slot for BluetoothDevice. + + // Note: Steps 6 - 7 are implemented in components/bluetooth/lib.rs in get_descriptor function + // and in handle_response function. + let sender = response_async(&p, attribute); + attribute.global().as_window().bluetooth_thread().send( + BluetoothRequest::GetGATTChildren(instance_id, result_uuid, single, child_type, sender)).unwrap(); + return p; +} + // https://webbluetoothcg.github.io/web-bluetooth/#bluetoothlescanfilterinit-canonicalizing fn canonicalize_filter(filter: &BluetoothLEScanFilterInit) -> Fallible<BluetoothScanfilter> { // Step 1. @@ -400,16 +468,11 @@ impl AsyncBluetoothListener for Bluetooth { if let Some(existing_device) = device_instance_map.get(&device.id.clone()) { return promise.resolve_native(promise_cx, &existing_device.get()); } - let ad_data = BluetoothAdvertisingData::new(&self.global(), - device.appearance, - device.tx_power, - device.rssi); let bt_device = BluetoothDevice::new(&self.global(), DOMString::from(device.id.clone()), device.name.map(DOMString::from), - &ad_data, &self); - device_instance_map.insert(device.id, MutHeap::new(&bt_device)); + device_instance_map.insert(device.id, MutJS::new(&bt_device)); // https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetooth-requestdevice // Step 5. promise.resolve_native(promise_cx, &bt_device); diff --git a/components/script/dom/bluetoothadvertisingdata.rs b/components/script/dom/bluetoothadvertisingdata.rs deleted file mode 100644 index 878f4fe82ec..00000000000 --- a/components/script/dom/bluetoothadvertisingdata.rs +++ /dev/null @@ -1,61 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -use dom::bindings::codegen::Bindings::BluetoothAdvertisingDataBinding; -use dom::bindings::codegen::Bindings::BluetoothAdvertisingDataBinding::BluetoothAdvertisingDataMethods; -use dom::bindings::js::Root; -use dom::bindings::reflector::{Reflector, reflect_dom_object}; -use dom::globalscope::GlobalScope; - -// https://webbluetoothcg.github.io/web-bluetooth/#bluetoothadvertisingdata -#[dom_struct] -pub struct BluetoothAdvertisingData { - reflector_: Reflector, - appearance: Option<u16>, - tx_power: Option<i8>, - rssi: Option<i8>, -} - -impl BluetoothAdvertisingData { - pub fn new_inherited(appearance: Option<u16>, - tx_power: Option<i8>, - rssi: Option<i8>) - -> BluetoothAdvertisingData { - BluetoothAdvertisingData { - reflector_: Reflector::new(), - appearance: appearance, - tx_power: tx_power, - rssi: rssi, - } - } - - pub fn new(global: &GlobalScope, - appearance: Option<u16>, - txPower: Option<i8>, - rssi: Option<i8>) - -> Root<BluetoothAdvertisingData> { - reflect_dom_object(box BluetoothAdvertisingData::new_inherited(appearance, - txPower, - rssi), - global, - BluetoothAdvertisingDataBinding::Wrap) - } -} - -impl BluetoothAdvertisingDataMethods for BluetoothAdvertisingData { - // https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetoothadvertisingdata-appearance - fn GetAppearance(&self) -> Option<u16> { - self.appearance - } - - // https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetoothadvertisingdata-txpower - fn GetTxPower(&self) -> Option<i8> { - self.tx_power - } - - // https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetoothadvertisingdata-rssi - fn GetRssi(&self) -> Option<i8> { - self.rssi - } -} diff --git a/components/script/dom/bluetoothadvertisingevent.rs b/components/script/dom/bluetoothadvertisingevent.rs new file mode 100644 index 00000000000..cc65aa4cd96 --- /dev/null +++ b/components/script/dom/bluetoothadvertisingevent.rs @@ -0,0 +1,126 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +use dom::bindings::codegen::Bindings::BluetoothAdvertisingEventBinding::{self, BluetoothAdvertisingEventInit}; +use dom::bindings::codegen::Bindings::BluetoothAdvertisingEventBinding::BluetoothAdvertisingEventMethods; +use dom::bindings::codegen::Bindings::EventBinding::EventBinding::EventMethods; +use dom::bindings::error::Fallible; +use dom::bindings::inheritance::Castable; +use dom::bindings::js::{JS, Root, RootedReference}; +use dom::bindings::reflector::reflect_dom_object; +use dom::bindings::str::DOMString; +use dom::bluetoothdevice::BluetoothDevice; +use dom::event::{Event, EventBubbles, EventCancelable}; +use dom::globalscope::GlobalScope; +use dom::window::Window; +use servo_atoms::Atom; + +// https://webbluetoothcg.github.io/web-bluetooth/#bluetoothadvertisingevent +#[dom_struct] +pub struct BluetoothAdvertisingEvent { + event: Event, + device: JS<BluetoothDevice>, + name: Option<DOMString>, + appearance: Option<u16>, + tx_power: Option<i8>, + rssi: Option<i8>, +} + +impl BluetoothAdvertisingEvent { + pub fn new_inherited(device: &BluetoothDevice, + name: Option<DOMString>, + appearance: Option<u16>, + tx_power: Option<i8>, + rssi: Option<i8>) + -> BluetoothAdvertisingEvent { + BluetoothAdvertisingEvent { + event: Event::new_inherited(), + device: JS::from_ref(device), + name: name, + appearance: appearance, + tx_power: tx_power, + rssi: rssi, + } + } + + pub fn new(global: &GlobalScope, + type_: Atom, + bubbles: EventBubbles, + cancelable: EventCancelable, + device: &BluetoothDevice, + name: Option<DOMString>, + appearance: Option<u16>, + txPower: Option<i8>, + rssi: Option<i8>) + -> Root<BluetoothAdvertisingEvent> { + let ev = reflect_dom_object(box BluetoothAdvertisingEvent::new_inherited(device, + name, + appearance, + txPower, + rssi), + global, + BluetoothAdvertisingEventBinding::Wrap); + { + let event = ev.upcast::<Event>(); + event.init_event(type_, bool::from(bubbles), bool::from(cancelable)); + } + ev + } + + // https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetoothadvertisingevent-bluetoothadvertisingevent + pub fn Constructor(window: &Window, + type_: DOMString, + init: &BluetoothAdvertisingEventInit) + -> Fallible<Root<BluetoothAdvertisingEvent>> { + let global = window.upcast::<GlobalScope>(); + let device = init.device.r(); + let name = init.name.clone(); + let appearance = init.appearance.clone(); + let txPower = init.txPower.clone(); + let rssi = init.rssi.clone(); + let bubbles = EventBubbles::from(init.parent.bubbles); + let cancelable = EventCancelable::from(init.parent.cancelable); + Ok(BluetoothAdvertisingEvent::new(global, + Atom::from(type_), + bubbles, + cancelable, + device, + name, + appearance, + txPower, + rssi)) + } +} + +impl BluetoothAdvertisingEventMethods for BluetoothAdvertisingEvent { + // https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetoothadvertisingevent-device + fn Device(&self) -> Root<BluetoothDevice> { + Root::from_ref(&*self.device) + } + + // https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetoothadvertisingevent-name + fn GetName(&self) -> Option<DOMString> { + self.name.clone() + } + + // https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetoothadvertisingevent-appearance + fn GetAppearance(&self) -> Option<u16> { + self.appearance + } + + // https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetoothadvertisingevent-txpower + fn GetTxPower(&self) -> Option<i8> { + self.tx_power + } + + // https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetoothadvertisingevent-rssi + fn GetRssi(&self) -> Option<i8> { + self.rssi + } + + // https://dom.spec.whatwg.org/#dom-event-istrusted + fn IsTrusted(&self) -> bool { + self.event.IsTrusted() + } +} diff --git a/components/script/dom/bluetoothdevice.rs b/components/script/dom/bluetoothdevice.rs index b257b82f343..d56970c0d98 100644 --- a/components/script/dom/bluetoothdevice.rs +++ b/components/script/dom/bluetoothdevice.rs @@ -2,17 +2,20 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -use bluetooth_traits::{BluetoothCharacteristicMsg, BluetoothDescriptorMsg, BluetoothServiceMsg}; +use bluetooth_traits::{BluetoothCharacteristicMsg, BluetoothDescriptorMsg}; +use bluetooth_traits::{BluetoothRequest, BluetoothResponse, BluetoothServiceMsg}; use dom::bindings::cell::DOMRefCell; use dom::bindings::codegen::Bindings::BluetoothDeviceBinding; use dom::bindings::codegen::Bindings::BluetoothDeviceBinding::BluetoothDeviceMethods; use dom::bindings::codegen::Bindings::BluetoothRemoteGATTServerBinding::BluetoothRemoteGATTServerMethods; use dom::bindings::codegen::Bindings::EventHandlerBinding::EventHandlerNonNull; -use dom::bindings::js::{JS, Root, MutHeap, MutNullableHeap}; +use dom::bindings::error::Error; +use dom::bindings::error::ErrorResult; +use dom::bindings::inheritance::Castable; +use dom::bindings::js::{MutJS, MutNullableJS, Root}; use dom::bindings::reflector::{DomObject, reflect_dom_object}; use dom::bindings::str::DOMString; -use dom::bluetooth::Bluetooth; -use dom::bluetoothadvertisingdata::BluetoothAdvertisingData; +use dom::bluetooth::{AsyncBluetoothListener, Bluetooth, response_async}; use dom::bluetoothcharacteristicproperties::BluetoothCharacteristicProperties; use dom::bluetoothremotegattcharacteristic::BluetoothRemoteGATTCharacteristic; use dom::bluetoothremotegattdescriptor::BluetoothRemoteGATTDescriptor; @@ -20,8 +23,12 @@ use dom::bluetoothremotegattserver::BluetoothRemoteGATTServer; use dom::bluetoothremotegattservice::BluetoothRemoteGATTService; use dom::eventtarget::EventTarget; use dom::globalscope::GlobalScope; +use dom::promise::Promise; +use ipc_channel::ipc::{self, IpcSender}; +use js::jsapi::JSContext; +use std::cell::Cell; use std::collections::HashMap; - +use std::rc::Rc; // https://webbluetoothcg.github.io/web-bluetooth/#bluetoothdevice #[dom_struct] @@ -29,47 +36,48 @@ pub struct BluetoothDevice { eventtarget: EventTarget, id: DOMString, name: Option<DOMString>, - ad_data: MutHeap<JS<BluetoothAdvertisingData>>, - gatt: MutNullableHeap<JS<BluetoothRemoteGATTServer>>, - context: MutHeap<JS<Bluetooth>>, - attribute_instance_map: (DOMRefCell<HashMap<String, MutHeap<JS<BluetoothRemoteGATTService>>>>, - DOMRefCell<HashMap<String, MutHeap<JS<BluetoothRemoteGATTCharacteristic>>>>, - DOMRefCell<HashMap<String, MutHeap<JS<BluetoothRemoteGATTDescriptor>>>>), + gatt: MutNullableJS<BluetoothRemoteGATTServer>, + context: MutJS<Bluetooth>, + attribute_instance_map: (DOMRefCell<HashMap<String, MutJS<BluetoothRemoteGATTService>>>, + DOMRefCell<HashMap<String, MutJS<BluetoothRemoteGATTCharacteristic>>>, + DOMRefCell<HashMap<String, MutJS<BluetoothRemoteGATTDescriptor>>>), + watching_advertisements: Cell<bool>, } impl BluetoothDevice { pub fn new_inherited(id: DOMString, name: Option<DOMString>, - ad_data: &BluetoothAdvertisingData, context: &Bluetooth) -> BluetoothDevice { BluetoothDevice { eventtarget: EventTarget::new_inherited(), id: id, name: name, - ad_data: MutHeap::new(ad_data), gatt: Default::default(), - context: MutHeap::new(context), + context: MutJS::new(context), attribute_instance_map: (DOMRefCell::new(HashMap::new()), DOMRefCell::new(HashMap::new()), DOMRefCell::new(HashMap::new())), + watching_advertisements: Cell::new(false), } } pub fn new(global: &GlobalScope, id: DOMString, name: Option<DOMString>, - adData: &BluetoothAdvertisingData, context: &Bluetooth) -> Root<BluetoothDevice> { reflect_dom_object(box BluetoothDevice::new_inherited(id, name, - adData, context), global, BluetoothDeviceBinding::Wrap) } + fn get_context(&self) -> Root<Bluetooth> { + self.context.get() + } + pub fn get_or_create_service(&self, service: &BluetoothServiceMsg, server: &BluetoothRemoteGATTServer) @@ -84,7 +92,7 @@ impl BluetoothDevice { DOMString::from(service.uuid.clone()), service.is_primary, service.instance_id.clone()); - service_map.insert(service.instance_id.clone(), MutHeap::new(&bt_service)); + service_map.insert(service.instance_id.clone(), MutJS::new(&bt_service)); return bt_service; } @@ -113,10 +121,17 @@ impl BluetoothDevice { DOMString::from(characteristic.uuid.clone()), &properties, characteristic.instance_id.clone()); - characteristic_map.insert(characteristic.instance_id.clone(), MutHeap::new(&bt_characteristic)); + characteristic_map.insert(characteristic.instance_id.clone(), MutJS::new(&bt_characteristic)); return bt_characteristic; } + pub fn is_represented_device_null(&self) -> bool { + let (sender, receiver) = ipc::channel().unwrap(); + self.get_bluetooth_thread().send( + BluetoothRequest::IsRepresentedDeviceNull(self.Id().to_string(), sender)).unwrap(); + receiver.recv().unwrap() + } + pub fn get_or_create_descriptor(&self, descriptor: &BluetoothDescriptorMsg, characteristic: &BluetoothRemoteGATTCharacteristic) @@ -130,9 +145,67 @@ impl BluetoothDevice { characteristic, DOMString::from(descriptor.uuid.clone()), descriptor.instance_id.clone()); - descriptor_map.insert(descriptor.instance_id.clone(), MutHeap::new(&bt_descriptor)); + descriptor_map.insert(descriptor.instance_id.clone(), MutJS::new(&bt_descriptor)); return bt_descriptor; } + + fn get_bluetooth_thread(&self) -> IpcSender<BluetoothRequest> { + self.global().as_window().bluetooth_thread() + } + + // https://webbluetoothcg.github.io/web-bluetooth/#clean-up-the-disconnected-device + #[allow(unrooted_must_root)] + pub fn clean_up_disconnected_device(&self) { + // Step 1. + self.Gatt().set_connected(false); + + // TODO: Step 2: Implement activeAlgorithms internal slot for BluetoothRemoteGATTServer. + + // Step 3: We don't need `context`, we get the attributeInstanceMap from the device. + // https://github.com/WebBluetoothCG/web-bluetooth/issues/330 + + // Step 4. + let mut service_map = self.attribute_instance_map.0.borrow_mut(); + let service_ids = service_map.drain().map(|(id, _)| id).collect(); + + let mut characteristic_map = self.attribute_instance_map.1.borrow_mut(); + let characteristic_ids = characteristic_map.drain().map(|(id, _)| id).collect(); + + let mut descriptor_map = self.attribute_instance_map.2.borrow_mut(); + let descriptor_ids = descriptor_map.drain().map(|(id, _)| id).collect(); + + // Step 5, 6.4, 7. + // TODO: Step 6: Implement `active notification context set` for BluetoothRemoteGATTCharacteristic. + let _ = self.get_bluetooth_thread().send( + BluetoothRequest::SetRepresentedToNull(service_ids, characteristic_ids, descriptor_ids)); + + // Step 8. + self.upcast::<EventTarget>().fire_bubbling_event(atom!("gattserverdisconnected")); + } + + // https://webbluetoothcg.github.io/web-bluetooth/#garbage-collect-the-connection + #[allow(unrooted_must_root)] + pub fn garbage_collect_the_connection(&self) -> ErrorResult { + // Step 1: TODO: Check if other systems using this device. + + // Step 2. + let context = self.get_context(); + for (id, device) in context.get_device_map().borrow().iter() { + // Step 2.1 - 2.2. + if id == &self.Id().to_string() { + if device.get().Gatt().Connected() { + return Ok(()); + } + // TODO: Step 2.3: Implement activeAlgorithms internal slot for BluetoothRemoteGATTServer. + } + } + + // Step 3. + let (sender, receiver) = ipc::channel().unwrap(); + self.get_bluetooth_thread().send( + BluetoothRequest::GATTServerDisconnect(String::from(self.Id()), sender)).unwrap(); + receiver.recv().unwrap().map_err(Error::from) + } } impl BluetoothDeviceMethods for BluetoothDevice { @@ -146,11 +219,6 @@ impl BluetoothDeviceMethods for BluetoothDevice { self.name.clone() } - // https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetoothdevice-addata - fn AdData(&self) -> Root<BluetoothAdvertisingData> { - self.ad_data.get() - } - // https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetoothdevice-gatt fn Gatt(&self) -> Root<BluetoothRemoteGATTServer> { // TODO: Step 1 - 2: Implement the Permission API. @@ -159,6 +227,46 @@ impl BluetoothDeviceMethods for BluetoothDevice { }) } + #[allow(unrooted_must_root)] + // https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetoothdevice-watchadvertisements + fn WatchAdvertisements(&self) -> Rc<Promise> { + let p = Promise::new(&self.global()); + let sender = response_async(&p, self); + // TODO: Step 1. + // Note: Steps 2 - 3 are implemented in components/bluetooth/lib.rs in watch_advertisements function + // and in handle_response function. + self.get_bluetooth_thread().send( + BluetoothRequest::WatchAdvertisements(String::from(self.Id()), sender)).unwrap(); + return p; + } + + // https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetoothdevice-unwatchadvertisements + fn UnwatchAdvertisements(&self) -> () { + // Step 1. + self.watching_advertisements.set(false) + // TODO: Step 2. + } + + // https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetoothdevice-watchingadvertisements + fn WatchingAdvertisements(&self) -> bool { + self.watching_advertisements.get() + } + // https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetoothdeviceeventhandlers-ongattserverdisconnected event_handler!(gattserverdisconnected, GetOngattserverdisconnected, SetOngattserverdisconnected); } + +impl AsyncBluetoothListener for BluetoothDevice { + fn handle_response(&self, response: BluetoothResponse, promise_cx: *mut JSContext, promise: &Rc<Promise>) { + match response { + // https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetoothdevice-unwatchadvertisements + BluetoothResponse::WatchAdvertisements(_result) => { + // Step 3.1. + self.watching_advertisements.set(true); + // Step 3.2. + promise.resolve_native(promise_cx, &()); + }, + _ => promise.reject_error(promise_cx, Error::Type("Something went wrong...".to_owned())), + } + } +} diff --git a/components/script/dom/bluetoothremotegattcharacteristic.rs b/components/script/dom/bluetoothremotegattcharacteristic.rs index eb41e6ec1db..b4b9941343b 100644 --- a/components/script/dom/bluetoothremotegattcharacteristic.rs +++ b/components/script/dom/bluetoothremotegattcharacteristic.rs @@ -2,7 +2,7 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -use bluetooth_traits::{BluetoothRequest, BluetoothResponse}; +use bluetooth_traits::{BluetoothRequest, BluetoothResponse, GATTType}; use bluetooth_traits::blocklist::{Blocklist, uuid_is_blocklisted}; use dom::bindings::cell::DOMRefCell; use dom::bindings::codegen::Bindings::BluetoothCharacteristicPropertiesBinding:: @@ -16,10 +16,10 @@ use dom::bindings::codegen::Bindings::BluetoothRemoteGATTServiceBinding::Bluetoo use dom::bindings::codegen::Bindings::EventHandlerBinding::EventHandlerNonNull; use dom::bindings::error::Error::{self, InvalidModification, Network, NotSupported, Security}; use dom::bindings::inheritance::Castable; -use dom::bindings::js::{JS, MutHeap, Root}; +use dom::bindings::js::{MutJS, Root}; use dom::bindings::reflector::{DomObject, reflect_dom_object}; use dom::bindings::str::{ByteString, DOMString}; -use dom::bluetooth::{AsyncBluetoothListener, response_async}; +use dom::bluetooth::{AsyncBluetoothListener, get_gatt_children, response_async}; use dom::bluetoothcharacteristicproperties::BluetoothCharacteristicProperties; use dom::bluetoothremotegattservice::BluetoothRemoteGATTService; use dom::bluetoothuuid::{BluetoothDescriptorUUID, BluetoothUUID}; @@ -38,9 +38,9 @@ pub const MAXIMUM_ATTRIBUTE_LENGTH: usize = 512; #[dom_struct] pub struct BluetoothRemoteGATTCharacteristic { eventtarget: EventTarget, - service: MutHeap<JS<BluetoothRemoteGATTService>>, + service: MutJS<BluetoothRemoteGATTService>, uuid: DOMString, - properties: MutHeap<JS<BluetoothCharacteristicProperties>>, + properties: MutJS<BluetoothCharacteristicProperties>, value: DOMRefCell<Option<ByteString>>, instance_id: String, } @@ -53,9 +53,9 @@ impl BluetoothRemoteGATTCharacteristic { -> BluetoothRemoteGATTCharacteristic { BluetoothRemoteGATTCharacteristic { eventtarget: EventTarget::new_inherited(), - service: MutHeap::new(service), + service: MutJS::new(service), uuid: uuid, - properties: MutHeap::new(properties), + properties: MutJS::new(properties), value: DOMRefCell::new(None), instance_id: instance_id, } @@ -102,83 +102,18 @@ impl BluetoothRemoteGATTCharacteristicMethods for BluetoothRemoteGATTCharacteris #[allow(unrooted_must_root)] // https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetoothremotegattcharacteristic-getdescriptor - // https://webbluetoothcg.github.io/web-bluetooth/#getgattchildren fn GetDescriptor(&self, descriptor: BluetoothDescriptorUUID) -> Rc<Promise> { - let p = Promise::new(&self.global()); - let p_cx = p.global().get_cx(); - - // Step 1. - let uuid = match BluetoothUUID::descriptor(descriptor) { - Ok(uuid) => uuid.to_string(), - Err(e) => { - p.reject_error(p_cx, e); - return p; - } - }; - - // Step 2. - if uuid_is_blocklisted(uuid.as_ref(), Blocklist::All) { - p.reject_error(p_cx, Security); - return p; - } - - // Step 3 - 4. - if !self.Service().Device().Gatt().Connected() { - p.reject_error(p_cx, Network); - return p; - } - - // TODO: Step 5: Implement representedService internal slot for BluetoothRemoteGATTService. - - // Note: Steps 6 - 7 are implemented in components/bluetooth/lib.rs in get_descriptor function - // and in handle_response function. - let sender = response_async(&p, self); - self.get_bluetooth_thread().send( - BluetoothRequest::GetDescriptor(self.get_instance_id(), uuid, sender)).unwrap(); - return p; + get_gatt_children(self, true, BluetoothUUID::descriptor, Some(descriptor), self.get_instance_id(), + self.Service().Device().Gatt().Connected(), GATTType::Descriptor) } #[allow(unrooted_must_root)] // https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetoothremotegattcharacteristic-getdescriptors - // https://webbluetoothcg.github.io/web-bluetooth/#getgattchildren fn GetDescriptors(&self, descriptor: Option<BluetoothDescriptorUUID>) -> Rc<Promise> { - let p = Promise::new(&self.global()); - let p_cx = p.global().get_cx(); - let mut uuid: Option<String> = None; - if let Some(d) = descriptor { - // Step 1. - uuid = match BluetoothUUID::descriptor(d) { - Ok(uuid) => Some(uuid.to_string()), - Err(e) => { - p.reject_error(p_cx, e); - return p; - } - }; - if let Some(ref uuid) = uuid { - // Step 2. - if uuid_is_blocklisted(uuid.as_ref(), Blocklist::All) { - p.reject_error(p_cx, Security); - return p; - } - } - }; - - // Step 3 - 4. - if !self.Service().Device().Gatt().Connected() { - p.reject_error(p_cx, Network); - return p; - } - - // TODO: Step 5: Implement representedService internal slot for BluetoothRemoteGATTService. - - // Note: Steps 6 - 7 are implemented in components/bluetooth/lib.rs in get_descriptors function - // and in handle_response function. - let sender = response_async(&p, self); - self.get_bluetooth_thread().send( - BluetoothRequest::GetDescriptors(self.get_instance_id(), uuid, sender)).unwrap(); - return p; + get_gatt_children(self, false, BluetoothUUID::descriptor, descriptor, self.get_instance_id(), + self.Service().Device().Gatt().Connected(), GATTType::Descriptor) } // https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetoothremotegattcharacteristic-value @@ -204,8 +139,6 @@ impl BluetoothRemoteGATTCharacteristicMethods for BluetoothRemoteGATTCharacteris return p; } - // TODO: Step 3 - 4: Implement representedCharacteristic internal slot for BluetoothRemoteGATTCharacteristic. - // TODO: Step 5: Implement the `connection-checking-wrapper` algorithm for BluetoothRemoteGATTServer. // Step 5.1. @@ -214,8 +147,8 @@ impl BluetoothRemoteGATTCharacteristicMethods for BluetoothRemoteGATTCharacteris return p; } - // Note: Remaining substeps of Step 5 are implemented in components/bluetooth/lib.rs in readValue function - // and in handle_response function. + // Note: Steps 3 - 4 and the remaining substeps of Step 5 are implemented in components/bluetooth/lib.rs + // in readValue function and in handle_response function. let sender = response_async(&p, self); self.get_bluetooth_thread().send( BluetoothRequest::ReadValue(self.get_instance_id(), sender)).unwrap(); @@ -246,8 +179,6 @@ impl BluetoothRemoteGATTCharacteristicMethods for BluetoothRemoteGATTCharacteris return p; } - // TODO: Step 5 - 6: Implement representedCharacteristic internal slot for BluetoothRemoteGATTCharacteristic. - // TODO: Step 7: Implement the `connection-checking-wrapper` algorithm for BluetoothRemoteGATTServer. // Step 7.1. @@ -258,8 +189,8 @@ impl BluetoothRemoteGATTCharacteristicMethods for BluetoothRemoteGATTCharacteris return p; } - // Note: Remaining substeps of Step 7 are implemented in components/bluetooth/lib.rs in writeValue function - // and in handle_response function. + // Note: Steps 5 - 6 and the remaining substeps of Step 7 are implemented in components/bluetooth/lib.rs + // in writeValue function and in handle_response function. let sender = response_async(&p, self); self.get_bluetooth_thread().send( BluetoothRequest::WriteValue(self.get_instance_id(), value, sender)).unwrap(); @@ -278,8 +209,6 @@ impl BluetoothRemoteGATTCharacteristicMethods for BluetoothRemoteGATTCharacteris return p; } - // TODO: Step 2 - 3: Implement representedCharacteristic internal slot for BluetoothRemoteGATTCharacteristic. - // Step 4. if !(self.Properties().Notify() || self.Properties().Indicate()) { @@ -295,7 +224,7 @@ impl BluetoothRemoteGATTCharacteristicMethods for BluetoothRemoteGATTCharacteris return p; } - // Note: Steps 7 - 11 are implemented in components/bluetooth/lib.rs in enable_notification function + // Note: Steps 2 - 3, 7 - 11 are implemented in components/bluetooth/lib.rs in enable_notification function // and in handle_response function. let sender = response_async(&p, self); self.get_bluetooth_thread().send( @@ -311,11 +240,10 @@ impl BluetoothRemoteGATTCharacteristicMethods for BluetoothRemoteGATTCharacteris let p = Promise::new(&self.global()); let sender = response_async(&p, self); - // TODO: Step 1 - 4: Implement representedCharacteristic internal slot and - // `active notification context set` for BluetoothRemoteGATTCharacteristic, + // TODO: Step 3 - 4: Implement `active notification context set` for BluetoothRemoteGATTCharacteristic, - // Note: Part of Step 4 and Step 5 are implemented in components/bluetooth/lib.rs in enable_notification - // function and in handle_response function. + // Note: Steps 1 - 2, and part of Step 4 and Step 5 are implemented in components/bluetooth/lib.rs + // in enable_notification function and in handle_response function. self.get_bluetooth_thread().send( BluetoothRequest::EnableNotification(self.get_instance_id(), false, @@ -331,17 +259,13 @@ impl AsyncBluetoothListener for BluetoothRemoteGATTCharacteristic { fn handle_response(&self, response: BluetoothResponse, promise_cx: *mut JSContext, promise: &Rc<Promise>) { let device = self.Service().Device(); match response { - // https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetoothremotegattcharacteristic-getdescriptor // https://webbluetoothcg.github.io/web-bluetooth/#getgattchildren // Step 7. - BluetoothResponse::GetDescriptor(descriptor) => { - let bt_descriptor = device.get_or_create_descriptor(&descriptor, &self); - promise.resolve_native(promise_cx, &bt_descriptor); - }, - // https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetoothremotegattcharacteristic-getdescriptors - // https://webbluetoothcg.github.io/web-bluetooth/#getgattchildren - // Step 7. - BluetoothResponse::GetDescriptors(descriptors_vec) => { + BluetoothResponse::GetDescriptors(descriptors_vec, single) => { + if single { + promise.resolve_native(promise_cx, &device.get_or_create_descriptor(&descriptors_vec[0], &self)); + return; + } let mut descriptors = vec!(); for descriptor in descriptors_vec { let bt_descriptor = device.get_or_create_descriptor(&descriptor, &self); diff --git a/components/script/dom/bluetoothremotegattdescriptor.rs b/components/script/dom/bluetoothremotegattdescriptor.rs index c31fae99070..b96a20c4a21 100644 --- a/components/script/dom/bluetoothremotegattdescriptor.rs +++ b/components/script/dom/bluetoothremotegattdescriptor.rs @@ -13,7 +13,7 @@ use dom::bindings::codegen::Bindings::BluetoothRemoteGATTDescriptorBinding::Blue use dom::bindings::codegen::Bindings::BluetoothRemoteGATTServerBinding::BluetoothRemoteGATTServerMethods; use dom::bindings::codegen::Bindings::BluetoothRemoteGATTServiceBinding::BluetoothRemoteGATTServiceMethods; use dom::bindings::error::Error::{self, InvalidModification, Network, Security}; -use dom::bindings::js::{JS, MutHeap, Root}; +use dom::bindings::js::{MutJS, Root}; use dom::bindings::reflector::{DomObject, Reflector, reflect_dom_object}; use dom::bindings::str::{ByteString, DOMString}; use dom::bluetooth::{AsyncBluetoothListener, response_async}; @@ -28,7 +28,7 @@ use std::rc::Rc; #[dom_struct] pub struct BluetoothRemoteGATTDescriptor { reflector_: Reflector, - characteristic: MutHeap<JS<BluetoothRemoteGATTCharacteristic>>, + characteristic: MutJS<BluetoothRemoteGATTCharacteristic>, uuid: DOMString, value: DOMRefCell<Option<ByteString>>, instance_id: String, @@ -41,7 +41,7 @@ impl BluetoothRemoteGATTDescriptor { -> BluetoothRemoteGATTDescriptor { BluetoothRemoteGATTDescriptor { reflector_: Reflector::new(), - characteristic: MutHeap::new(characteristic), + characteristic: MutJS::new(characteristic), uuid: uuid, value: DOMRefCell::new(None), instance_id: instance_id, @@ -103,11 +103,9 @@ impl BluetoothRemoteGATTDescriptorMethods for BluetoothRemoteGATTDescriptor { return p; } - // TODO: Step 3 - 4: Implement representedDescriptor internal slot for BluetoothRemoteGATTDescriptor. - // TODO: Step 5: Implement the `connection-checking-wrapper` algorithm for BluetoothRemoteGATTServer. - // Note: Substeps of Step 5 are implemented in components/bluetooth/lib.rs in readValue function - // and in handle_response function. + // Note: Steps 3 - 4 and substeps of Step 5 are implemented in components/bluetooth/lib.rs + // in readValue function and in handle_response function. let sender = response_async(&p, self); self.get_bluetooth_thread().send( BluetoothRequest::ReadValue(self.get_instance_id(), sender)).unwrap(); @@ -138,11 +136,9 @@ impl BluetoothRemoteGATTDescriptorMethods for BluetoothRemoteGATTDescriptor { return p; } - // TODO: Step 5 - 6: Implement representedCharacteristic internal slot for BluetoothRemoteGATTCharacteristic. - // TODO: Step 7: Implement the `connection-checking-wrapper` algorithm for BluetoothRemoteGATTServer. - // Note: Substeps of Step 7 are implemented in components/bluetooth/lib.rs in writeValue function - // and in handle_response function. + // Note: Steps 5 - 6 and substeps of Step 7 are implemented in components/bluetooth/lib.rs + // in writeValue function and in handle_response function. let sender = response_async(&p, self); self.get_bluetooth_thread().send( BluetoothRequest::WriteValue(self.get_instance_id(), value, sender)).unwrap(); diff --git a/components/script/dom/bluetoothremotegattserver.rs b/components/script/dom/bluetoothremotegattserver.rs index d9d57ae51f1..e81aae08abe 100644 --- a/components/script/dom/bluetoothremotegattserver.rs +++ b/components/script/dom/bluetoothremotegattserver.rs @@ -2,21 +2,20 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -use bluetooth_traits::{BluetoothRequest, BluetoothResponse}; -use bluetooth_traits::blocklist::{Blocklist, uuid_is_blocklisted}; +use bluetooth_traits::{BluetoothRequest, BluetoothResponse, GATTType}; use dom::bindings::codegen::Bindings::BluetoothDeviceBinding::BluetoothDeviceMethods; use dom::bindings::codegen::Bindings::BluetoothRemoteGATTServerBinding; use dom::bindings::codegen::Bindings::BluetoothRemoteGATTServerBinding::BluetoothRemoteGATTServerMethods; -use dom::bindings::error::Error::{self, Network, Security}; +use dom::bindings::error::Error; use dom::bindings::error::ErrorResult; -use dom::bindings::js::{JS, MutHeap, Root}; +use dom::bindings::js::{MutJS, Root}; use dom::bindings::reflector::{DomObject, Reflector, reflect_dom_object}; -use dom::bluetooth::{AsyncBluetoothListener, response_async}; +use dom::bluetooth::{AsyncBluetoothListener, get_gatt_children, response_async}; use dom::bluetoothdevice::BluetoothDevice; use dom::bluetoothuuid::{BluetoothServiceUUID, BluetoothUUID}; use dom::globalscope::GlobalScope; use dom::promise::Promise; -use ipc_channel::ipc::{self, IpcSender}; +use ipc_channel::ipc::IpcSender; use js::jsapi::JSContext; use std::cell::Cell; use std::rc::Rc; @@ -25,7 +24,7 @@ use std::rc::Rc; #[dom_struct] pub struct BluetoothRemoteGATTServer { reflector_: Reflector, - device: MutHeap<JS<BluetoothDevice>>, + device: MutJS<BluetoothDevice>, connected: Cell<bool>, } @@ -33,7 +32,7 @@ impl BluetoothRemoteGATTServer { pub fn new_inherited(device: &BluetoothDevice) -> BluetoothRemoteGATTServer { BluetoothRemoteGATTServer { reflector_: Reflector::new(), - device: MutHeap::new(device), + device: MutJS::new(device), connected: Cell::new(false), } } @@ -47,6 +46,10 @@ impl BluetoothRemoteGATTServer { fn get_bluetooth_thread(&self) -> IpcSender<BluetoothRequest> { self.global().as_window().bluetooth_thread() } + + pub fn set_connected(&self, connected: bool) { + self.connected.set(connected); + } } impl BluetoothRemoteGATTServerMethods for BluetoothRemoteGATTServer { @@ -67,17 +70,14 @@ impl BluetoothRemoteGATTServerMethods for BluetoothRemoteGATTServer { let p = Promise::new(&self.global()); let sender = response_async(&p, self); - // TODO: Step 2: Implement representedDevice internal slot for BluetoothDevice. - // TODO: Step 3: Check if the UA is currently using the Bluetooth system. // TODO: Step 4: Implement activeAlgorithms internal slot for BluetoothRemoteGATTServer. - // TODO: Step 5.1 - 5.2: Implement activeAlgorithms, representedDevice internal slots - // and the` garbage-collect the connection` algorithm. + // TODO: Step 5.1 - 5.2: Implement activeAlgorithms internal slot for BluetoothRemoteGATTServer. - // Note: Steps 5.1.1 and 5.1.3 are in components/bluetooth/lib.rs in the gatt_server_connect function. - // Steps 5.2.4 - 5.2.5 are in response function. + // Note: Steps 2, 5.1.1 and 5.1.3 are in components/bluetooth/lib.rs in the gatt_server_connect function. + // Steps 5.2.3 - 5.2.5 are in response function. self.get_bluetooth_thread().send( BluetoothRequest::GATTServerConnect(String::from(self.Device().Id()), sender)).unwrap(); // Step 5: return promise. @@ -90,135 +90,63 @@ impl BluetoothRemoteGATTServerMethods for BluetoothRemoteGATTServer { // Step 2. if !self.Connected() { - return Ok(()); + return Ok(()) } - let (sender, receiver) = ipc::channel().unwrap(); - self.get_bluetooth_thread().send( - BluetoothRequest::GATTServerDisconnect(String::from(self.Device().Id()), sender)).unwrap(); - let server = receiver.recv().unwrap(); - - // TODO: Step 3: Implement the `clean up the disconnected device` algorithm. - // TODO: Step 4: Implement representedDevice internal slot for BluetoothDevice. + // Step 3. + self.Device().clean_up_disconnected_device(); - // TODO: Step 5: Implement the `garbage-collect the connection` algorithm. - match server { - Ok(connected) => { - self.connected.set(connected); - Ok(()) - }, - Err(error) => { - Err(Error::from(error)) - }, - } + // Step 4 - 5: + self.Device().garbage_collect_the_connection() } #[allow(unrooted_must_root)] // https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetoothremotegattserver-getprimaryservice fn GetPrimaryService(&self, service: BluetoothServiceUUID) -> Rc<Promise> { // TODO: Step 1: Implement the Permission API and the allowedServices BluetoothDevice internal slot. - // Subsequent steps are relative to https://webbluetoothcg.github.io/web-bluetooth/#getgattchildren - let p = Promise::new(&self.global()); - let p_cx = p.global().get_cx(); - - // Step 1. - let uuid = match BluetoothUUID::service(service) { - Ok(uuid) => uuid.to_string(), - Err(e) => { - p.reject_error(p_cx, e); - return p; - } - }; - // Step 2. - if uuid_is_blocklisted(uuid.as_ref(), Blocklist::All) { - p.reject_error(p_cx, Security); - return p; - } - - // Step 3 - 4. - if !self.Device().Gatt().Connected() { - p.reject_error(p_cx, Network); - return p; - } - - // TODO: Step 5: Implement representedDevice internal slot for BluetoothDevice. - - // Note: Steps 6 - 7 are implemented in components/bluetooth/lib.rs in get_primary_service function - // and in handle_response function. - let sender = response_async(&p, self); - self.get_bluetooth_thread().send( - BluetoothRequest::GetPrimaryService(String::from(self.Device().Id()), uuid, sender)).unwrap(); - return p; + get_gatt_children(self, true, BluetoothUUID::service, Some(service), String::from(self.Device().Id()), + self.Device().Gatt().Connected(), GATTType::PrimaryService) } #[allow(unrooted_must_root)] // https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetoothremotegattserver-getprimaryservices fn GetPrimaryServices(&self, service: Option<BluetoothServiceUUID>) -> Rc<Promise> { // TODO: Step 1: Implement the Permission API and the allowedServices BluetoothDevice internal slot. - // Subsequent steps are relative to https://webbluetoothcg.github.io/web-bluetooth/#getgattchildren - let p = Promise::new(&self.global()); - let p_cx = p.global().get_cx(); - - let mut uuid: Option<String> = None; - if let Some(s) = service { - // Step 1. - uuid = match BluetoothUUID::service(s) { - Ok(uuid) => Some(uuid.to_string()), - Err(e) => { - p.reject_error(p_cx, e); - return p; - } - }; - if let Some(ref uuid) = uuid { - // Step 2. - if uuid_is_blocklisted(uuid.as_ref(), Blocklist::All) { - p.reject_error(p_cx, Security); - return p; - } - } - }; - - // Step 3 - 4. - if !self.Device().Gatt().Connected() { - p.reject_error(p_cx, Network); - return p; - } - - // TODO: Step 5: Implement representedDevice internal slot for BluetoothDevice. + // Step 2. + get_gatt_children(self, false, BluetoothUUID::service, service, String::from(self.Device().Id()), + self.Connected(), GATTType::PrimaryService) - // Note: Steps 6 - 7 are implemented in components/bluetooth/lib.rs in get_primary_services function - // and in handle_response function. - let sender = response_async(&p, self); - self.get_bluetooth_thread().send( - BluetoothRequest::GetPrimaryServices(String::from(self.Device().Id()), uuid, sender)).unwrap(); - return p; } } impl AsyncBluetoothListener for BluetoothRemoteGATTServer { fn handle_response(&self, response: BluetoothResponse, promise_cx: *mut JSContext, promise: &Rc<Promise>) { - let device = self.Device(); match response { // https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetoothremotegattserver-connect BluetoothResponse::GATTServerConnect(connected) => { + // Step 5.2.3 + if self.Device().is_represented_device_null() { + if let Err(e) = self.Device().garbage_collect_the_connection() { + return promise.reject_error(promise_cx, Error::from(e)); + } + return promise.reject_error(promise_cx, Error::Network); + } + // Step 5.2.4. self.connected.set(connected); // Step 5.2.5. promise.resolve_native(promise_cx, self); }, - // https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetoothremotegattserver-getprimaryservice // https://webbluetoothcg.github.io/web-bluetooth/#getgattchildren // Step 7. - BluetoothResponse::GetPrimaryService(service) => { - let bt_service = device.get_or_create_service(&service, &self); - promise.resolve_native(promise_cx, &bt_service); - }, - // https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetoothremotegattserver-getprimaryservices - // https://webbluetoothcg.github.io/web-bluetooth/#getgattchildren - // Step 7. - BluetoothResponse::GetPrimaryServices(services_vec) => { + BluetoothResponse::GetPrimaryServices(services_vec, single) => { + let device = self.Device(); + if single { + promise.resolve_native(promise_cx, &device.get_or_create_service(&services_vec[0], &self)); + return; + } let mut services = vec!(); for service in services_vec { let bt_service = device.get_or_create_service(&service, &self); diff --git a/components/script/dom/bluetoothremotegattservice.rs b/components/script/dom/bluetoothremotegattservice.rs index f4aed154c7c..304cbb7d5b9 100644 --- a/components/script/dom/bluetoothremotegattservice.rs +++ b/components/script/dom/bluetoothremotegattservice.rs @@ -2,24 +2,22 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -use bluetooth_traits::{BluetoothRequest, BluetoothResponse}; -use bluetooth_traits::blocklist::{Blocklist, uuid_is_blocklisted}; +use bluetooth_traits::{BluetoothResponse, GATTType}; use dom::bindings::codegen::Bindings::BluetoothDeviceBinding::BluetoothDeviceMethods; use dom::bindings::codegen::Bindings::BluetoothRemoteGATTServerBinding::BluetoothRemoteGATTServerMethods; use dom::bindings::codegen::Bindings::BluetoothRemoteGATTServiceBinding; use dom::bindings::codegen::Bindings::BluetoothRemoteGATTServiceBinding::BluetoothRemoteGATTServiceMethods; use dom::bindings::codegen::Bindings::EventHandlerBinding::EventHandlerNonNull; -use dom::bindings::error::Error::{self, Network, Security}; -use dom::bindings::js::{JS, MutHeap, Root}; -use dom::bindings::reflector::{DomObject, reflect_dom_object}; +use dom::bindings::error::Error; +use dom::bindings::js::{MutJS, Root}; +use dom::bindings::reflector::reflect_dom_object; use dom::bindings::str::DOMString; -use dom::bluetooth::{AsyncBluetoothListener, response_async}; +use dom::bluetooth::{AsyncBluetoothListener, get_gatt_children}; use dom::bluetoothdevice::BluetoothDevice; use dom::bluetoothuuid::{BluetoothCharacteristicUUID, BluetoothServiceUUID, BluetoothUUID}; use dom::eventtarget::EventTarget; use dom::globalscope::GlobalScope; use dom::promise::Promise; -use ipc_channel::ipc::IpcSender; use js::jsapi::JSContext; use std::rc::Rc; @@ -27,7 +25,7 @@ use std::rc::Rc; #[dom_struct] pub struct BluetoothRemoteGATTService { eventtarget: EventTarget, - device: MutHeap<JS<BluetoothDevice>>, + device: MutJS<BluetoothDevice>, uuid: DOMString, is_primary: bool, instance_id: String, @@ -41,7 +39,7 @@ impl BluetoothRemoteGATTService { -> BluetoothRemoteGATTService { BluetoothRemoteGATTService { eventtarget: EventTarget::new_inherited(), - device: MutHeap::new(device), + device: MutJS::new(device), uuid: uuid, is_primary: is_primary, instance_id: instance_id, @@ -62,10 +60,6 @@ impl BluetoothRemoteGATTService { BluetoothRemoteGATTServiceBinding::Wrap) } - fn get_bluetooth_thread(&self) -> IpcSender<BluetoothRequest> { - self.global().as_window().bluetooth_thread() - } - fn get_instance_id(&self) -> String { self.instance_id.clone() } @@ -89,173 +83,39 @@ impl BluetoothRemoteGATTServiceMethods for BluetoothRemoteGATTService { #[allow(unrooted_must_root)] // https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetoothremotegattservice-getcharacteristic - // https://webbluetoothcg.github.io/web-bluetooth/#getgattchildren fn GetCharacteristic(&self, characteristic: BluetoothCharacteristicUUID) -> Rc<Promise> { - let p = Promise::new(&self.global()); - let p_cx = p.global().get_cx(); - - // Step 1. - let uuid = match BluetoothUUID::characteristic(characteristic) { - Ok(uuid) => uuid.to_string(), - Err(e) => { - p.reject_error(p_cx, e); - return p; - } - }; - - // Step 2. - if uuid_is_blocklisted(uuid.as_ref(), Blocklist::All) { - p.reject_error(p_cx, Security); - return p; - } - - // Step 3 - 4. - if !self.Device().Gatt().Connected() { - p.reject_error(p_cx, Network); - return p; - } - - // TODO: Step 5: Implement representedService internal slot for BluetootRemoteGATTService. - - // Note: Steps 6 - 7 are implemented is components/bluetooth/lib.rs in get_characteristic function - // and in handle_response function. - let sender = response_async(&p, self); - self.get_bluetooth_thread().send( - BluetoothRequest::GetCharacteristic(self.get_instance_id(), uuid, sender)).unwrap(); - return p; + get_gatt_children(self, true, BluetoothUUID::characteristic, Some(characteristic), self.get_instance_id(), + self.Device().Gatt().Connected(), GATTType::Characteristic) } #[allow(unrooted_must_root)] // https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetoothremotegattservice-getcharacteristics - // https://webbluetoothcg.github.io/web-bluetooth/#getgattchildren fn GetCharacteristics(&self, characteristic: Option<BluetoothCharacteristicUUID>) -> Rc<Promise> { - let p = Promise::new(&self.global()); - let p_cx = p.global().get_cx(); - let mut uuid: Option<String> = None; - if let Some(c) = characteristic { - // Step 1. - uuid = match BluetoothUUID::characteristic(c) { - Ok(uuid) => Some(uuid.to_string()), - Err(e) => { - p.reject_error(p_cx, e); - return p; - } - }; - if let Some(ref uuid) = uuid { - // Step 2. - if uuid_is_blocklisted(uuid.as_ref(), Blocklist::All) { - p.reject_error(p_cx, Security); - return p; - } - } - }; - - // Step 3 - 4. - if !self.Device().Gatt().Connected() { - p.reject_error(p_cx, Network); - return p; - } - - // TODO: Step 5: Implement representedService internal slot for BluetootRemoteGATTService. - - // Note: Steps 6 - 7 are implemented is components/bluetooth/lib.rs in get_characteristics function - // and in handle_response function. - let sender = response_async(&p, self); - self.get_bluetooth_thread().send( - BluetoothRequest::GetCharacteristics(self.get_instance_id(), uuid, sender)).unwrap(); - return p; + get_gatt_children(self, false, BluetoothUUID::characteristic, characteristic, self.get_instance_id(), + self.Device().Gatt().Connected(), GATTType::Characteristic) } #[allow(unrooted_must_root)] // https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetoothremotegattservice-getincludedservice - // https://webbluetoothcg.github.io/web-bluetooth/#getgattchildren fn GetIncludedService(&self, service: BluetoothServiceUUID) -> Rc<Promise> { - let p = Promise::new(&self.global()); - let p_cx = p.global().get_cx(); - - // Step 1. - let uuid = match BluetoothUUID::service(service) { - Ok(uuid) => uuid.to_string(), - Err(e) => { - p.reject_error(p_cx, e); - return p; - } - }; - - // Step 2. - if uuid_is_blocklisted(uuid.as_ref(), Blocklist::All) { - p.reject_error(p_cx, Security); - return p; - } - - // Step 3 - 4. - if !self.Device().Gatt().Connected() { - p.reject_error(p_cx, Network); - return p; - } - - // TODO: Step 5: Implement representedService internal slot for BluetootRemoteGATTService. - - // Note: Steps 6 - 7 are implemented is components/bluetooth/lib.rs in get_included_service function - // and in handle_response function. - let sender = response_async(&p, self); - self.get_bluetooth_thread().send( - BluetoothRequest::GetIncludedService(self.get_instance_id(), - uuid, - sender)).unwrap(); - return p; + get_gatt_children(self, false, BluetoothUUID::service, Some(service), self.get_instance_id(), + self.Device().Gatt().Connected(), GATTType::IncludedService) } #[allow(unrooted_must_root)] // https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetoothremotegattservice-getincludedservices - // https://webbluetoothcg.github.io/web-bluetooth/#getgattchildren fn GetIncludedServices(&self, service: Option<BluetoothServiceUUID>) -> Rc<Promise> { - let p = Promise::new(&self.global()); - let p_cx = p.global().get_cx(); - let mut uuid: Option<String> = None; - if let Some(s) = service { - // Step 1. - uuid = match BluetoothUUID::service(s) { - Ok(uuid) => Some(uuid.to_string()), - Err(e) => { - p.reject_error(p_cx, e); - return p; - } - }; - if let Some(ref uuid) = uuid { - // Step 2. - if uuid_is_blocklisted(uuid.as_ref(), Blocklist::All) { - p.reject_error(p_cx, Security); - return p; - } - } - }; - - // Step 3 - 4. - if !self.Device().Gatt().Connected() { - p.reject_error(p_cx, Network); - return p; - } - - // TODO: Step 5: Implement representedService internal slot for BluetootRemoteGATTService. - - // Note: Steps 6 - 7 are implemented is components/bluetooth/lib.rs in get_included_services function - // and in handle_response function. - let sender = response_async(&p, self); - self.get_bluetooth_thread().send( - BluetoothRequest::GetIncludedServices(self.get_instance_id(), - uuid, - sender)).unwrap(); - return p; + get_gatt_children(self, false, BluetoothUUID::service, service, self.get_instance_id(), + self.Device().Gatt().Connected(), GATTType::IncludedService) } // https://webbluetoothcg.github.io/web-bluetooth/#dom-serviceeventhandlers-onserviceadded @@ -272,17 +132,14 @@ impl AsyncBluetoothListener for BluetoothRemoteGATTService { fn handle_response(&self, response: BluetoothResponse, promise_cx: *mut JSContext, promise: &Rc<Promise>) { let device = self.Device(); match response { - // https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetoothremotegattservice-getcharacteristic // https://webbluetoothcg.github.io/web-bluetooth/#getgattchildren // Step 7. - BluetoothResponse::GetCharacteristic(characteristic) => { - let bt_characteristic = device.get_or_create_characteristic(&characteristic, &self); - promise.resolve_native(promise_cx, &bt_characteristic); - }, - // https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetoothremotegattservice-getcharacteristics - // https://webbluetoothcg.github.io/web-bluetooth/#getgattchildren - // Step 7. - BluetoothResponse::GetCharacteristics(characteristics_vec) => { + BluetoothResponse::GetCharacteristics(characteristics_vec, single) => { + if single { + promise.resolve_native(promise_cx, + &device.get_or_create_characteristic(&characteristics_vec[0], &self)); + return; + } let mut characteristics = vec!(); for characteristic in characteristics_vec { let bt_characteristic = device.get_or_create_characteristic(&characteristic, &self); @@ -290,31 +147,19 @@ impl AsyncBluetoothListener for BluetoothRemoteGATTService { } promise.resolve_native(promise_cx, &characteristics); }, - // https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetoothremotegattservice-getincludedservice // https://webbluetoothcg.github.io/web-bluetooth/#getgattchildren // Step 7. - BluetoothResponse::GetIncludedService(service) => { - let s = - BluetoothRemoteGATTService::new(&self.global(), - &self.device.get(), - DOMString::from(service.uuid), - service.is_primary, - service.instance_id); - promise.resolve_native(promise_cx, &s); - }, - // https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetoothremotegattservice-getincludedservices - // https://webbluetoothcg.github.io/web-bluetooth/#getgattchildren - // Step 7. - BluetoothResponse::GetIncludedServices(services_vec) => { - let s: Vec<Root<BluetoothRemoteGATTService>> = - services_vec.into_iter() - .map(|service| BluetoothRemoteGATTService::new(&self.global(), - &self.device.get(), - DOMString::from(service.uuid), - service.is_primary, - service.instance_id)) - .collect(); - promise.resolve_native(promise_cx, &s); + BluetoothResponse::GetIncludedServices(services_vec, single) => { + if single { + promise.resolve_native(promise_cx, &device.get_or_create_service(&services_vec[0], &device.Gatt())); + return; + } + let mut services = vec!(); + for service in services_vec { + let bt_service = device.get_or_create_service(&service, &device.Gatt()); + services.push(bt_service); + } + promise.resolve_native(promise_cx, &services); }, _ => promise.reject_error(promise_cx, Error::Type("Something went wrong...".to_owned())), } diff --git a/components/script/dom/browsingcontext.rs b/components/script/dom/browsingcontext.rs index 76b8badbe76..1a7f26253a0 100644 --- a/components/script/dom/browsingcontext.rs +++ b/components/script/dom/browsingcontext.rs @@ -4,7 +4,7 @@ use dom::bindings::conversions::{ToJSValConvertible, root_from_handleobject}; use dom::bindings::inheritance::Castable; -use dom::bindings::js::{JS, MutNullableHeap, Root, RootedReference}; +use dom::bindings::js::{JS, MutNullableJS, Root, RootedReference}; use dom::bindings::proxyhandler::{fill_property_descriptor, get_property_descriptor}; use dom::bindings::reflector::{DomObject, MutDomObject, Reflector}; use dom::bindings::trace::JSTraceable; @@ -43,7 +43,7 @@ pub struct BrowsingContext { /// The current active document. /// Note that the session history is stored in the constellation, /// in the script thread we just track the current active document. - active_document: MutNullableHeap<JS<Document>>, + active_document: MutNullableJS<Document>, /// The containing iframe element, if this is a same-origin iframe frame_element: Option<JS<Element>>, diff --git a/components/script/dom/characterdata.rs b/components/script/dom/characterdata.rs index 01f11e3ac50..a2c456317dc 100644 --- a/components/script/dom/characterdata.rs +++ b/components/script/dom/characterdata.rs @@ -19,8 +19,8 @@ use dom::element::Element; use dom::node::{Node, NodeDamage}; use dom::processinginstruction::ProcessingInstruction; use dom::text::Text; +use servo_config::opts; use std::cell::Ref; -use util::opts; // https://dom.spec.whatwg.org/#characterdata #[dom_struct] diff --git a/components/script/dom/client.rs b/components/script/dom/client.rs index 496a13d32dc..d9d43ce7e01 100644 --- a/components/script/dom/client.rs +++ b/components/script/dom/client.rs @@ -4,7 +4,7 @@ use dom::bindings::codegen::Bindings::ClientBinding::{ClientMethods, Wrap}; use dom::bindings::codegen::Bindings::ClientBinding::FrameType; -use dom::bindings::js::{JS, Root, MutNullableHeap}; +use dom::bindings::js::{Root, MutNullableJS}; use dom::bindings::reflector::{Reflector, reflect_dom_object}; use dom::bindings::str::{DOMString, USVString}; use dom::serviceworker::ServiceWorker; @@ -16,7 +16,7 @@ use uuid::Uuid; #[dom_struct] pub struct Client { reflector_: Reflector, - active_worker: MutNullableHeap<JS<ServiceWorker>>, + active_worker: MutNullableJS<ServiceWorker>, url: ServoUrl, frame_type: FrameType, #[ignore_heap_size_of = "Defined in uuid"] diff --git a/components/script/dom/create.rs b/components/script/dom/create.rs index 42a3c8158a1..7c9a9eeea9c 100644 --- a/components/script/dom/create.rs +++ b/components/script/dom/create.rs @@ -78,7 +78,7 @@ use dom::htmlunknownelement::HTMLUnknownElement; use dom::htmlvideoelement::HTMLVideoElement; use dom::svgsvgelement::SVGSVGElement; use html5ever_atoms::{Prefix, QualName}; -use util::prefs::PREFS; +use servo_config::prefs::PREFS; fn create_svg_element(name: QualName, prefix: Option<DOMString>, @@ -244,7 +244,7 @@ fn create_html_element(name: QualName, local_name!("span") => make!(HTMLSpanElement), local_name!("strike") => make!(HTMLElement), local_name!("strong") => make!(HTMLElement), - local_name!("style") => make!(HTMLStyleElement), + local_name!("style") => make!(HTMLStyleElement, creator), local_name!("sub") => make!(HTMLElement), local_name!("summary") => make!(HTMLElement), local_name!("sup") => make!(HTMLElement), diff --git a/components/script/dom/crypto.rs b/components/script/dom/crypto.rs index 4120456c77c..57b561e8a58 100644 --- a/components/script/dom/crypto.rs +++ b/components/script/dom/crypto.rs @@ -6,7 +6,6 @@ use core::nonzero::NonZero; use dom::bindings::cell::DOMRefCell; use dom::bindings::codegen::Bindings::CryptoBinding; use dom::bindings::codegen::Bindings::CryptoBinding::CryptoMethods; -use dom::bindings::conversions::array_buffer_view_data; use dom::bindings::error::{Error, Fallible}; use dom::bindings::js::Root; use dom::bindings::reflector::{Reflector, reflect_dom_object}; @@ -46,9 +45,10 @@ impl CryptoMethods for Crypto { input: *mut JSObject) -> Fallible<NonZero<*mut JSObject>> { assert!(!input.is_null()); - let mut data = match array_buffer_view_data::<u8>(input) { - Some(data) => data, - None => { + typedarray!(in(_cx) let mut array_buffer_view: ArrayBufferView = input); + let mut data = match array_buffer_view.as_mut() { + Ok(x) => x.as_mut_slice(), + Err(_) => { return Err(Error::Type("Argument to Crypto.getRandomValues is not an ArrayBufferView" .to_owned())); } diff --git a/components/script/dom/cssgroupingrule.rs b/components/script/dom/cssgroupingrule.rs index e8651c551d3..b793b04b28c 100644 --- a/components/script/dom/cssgroupingrule.rs +++ b/components/script/dom/cssgroupingrule.rs @@ -2,17 +2,15 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -use dom::bindings::codegen::Bindings::CSSGroupingRuleBinding; use dom::bindings::codegen::Bindings::CSSGroupingRuleBinding::CSSGroupingRuleMethods; use dom::bindings::error::{ErrorResult, Fallible}; use dom::bindings::inheritance::Castable; -use dom::bindings::js::{JS, MutNullableHeap, Root}; -use dom::bindings::reflector::{DomObject, reflect_dom_object}; +use dom::bindings::js::{MutNullableJS, Root}; +use dom::bindings::reflector::DomObject; use dom::bindings::str::DOMString; use dom::cssrule::CSSRule; use dom::cssrulelist::{CSSRuleList, RulesSource}; use dom::cssstylesheet::CSSStyleSheet; -use dom::window::Window; use parking_lot::RwLock; use std::sync::Arc; use style::stylesheets::CssRules as StyleCssRules; @@ -22,7 +20,7 @@ pub struct CSSGroupingRule { cssrule: CSSRule, #[ignore_heap_size_of = "Arc"] rules: Arc<RwLock<StyleCssRules>>, - rulelist: MutNullableHeap<JS<CSSRuleList>>, + rulelist: MutNullableJS<CSSRuleList>, } impl CSSGroupingRule { @@ -31,18 +29,10 @@ impl CSSGroupingRule { CSSGroupingRule { cssrule: CSSRule::new_inherited(parent_stylesheet), rules: rules, - rulelist: MutNullableHeap::new(None), + rulelist: MutNullableJS::new(None), } } - #[allow(unrooted_must_root)] - pub fn new(window: &Window, parent_stylesheet: &CSSStyleSheet, - rules: Arc<RwLock<StyleCssRules>>) -> Root<CSSGroupingRule> { - reflect_dom_object(box CSSGroupingRule::new_inherited(parent_stylesheet, rules), - window, - CSSGroupingRuleBinding::Wrap) - } - fn rulelist(&self) -> Root<CSSRuleList> { let parent_stylesheet = self.upcast::<CSSRule>().parent_stylesheet(); self.rulelist.or_init(|| CSSRuleList::new(self.global().as_window(), diff --git a/components/script/dom/cssimportrule.rs b/components/script/dom/cssimportrule.rs new file mode 100644 index 00000000000..582a6f597f9 --- /dev/null +++ b/components/script/dom/cssimportrule.rs @@ -0,0 +1,53 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +use dom::bindings::codegen::Bindings::CSSImportRuleBinding; +use dom::bindings::js::Root; +use dom::bindings::reflector::reflect_dom_object; +use dom::bindings::str::DOMString; +use dom::cssrule::{CSSRule, SpecificCSSRule}; +use dom::cssstylesheet::CSSStyleSheet; +use dom::window::Window; +use parking_lot::RwLock; +use std::sync::Arc; +use style::stylesheets::ImportRule; +use style_traits::ToCss; + +#[dom_struct] +pub struct CSSImportRule { + cssrule: CSSRule, + #[ignore_heap_size_of = "Arc"] + import_rule: Arc<RwLock<ImportRule>>, +} + +impl CSSImportRule { + fn new_inherited(parent_stylesheet: &CSSStyleSheet, + import_rule: Arc<RwLock<ImportRule>>) + -> Self { + CSSImportRule { + cssrule: CSSRule::new_inherited(parent_stylesheet), + import_rule: import_rule, + } + } + + #[allow(unrooted_must_root)] + pub fn new(window: &Window, + parent_stylesheet: &CSSStyleSheet, + import_rule: Arc<RwLock<ImportRule>>) -> Root<Self> { + reflect_dom_object(box Self::new_inherited(parent_stylesheet, import_rule), + window, + CSSImportRuleBinding::Wrap) + } +} + +impl SpecificCSSRule for CSSImportRule { + fn ty(&self) -> u16 { + use dom::bindings::codegen::Bindings::CSSRuleBinding::CSSRuleConstants; + CSSRuleConstants::IMPORT_RULE + } + + fn get_css(&self) -> DOMString { + self.import_rule.read().to_css_string().into() + } +} diff --git a/components/script/dom/csskeyframesrule.rs b/components/script/dom/csskeyframesrule.rs index 46ed79435c1..1c94e0e99fb 100644 --- a/components/script/dom/csskeyframesrule.rs +++ b/components/script/dom/csskeyframesrule.rs @@ -5,8 +5,9 @@ use cssparser::Parser; use dom::bindings::codegen::Bindings::CSSKeyframesRuleBinding; use dom::bindings::codegen::Bindings::CSSKeyframesRuleBinding::CSSKeyframesRuleMethods; +use dom::bindings::error::{Error, ErrorResult}; use dom::bindings::inheritance::Castable; -use dom::bindings::js::{JS, MutNullableHeap, Root}; +use dom::bindings::js::{MutNullableJS, Root}; use dom::bindings::reflector::{DomObject, reflect_dom_object}; use dom::bindings::str::DOMString; use dom::csskeyframerule::CSSKeyframeRule; @@ -15,6 +16,7 @@ use dom::cssrulelist::{CSSRuleList, RulesSource}; use dom::cssstylesheet::CSSStyleSheet; use dom::window::Window; use parking_lot::RwLock; +use servo_atoms::Atom; use std::sync::Arc; use style::keyframes::{Keyframe, KeyframeSelector}; use style::parser::ParserContextExtraData; @@ -26,7 +28,7 @@ pub struct CSSKeyframesRule { cssrule: CSSRule, #[ignore_heap_size_of = "Arc"] keyframesrule: Arc<RwLock<KeyframesRule>>, - rulelist: MutNullableHeap<JS<CSSRuleList>>, + rulelist: MutNullableJS<CSSRuleList>, } impl CSSKeyframesRule { @@ -35,7 +37,7 @@ impl CSSKeyframesRule { CSSKeyframesRule { cssrule: CSSRule::new_inherited(parent_stylesheet), keyframesrule: keyframesrule, - rulelist: MutNullableHeap::new(None), + rulelist: MutNullableJS::new(None), } } @@ -101,6 +103,27 @@ impl CSSKeyframesRuleMethods for CSSKeyframesRule { self.rulelist().item(idx as u32) }).and_then(Root::downcast) } + + // https://drafts.csswg.org/css-animations/#dom-csskeyframesrule-name + fn Name(&self) -> DOMString { + DOMString::from(&*self.keyframesrule.read().name) + } + + // https://drafts.csswg.org/css-animations/#dom-csskeyframesrule-name + fn SetName(&self, value: DOMString) -> ErrorResult { + // https://github.com/w3c/csswg-drafts/issues/801 + // Setting this property to a CSS-wide keyword or `none` will + // throw a Syntax Error. + match_ignore_ascii_case! { value, + "initial" => return Err(Error::Syntax), + "inherit" => return Err(Error::Syntax), + "unset" => return Err(Error::Syntax), + "none" => return Err(Error::Syntax), + _ => () + } + self.keyframesrule.write().name = Atom::from(value); + Ok(()) + } } impl SpecificCSSRule for CSSKeyframesRule { diff --git a/components/script/dom/cssmediarule.rs b/components/script/dom/cssmediarule.rs index 0e1fc145e7d..b6b04dde9d8 100644 --- a/components/script/dom/cssmediarule.rs +++ b/components/script/dom/cssmediarule.rs @@ -4,7 +4,7 @@ use dom::bindings::codegen::Bindings::CSSMediaRuleBinding; use dom::bindings::codegen::Bindings::CSSMediaRuleBinding::CSSMediaRuleMethods; -use dom::bindings::js::{JS, MutNullableHeap, Root}; +use dom::bindings::js::{MutNullableJS, Root}; use dom::bindings::reflector::{DomObject, reflect_dom_object}; use dom::bindings::str::DOMString; use dom::cssgroupingrule::CSSGroupingRule; @@ -22,7 +22,7 @@ pub struct CSSMediaRule { cssrule: CSSGroupingRule, #[ignore_heap_size_of = "Arc"] mediarule: Arc<RwLock<MediaRule>>, - medialist: MutNullableHeap<JS<MediaList>>, + medialist: MutNullableJS<MediaList>, } impl CSSMediaRule { @@ -32,7 +32,7 @@ impl CSSMediaRule { CSSMediaRule { cssrule: CSSGroupingRule::new_inherited(parent_stylesheet, list), mediarule: mediarule, - medialist: MutNullableHeap::new(None), + medialist: MutNullableJS::new(None), } } diff --git a/components/script/dom/cssrule.rs b/components/script/dom/cssrule.rs index 603354c8621..8323d7e22b0 100644 --- a/components/script/dom/cssrule.rs +++ b/components/script/dom/cssrule.rs @@ -2,13 +2,13 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -use dom::bindings::codegen::Bindings::CSSRuleBinding; use dom::bindings::codegen::Bindings::CSSRuleBinding::CSSRuleMethods; use dom::bindings::inheritance::Castable; use dom::bindings::js::{JS, Root}; -use dom::bindings::reflector::{Reflector, reflect_dom_object}; +use dom::bindings::reflector::Reflector; use dom::bindings::str::DOMString; use dom::cssfontfacerule::CSSFontFaceRule; +use dom::cssimportrule::CSSImportRule; use dom::csskeyframerule::CSSKeyframeRule; use dom::csskeyframesrule::CSSKeyframesRule; use dom::cssmediarule::CSSMediaRule; @@ -42,13 +42,6 @@ impl CSSRule { } } - #[allow(unrooted_must_root)] - pub fn new(window: &Window, parent_stylesheet: &CSSStyleSheet) -> Root<CSSRule> { - reflect_dom_object(box CSSRule::new_inherited(parent_stylesheet), - window, - CSSRuleBinding::Wrap) - } - pub fn as_specific(&self) -> &SpecificCSSRule { if let Some(rule) = self.downcast::<CSSStyleRule>() { rule as &SpecificCSSRule @@ -64,6 +57,8 @@ impl CSSRule { rule as &SpecificCSSRule } else if let Some(rule) = self.downcast::<CSSKeyframeRule>() { rule as &SpecificCSSRule + } else if let Some(rule) = self.downcast::<CSSImportRule>() { + rule as &SpecificCSSRule } else { unreachable!() } @@ -75,6 +70,7 @@ impl CSSRule { rule: StyleCssRule) -> Root<CSSRule> { // be sure to update the match in as_specific when this is updated match rule { + StyleCssRule::Import(s) => Root::upcast(CSSImportRule::new(window, parent_stylesheet, s)), StyleCssRule::Style(s) => Root::upcast(CSSStyleRule::new(window, parent_stylesheet, s)), StyleCssRule::FontFace(s) => Root::upcast(CSSFontFaceRule::new(window, parent_stylesheet, s)), StyleCssRule::Keyframes(s) => Root::upcast(CSSKeyframesRule::new(window, parent_stylesheet, s)), diff --git a/components/script/dom/cssrulelist.rs b/components/script/dom/cssrulelist.rs index 988f839a87a..f667638b022 100644 --- a/components/script/dom/cssrulelist.rs +++ b/components/script/dom/cssrulelist.rs @@ -6,7 +6,7 @@ use dom::bindings::cell::DOMRefCell; use dom::bindings::codegen::Bindings::CSSRuleListBinding; use dom::bindings::codegen::Bindings::CSSRuleListBinding::CSSRuleListMethods; use dom::bindings::error::{Error, ErrorResult, Fallible}; -use dom::bindings::js::{JS, MutNullableHeap, Root}; +use dom::bindings::js::{JS, MutNullableJS, Root}; use dom::bindings::reflector::{DomObject, Reflector, reflect_dom_object}; use dom::csskeyframerule::CSSKeyframeRule; use dom::cssrule::CSSRule; @@ -38,7 +38,7 @@ pub struct CSSRuleList { parent_stylesheet: JS<CSSStyleSheet>, #[ignore_heap_size_of = "Arc"] rules: RulesSource, - dom_rules: DOMRefCell<Vec<MutNullableHeap<JS<CSSRule>>>> + dom_rules: DOMRefCell<Vec<MutNullableJS<CSSRule>>> } pub enum RulesSource { @@ -51,10 +51,10 @@ impl CSSRuleList { pub fn new_inherited(parent_stylesheet: &CSSStyleSheet, rules: RulesSource) -> CSSRuleList { let dom_rules = match rules { RulesSource::Rules(ref rules) => { - rules.read().0.iter().map(|_| MutNullableHeap::new(None)).collect() + rules.read().0.iter().map(|_| MutNullableJS::new(None)).collect() } RulesSource::Keyframes(ref rules) => { - rules.read().keyframes.iter().map(|_| MutNullableHeap::new(None)).collect() + rules.read().keyframes.iter().map(|_| MutNullableJS::new(None)).collect() } }; @@ -92,7 +92,7 @@ impl CSSRuleList { let parent_stylesheet = &*self.parent_stylesheet; let dom_rule = CSSRule::new_specific(&window, parent_stylesheet, new_rule); - self.dom_rules.borrow_mut().insert(index, MutNullableHeap::new(Some(&*dom_rule))); + self.dom_rules.borrow_mut().insert(index, MutNullableJS::new(Some(&*dom_rule))); Ok((idx)) } @@ -158,7 +158,7 @@ impl CSSRuleList { if let RulesSource::Rules(..) = self.rules { panic!("Can only call append_lazy_rule with keyframes-backed CSSRules"); } - self.dom_rules.borrow_mut().push(MutNullableHeap::new(None)); + self.dom_rules.borrow_mut().push(MutNullableJS::new(None)); } } diff --git a/components/script/dom/cssstyledeclaration.rs b/components/script/dom/cssstyledeclaration.rs index c6280597b17..7cd63aa12b0 100644 --- a/components/script/dom/cssstyledeclaration.rs +++ b/components/script/dom/cssstyledeclaration.rs @@ -3,6 +3,7 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ use dom::bindings::codegen::Bindings::CSSStyleDeclarationBinding::{self, CSSStyleDeclarationMethods}; +use dom::bindings::codegen::Bindings::WindowBinding::WindowMethods; use dom::bindings::error::{Error, ErrorResult, Fallible}; use dom::bindings::inheritance::Castable; use dom::bindings::js::{JS, Root}; @@ -12,12 +13,11 @@ use dom::element::Element; use dom::node::{Node, NodeDamage, window_from_node}; use dom::window::Window; use parking_lot::RwLock; -use servo_atoms::Atom; use std::ascii::AsciiExt; use std::sync::Arc; use style::parser::ParserContextExtraData; -use style::properties::{Shorthand, Importance, PropertyDeclarationBlock}; -use style::properties::{is_supported_property, parse_one_declaration, parse_style_attribute}; +use style::properties::{Importance, PropertyDeclarationBlock, PropertyId, LonghandId, ShorthandId}; +use style::properties::{parse_one_declaration, parse_style_attribute}; use style::selector_parser::PseudoElement; use style_traits::ToCss; @@ -25,11 +25,59 @@ use style_traits::ToCss; #[dom_struct] pub struct CSSStyleDeclaration { reflector_: Reflector, - owner: JS<Element>, + owner: CSSStyleOwner, readonly: bool, pseudo: Option<PseudoElement>, } +#[derive(HeapSizeOf, JSTraceable)] +#[must_root] +pub enum CSSStyleOwner { + Element(JS<Element>), + CSSStyleRule(JS<Window>, + #[ignore_heap_size_of = "Arc"] + Arc<RwLock<PropertyDeclarationBlock>>), +} + +impl CSSStyleOwner { + fn style_attribute(&self) -> Option<Arc<RwLock<PropertyDeclarationBlock>>> { + match *self { + CSSStyleOwner::Element(ref el) => { + if let Some(ref pdb) = *el.style_attribute().borrow() { + Some(pdb.clone()) + } else { + None + } + } + CSSStyleOwner::CSSStyleRule(_, ref pdb) => { + Some(pdb.clone()) + } + } + } + + fn window(&self) -> Root<Window> { + match *self { + CSSStyleOwner::Element(ref el) => window_from_node(&**el), + CSSStyleOwner::CSSStyleRule(ref window, _) => Root::from_ref(&**window), + } + } + + fn flush_style(&self, pdb: &PropertyDeclarationBlock) { + if let CSSStyleOwner::Element(ref el) = *self { + el.set_style_attr(pdb.to_css_string()); + } + } + + fn dirty(&self) { + match *self { + CSSStyleOwner::Element(ref el) => + el.upcast::<Node>().dirty(NodeDamage::NodeStyleDamaged), + CSSStyleOwner::CSSStyleRule(ref window, _) => + window.Document().invalidate_stylesheets(), + } + } +} + #[derive(PartialEq, HeapSizeOf)] pub enum CSSModificationAccess { ReadWrite, @@ -37,33 +85,35 @@ pub enum CSSModificationAccess { } macro_rules! css_properties( - ( $([$getter:ident, $setter:ident, $cssprop:expr]),* ) => ( + ( $([$getter:ident, $setter:ident, $id:expr],)* ) => ( $( fn $getter(&self) -> DOMString { - self.GetPropertyValue(DOMString::from($cssprop)) + self.get_property_value($id) } fn $setter(&self, value: DOMString) -> ErrorResult { - self.SetPropertyValue(DOMString::from($cssprop), value) + self.set_property($id, value, DOMString::new()) } )* ); ); impl CSSStyleDeclaration { - pub fn new_inherited(owner: &Element, + #[allow(unrooted_must_root)] + pub fn new_inherited(owner: CSSStyleOwner, pseudo: Option<PseudoElement>, modification_access: CSSModificationAccess) -> CSSStyleDeclaration { CSSStyleDeclaration { reflector_: Reflector::new(), - owner: JS::from_ref(owner), + owner: owner, readonly: modification_access == CSSModificationAccess::Readonly, pseudo: pseudo, } } + #[allow(unrooted_must_root)] pub fn new(global: &Window, - owner: &Element, + owner: CSSStyleOwner, pseudo: Option<PseudoElement>, modification_access: CSSModificationAccess) -> Root<CSSStyleDeclaration> { @@ -74,108 +124,59 @@ impl CSSStyleDeclaration { CSSStyleDeclarationBinding::Wrap) } - fn get_computed_style(&self, property: &Atom) -> Option<DOMString> { - let node = self.owner.upcast::<Node>(); - if !node.is_in_doc() { - // TODO: Node should be matched against the style rules of this window. - // Firefox is currently the only browser to implement this. - return None; + fn get_computed_style(&self, property: PropertyId) -> DOMString { + match self.owner { + CSSStyleOwner::CSSStyleRule(..) => + panic!("get_computed_style called on CSSStyleDeclaration with a CSSStyleRule owner"), + CSSStyleOwner::Element(ref el) => { + let node = el.upcast::<Node>(); + if !node.is_in_doc() { + // TODO: Node should be matched against the style rules of this window. + // Firefox is currently the only browser to implement this. + return DOMString::new(); + } + let addr = node.to_trusted_node_address(); + window_from_node(node).resolved_style_query(addr, self.pseudo.clone(), property) + } } - let addr = node.to_trusted_node_address(); - window_from_node(&*self.owner).resolved_style_query(addr, self.pseudo.clone(), property) - } -} - -impl CSSStyleDeclarationMethods for CSSStyleDeclaration { - // https://dev.w3.org/csswg/cssom/#dom-cssstyledeclaration-length - fn Length(&self) -> u32 { - let elem = self.owner.upcast::<Element>(); - let len = match *elem.style_attribute().borrow() { - Some(ref lock) => lock.read().declarations.len(), - None => 0, - }; - len as u32 - } - - // https://dev.w3.org/csswg/cssom/#dom-cssstyledeclaration-item - fn Item(&self, index: u32) -> DOMString { - self.IndexedGetter(index).unwrap_or_default() } - // https://dev.w3.org/csswg/cssom/#dom-cssstyledeclaration-getpropertyvalue - fn GetPropertyValue(&self, mut property: DOMString) -> DOMString { + fn get_property_value(&self, id: PropertyId) -> DOMString { if self.readonly { // Readonly style declarations are used for getComputedStyle. - property.make_ascii_lowercase(); - let property = Atom::from(property); - return self.get_computed_style(&property).unwrap_or(DOMString::new()); + return self.get_computed_style(id); } - let style_attribute = self.owner.style_attribute().borrow(); - let style_attribute = if let Some(ref lock) = *style_attribute { - lock.read() + if let Some(ref lock) = self.owner.style_attribute() { + let mut string = String::new(); + lock.read().property_value_to_css(&id, &mut string).unwrap(); + DOMString::from(string) } else { // No style attribute is like an empty style attribute: no matching declaration. - return DOMString::new() - }; - - let mut string = String::new(); - style_attribute.property_value_to_css(&property, &mut string).unwrap(); - DOMString::from(string) - } - - // https://dev.w3.org/csswg/cssom/#dom-cssstyledeclaration-getpropertypriority - fn GetPropertyPriority(&self, property: DOMString) -> DOMString { - let style_attribute = self.owner.style_attribute().borrow(); - let style_attribute = if let Some(ref lock) = *style_attribute { - lock.read() - } else { - // No style attribute is like an empty style attribute: no matching declaration. - return DOMString::new() - }; - - if style_attribute.property_priority(&property).important() { - DOMString::from("important") - } else { - // Step 4 DOMString::new() } } - // https://dev.w3.org/csswg/cssom/#dom-cssstyledeclaration-setproperty - fn SetProperty(&self, - property: DOMString, - value: DOMString, - priority: DOMString) - -> ErrorResult { + fn set_property(&self, id: PropertyId, value: DOMString, priority: DOMString) -> ErrorResult { // Step 1 if self.readonly { return Err(Error::NoModificationAllowed); } - // Step 3 - if !is_supported_property(&property) { - return Ok(()); - } - - let mut style_attribute = self.owner.style_attribute().borrow_mut(); - if value.is_empty() { // Step 4 - let empty; - { - let mut style_attribute = if let Some(ref lock) = *style_attribute { - lock.write() + let empty = { + if let Some(ref lock) = self.owner.style_attribute() { + let mut style_attribute = lock.write(); + style_attribute.remove_property(&id); + style_attribute.declarations.is_empty() } else { // No style attribute is like an empty style attribute: nothing to remove. return Ok(()) - }; - - style_attribute.remove_property(&property); - empty = style_attribute.declarations.is_empty() - } - if empty { - *style_attribute = None; + } + }; + if let (&CSSStyleOwner::Element(ref el), true) = (&self.owner, empty) { + *el.style_attribute().borrow_mut() = None; } } else { // Step 5 @@ -186,29 +187,28 @@ impl CSSStyleDeclarationMethods for CSSStyleDeclaration { }; // Step 6 - let window = window_from_node(&*self.owner); + let window = self.owner.window(); let declarations = - parse_one_declaration(&property, &value, &window.get_url(), window.css_error_reporter(), + parse_one_declaration(id, &value, &window.get_url(), window.css_error_reporter(), ParserContextExtraData::default()); // Step 7 - let declarations = if let Ok(declarations) = declarations { - declarations - } else { - return Ok(()); + let declarations = match declarations { + Ok(declarations) => declarations, + Err(_) => return Ok(()) }; // Step 8 // Step 9 - match *style_attribute { + match self.owner.style_attribute() { Some(ref lock) => { let mut style_attribute = lock.write(); for declaration in declarations { style_attribute.set_parsed_declaration(declaration, importance); } - self.owner.set_style_attr(style_attribute.to_css_string()); + self.owner.flush_style(&style_attribute); } - ref mut option @ None => { + None => { let important_count = if importance.important() { declarations.len() as u32 } else { @@ -218,16 +218,80 @@ impl CSSStyleDeclarationMethods for CSSStyleDeclaration { declarations: declarations.into_iter().map(|d| (d, importance)).collect(), important_count: important_count, }; - self.owner.set_style_attr(block.to_css_string()); - *option = Some(Arc::new(RwLock::new(block))); + if let CSSStyleOwner::Element(ref el) = self.owner { + el.set_style_attr(block.to_css_string()); + *el.style_attribute().borrow_mut() = Some(Arc::new(RwLock::new(block))); + } else { + panic!("set_property called on a CSSStyleDeclaration with a non-Element owner"); + } } } } - let node = self.owner.upcast::<Node>(); - node.dirty(NodeDamage::NodeStyleDamaged); + self.owner.dirty(); Ok(()) } +} + +impl CSSStyleDeclarationMethods for CSSStyleDeclaration { + // https://dev.w3.org/csswg/cssom/#dom-cssstyledeclaration-length + fn Length(&self) -> u32 { + self.owner.style_attribute().as_ref().map_or(0, |lock| lock.read().declarations.len() as u32) + } + + // https://dev.w3.org/csswg/cssom/#dom-cssstyledeclaration-item + fn Item(&self, index: u32) -> DOMString { + self.IndexedGetter(index).unwrap_or_default() + } + + // https://dev.w3.org/csswg/cssom/#dom-cssstyledeclaration-getpropertyvalue + fn GetPropertyValue(&self, property: DOMString) -> DOMString { + let id = if let Ok(id) = PropertyId::parse(property.into()) { + id + } else { + // Unkwown property + return DOMString::new() + }; + self.get_property_value(id) + } + + // https://dev.w3.org/csswg/cssom/#dom-cssstyledeclaration-getpropertypriority + fn GetPropertyPriority(&self, property: DOMString) -> DOMString { + let id = if let Ok(id) = PropertyId::parse(property.into()) { + id + } else { + // Unkwown property + return DOMString::new() + }; + + if let Some(ref lock) = self.owner.style_attribute() { + if lock.read().property_priority(&id).important() { + DOMString::from("important") + } else { + // Step 4 + DOMString::new() + } + } else { + // No style attribute is like an empty style attribute: no matching declaration. + DOMString::new() + } + } + + // https://dev.w3.org/csswg/cssom/#dom-cssstyledeclaration-setproperty + fn SetProperty(&self, + property: DOMString, + value: DOMString, + priority: DOMString) + -> ErrorResult { + // Step 3 + let id = if let Ok(id) = PropertyId::parse(property.into()) { + id + } else { + // Unknown property + return Ok(()) + }; + self.set_property(id, value, priority) + } // https://dev.w3.org/csswg/cssom/#dom-cssstyledeclaration-setpropertypriority fn SetPropertyPriority(&self, property: DOMString, priority: DOMString) -> ErrorResult { @@ -237,9 +301,12 @@ impl CSSStyleDeclarationMethods for CSSStyleDeclaration { } // Step 2 & 3 - if !is_supported_property(&property) { - return Ok(()); - } + let id = if let Ok(id) = PropertyId::parse(property.into()) { + id + } else { + // Unkwown property + return Ok(()) + }; // Step 4 let importance = match &*priority { @@ -248,19 +315,14 @@ impl CSSStyleDeclarationMethods for CSSStyleDeclaration { _ => return Ok(()), }; - let style_attribute = self.owner.style_attribute().borrow(); - if let Some(ref lock) = *style_attribute { + if let Some(ref lock) = self.owner.style_attribute() { let mut style_attribute = lock.write(); // Step 5 & 6 - match Shorthand::from_name(&property) { - Some(shorthand) => style_attribute.set_importance(shorthand.longhands(), importance), - None => style_attribute.set_importance(&[&*property], importance), - } + style_attribute.set_importance(&id, importance); - self.owner.set_style_attr(style_attribute.to_css_string()); - let node = self.owner.upcast::<Node>(); - node.dirty(NodeDamage::NodeStyleDamaged); + self.owner.flush_style(&style_attribute); + self.owner.dirty(); } Ok(()) } @@ -277,31 +339,33 @@ impl CSSStyleDeclarationMethods for CSSStyleDeclaration { return Err(Error::NoModificationAllowed); } - let mut style_attribute = self.owner.style_attribute().borrow_mut(); + let id = if let Ok(id) = PropertyId::parse(property.into()) { + id + } else { + // Unkwown property, cannot be there to remove. + return Ok(DOMString::new()) + }; + let mut string = String::new(); - let empty; - { - let mut style_attribute = if let Some(ref lock) = *style_attribute { - lock.write() + let empty = { + if let Some(ref lock) = self.owner.style_attribute() { + let mut style_attribute = lock.write(); + // Step 3 + style_attribute.property_value_to_css(&id, &mut string).unwrap(); + + // Step 4 & 5 + style_attribute.remove_property(&id); + self.owner.flush_style(&style_attribute); + style_attribute.declarations.is_empty() } else { // No style attribute is like an empty style attribute: nothing to remove. return Ok(DOMString::new()) - }; - - // Step 3 - style_attribute.property_value_to_css(&property, &mut string).unwrap(); - - // Step 4 & 5 - style_attribute.remove_property(&property); - self.owner.set_style_attr(style_attribute.to_css_string()); - empty = style_attribute.declarations.is_empty() - } - if empty { - *style_attribute = None; + } + }; + if let (&CSSStyleOwner::Element(ref el), true) = (&self.owner, empty) { + *el.style_attribute().borrow_mut() = None; } - - let node = self.owner.upcast::<Node>(); - node.dirty(NodeDamage::NodeStyleDamaged); + self.owner.dirty(); // Step 6 Ok(DOMString::from(string)) @@ -319,11 +383,8 @@ impl CSSStyleDeclarationMethods for CSSStyleDeclaration { // https://dev.w3.org/csswg/cssom/#the-cssstyledeclaration-interface fn IndexedGetter(&self, index: u32) -> Option<DOMString> { - let index = index as usize; - let elem = self.owner.upcast::<Element>(); - let style_attribute = elem.style_attribute().borrow(); - style_attribute.as_ref().and_then(|lock| { - lock.read().declarations.get(index).map(|entry| { + self.owner.style_attribute().as_ref().and_then(|lock| { + lock.read().declarations.get(index as usize).map(|entry| { let (ref declaration, importance) = *entry; let mut css = declaration.to_css_string(); if importance.important() { @@ -336,19 +397,13 @@ impl CSSStyleDeclarationMethods for CSSStyleDeclaration { // https://drafts.csswg.org/cssom/#dom-cssstyledeclaration-csstext fn CssText(&self) -> DOMString { - let elem = self.owner.upcast::<Element>(); - let style_attribute = elem.style_attribute().borrow(); - - if let Some(lock) = style_attribute.as_ref() { - DOMString::from(lock.read().to_css_string()) - } else { - DOMString::new() - } + self.owner.style_attribute().as_ref().map_or(DOMString::new(), |lock| + DOMString::from(lock.read().to_css_string())) } // https://drafts.csswg.org/cssom/#dom-cssstyledeclaration-csstext fn SetCssText(&self, value: DOMString) -> ErrorResult { - let window = window_from_node(self.owner.upcast::<Node>()); + let window = self.owner.window(); // Step 1 if self.readonly { @@ -358,15 +413,16 @@ impl CSSStyleDeclarationMethods for CSSStyleDeclaration { // Step 3 let decl_block = parse_style_attribute(&value, &window.get_url(), window.css_error_reporter(), ParserContextExtraData::default()); - *self.owner.style_attribute().borrow_mut() = if decl_block.declarations.is_empty() { - self.owner.set_style_attr(String::new()); - None // Step 2 - } else { - self.owner.set_style_attr(decl_block.to_css_string()); - Some(Arc::new(RwLock::new(decl_block))) - }; - let node = self.owner.upcast::<Node>(); - node.dirty(NodeDamage::NodeStyleDamaged); + if let CSSStyleOwner::Element(ref el) = self.owner { + *el.style_attribute().borrow_mut() = if decl_block.declarations.is_empty() { + el.set_style_attr(String::new()); + None // Step 2 + } else { + el.set_style_attr(decl_block.to_css_string()); + Some(Arc::new(RwLock::new(decl_block))) + }; + } + self.owner.dirty(); Ok(()) } diff --git a/components/script/dom/cssstylerule.rs b/components/script/dom/cssstylerule.rs index 091704f42d5..3e23864ae61 100644 --- a/components/script/dom/cssstylerule.rs +++ b/components/script/dom/cssstylerule.rs @@ -2,11 +2,12 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -use dom::bindings::codegen::Bindings::CSSStyleRuleBinding; -use dom::bindings::js::Root; -use dom::bindings::reflector::reflect_dom_object; +use dom::bindings::codegen::Bindings::CSSStyleRuleBinding::{self, CSSStyleRuleMethods}; +use dom::bindings::js::{JS, MutNullableJS, Root}; +use dom::bindings::reflector::{DomObject, reflect_dom_object}; use dom::bindings::str::DOMString; use dom::cssrule::{CSSRule, SpecificCSSRule}; +use dom::cssstyledeclaration::{CSSModificationAccess, CSSStyleDeclaration, CSSStyleOwner}; use dom::cssstylesheet::CSSStyleSheet; use dom::window::Window; use parking_lot::RwLock; @@ -19,6 +20,7 @@ pub struct CSSStyleRule { cssrule: CSSRule, #[ignore_heap_size_of = "Arc"] stylerule: Arc<RwLock<StyleRule>>, + style_decl: MutNullableJS<CSSStyleDeclaration>, } impl CSSStyleRule { @@ -27,6 +29,7 @@ impl CSSStyleRule { CSSStyleRule { cssrule: CSSRule::new_inherited(parent_stylesheet), stylerule: stylerule, + style_decl: Default::default(), } } @@ -49,3 +52,16 @@ impl SpecificCSSRule for CSSStyleRule { self.stylerule.read().to_css_string().into() } } + +impl CSSStyleRuleMethods for CSSStyleRule { + // https://drafts.csswg.org/cssom/#dom-cssstylerule-style + fn Style(&self) -> Root<CSSStyleDeclaration> { + self.style_decl.or_init(|| { + CSSStyleDeclaration::new(self.global().as_window(), + CSSStyleOwner::CSSStyleRule(JS::from_ref(self.global().as_window()), + self.stylerule.read().block.clone()), + None, + CSSModificationAccess::ReadWrite) + }) + } +} diff --git a/components/script/dom/cssstylesheet.rs b/components/script/dom/cssstylesheet.rs index 106b9b5805d..908cfad2cd5 100644 --- a/components/script/dom/cssstylesheet.rs +++ b/components/script/dom/cssstylesheet.rs @@ -6,7 +6,7 @@ use dom::bindings::codegen::Bindings::CSSStyleSheetBinding; use dom::bindings::codegen::Bindings::CSSStyleSheetBinding::CSSStyleSheetMethods; use dom::bindings::codegen::Bindings::WindowBinding::WindowBinding::WindowMethods; use dom::bindings::error::{ErrorResult, Fallible}; -use dom::bindings::js::{JS, Root, MutNullableHeap}; +use dom::bindings::js::{JS, MutNullableJS, Root}; use dom::bindings::reflector::{reflect_dom_object, DomObject}; use dom::bindings::str::DOMString; use dom::cssrulelist::{CSSRuleList, RulesSource}; @@ -20,7 +20,7 @@ use style::stylesheets::Stylesheet as StyleStyleSheet; pub struct CSSStyleSheet { stylesheet: StyleSheet, owner: JS<Element>, - rulelist: MutNullableHeap<JS<CSSRuleList>>, + rulelist: MutNullableJS<CSSRuleList>, #[ignore_heap_size_of = "Arc"] style_stylesheet: Arc<StyleStyleSheet>, } @@ -34,7 +34,7 @@ impl CSSStyleSheet { CSSStyleSheet { stylesheet: StyleSheet::new_inherited(type_, href, title), owner: JS::from_ref(owner), - rulelist: MutNullableHeap::new(None), + rulelist: MutNullableJS::new(None), style_stylesheet: stylesheet, } } diff --git a/components/script/dom/dedicatedworkerglobalscope.rs b/components/script/dom/dedicatedworkerglobalscope.rs index 96ee1f871eb..911847aadb8 100644 --- a/components/script/dom/dedicatedworkerglobalscope.rs +++ b/components/script/dom/dedicatedworkerglobalscope.rs @@ -38,8 +38,8 @@ use std::mem::replace; use std::sync::{Arc, Mutex}; use std::sync::atomic::AtomicBool; use std::sync::mpsc::{Receiver, RecvError, Select, Sender, channel}; +use std::thread; use style::thread_state; -use util::thread::spawn_named; /// Set the `worker` field of a related DedicatedWorkerGlobalScope object to a particular /// value for the duration of this object's lifetime. This ensures that the related Worker @@ -160,7 +160,7 @@ impl DedicatedWorkerGlobalScope { let name = format!("WebWorker for {}", serialized_worker_url); let top_level_frame_id = FrameId::installed(); - spawn_named(name, move || { + thread::Builder::new().name(name).spawn(move || { thread_state::initialize(thread_state::SCRIPT | thread_state::IN_WORKER); if let Some(top_level_frame_id) = top_level_frame_id { @@ -243,7 +243,7 @@ impl DedicatedWorkerGlobalScope { global.handle_event(event); } }, reporter_name, parent_sender, CommonScriptMsg::CollectReports); - }); + }).expect("Thread spawning failed"); } pub fn script_chan(&self) -> Box<ScriptChan + Send> { diff --git a/components/script/dom/document.rs b/components/script/dom/document.rs index 9704b4ba0ab..6f8f2435311 100644 --- a/components/script/dom/document.rs +++ b/components/script/dom/document.rs @@ -24,7 +24,7 @@ use dom::bindings::codegen::Bindings::WindowBinding::{FrameRequestCallback, Scro use dom::bindings::codegen::UnionTypes::NodeOrString; use dom::bindings::error::{Error, ErrorResult, Fallible}; use dom::bindings::inheritance::{Castable, ElementTypeId, HTMLElementTypeId, NodeTypeId}; -use dom::bindings::js::{JS, LayoutJS, MutNullableHeap, Root}; +use dom::bindings::js::{JS, LayoutJS, MutNullableJS, Root}; use dom::bindings::js::RootedReference; use dom::bindings::num::Finite; use dom::bindings::refcounted::{Trusted, TrustedPromise}; @@ -91,8 +91,9 @@ use encoding::EncodingRef; use encoding::all::UTF_8; use euclid::point::Point2D; use gfx_traits::ScrollRootId; -use html5ever::tree_builder::{LimitedQuirks, NoQuirks, Quirks, QuirksMode}; use html5ever_atoms::{LocalName, QualName}; +use hyper::header::{Header, SetCookie}; +use hyper_serde::Serde; use ipc_channel::ipc::{self, IpcSender}; use js::jsapi::{JSContext, JSObject, JSRuntime}; use js::jsapi::JS_GetRuntime; @@ -113,6 +114,7 @@ use script_traits::{ScriptMsg as ConstellationMsg, TouchpadPressurePhase}; use script_traits::{TouchEventType, TouchId}; use script_traits::UntrustedNodeAddress; use servo_atoms::Atom; +use servo_config::prefs::PREFS; use servo_url::ServoUrl; use std::ascii::AsciiExt; use std::borrow::ToOwned; @@ -126,14 +128,13 @@ use std::rc::Rc; use std::sync::Arc; use std::time::{Duration, Instant}; use style::attr::AttrValue; -use style::context::ReflowGoal; +use style::context::{QuirksMode, ReflowGoal}; use style::restyle_hints::RestyleHint; use style::selector_parser::{RestyleDamage, Snapshot}; use style::str::{split_html_space_chars, str_join}; use style::stylesheets::Stylesheet; use time; use url::percent_encoding::percent_decode; -use util::prefs::PREFS; pub enum TouchEventResult { Processed(bool), @@ -184,8 +185,8 @@ pub struct Document { window: JS<Window>, /// https://html.spec.whatwg.org/multipage/#concept-document-bc browsing_context: Option<JS<BrowsingContext>>, - implementation: MutNullableHeap<JS<DOMImplementation>>, - location: MutNullableHeap<JS<Location>>, + implementation: MutNullableJS<DOMImplementation>, + location: MutNullableJS<Location>, content_type: DOMString, last_modified: Option<String>, encoding: Cell<EncodingRef>, @@ -197,29 +198,29 @@ pub struct Document { tag_map: DOMRefCell<HashMap<LocalName, JS<HTMLCollection>>>, tagns_map: DOMRefCell<HashMap<QualName, JS<HTMLCollection>>>, classes_map: DOMRefCell<HashMap<Vec<Atom>, JS<HTMLCollection>>>, - images: MutNullableHeap<JS<HTMLCollection>>, - embeds: MutNullableHeap<JS<HTMLCollection>>, - links: MutNullableHeap<JS<HTMLCollection>>, - forms: MutNullableHeap<JS<HTMLCollection>>, - scripts: MutNullableHeap<JS<HTMLCollection>>, - anchors: MutNullableHeap<JS<HTMLCollection>>, - applets: MutNullableHeap<JS<HTMLCollection>>, + images: MutNullableJS<HTMLCollection>, + embeds: MutNullableJS<HTMLCollection>, + links: MutNullableJS<HTMLCollection>, + forms: MutNullableJS<HTMLCollection>, + scripts: MutNullableJS<HTMLCollection>, + anchors: MutNullableJS<HTMLCollection>, + applets: MutNullableJS<HTMLCollection>, /// List of stylesheets associated with nodes in this document. |None| if the list needs to be refreshed. stylesheets: DOMRefCell<Option<Vec<StylesheetInDocument>>>, /// Whether the list of stylesheets has changed since the last reflow was triggered. stylesheets_changed_since_reflow: Cell<bool>, - stylesheet_list: MutNullableHeap<JS<StyleSheetList>>, + stylesheet_list: MutNullableJS<StyleSheetList>, ready_state: Cell<DocumentReadyState>, /// Whether the DOMContentLoaded event has already been dispatched. domcontentloaded_dispatched: Cell<bool>, /// The element that has most recently requested focus for itself. - possibly_focused: MutNullableHeap<JS<Element>>, + possibly_focused: MutNullableJS<Element>, /// The element that currently has the document focus context. - focused: MutNullableHeap<JS<Element>>, + focused: MutNullableJS<Element>, /// The script element that is currently executing. - current_script: MutNullableHeap<JS<HTMLScriptElement>>, + current_script: MutNullableJS<HTMLScriptElement>, /// https://html.spec.whatwg.org/multipage/#pending-parsing-blocking-script - pending_parsing_blocking_script: MutNullableHeap<JS<HTMLScriptElement>>, + pending_parsing_blocking_script: MutNullableJS<HTMLScriptElement>, /// Number of stylesheets that block executing the next parser-inserted script script_blocking_stylesheets_count: Cell<u32>, /// https://html.spec.whatwg.org/multipage/#list-of-scripts-that-will-execute-when-the-document-has-finished-parsing @@ -245,14 +246,14 @@ pub struct Document { /// Tracks all outstanding loads related to this document. loader: DOMRefCell<DocumentLoader>, /// The current active HTML parser, to allow resuming after interruptions. - current_parser: MutNullableHeap<JS<ServoParser>>, + current_parser: MutNullableJS<ServoParser>, /// When we should kick off a reflow. This happens during parsing. reflow_timeout: Cell<Option<u64>>, /// The cached first `base` element with an `href` attribute. - base_element: MutNullableHeap<JS<HTMLBaseElement>>, + base_element: MutNullableJS<HTMLBaseElement>, /// This field is set to the document itself for inert documents. /// https://html.spec.whatwg.org/multipage/#appropriate-template-contents-owner-document - appropriate_template_contents_owner_document: MutNullableHeap<JS<Document>>, + appropriate_template_contents_owner_document: MutNullableJS<Document>, /// Information on elements needing restyle to ship over to the layout thread when the /// time comes. pending_restyles: DOMRefCell<HashMap<JS<Element>, PendingRestyle>>, @@ -280,7 +281,7 @@ pub struct Document { /// https://html.spec.whatwg.org/multipage/#dom-document-referrer referrer: Option<String>, /// https://html.spec.whatwg.org/multipage/#target-element - target_element: MutNullableHeap<JS<Element>>, + target_element: MutNullableJS<Element>, /// https://w3c.github.io/uievents/#event-type-dblclick #[ignore_heap_size_of = "Defined in std"] last_click_info: DOMRefCell<Option<(Instant, Point2D<f32>)>>, @@ -293,7 +294,7 @@ pub struct Document { /// See also: https://github.com/servo/servo/issues/10110 dom_count: Cell<u32>, /// Entry node for fullscreen. - fullscreen_element: MutNullableHeap<JS<Element>>, + fullscreen_element: MutNullableJS<Element>, } #[derive(JSTraceable, HeapSizeOf)] @@ -488,7 +489,7 @@ impl Document { pub fn set_quirks_mode(&self, mode: QuirksMode) { self.quirks_mode.set(mode); - if mode == Quirks { + if mode == QuirksMode::Quirks { self.window.layout_chan().send(Msg::SetQuirksMode).unwrap(); } } @@ -1036,7 +1037,7 @@ impl Document { pub fn handle_mouse_move_event(&self, js_runtime: *mut JSRuntime, client_point: Option<Point2D<f32>>, - prev_mouse_over_target: &MutNullableHeap<JS<Element>>) { + prev_mouse_over_target: &MutNullableJS<Element>) { let client_point = match client_point { None => { // If there's no point, there's no target under the mouse @@ -1521,8 +1522,11 @@ impl Document { /// https://html.spec.whatwg.org/multipage/#run-the-animation-frame-callbacks pub fn run_the_animation_frame_callbacks(&self) { - let mut animation_frame_list = - mem::replace(&mut *self.animation_frame_list.borrow_mut(), vec![]); + rooted_vec!(let mut animation_frame_list); + mem::swap( + &mut *animation_frame_list, + &mut *self.animation_frame_list.borrow_mut()); + self.running_animation_callbacks.set(true); let timing = self.window.Performance().Now(); @@ -1538,7 +1542,7 @@ impl Document { // message quickly followed by an AnimationCallbacksPresent message. if self.animation_frame_list.borrow().is_empty() { mem::swap(&mut *self.animation_frame_list.borrow_mut(), - &mut animation_frame_list); + &mut *animation_frame_list); let global_scope = self.window.upcast::<GlobalScope>(); let event = ConstellationMsg::ChangeRunningAnimationsState(global_scope.pipeline_id(), AnimationState::NoAnimationCallbacksPresent); @@ -1772,6 +1776,7 @@ pub trait LayoutDocumentHelpers { unsafe fn drain_pending_restyles(&self) -> Vec<(LayoutJS<Element>, PendingRestyle)>; unsafe fn needs_paint_from_layout(&self); unsafe fn will_paint(&self); + unsafe fn quirks_mode(&self) -> QuirksMode; } #[allow(unsafe_code)] @@ -1798,6 +1803,11 @@ impl LayoutDocumentHelpers for LayoutJS<Document> { unsafe fn will_paint(&self) { (*self.unsafe_get()).needs_paint.set(false) } + + #[inline] + unsafe fn quirks_mode(&self) -> QuirksMode { + (*self.unsafe_get()).quirks_mode() + } } /// https://url.spec.whatwg.org/#network-scheme @@ -1855,7 +1865,7 @@ impl Document { last_modified: last_modified, url: DOMRefCell::new(url), // https://dom.spec.whatwg.org/#concept-document-quirks - quirks_mode: Cell::new(NoQuirks), + quirks_mode: Cell::new(QuirksMode::NoQuirks), // https://dom.spec.whatwg.org/#concept-document-encoding encoding: Cell::new(UTF_8), is_html_document: is_html_document == IsHTMLDocument::HTMLDocument, @@ -1872,7 +1882,7 @@ impl Document { applets: Default::default(), stylesheets: DOMRefCell::new(None), stylesheets_changed_since_reflow: Cell::new(false), - stylesheet_list: MutNullableHeap::new(None), + stylesheet_list: MutNullableJS::new(None), ready_state: Cell::new(ready_state), domcontentloaded_dispatched: Cell::new(domcontentloaded_dispatched), possibly_focused: Default::default(), @@ -1907,11 +1917,11 @@ impl Document { origin: origin, referrer: referrer, referrer_policy: Cell::new(referrer_policy), - target_element: MutNullableHeap::new(None), + target_element: MutNullableJS::new(None), last_click_info: DOMRefCell::new(None), ignore_destructive_writes_counter: Default::default(), dom_count: Cell::new(1), - fullscreen_element: MutNullableHeap::new(None), + fullscreen_element: MutNullableJS::new(None), } } @@ -2298,8 +2308,8 @@ impl DocumentMethods for Document { // https://dom.spec.whatwg.org/#dom-document-compatmode fn CompatMode(&self) -> DOMString { DOMString::from(match self.quirks_mode.get() { - LimitedQuirks | NoQuirks => "CSS1Compat", - Quirks => "BackCompat", + QuirksMode::LimitedQuirks | QuirksMode::NoQuirks => "CSS1Compat", + QuirksMode::Quirks => "BackCompat", }) } @@ -2667,7 +2677,7 @@ impl DocumentMethods for Document { None => DOMString::new(), Some(ref title) => { // Steps 3-4. - let value = Node::collect_text_contents(title.children()); + let value = title.child_text_content(); DOMString::from(str_join(split_html_space_chars(&value), " ")) }, } @@ -2957,11 +2967,15 @@ impl DocumentMethods for Document { return Err(Error::Security); } - let url = self.url(); - let _ = self.window - .upcast::<GlobalScope>() - .resource_threads() - .send(SetCookiesForUrl(url, String::from(cookie), NonHTTP)); + let header = Header::parse_header(&[cookie.into()]); + if let Ok(SetCookie(cookies)) = header { + let cookies = cookies.into_iter().map(Serde).collect(); + let _ = self.window + .upcast::<GlobalScope>() + .resource_threads() + .send(SetCookiesForUrl(self.url(), cookies, NonHTTP)); + } + Ok(()) } diff --git a/components/script/dom/domexception.rs b/components/script/dom/domexception.rs index 2a5946193b6..7428a986c48 100644 --- a/components/script/dom/domexception.rs +++ b/components/script/dom/domexception.rs @@ -29,13 +29,11 @@ pub enum DOMErrorName { SecurityError = DOMExceptionConstants::SECURITY_ERR, NetworkError = DOMExceptionConstants::NETWORK_ERR, AbortError = DOMExceptionConstants::ABORT_ERR, - URLMismatchError = DOMExceptionConstants::URL_MISMATCH_ERR, TypeMismatchError = DOMExceptionConstants::TYPE_MISMATCH_ERR, QuotaExceededError = DOMExceptionConstants::QUOTA_EXCEEDED_ERR, TimeoutError = DOMExceptionConstants::TIMEOUT_ERR, InvalidNodeTypeError = DOMExceptionConstants::INVALID_NODE_TYPE_ERR, DataCloneError = DOMExceptionConstants::DATA_CLONE_ERR, - EncodingError, } #[dom_struct] @@ -62,11 +60,7 @@ impl DOMException { impl DOMExceptionMethods for DOMException { // https://heycam.github.io/webidl/#dfn-DOMException fn Code(&self) -> u16 { - match self.code { - // https://heycam.github.io/webidl/#dfn-throw - DOMErrorName::EncodingError => 0, - code => code as u16, - } + self.code as u16 } // https://heycam.github.io/webidl/#idl-DOMException-error-names @@ -93,14 +87,12 @@ impl DOMExceptionMethods for DOMException { DOMErrorName::SecurityError => "The operation is insecure.", DOMErrorName::NetworkError => "A network error occurred.", DOMErrorName::AbortError => "The operation was aborted.", - DOMErrorName::URLMismatchError => "The given URL does not match another URL.", DOMErrorName::TypeMismatchError => "The given type does not match any expected type.", DOMErrorName::QuotaExceededError => "The quota has been exceeded.", DOMErrorName::TimeoutError => "The operation timed out.", DOMErrorName::InvalidNodeTypeError => "The supplied node is incorrect or has an incorrect ancestor for this operation.", DOMErrorName::DataCloneError => "The object can not be cloned.", - DOMErrorName::EncodingError => "The encoding operation (either encoded or decoding) failed." }; DOMString::from(message) diff --git a/components/script/dom/domimplementation.rs b/components/script/dom/domimplementation.rs index 7556e64d0a7..cbc69b318df 100644 --- a/components/script/dom/domimplementation.rs +++ b/components/script/dom/domimplementation.rs @@ -155,20 +155,17 @@ impl DOMImplementationMethods for DOMImplementation { doc_html.AppendChild(&doc_head).unwrap(); // Step 6. - match title { - None => (), - Some(title_str) => { - // Step 6.1. - let doc_title = - Root::upcast::<Node>(HTMLTitleElement::new(local_name!("title"), - None, - &doc)); - doc_head.AppendChild(&doc_title).unwrap(); - - // Step 6.2. - let title_text = Text::new(title_str, &doc); - doc_title.AppendChild(title_text.upcast()).unwrap(); - } + if let Some(title_str) = title { + // Step 6.1. + let doc_title = + Root::upcast::<Node>(HTMLTitleElement::new(local_name!("title"), + None, + &doc)); + doc_head.AppendChild(&doc_title).unwrap(); + + // Step 6.2. + let title_text = Text::new(title_str, &doc); + doc_title.AppendChild(title_text.upcast()).unwrap(); } } diff --git a/components/script/dom/element.rs b/components/script/dom/element.rs index 4a94f345b02..d9c2f6907e7 100644 --- a/components/script/dom/element.rs +++ b/components/script/dom/element.rs @@ -22,7 +22,7 @@ use dom::bindings::codegen::Bindings::WindowBinding::WindowMethods; use dom::bindings::codegen::UnionTypes::NodeOrString; use dom::bindings::error::{Error, ErrorResult, Fallible}; use dom::bindings::inheritance::{Castable, ElementTypeId, HTMLElementTypeId, NodeTypeId}; -use dom::bindings::js::{JS, LayoutJS, MutNullableHeap}; +use dom::bindings::js::{JS, LayoutJS, MutNullableJS}; use dom::bindings::js::{Root, RootedReference}; use dom::bindings::refcounted::{Trusted, TrustedPromise}; use dom::bindings::reflector::DomObject; @@ -51,9 +51,11 @@ use dom::htmlimageelement::{HTMLImageElement, LayoutHTMLImageElementHelpers}; use dom::htmlinputelement::{HTMLInputElement, LayoutHTMLInputElementHelpers}; use dom::htmllabelelement::HTMLLabelElement; use dom::htmllegendelement::HTMLLegendElement; +use dom::htmllinkelement::HTMLLinkElement; use dom::htmlobjectelement::HTMLObjectElement; use dom::htmloptgroupelement::HTMLOptGroupElement; use dom::htmlselectelement::HTMLSelectElement; +use dom::htmlstyleelement::HTMLStyleElement; use dom::htmltablecellelement::{HTMLTableCellElement, HTMLTableCellElementLayoutHelpers}; use dom::htmltableelement::{HTMLTableElement, HTMLTableElementLayoutHelpers}; use dom::htmltablerowelement::{HTMLTableRowElement, HTMLTableRowElementLayoutHelpers}; @@ -75,7 +77,6 @@ use html5ever::serialize; use html5ever::serialize::SerializeOpts; use html5ever::serialize::TraversalScope; use html5ever::serialize::TraversalScope::{ChildrenOnly, IncludeNode}; -use html5ever::tree_builder::{LimitedQuirks, NoQuirks, Quirks}; use html5ever_atoms::{Prefix, LocalName, Namespace, QualName}; use js::jsapi::{HandleValue, JSAutoCompartment}; use parking_lot::RwLock; @@ -96,8 +97,7 @@ use std::rc::Rc; use std::sync::Arc; use std::sync::atomic::{AtomicUsize, Ordering}; use style::attr::{AttrValue, LengthOrPercentageOrAuto}; -use style::context::ReflowGoal; -use style::dom::TRestyleDamage; +use style::context::{QuirksMode, ReflowGoal}; use style::element_state::*; use style::matching::{common_style_affecting_attributes, rare_style_affecting_attributes}; use style::parser::ParserContextExtraData; @@ -110,6 +110,7 @@ use style::sink::Push; use style::stylist::ApplicableDeclarationBlock; use style::values::CSSFloat; use style::values::specified::{self, CSSColor, CSSRGBA, LengthOrPercentage}; +use stylesheet_loader::StylesheetOwner; // TODO: Update focus state when the top-level browsing context gains or loses system focus, // and when the element enters or leaves a browsing context container. @@ -126,8 +127,8 @@ pub struct Element { id_attribute: DOMRefCell<Option<Atom>>, #[ignore_heap_size_of = "Arc"] style_attribute: DOMRefCell<Option<Arc<RwLock<PropertyDeclarationBlock>>>>, - attr_list: MutNullableHeap<JS<NamedNodeMap>>, - class_list: MutNullableHeap<JS<DOMTokenList>>, + attr_list: MutNullableJS<NamedNodeMap>, + class_list: MutNullableJS<DOMTokenList>, state: Cell<ElementState>, atomic_flags: AtomicElementFlags, } @@ -398,7 +399,7 @@ impl LayoutElementHelpers for LayoutJS<Element> { PropertyDeclaration::BackgroundImage(DeclaredValue::Value( background_image::SpecifiedValue(vec![ background_image::single_value::SpecifiedValue(Some( - specified::Image::for_cascade(Some(url.into()), specified::url::UrlExtraData { }) + specified::Image::for_cascade(url.into(), specified::url::UrlExtraData { }) )) ]))))); } @@ -1095,8 +1096,8 @@ impl Element { let quirks_mode = document_from_node(self).quirks_mode(); let is_equal = |lhs: &Atom, rhs: &Atom| { match quirks_mode { - NoQuirks | LimitedQuirks => lhs == rhs, - Quirks => lhs.eq_ignore_ascii_case(&rhs), + QuirksMode::NoQuirks | QuirksMode::LimitedQuirks => lhs == rhs, + QuirksMode::Quirks => lhs.eq_ignore_ascii_case(&rhs), } }; self.get_attribute(&ns!(), &local_name!("class")) @@ -1276,7 +1277,7 @@ impl Element { // Step 7 if *self.root_element() == *self { - if doc.quirks_mode() != Quirks { + if doc.quirks_mode() != QuirksMode::Quirks { win.scroll(x, y, behavior); } @@ -1285,7 +1286,7 @@ impl Element { // Step 9 if doc.GetBody().r() == self.downcast::<HTMLElement>() && - doc.quirks_mode() == Quirks && + doc.quirks_mode() == QuirksMode::Quirks && !self.potentially_scrollable() { win.scroll(x, y, behavior); return; @@ -1656,7 +1657,7 @@ impl ElementMethods for Element { // Step 5 if *self.root_element() == *self { - if doc.quirks_mode() == Quirks { + if doc.quirks_mode() == QuirksMode::Quirks { return 0.0; } @@ -1666,7 +1667,7 @@ impl ElementMethods for Element { // Step 7 if doc.GetBody().r() == self.downcast::<HTMLElement>() && - doc.quirks_mode() == Quirks && + doc.quirks_mode() == QuirksMode::Quirks && !self.potentially_scrollable() { return win.ScrollY() as f64; } @@ -1707,7 +1708,7 @@ impl ElementMethods for Element { // Step 7 if *self.root_element() == *self { - if doc.quirks_mode() != Quirks { + if doc.quirks_mode() != QuirksMode::Quirks { win.scroll(win.ScrollX() as f64, y, behavior); } @@ -1716,7 +1717,7 @@ impl ElementMethods for Element { // Step 9 if doc.GetBody().r() == self.downcast::<HTMLElement>() && - doc.quirks_mode() == Quirks && + doc.quirks_mode() == QuirksMode::Quirks && !self.potentially_scrollable() { win.scroll(win.ScrollX() as f64, y, behavior); return; @@ -1748,7 +1749,7 @@ impl ElementMethods for Element { // Step 5 if *self.root_element() == *self { - if doc.quirks_mode() != Quirks { + if doc.quirks_mode() != QuirksMode::Quirks { // Step 6 return win.ScrollX() as f64; } @@ -1758,7 +1759,7 @@ impl ElementMethods for Element { // Step 7 if doc.GetBody().r() == self.downcast::<HTMLElement>() && - doc.quirks_mode() == Quirks && + doc.quirks_mode() == QuirksMode::Quirks && !self.potentially_scrollable() { return win.ScrollX() as f64; } @@ -1799,7 +1800,7 @@ impl ElementMethods for Element { // Step 7 if *self.root_element() == *self { - if doc.quirks_mode() == Quirks { + if doc.quirks_mode() == QuirksMode::Quirks { return; } @@ -1809,7 +1810,7 @@ impl ElementMethods for Element { // Step 9 if doc.GetBody().r() == self.downcast::<HTMLElement>() && - doc.quirks_mode() == Quirks && + doc.quirks_mode() == QuirksMode::Quirks && !self.potentially_scrollable() { win.scroll(x, win.ScrollY() as f64, behavior); return; @@ -2421,6 +2422,18 @@ impl Element { }) } + pub fn as_stylesheet_owner(&self) -> Option<&StylesheetOwner> { + if let Some(s) = self.downcast::<HTMLStyleElement>() { + return Some(s as &StylesheetOwner) + } + + if let Some(l) = self.downcast::<HTMLLinkElement>() { + return Some(l as &StylesheetOwner) + } + + None + } + // https://html.spec.whatwg.org/multipage/#category-submit pub fn as_maybe_validatable(&self) -> Option<&Validatable> { let element = match self.upcast::<Node>().type_id() { @@ -2663,15 +2676,11 @@ impl Element { self.set_enabled_state(false); return; } - match ancestor.children() - .find(|child| child.is::<HTMLLegendElement>()) { - Some(ref legend) => { - // XXXabinader: should we save previous ancestor to avoid this iteration? - if node.ancestors().any(|ancestor| ancestor == *legend) { - continue; - } - }, - None => (), + if let Some(ref legend) = ancestor.children().find(|n| n.is::<HTMLLegendElement>()) { + // XXXabinader: should we save previous ancestor to avoid this iteration? + if node.ancestors().any(|ancestor| ancestor == *legend) { + continue; + } } self.set_disabled_state(true); self.set_enabled_state(false); diff --git a/components/script/dom/event.rs b/components/script/dom/event.rs index d67d1f64e78..d471c25d873 100644 --- a/components/script/dom/event.rs +++ b/components/script/dom/event.rs @@ -6,7 +6,7 @@ use dom::bindings::cell::DOMRefCell; use dom::bindings::codegen::Bindings::EventBinding; use dom::bindings::codegen::Bindings::EventBinding::{EventConstants, EventMethods}; use dom::bindings::error::Fallible; -use dom::bindings::js::{JS, MutNullableHeap, Root}; +use dom::bindings::js::{MutNullableJS, Root}; use dom::bindings::refcounted::Trusted; use dom::bindings::reflector::{Reflector, reflect_dom_object}; use dom::bindings::str::DOMString; @@ -80,8 +80,8 @@ impl From<bool> for EventCancelable { #[dom_struct] pub struct Event { reflector_: Reflector, - current_target: MutNullableHeap<JS<EventTarget>>, - target: MutNullableHeap<JS<EventTarget>>, + current_target: MutNullableJS<EventTarget>, + target: MutNullableJS<EventTarget>, type_: DOMRefCell<Atom>, phase: Cell<EventPhase>, canceled: Cell<bool>, diff --git a/components/script/dom/eventdispatcher.rs b/components/script/dom/eventdispatcher.rs index d5e4bf51338..bdec56532dc 100644 --- a/components/script/dom/eventdispatcher.rs +++ b/components/script/dom/eventdispatcher.rs @@ -156,15 +156,11 @@ pub fn dispatch_event(target: &EventTarget, dispatch_to_listeners(event, target, event_path.r()); // Default action. - let target = event.GetTarget(); - match target { - Some(ref target) => { - if let Some(node) = target.downcast::<Node>() { - let vtable = vtable_for(&node); - vtable.handle_event(event); - } + if let Some(target) = event.GetTarget() { + if let Some(node) = target.downcast::<Node>() { + let vtable = vtable_for(&node); + vtable.handle_event(event); } - None => {} } // Step 10-12. diff --git a/components/script/dom/filereader.rs b/components/script/dom/filereader.rs index bb57ad5d9de..9b5c39b013c 100644 --- a/components/script/dom/filereader.rs +++ b/components/script/dom/filereader.rs @@ -9,7 +9,7 @@ use dom::bindings::codegen::Bindings::FileReaderBinding::{self, FileReaderConsta use dom::bindings::codegen::UnionTypes::StringOrObject; use dom::bindings::error::{Error, ErrorResult, Fallible}; use dom::bindings::inheritance::Castable; -use dom::bindings::js::{JS, MutNullableHeap, Root}; +use dom::bindings::js::{MutNullableJS, Root}; use dom::bindings::refcounted::Trusted; use dom::bindings::reflector::{DomObject, reflect_dom_object}; use dom::bindings::str::DOMString; @@ -34,9 +34,9 @@ use servo_atoms::Atom; use std::cell::Cell; use std::ptr; use std::sync::Arc; +use std::thread; use task_source::TaskSource; use task_source::file_reading::{FileReadingTaskSource, FileReadingRunnable, FileReadingTask}; -use util::thread::spawn_named; #[derive(PartialEq, Clone, Copy, JSTraceable, HeapSizeOf)] pub enum FileReaderFunction { @@ -86,7 +86,7 @@ pub enum FileReaderResult { pub struct FileReader { eventtarget: EventTarget, ready_state: Cell<FileReaderReadyState>, - error: MutNullableHeap<JS<DOMException>>, + error: MutNullableJS<DOMException>, result: DOMRefCell<Option<FileReaderResult>>, generation_id: Cell<GenerationId>, } @@ -96,7 +96,7 @@ impl FileReader { FileReader { eventtarget: EventTarget::new_inherited(), ready_state: Cell::new(FileReaderReadyState::Empty), - error: MutNullableHeap::new(None), + error: MutNullableJS::new(None), result: DOMRefCell::new(None), generation_id: Cell::new(GenerationId(0)), } @@ -401,9 +401,10 @@ impl FileReader { let wrapper = global.get_runnable_wrapper(); let task_source = global.file_reading_task_source(); - spawn_named("file reader async operation".to_owned(), move || { + thread::Builder::new().name("file reader async operation".to_owned()).spawn(move || { perform_annotated_read_operation(gen_id, load_data, blob_contents, fr, task_source, wrapper) - }); + }).expect("Thread spawning failed"); + Ok(()) } diff --git a/components/script/dom/focusevent.rs b/components/script/dom/focusevent.rs index 1eb3983737d..c7e48531479 100644 --- a/components/script/dom/focusevent.rs +++ b/components/script/dom/focusevent.rs @@ -7,7 +7,7 @@ use dom::bindings::codegen::Bindings::FocusEventBinding::FocusEventMethods; use dom::bindings::codegen::Bindings::UIEventBinding::UIEventMethods; use dom::bindings::error::Fallible; use dom::bindings::inheritance::Castable; -use dom::bindings::js::{JS, MutNullableHeap, Root, RootedReference}; +use dom::bindings::js::{MutNullableJS, Root, RootedReference}; use dom::bindings::reflector::reflect_dom_object; use dom::bindings::str::DOMString; use dom::event::{EventBubbles, EventCancelable}; @@ -20,7 +20,7 @@ use std::default::Default; #[dom_struct] pub struct FocusEvent { uievent: UIEvent, - related_target: MutNullableHeap<JS<EventTarget>>, + related_target: MutNullableJS<EventTarget>, } impl FocusEvent { diff --git a/components/script/dom/globalscope.rs b/components/script/dom/globalscope.rs index 19436804b19..ae08bc0e5fd 100644 --- a/components/script/dom/globalscope.rs +++ b/components/script/dom/globalscope.rs @@ -8,7 +8,7 @@ use dom::bindings::codegen::Bindings::WindowBinding::WindowMethods; use dom::bindings::conversions::root_from_object; use dom::bindings::error::{ErrorInfo, report_pending_exception}; use dom::bindings::inheritance::Castable; -use dom::bindings::js::{JS, MutNullableHeap, Root}; +use dom::bindings::js::{MutNullableJS, Root}; use dom::bindings::reflector::DomObject; use dom::bindings::str::DOMString; use dom::crypto::Crypto; @@ -50,7 +50,7 @@ use timers::{OneshotTimers, TimerCallback}; #[dom_struct] pub struct GlobalScope { eventtarget: EventTarget, - crypto: MutNullableHeap<JS<Crypto>>, + crypto: MutNullableJS<Crypto>, next_worker_id: Cell<WorkerId>, /// Pipeline id associated with this global. diff --git a/components/script/dom/htmlanchorelement.rs b/components/script/dom/htmlanchorelement.rs index f92290b2c97..52c355f2bab 100644 --- a/components/script/dom/htmlanchorelement.rs +++ b/components/script/dom/htmlanchorelement.rs @@ -11,7 +11,7 @@ use dom::bindings::codegen::Bindings::HTMLAnchorElementBinding::HTMLAnchorElemen use dom::bindings::codegen::Bindings::MouseEventBinding::MouseEventMethods; use dom::bindings::codegen::Bindings::NodeBinding::NodeMethods; use dom::bindings::inheritance::Castable; -use dom::bindings::js::{JS, MutNullableHeap, Root}; +use dom::bindings::js::{MutNullableJS, Root}; use dom::bindings::str::{DOMString, USVString}; use dom::document::Document; use dom::domtokenlist::DOMTokenList; @@ -28,15 +28,15 @@ use html5ever_atoms::LocalName; use net_traits::ReferrerPolicy; use num_traits::ToPrimitive; use script_traits::MozBrowserEvent; +use servo_config::prefs::PREFS; use servo_url::ServoUrl; use std::default::Default; use style::attr::AttrValue; -use util::prefs::PREFS; #[dom_struct] pub struct HTMLAnchorElement { htmlelement: HTMLElement, - rel_list: MutNullableHeap<JS<DOMTokenList>>, + rel_list: MutNullableJS<DOMTokenList>, url: DOMRefCell<Option<ServoUrl>>, } diff --git a/components/script/dom/htmlareaelement.rs b/components/script/dom/htmlareaelement.rs index b8df3806a3f..79240885167 100644 --- a/components/script/dom/htmlareaelement.rs +++ b/components/script/dom/htmlareaelement.rs @@ -5,7 +5,7 @@ use dom::bindings::codegen::Bindings::HTMLAreaElementBinding; use dom::bindings::codegen::Bindings::HTMLAreaElementBinding::HTMLAreaElementMethods; use dom::bindings::inheritance::Castable; -use dom::bindings::js::{JS, MutNullableHeap, Root}; +use dom::bindings::js::{MutNullableJS, Root}; use dom::bindings::str::DOMString; use dom::document::Document; use dom::domtokenlist::DOMTokenList; @@ -19,7 +19,7 @@ use style::attr::AttrValue; #[dom_struct] pub struct HTMLAreaElement { htmlelement: HTMLElement, - rel_list: MutNullableHeap<JS<DOMTokenList>>, + rel_list: MutNullableJS<DOMTokenList>, } impl HTMLAreaElement { diff --git a/components/script/dom/htmlcanvaselement.rs b/components/script/dom/htmlcanvaselement.rs index b9d7731d652..b174d2ec9a8 100644 --- a/components/script/dom/htmlcanvaselement.rs +++ b/components/script/dom/htmlcanvaselement.rs @@ -13,7 +13,7 @@ use dom::bindings::codegen::UnionTypes::CanvasRenderingContext2DOrWebGLRendering use dom::bindings::conversions::ConversionResult; use dom::bindings::error::{Error, Fallible}; use dom::bindings::inheritance::Castable; -use dom::bindings::js::{HeapGCValue, JS, LayoutJS, Root}; +use dom::bindings::js::{JS, LayoutJS, Root}; use dom::bindings::num::Finite; use dom::bindings::str::DOMString; use dom::canvasrenderingcontext2d::{CanvasRenderingContext2D, LayoutCanvasRenderingContext2DHelpers}; @@ -47,8 +47,6 @@ pub enum CanvasContext { WebGL(JS<WebGLRenderingContext>), } -impl HeapGCValue for CanvasContext {} - #[dom_struct] pub struct HTMLCanvasElement { htmlelement: HTMLElement, diff --git a/components/script/dom/htmlcollection.rs b/components/script/dom/htmlcollection.rs index 959265e82e0..eacffd6cded 100644 --- a/components/script/dom/htmlcollection.rs +++ b/components/script/dom/htmlcollection.rs @@ -5,7 +5,7 @@ use dom::bindings::codegen::Bindings::HTMLCollectionBinding; use dom::bindings::codegen::Bindings::HTMLCollectionBinding::HTMLCollectionMethods; use dom::bindings::inheritance::Castable; -use dom::bindings::js::{JS, Root, MutNullableHeap}; +use dom::bindings::js::{JS, Root, MutNullableJS}; use dom::bindings::reflector::{Reflector, reflect_dom_object}; use dom::bindings::str::DOMString; use dom::bindings::trace::JSTraceable; @@ -59,7 +59,7 @@ pub struct HTMLCollection { // the length of the collection, and a cursor into the collection. // FIXME: make the cached cursor element a weak pointer cached_version: Cell<u64>, - cached_cursor_element: MutNullableHeap<JS<Element>>, + cached_cursor_element: MutNullableJS<Element>, cached_cursor_index: Cell<OptionU32>, cached_length: Cell<OptionU32>, } @@ -73,7 +73,7 @@ impl HTMLCollection { filter: filter, // Default values for the cache cached_version: Cell::new(root.inclusive_descendants_version()), - cached_cursor_element: MutNullableHeap::new(None), + cached_cursor_element: MutNullableJS::new(None), cached_cursor_index: Cell::new(OptionU32::none()), cached_length: Cell::new(OptionU32::none()), } diff --git a/components/script/dom/htmlelement.rs b/components/script/dom/htmlelement.rs index d4490357650..6725fdb5dfb 100644 --- a/components/script/dom/htmlelement.rs +++ b/components/script/dom/htmlelement.rs @@ -13,9 +13,9 @@ use dom::bindings::codegen::Bindings::WindowBinding::WindowMethods; use dom::bindings::error::{Error, ErrorResult}; use dom::bindings::inheritance::{ElementTypeId, HTMLElementTypeId, NodeTypeId}; use dom::bindings::inheritance::Castable; -use dom::bindings::js::{JS, MutNullableHeap, Root, RootedReference}; +use dom::bindings::js::{JS, MutNullableJS, Root, RootedReference}; use dom::bindings::str::DOMString; -use dom::cssstyledeclaration::{CSSModificationAccess, CSSStyleDeclaration}; +use dom::cssstyledeclaration::{CSSModificationAccess, CSSStyleDeclaration, CSSStyleOwner}; use dom::document::{Document, FocusType}; use dom::domstringmap::DOMStringMap; use dom::element::{AttributeMutation, Element}; @@ -40,8 +40,8 @@ use style::element_state::*; #[dom_struct] pub struct HTMLElement { element: Element, - style_decl: MutNullableHeap<JS<CSSStyleDeclaration>>, - dataset: MutNullableHeap<JS<DOMStringMap>>, + style_decl: MutNullableJS<CSSStyleDeclaration>, + dataset: MutNullableJS<DOMStringMap>, } impl HTMLElement { @@ -115,7 +115,10 @@ impl HTMLElementMethods for HTMLElement { fn Style(&self) -> Root<CSSStyleDeclaration> { self.style_decl.or_init(|| { let global = window_from_node(self); - CSSStyleDeclaration::new(&global, self.upcast::<Element>(), None, CSSModificationAccess::ReadWrite) + CSSStyleDeclaration::new(&global, + CSSStyleOwner::Element(JS::from_ref(self.upcast())), + None, + CSSModificationAccess::ReadWrite) }) } diff --git a/components/script/dom/htmlformelement.rs b/components/script/dom/htmlformelement.rs index 90abdbafefd..a0a34b081c8 100755 --- a/components/script/dom/htmlformelement.rs +++ b/components/script/dom/htmlformelement.rs @@ -13,7 +13,7 @@ use dom::bindings::codegen::Bindings::HTMLInputElementBinding::HTMLInputElementM use dom::bindings::codegen::Bindings::HTMLTextAreaElementBinding::HTMLTextAreaElementMethods; use dom::bindings::conversions::DerivedFrom; use dom::bindings::inheritance::{Castable, ElementTypeId, HTMLElementTypeId, NodeTypeId}; -use dom::bindings::js::{JS, MutNullableHeap, Root}; +use dom::bindings::js::{MutNullableJS, Root}; use dom::bindings::refcounted::Trusted; use dom::bindings::reflector::DomObject; use dom::bindings::str::DOMString; @@ -61,7 +61,7 @@ pub struct GenerationId(u32); pub struct HTMLFormElement { htmlelement: HTMLElement, marked_for_reset: Cell<bool>, - elements: MutNullableHeap<JS<HTMLFormControlsCollection>>, + elements: MutNullableJS<HTMLFormControlsCollection>, generation_id: Cell<GenerationId> } @@ -85,10 +85,6 @@ impl HTMLFormElement { document, HTMLFormElementBinding::Wrap) } - - pub fn generation_id(&self) -> GenerationId { - self.generation_id.get() - } } impl HTMLFormElementMethods for HTMLFormElement { @@ -662,6 +658,7 @@ impl HTMLFormElement { #[derive(JSTraceable, HeapSizeOf, Clone)] pub enum FormDatumValue { + #[allow(dead_code)] File(Root<File>), String(DOMString) } @@ -701,6 +698,7 @@ pub enum FormMethod { } #[derive(HeapSizeOf)] +#[allow(dead_code)] pub enum FormSubmittableElement { ButtonElement(Root<HTMLButtonElement>), InputElement(Root<HTMLInputElement>), diff --git a/components/script/dom/htmliframeelement.rs b/components/script/dom/htmliframeelement.rs index 44323e1c1ef..53c7e34f94f 100644 --- a/components/script/dom/htmliframeelement.rs +++ b/components/script/dom/htmliframeelement.rs @@ -19,7 +19,7 @@ use dom::bindings::codegen::Bindings::WindowBinding::WindowBinding::WindowMethod use dom::bindings::conversions::ToJSValConvertible; use dom::bindings::error::{Error, ErrorResult, Fallible}; use dom::bindings::inheritance::Castable; -use dom::bindings::js::{JS, LayoutJS, MutNullableHeap, Root}; +use dom::bindings::js::{LayoutJS, MutNullableJS, Root}; use dom::bindings::refcounted::Trusted; use dom::bindings::reflector::DomObject; use dom::bindings::str::DOMString; @@ -48,13 +48,13 @@ use script_traits::{IFrameLoadInfo, IFrameLoadInfoWithData, LoadData}; use script_traits::{MozBrowserEvent, NewLayoutInfo, ScriptMsg as ConstellationMsg}; use script_traits::IFrameSandboxState::{IFrameSandboxed, IFrameUnsandboxed}; use servo_atoms::Atom; +use servo_config::prefs::PREFS; +use servo_config::servo_version; use servo_url::ServoUrl; use std::cell::Cell; use style::attr::{AttrValue, LengthOrPercentageOrAuto}; use style::context::ReflowGoal; use task_source::TaskSource; -use util::prefs::PREFS; -use util::servo_version; bitflags! { #[derive(JSTraceable, HeapSizeOf)] @@ -80,7 +80,7 @@ pub struct HTMLIFrameElement { htmlelement: HTMLElement, frame_id: FrameId, pipeline_id: Cell<Option<PipelineId>>, - sandbox: MutNullableHeap<JS<DOMTokenList>>, + sandbox: MutNullableJS<DOMTokenList>, sandbox_allowance: Cell<Option<SandboxAllowance>>, load_blocker: DOMRefCell<Option<LoadBlocker>>, visibility: Cell<bool>, diff --git a/components/script/dom/htmlinputelement.rs b/components/script/dom/htmlinputelement.rs index 90cf630e9fe..eb344ef0a79 100755 --- a/components/script/dom/htmlinputelement.rs +++ b/components/script/dom/htmlinputelement.rs @@ -13,7 +13,7 @@ use dom::bindings::codegen::Bindings::HTMLInputElementBinding::HTMLInputElementM use dom::bindings::codegen::Bindings::KeyboardEventBinding::KeyboardEventMethods; use dom::bindings::error::{Error, ErrorResult}; use dom::bindings::inheritance::Castable; -use dom::bindings::js::{JS, LayoutJS, MutNullableHeap, Root, RootedReference}; +use dom::bindings::js::{JS, LayoutJS, MutNullableJS, Root, RootedReference}; use dom::bindings::str::DOMString; use dom::document::Document; use dom::element::{AttributeMutation, Element, LayoutElementHelpers, RawLayoutElementHelpers}; @@ -94,7 +94,7 @@ pub struct HTMLInputElement { // https://html.spec.whatwg.org/multipage/#concept-input-value-dirty-flag value_dirty: Cell<bool>, - filelist: MutNullableHeap<JS<FileList>>, + filelist: MutNullableJS<FileList>, } #[derive(JSTraceable)] @@ -150,7 +150,7 @@ impl HTMLInputElement { SelectionDirection::None)), activation_state: DOMRefCell::new(InputActivationState::new()), value_dirty: Cell::new(false), - filelist: MutNullableHeap::new(None), + filelist: MutNullableJS::new(None), } } diff --git a/components/script/dom/htmllinkelement.rs b/components/script/dom/htmllinkelement.rs index 1985e511c4d..ee4ee4718cf 100644 --- a/components/script/dom/htmllinkelement.rs +++ b/components/script/dom/htmllinkelement.rs @@ -3,65 +3,54 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ use cssparser::Parser as CssParser; -use document_loader::LoadType; use dom::attr::Attr; use dom::bindings::cell::DOMRefCell; -use dom::bindings::codegen::Bindings::DOMTokenListBinding::DOMTokenListMethods; +use dom::bindings::codegen::Bindings::DOMTokenListBinding::DOMTokenListBinding::DOMTokenListMethods; use dom::bindings::codegen::Bindings::HTMLLinkElementBinding; use dom::bindings::codegen::Bindings::HTMLLinkElementBinding::HTMLLinkElementMethods; use dom::bindings::inheritance::Castable; -use dom::bindings::js::{JS, MutNullableHeap, Root, RootedReference}; -use dom::bindings::refcounted::Trusted; -use dom::bindings::reflector::DomObject; +use dom::bindings::js::{MutNullableJS, Root, RootedReference}; use dom::bindings::str::DOMString; use dom::cssstylesheet::CSSStyleSheet; use dom::document::Document; use dom::domtokenlist::DOMTokenList; use dom::element::{AttributeMutation, Element, ElementCreator}; -use dom::eventtarget::EventTarget; use dom::globalscope::GlobalScope; use dom::htmlelement::HTMLElement; use dom::node::{Node, document_from_node, window_from_node}; use dom::stylesheet::StyleSheet as DOMStyleSheet; use dom::virtualmethods::VirtualMethods; -use encoding::EncodingRef; -use encoding::all::UTF_8; use html5ever_atoms::LocalName; -use hyper::header::ContentType; -use hyper::mime::{Mime, TopLevel, SubLevel}; -use hyper_serde::Serde; -use ipc_channel::ipc; -use ipc_channel::router::ROUTER; -use net_traits::{FetchResponseListener, FetchMetadata, Metadata, NetworkError, ReferrerPolicy}; -use net_traits::request::{CredentialsMode, Destination, RequestInit, Type as RequestType}; -use network_listener::{NetworkListener, PreInvoke}; -use script_layout_interface::message::Msg; +use net_traits::ReferrerPolicy; use script_traits::{MozBrowserEvent, ScriptMsg as ConstellationMsg}; -use servo_url::ServoUrl; use std::ascii::AsciiExt; use std::borrow::ToOwned; use std::cell::Cell; use std::default::Default; -use std::mem; -use std::sync::{Arc, Mutex}; +use std::sync::Arc; use style::attr::AttrValue; -use style::media_queries::{MediaList, parse_media_query_list}; -use style::parser::ParserContextExtraData; +use style::media_queries::parse_media_query_list; use style::str::HTML_SPACE_CHARACTERS; -use style::stylesheets::{Stylesheet, Origin}; +use style::stylesheets::Stylesheet; +use stylesheet_loader::{StylesheetLoader, StylesheetContextSource, StylesheetOwner}; unsafe_no_jsmanaged_fields!(Stylesheet); #[dom_struct] pub struct HTMLLinkElement { htmlelement: HTMLElement, - rel_list: MutNullableHeap<JS<DOMTokenList>>, + rel_list: MutNullableJS<DOMTokenList>, #[ignore_heap_size_of = "Arc"] stylesheet: DOMRefCell<Option<Arc<Stylesheet>>>, - cssom_stylesheet: MutNullableHeap<JS<CSSStyleSheet>>, + cssom_stylesheet: MutNullableJS<CSSStyleSheet>, /// https://html.spec.whatwg.org/multipage/#a-style-sheet-that-is-blocking-scripts parser_inserted: Cell<bool>, + /// The number of loads that this link element has triggered (could be more + /// than one because of imports) and have not yet finished. + pending_loads: Cell<u32>, + /// Whether any of the loads have failed. + any_failed_load: Cell<bool>, } impl HTMLLinkElement { @@ -72,7 +61,9 @@ impl HTMLLinkElement { rel_list: Default::default(), parser_inserted: Cell::new(creator == ElementCreator::ParserCreated), stylesheet: DOMRefCell::new(None), - cssom_stylesheet: MutNullableHeap::new(None), + cssom_stylesheet: MutNullableJS::new(None), + pending_loads: Cell::new(0), + any_failed_load: Cell::new(false), } } @@ -86,6 +77,12 @@ impl HTMLLinkElement { HTMLLinkElementBinding::Wrap) } + pub fn set_stylesheet(&self, s: Arc<Stylesheet>) { + assert!(self.stylesheet.borrow().is_none()); + *self.stylesheet.borrow_mut() = Some(s); + } + + pub fn get_stylesheet(&self) -> Option<Arc<Stylesheet>> { self.stylesheet.borrow().clone() } @@ -231,8 +228,11 @@ impl HTMLLinkElement { // Step 2. let url = match document.base_url().join(href) { - Err(e) => return debug!("Parsing url {} failed: {}", href, e), Ok(url) => url, + Err(e) => { + debug!("Parsing url {} failed: {}", href, e); + return; + } }; let element = self.upcast::<Element>(); @@ -246,50 +246,13 @@ impl HTMLLinkElement { let mut css_parser = CssParser::new(&mq_str); let media = parse_media_query_list(&mut css_parser); - // TODO: #8085 - Don't load external stylesheets if the node's mq doesn't match. - let elem = Trusted::new(self); - - let context = Arc::new(Mutex::new(StylesheetContext { - elem: elem, + // TODO: #8085 - Don't load external stylesheets if the node's mq + // doesn't match. + let loader = StylesheetLoader::for_element(self.upcast()); + loader.load(StylesheetContextSource::LinkElement { + url: url, media: Some(media), - data: vec!(), - metadata: None, - url: url.clone(), - })); - - let (action_sender, action_receiver) = ipc::channel().unwrap(); - let listener = NetworkListener { - context: context, - task_source: document.window().networking_task_source(), - wrapper: Some(document.window().get_runnable_wrapper()) - }; - ROUTER.add_route(action_receiver.to_opaque(), box move |message| { - listener.notify_fetch(message.to().unwrap()); }); - - if self.parser_inserted.get() { - document.increment_script_blocking_stylesheet_count(); - } - - let referrer_policy = match self.RelList().Contains("noreferrer".into()) { - true => Some(ReferrerPolicy::NoReferrer), - false => document.get_referrer_policy(), - }; - - let request = RequestInit { - url: url.clone(), - type_: RequestType::Style, - destination: Destination::Style, - credentials_mode: CredentialsMode::Include, - use_url_credentials: true, - origin: document.url(), - pipeline_id: Some(self.global().pipeline_id()), - referrer_url: Some(document.url()), - referrer_policy: referrer_policy, - .. RequestInit::default() - }; - - document.fetch_async(LoadType::Stylesheet(url), request, action_sender); } fn handle_favicon_url(&self, rel: &str, href: &str, sizes: &Option<String>) { @@ -310,92 +273,37 @@ impl HTMLLinkElement { } } -/// The context required for asynchronously loading an external stylesheet. -struct StylesheetContext { - /// The element that initiated the request. - elem: Trusted<HTMLLinkElement>, - media: Option<MediaList>, - /// The response body received to date. - data: Vec<u8>, - /// The response metadata received to date. - metadata: Option<Metadata>, - /// The initial URL requested. - url: ServoUrl, -} - -impl PreInvoke for StylesheetContext {} - -impl FetchResponseListener for StylesheetContext { - fn process_request_body(&mut self) {} +impl StylesheetOwner for HTMLLinkElement { + fn increment_pending_loads_count(&self) { + self.pending_loads.set(self.pending_loads.get() + 1) + } - fn process_request_eof(&mut self) {} + fn load_finished(&self, succeeded: bool) -> Option<bool> { + assert!(self.pending_loads.get() > 0, "What finished?"); + if !succeeded { + self.any_failed_load.set(true); + } - fn process_response(&mut self, - metadata: Result<FetchMetadata, NetworkError>) { - self.metadata = metadata.ok().map(|m| { - match m { - FetchMetadata::Unfiltered(m) => m, - FetchMetadata::Filtered { unsafe_, .. } => unsafe_ - } - }); - if let Some(ref meta) = self.metadata { - if let Some(Serde(ContentType(Mime(TopLevel::Text, SubLevel::Css, _)))) = meta.content_type { - } else { - self.elem.root().upcast::<EventTarget>().fire_event(atom!("error")); - } + self.pending_loads.set(self.pending_loads.get() - 1); + if self.pending_loads.get() != 0 { + return None; } - } - fn process_response_chunk(&mut self, mut payload: Vec<u8>) { - self.data.append(&mut payload); + let any_failed = self.any_failed_load.get(); + self.any_failed_load.set(false); + Some(any_failed) } - fn process_response_eof(&mut self, status: Result<(), NetworkError>) { - let elem = self.elem.root(); - let document = document_from_node(&*elem); - let mut successful = false; - - if status.is_ok() { - let metadata = match self.metadata.take() { - Some(meta) => meta, - None => return, - }; - let is_css = metadata.content_type.map_or(false, |Serde(ContentType(Mime(top, sub, _)))| - top == TopLevel::Text && sub == SubLevel::Css); - - let data = if is_css { mem::replace(&mut self.data, vec!()) } else { vec!() }; - - // TODO: Get the actual value. http://dev.w3.org/csswg/css-syntax/#environment-encoding - let environment_encoding = UTF_8 as EncodingRef; - let protocol_encoding_label = metadata.charset.as_ref().map(|s| &**s); - let final_url = metadata.final_url; - - let win = window_from_node(&*elem); - - let sheet = Arc::new(Stylesheet::from_bytes( - &data, final_url, protocol_encoding_label, Some(environment_encoding), - Origin::Author, self.media.take().unwrap(), win.css_error_reporter(), - ParserContextExtraData::default())); - - let win = window_from_node(&*elem); - win.layout_chan().send(Msg::AddStylesheet(sheet.clone())).unwrap(); - - *elem.stylesheet.borrow_mut() = Some(sheet); - document.invalidate_stylesheets(); - - // FIXME: Revisit once consensus is reached at: https://github.com/whatwg/html/issues/1142 - successful = metadata.status.map_or(false, |(code, _)| code == 200); - } + fn parser_inserted(&self) -> bool { + self.parser_inserted.get() + } - if elem.parser_inserted.get() { - document.decrement_script_blocking_stylesheet_count(); + fn referrer_policy(&self) -> Option<ReferrerPolicy> { + if self.RelList().Contains("noreferrer".into()) { + return Some(ReferrerPolicy::NoReferrer) } - document.finish_load(LoadType::Stylesheet(self.url.clone())); - - let event = if successful { atom!("load") } else { atom!("error") }; - - elem.upcast::<EventTarget>().fire_event(event); + None } } diff --git a/components/script/dom/htmlmediaelement.rs b/components/script/dom/htmlmediaelement.rs index 778c0d6b560..fd327404b4d 100644 --- a/components/script/dom/htmlmediaelement.rs +++ b/components/script/dom/htmlmediaelement.rs @@ -13,7 +13,7 @@ use dom::bindings::codegen::Bindings::HTMLMediaElementBinding::HTMLMediaElementM use dom::bindings::codegen::Bindings::MediaErrorBinding::MediaErrorConstants::*; use dom::bindings::codegen::Bindings::MediaErrorBinding::MediaErrorMethods; use dom::bindings::inheritance::Castable; -use dom::bindings::js::{Root, MutNullableHeap, JS}; +use dom::bindings::js::{MutNullableJS, Root}; use dom::bindings::refcounted::Trusted; use dom::bindings::reflector::DomObject; use dom::bindings::str::DOMString; @@ -218,7 +218,7 @@ pub struct HTMLMediaElement { current_src: DOMRefCell<String>, generation_id: Cell<u32>, first_data_load: Cell<bool>, - error: MutNullableHeap<JS<MediaError>>, + error: MutNullableJS<MediaError>, paused: Cell<bool>, autoplaying: Cell<bool>, video: DOMRefCell<Option<VideoMedia>>, @@ -243,11 +243,6 @@ impl HTMLMediaElement { } } - #[inline] - pub fn htmlelement(&self) -> &HTMLElement { - &self.htmlelement - } - // https://html.spec.whatwg.org/multipage/#internal-pause-steps fn internal_pause_steps(&self) { // Step 1 @@ -437,6 +432,7 @@ impl HTMLMediaElement { } // https://html.spec.whatwg.org/multipage/#concept-media-load-algorithm + #[allow(unreachable_code)] fn resource_selection_algorithm_sync(&self, base_url: ServoUrl) { // TODO step 5 (populate pending text tracks) @@ -446,7 +442,7 @@ impl HTMLMediaElement { ResourceSelectionMode::Object } else if let Some(attr) = self.upcast::<Element>().get_attribute(&ns!(), &local_name!("src")) { ResourceSelectionMode::Attribute(attr.Value().to_string()) - } else if false { + } else if false { // TODO: when implementing this remove #[allow(unreachable_code)] above. // TODO <source> child ResourceSelectionMode::Children(panic!()) } else { diff --git a/components/script/dom/htmlmetaelement.rs b/components/script/dom/htmlmetaelement.rs index bcf112cce94..cf9d078e39f 100644 --- a/components/script/dom/htmlmetaelement.rs +++ b/components/script/dom/htmlmetaelement.rs @@ -8,7 +8,7 @@ use dom::bindings::codegen::Bindings::HTMLMetaElementBinding; use dom::bindings::codegen::Bindings::HTMLMetaElementBinding::HTMLMetaElementMethods; use dom::bindings::codegen::Bindings::NodeBinding::NodeMethods; use dom::bindings::inheritance::Castable; -use dom::bindings::js::{JS, MutNullableHeap, Root, RootedReference}; +use dom::bindings::js::{MutNullableJS, Root, RootedReference}; use dom::bindings::str::DOMString; use dom::cssstylesheet::CSSStyleSheet; use dom::document::Document; @@ -19,6 +19,7 @@ use dom::node::{Node, UnbindContext, document_from_node, window_from_node}; use dom::virtualmethods::VirtualMethods; use html5ever_atoms::LocalName; use parking_lot::RwLock; +use servo_config::prefs::PREFS; use std::ascii::AsciiExt; use std::sync::Arc; use std::sync::atomic::AtomicBool; @@ -32,7 +33,7 @@ pub struct HTMLMetaElement { htmlelement: HTMLElement, #[ignore_heap_size_of = "Arc"] stylesheet: DOMRefCell<Option<Arc<Stylesheet>>>, - cssom_stylesheet: MutNullableHeap<JS<CSSStyleSheet>>, + cssom_stylesheet: MutNullableJS<CSSStyleSheet>, } impl HTMLMetaElement { @@ -42,7 +43,7 @@ impl HTMLMetaElement { HTMLMetaElement { htmlelement: HTMLElement::new_inherited(local_name, prefix, document), stylesheet: DOMRefCell::new(None), - cssom_stylesheet: MutNullableHeap::new(None), + cssom_stylesheet: MutNullableJS::new(None), } } @@ -89,7 +90,7 @@ impl HTMLMetaElement { } fn apply_viewport(&self) { - if !::util::prefs::PREFS.get("layout.viewport.enabled").as_boolean().unwrap_or(false) { + if !PREFS.get("layout.viewport.enabled").as_boolean().unwrap_or(false) { return; } let element = self.upcast::<Element>(); diff --git a/components/script/dom/htmlscriptelement.rs b/components/script/dom/htmlscriptelement.rs index bccde70bb88..9558d9c4b41 100644 --- a/components/script/dom/htmlscriptelement.rs +++ b/components/script/dom/htmlscriptelement.rs @@ -713,7 +713,7 @@ impl HTMLScriptElementMethods for HTMLScriptElement { // https://html.spec.whatwg.org/multipage/#dom-script-text fn Text(&self) -> DOMString { - Node::collect_text_contents(self.upcast::<Node>().children()) + self.upcast::<Node>().child_text_content() } // https://html.spec.whatwg.org/multipage/#dom-script-text diff --git a/components/script/dom/htmlselectelement.rs b/components/script/dom/htmlselectelement.rs index ad66f2b05f3..25977da8095 100755 --- a/components/script/dom/htmlselectelement.rs +++ b/components/script/dom/htmlselectelement.rs @@ -14,7 +14,7 @@ use dom::bindings::codegen::UnionTypes::HTMLElementOrLong; use dom::bindings::codegen::UnionTypes::HTMLOptionElementOrHTMLOptGroupElement; //use dom::bindings::error::ErrorResult; use dom::bindings::inheritance::Castable; -use dom::bindings::js::{JS, MutNullableHeap, Root}; +use dom::bindings::js::{MutNullableJS, Root}; use dom::bindings::str::DOMString; use dom::document::Document; use dom::element::{AttributeMutation, Element}; @@ -31,6 +31,7 @@ use dom::validation::Validatable; use dom::validitystate::{ValidityState, ValidationFlags}; use dom::virtualmethods::VirtualMethods; use html5ever_atoms::LocalName; +use std::iter; use style::attr::AttrValue; use style::element_state::*; @@ -58,7 +59,7 @@ impl CollectionFilter for OptionsFilter { #[dom_struct] pub struct HTMLSelectElement { htmlelement: HTMLElement, - options: MutNullableHeap<JS<HTMLOptionsCollection>>, + options: MutNullableJS<HTMLOptionsCollection>, } static DEFAULT_SELECT_SIZE: u32 = 0; @@ -84,10 +85,25 @@ impl HTMLSelectElement { HTMLSelectElementBinding::Wrap) } + // https://html.spec.whatwg.org/multipage/#concept-select-option-list + fn list_of_options(&self) -> impl Iterator<Item=Root<HTMLOptionElement>> { + self.upcast::<Node>() + .children() + .flat_map(|node| { + if node.is::<HTMLOptionElement>() { + let node = Root::downcast::<HTMLOptionElement>(node).unwrap(); + Choice3::First(iter::once(node)) + } else if node.is::<HTMLOptGroupElement>() { + Choice3::Second(node.children().filter_map(Root::downcast)) + } else { + Choice3::Third(iter::empty()) + } + }) + } + // https://html.spec.whatwg.org/multipage/#the-select-element:concept-form-reset-control pub fn reset(&self) { - let node = self.upcast::<Node>(); - for opt in node.traverse_preorder().filter_map(Root::downcast::<HTMLOptionElement>) { + for opt in self.list_of_options() { opt.set_selectedness(opt.DefaultSelected()); opt.set_dirtiness(false); } @@ -103,8 +119,7 @@ impl HTMLSelectElement { let mut first_enabled: Option<Root<HTMLOptionElement>> = None; let mut last_selected: Option<Root<HTMLOptionElement>> = None; - let node = self.upcast::<Node>(); - for opt in node.traverse_preorder().filter_map(Root::downcast::<HTMLOptionElement>) { + for opt in self.list_of_options() { if opt.Selected() { opt.set_selectedness(false); last_selected = Some(Root::from_ref(&opt)); @@ -127,11 +142,10 @@ impl HTMLSelectElement { } pub fn push_form_data(&self, data_set: &mut Vec<FormDatum>) { - let node = self.upcast::<Node>(); if self.Name().is_empty() { return; } - for opt in node.traverse_preorder().filter_map(Root::downcast::<HTMLOptionElement>) { + for opt in self.list_of_options() { let element = opt.upcast::<Element>(); if opt.Selected() && element.enabled_state() { data_set.push(FormDatum { @@ -146,9 +160,8 @@ impl HTMLSelectElement { // https://html.spec.whatwg.org/multipage/#concept-select-pick pub fn pick_option(&self, picked: &HTMLOptionElement) { if !self.Multiple() { - let node = self.upcast::<Node>(); let picked = picked.upcast(); - for opt in node.traverse_preorder().filter_map(Root::downcast::<HTMLOptionElement>) { + for opt in self.list_of_options() { if opt.upcast::<HTMLElement>() != picked { opt.set_selectedness(false); } @@ -271,9 +284,7 @@ impl HTMLSelectElementMethods for HTMLSelectElement { // https://html.spec.whatwg.org/multipage/#dom-select-value fn Value(&self) -> DOMString { - self.upcast::<Node>() - .traverse_preorder() - .filter_map(Root::downcast::<HTMLOptionElement>) + self.list_of_options() .filter(|opt_elem| opt_elem.Selected()) .map(|opt_elem| opt_elem.Value()) .next() @@ -282,9 +293,7 @@ impl HTMLSelectElementMethods for HTMLSelectElement { // https://html.spec.whatwg.org/multipage/#dom-select-value fn SetValue(&self, value: DOMString) { - let mut opt_iter = self.upcast::<Node>() - .traverse_preorder() - .filter_map(Root::downcast::<HTMLOptionElement>); + let mut opt_iter = self.list_of_options(); // Reset until we find an <option> with a matching value for opt in opt_iter.by_ref() { if opt.Value() == value { @@ -302,9 +311,7 @@ impl HTMLSelectElementMethods for HTMLSelectElement { // https://html.spec.whatwg.org/multipage/#dom-select-selectedindex fn SelectedIndex(&self) -> i32 { - self.upcast::<Node>() - .traverse_preorder() - .filter_map(Root::downcast::<HTMLOptionElement>) + self.list_of_options() .enumerate() .filter(|&(_, ref opt_elem)| opt_elem.Selected()) .map(|(i, _)| i as i32) @@ -314,9 +321,7 @@ impl HTMLSelectElementMethods for HTMLSelectElement { // https://html.spec.whatwg.org/multipage/#dom-select-selectedindex fn SetSelectedIndex(&self, index: i32) { - let mut opt_iter = self.upcast::<Node>() - .traverse_preorder() - .filter_map(Root::downcast::<HTMLOptionElement>); + let mut opt_iter = self.list_of_options(); for opt in opt_iter.by_ref().take(index as usize) { opt.set_selectedness(false); } @@ -394,3 +399,23 @@ impl Validatable for HTMLSelectElement { true } } + +enum Choice3<I, J, K> { + First(I), + Second(J), + Third(K), +} + +impl<I, J, K, T> Iterator for Choice3<I, J, K> + where I: Iterator<Item=T>, J: Iterator<Item=T>, K: Iterator<Item=T> +{ + type Item = T; + + fn next(&mut self) -> Option<T> { + match *self { + Choice3::First(ref mut i) => i.next(), + Choice3::Second(ref mut j) => j.next(), + Choice3::Third(ref mut k) => k.next(), + } + } +} diff --git a/components/script/dom/htmlstyleelement.rs b/components/script/dom/htmlstyleelement.rs index 5a61d6f5b3a..2507f7bee35 100644 --- a/components/script/dom/htmlstyleelement.rs +++ b/components/script/dom/htmlstyleelement.rs @@ -8,46 +8,59 @@ use dom::bindings::codegen::Bindings::HTMLStyleElementBinding; use dom::bindings::codegen::Bindings::HTMLStyleElementBinding::HTMLStyleElementMethods; use dom::bindings::codegen::Bindings::NodeBinding::NodeMethods; use dom::bindings::inheritance::Castable; -use dom::bindings::js::{JS, MutNullableHeap, Root}; +use dom::bindings::js::{MutNullableJS, Root}; use dom::bindings::str::DOMString; use dom::cssstylesheet::CSSStyleSheet; use dom::document::Document; -use dom::element::Element; +use dom::element::{Element, ElementCreator}; +use dom::eventtarget::EventTarget; use dom::htmlelement::HTMLElement; use dom::node::{ChildrenMutation, Node, document_from_node, window_from_node}; use dom::stylesheet::StyleSheet as DOMStyleSheet; use dom::virtualmethods::VirtualMethods; use html5ever_atoms::LocalName; +use net_traits::ReferrerPolicy; use script_layout_interface::message::Msg; +use std::cell::Cell; use std::sync::Arc; use style::media_queries::parse_media_query_list; use style::parser::ParserContextExtraData; use style::stylesheets::{Stylesheet, Origin}; +use stylesheet_loader::{StylesheetLoader, StylesheetOwner}; #[dom_struct] pub struct HTMLStyleElement { htmlelement: HTMLElement, #[ignore_heap_size_of = "Arc"] stylesheet: DOMRefCell<Option<Arc<Stylesheet>>>, - cssom_stylesheet: MutNullableHeap<JS<CSSStyleSheet>>, + cssom_stylesheet: MutNullableJS<CSSStyleSheet>, + /// https://html.spec.whatwg.org/multipage/#a-style-sheet-that-is-blocking-scripts + parser_inserted: Cell<bool>, + pending_loads: Cell<u32>, + any_failed_load: Cell<bool>, } impl HTMLStyleElement { fn new_inherited(local_name: LocalName, prefix: Option<DOMString>, - document: &Document) -> HTMLStyleElement { + document: &Document, + creator: ElementCreator) -> HTMLStyleElement { HTMLStyleElement { htmlelement: HTMLElement::new_inherited(local_name, prefix, document), stylesheet: DOMRefCell::new(None), - cssom_stylesheet: MutNullableHeap::new(None), + cssom_stylesheet: MutNullableJS::new(None), + parser_inserted: Cell::new(creator == ElementCreator::ParserCreated), + pending_loads: Cell::new(0), + any_failed_load: Cell::new(false), } } #[allow(unrooted_must_root)] pub fn new(local_name: LocalName, prefix: Option<DOMString>, - document: &Document) -> Root<HTMLStyleElement> { - Node::reflect_node(box HTMLStyleElement::new_inherited(local_name, prefix, document), + document: &Document, + creator: ElementCreator) -> Root<HTMLStyleElement> { + Node::reflect_node(box HTMLStyleElement::new_inherited(local_name, prefix, document, creator), document, HTMLStyleElementBinding::Wrap) } @@ -68,10 +81,19 @@ impl HTMLStyleElement { let data = node.GetTextContent().expect("Element.textContent must be a string"); let mq = parse_media_query_list(&mut CssParser::new(&mq_str)); - let sheet = Stylesheet::from_str(&data, url, Origin::Author, mq, win.css_error_reporter(), + let loader = StylesheetLoader::for_element(self.upcast()); + let sheet = Stylesheet::from_str(&data, url, Origin::Author, mq, + Some(&loader), + win.css_error_reporter(), ParserContextExtraData::default()); + let sheet = Arc::new(sheet); + // No subresource loads were triggered, just fire the load event now. + if self.pending_loads.get() == 0 { + self.upcast::<EventTarget>().fire_event(atom!("load")); + } + win.layout_chan().send(Msg::AddStylesheet(sheet.clone())).unwrap(); *self.stylesheet.borrow_mut() = Some(sheet); let doc = document_from_node(self); @@ -121,6 +143,37 @@ impl VirtualMethods for HTMLStyleElement { } } +impl StylesheetOwner for HTMLStyleElement { + fn increment_pending_loads_count(&self) { + self.pending_loads.set(self.pending_loads.get() + 1) + } + + fn load_finished(&self, succeeded: bool) -> Option<bool> { + assert!(self.pending_loads.get() > 0, "What finished?"); + if !succeeded { + self.any_failed_load.set(true); + } + + self.pending_loads.set(self.pending_loads.get() - 1); + if self.pending_loads.get() != 0 { + return None; + } + + let any_failed = self.any_failed_load.get(); + self.any_failed_load.set(false); + Some(any_failed) + } + + fn parser_inserted(&self) -> bool { + self.parser_inserted.get() + } + + fn referrer_policy(&self) -> Option<ReferrerPolicy> { + None + } +} + + impl HTMLStyleElementMethods for HTMLStyleElement { // https://drafts.csswg.org/cssom/#dom-linkstyle-sheet fn GetSheet(&self) -> Option<Root<DOMStyleSheet>> { diff --git a/components/script/dom/htmltablecellelement.rs b/components/script/dom/htmltablecellelement.rs index b4bd885d4ed..4a6ca5ca9b1 100644 --- a/components/script/dom/htmltablecellelement.rs +++ b/components/script/dom/htmltablecellelement.rs @@ -34,11 +34,6 @@ impl HTMLTableCellElement { htmlelement: HTMLElement::new_inherited(tag_name, prefix, document), } } - - #[inline] - pub fn htmlelement(&self) -> &HTMLElement { - &self.htmlelement - } } impl HTMLTableCellElementMethods for HTMLTableCellElement { diff --git a/components/script/dom/htmltableelement.rs b/components/script/dom/htmltableelement.rs index e533c9acdcd..741b53c38ac 100644 --- a/components/script/dom/htmltableelement.rs +++ b/components/script/dom/htmltableelement.rs @@ -10,7 +10,7 @@ use dom::bindings::codegen::Bindings::HTMLTableElementBinding::HTMLTableElementM use dom::bindings::codegen::Bindings::NodeBinding::NodeMethods; use dom::bindings::error::{Error, ErrorResult, Fallible}; use dom::bindings::inheritance::Castable; -use dom::bindings::js::{JS, LayoutJS, MutNullableHeap, Root, RootedReference}; +use dom::bindings::js::{JS, LayoutJS, MutNullableJS, Root, RootedReference}; use dom::bindings::str::DOMString; use dom::document::Document; use dom::element::{AttributeMutation, Element, RawLayoutElementHelpers}; @@ -31,7 +31,7 @@ pub struct HTMLTableElement { htmlelement: HTMLElement, border: Cell<Option<u32>>, cellspacing: Cell<Option<u32>>, - tbodies: MutNullableHeap<JS<HTMLCollection>>, + tbodies: MutNullableJS<HTMLCollection>, } #[allow(unrooted_must_root)] diff --git a/components/script/dom/htmltablerowelement.rs b/components/script/dom/htmltablerowelement.rs index b95aba1c3e0..c6b04648dc2 100644 --- a/components/script/dom/htmltablerowelement.rs +++ b/components/script/dom/htmltablerowelement.rs @@ -9,7 +9,7 @@ use dom::bindings::codegen::Bindings::HTMLTableSectionElementBinding::HTMLTableS use dom::bindings::codegen::Bindings::NodeBinding::NodeMethods; use dom::bindings::error::{ErrorResult, Fallible}; use dom::bindings::inheritance::Castable; -use dom::bindings::js::{JS, LayoutJS, MutNullableHeap, Root, RootedReference}; +use dom::bindings::js::{LayoutJS, MutNullableJS, Root, RootedReference}; use dom::bindings::str::DOMString; use dom::document::Document; use dom::element::{Element, RawLayoutElementHelpers}; @@ -36,7 +36,7 @@ impl CollectionFilter for CellsFilter { #[dom_struct] pub struct HTMLTableRowElement { htmlelement: HTMLElement, - cells: MutNullableHeap<JS<HTMLCollection>>, + cells: MutNullableJS<HTMLCollection>, } impl HTMLTableRowElement { diff --git a/components/script/dom/htmltemplateelement.rs b/components/script/dom/htmltemplateelement.rs index 7ee8d03b163..1c9b2c0aacd 100644 --- a/components/script/dom/htmltemplateelement.rs +++ b/components/script/dom/htmltemplateelement.rs @@ -7,7 +7,7 @@ use dom::bindings::codegen::Bindings::HTMLTemplateElementBinding; use dom::bindings::codegen::Bindings::HTMLTemplateElementBinding::HTMLTemplateElementMethods; use dom::bindings::codegen::Bindings::NodeBinding::NodeMethods; use dom::bindings::inheritance::Castable; -use dom::bindings::js::{JS, MutNullableHeap, Root}; +use dom::bindings::js::{MutNullableJS, Root}; use dom::bindings::str::DOMString; use dom::document::Document; use dom::documentfragment::DocumentFragment; @@ -21,7 +21,7 @@ pub struct HTMLTemplateElement { htmlelement: HTMLElement, /// https://html.spec.whatwg.org/multipage/#template-contents - contents: MutNullableHeap<JS<DocumentFragment>>, + contents: MutNullableJS<DocumentFragment>, } impl HTMLTemplateElement { @@ -31,7 +31,7 @@ impl HTMLTemplateElement { HTMLTemplateElement { htmlelement: HTMLElement::new_inherited(local_name, prefix, document), - contents: MutNullableHeap::new(None), + contents: MutNullableJS::new(None), } } diff --git a/components/script/dom/htmltextareaelement.rs b/components/script/dom/htmltextareaelement.rs index 47b9bb6ee0b..fd5b42fa25c 100755 --- a/components/script/dom/htmltextareaelement.rs +++ b/components/script/dom/htmltextareaelement.rs @@ -39,6 +39,7 @@ pub struct HTMLTextAreaElement { htmlelement: HTMLElement, #[ignore_heap_size_of = "#7193"] textinput: DOMRefCell<TextInput<IpcSender<ConstellationMsg>>>, + placeholder: DOMRefCell<DOMString>, // https://html.spec.whatwg.org/multipage/#concept-textarea-dirty value_changed: Cell<bool>, } @@ -58,7 +59,12 @@ impl LayoutHTMLTextAreaElementHelpers for LayoutJS<HTMLTextAreaElement> { #[allow(unrooted_must_root)] #[allow(unsafe_code)] unsafe fn get_value_for_layout(self) -> String { - String::from((*self.unsafe_get()).textinput.borrow_for_layout().get_content()) + let text = (*self.unsafe_get()).textinput.borrow_for_layout().get_content(); + String::from(if text.is_empty() { + (*self.unsafe_get()).placeholder.borrow_for_layout().clone() + } else { + text + }) } #[allow(unrooted_must_root)] @@ -105,6 +111,7 @@ impl HTMLTextAreaElement { htmlelement: HTMLElement::new_inherited_with_state(IN_ENABLED_STATE | IN_READ_WRITE_STATE, local_name, prefix, document), + placeholder: DOMRefCell::new(DOMString::new()), textinput: DOMRefCell::new(TextInput::new( Lines::Multiple, DOMString::new(), chan, None, None, SelectionDirection::None)), value_changed: Cell::new(false), @@ -119,6 +126,14 @@ impl HTMLTextAreaElement { document, HTMLTextAreaElementBinding::Wrap) } + + fn update_placeholder_shown_state(&self) { + let has_placeholder = !self.placeholder.borrow().is_empty(); + let has_value = !self.textinput.borrow().is_empty(); + let el = self.upcast::<Element>(); + el.set_placeholder_shown_state(has_placeholder && !has_value); + el.set_placeholder_shown_state(has_placeholder); + } } impl HTMLTextAreaElementMethods for HTMLTextAreaElement { @@ -270,11 +285,6 @@ impl HTMLTextAreaElementMethods for HTMLTextAreaElement { impl HTMLTextAreaElement { - // https://html.spec.whatwg.org/multipage/#concept-fe-mutable - pub fn mutable(&self) -> bool { - // https://html.spec.whatwg.org/multipage/#the-textarea-element:concept-fe-mutable - !(self.Disabled() || self.ReadOnly()) - } pub fn reset(&self) { // https://html.spec.whatwg.org/multipage/#the-textarea-element:concept-form-reset-control self.SetValue(self.DefaultValue()); @@ -311,6 +321,16 @@ impl VirtualMethods for HTMLTextAreaElement { } } }, + local_name!("placeholder") => { + { + let mut placeholder = self.placeholder.borrow_mut(); + placeholder.clear(); + if let AttributeMutation::Set(_) = mutation { + placeholder.push_str(&attr.value()); + } + } + self.update_placeholder_shown_state(); + }, local_name!("readonly") => { let el = self.upcast::<Element>(); match mutation { @@ -375,10 +395,14 @@ impl VirtualMethods for HTMLTextAreaElement { document_from_node(self).request_focus(self.upcast()); } else if event.type_() == atom!("keydown") && !event.DefaultPrevented() { if let Some(kevent) = event.downcast::<KeyboardEvent>() { - match self.textinput.borrow_mut().handle_keydown(kevent) { + // This can't be inlined, as holding on to textinput.borrow_mut() + // during self.implicit_submission will cause a panic. + let action = self.textinput.borrow_mut().handle_keydown(kevent); + match action { KeyReaction::TriggerDefaultAction => (), KeyReaction::DispatchInput => { self.value_changed.set(true); + self.update_placeholder_shown_state(); if event.IsTrusted() { let window = window_from_node(self); diff --git a/components/script/dom/htmltimeelement.rs b/components/script/dom/htmltimeelement.rs index 84794443e02..c5286dd685f 100644 --- a/components/script/dom/htmltimeelement.rs +++ b/components/script/dom/htmltimeelement.rs @@ -2,14 +2,11 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -use dom::bindings::codegen::Bindings::ElementBinding::ElementBinding::ElementMethods; use dom::bindings::codegen::Bindings::HTMLTimeElementBinding; use dom::bindings::codegen::Bindings::HTMLTimeElementBinding::HTMLTimeElementMethods; -use dom::bindings::inheritance::Castable; use dom::bindings::js::Root; use dom::bindings::str::DOMString; use dom::document::Document; -use dom::element::Element; use dom::htmlelement::HTMLElement; use dom::node::Node; use html5ever_atoms::LocalName; @@ -38,18 +35,7 @@ impl HTMLTimeElement { impl HTMLTimeElementMethods for HTMLTimeElement { // https://html.spec.whatwg.org/multipage/#dom-time-datetime - //make_getter!(DateTime, "datetime"); - fn DateTime(&self) -> DOMString { - let element = self.upcast::<Element>(); - if element.has_attribute(&local_name!("datetime")) { - return element.get_string_attribute(&local_name!("datetime")) - } else { - match element.GetInnerHTML() { - Ok(x) => x, - _ => DOMString::new(), - } - } - } + make_getter!(DateTime, "datetime"); // https://html.spec.whatwg.org/multipage/#dom-time-datetime make_setter!(SetDateTime, "datetime"); diff --git a/components/script/dom/htmltitleelement.rs b/components/script/dom/htmltitleelement.rs index f3ec357cb56..6dde6a6203b 100644 --- a/components/script/dom/htmltitleelement.rs +++ b/components/script/dom/htmltitleelement.rs @@ -8,11 +8,9 @@ use dom::bindings::codegen::Bindings::NodeBinding::NodeMethods; use dom::bindings::inheritance::Castable; use dom::bindings::js::Root; use dom::bindings::str::DOMString; -use dom::characterdata::CharacterData; use dom::document::Document; use dom::htmlelement::HTMLElement; use dom::node::{ChildrenMutation, Node}; -use dom::text::Text; use dom::virtualmethods::VirtualMethods; use html5ever_atoms::LocalName; @@ -41,13 +39,7 @@ impl HTMLTitleElement { impl HTMLTitleElementMethods for HTMLTitleElement { // https://html.spec.whatwg.org/multipage/#dom-title-text fn Text(&self) -> DOMString { - let mut content = String::new(); - for child in self.upcast::<Node>().children() { - if let Some(text) = child.downcast::<Text>() { - content.push_str(&text.upcast::<CharacterData>().data()); - } - } - DOMString::from(content) + self.upcast::<Node>().child_text_content() } // https://html.spec.whatwg.org/multipage/#dom-title-text diff --git a/components/script/dom/macros.rs b/components/script/dom/macros.rs index 99b06bae39d..f2174bdd552 100644 --- a/components/script/dom/macros.rs +++ b/components/script/dom/macros.rs @@ -537,14 +537,15 @@ macro_rules! document_and_element_event_handlers( #[macro_export] macro_rules! rooted_vec { (let mut $name:ident) => { - rooted_vec!(let mut $name <- ::std::iter::empty()) + let mut root = $crate::dom::bindings::trace::RootableVec::new_unrooted(); + let mut $name = $crate::dom::bindings::trace::RootedVec::new(&mut root); }; (let $name:ident <- $iter:expr) => { - let mut __root = $crate::dom::bindings::trace::RootableVec::new_unrooted(); - let $name = $crate::dom::bindings::trace::RootedVec::new(&mut __root, $iter); + let mut root = $crate::dom::bindings::trace::RootableVec::new_unrooted(); + let $name = $crate::dom::bindings::trace::RootedVec::from_iter(&mut root, $iter); }; (let mut $name:ident <- $iter:expr) => { - let mut __root = $crate::dom::bindings::trace::RootableVec::new_unrooted(); - let mut $name = $crate::dom::bindings::trace::RootedVec::new(&mut __root, $iter); + let mut root = $crate::dom::bindings::trace::RootableVec::new_unrooted(); + let mut $name = $crate::dom::bindings::trace::RootedVec::from_iter(&mut root, $iter); } } diff --git a/components/script/dom/mediaquerylist.rs b/components/script/dom/mediaquerylist.rs index 86f67cdd8a1..db96a4760cd 100644 --- a/components/script/dom/mediaquerylist.rs +++ b/components/script/dom/mediaquerylist.rs @@ -9,12 +9,15 @@ use dom::bindings::codegen::Bindings::EventTargetBinding::EventTargetMethods; use dom::bindings::codegen::Bindings::MediaQueryListBinding::{self, MediaQueryListMethods}; use dom::bindings::inheritance::Castable; use dom::bindings::js::{JS, Root}; +use dom::bindings::reflector::DomObject; use dom::bindings::reflector::reflect_dom_object; use dom::bindings::str::DOMString; use dom::bindings::trace::JSTraceable; use dom::bindings::weakref::{WeakRef, WeakRefVec}; use dom::document::Document; +use dom::event::Event; use dom::eventtarget::EventTarget; +use dom::mediaquerylistevent::MediaQueryListEvent; use euclid::scale_factor::ScaleFactor; use js::jsapi::JSTracer; use std::cell::Cell; @@ -136,8 +139,14 @@ impl WeakMediaQueryListVec { /// https://drafts.csswg.org/cssom-view/#evaluate-media-queries-and-report-changes pub fn evaluate_and_report_changes(&self) { for mql in self.cell.borrow().iter() { - if let MediaQueryListMatchState::Changed(_) = mql.root().unwrap().evaluate_changes() { - mql.root().unwrap().upcast::<EventTarget>().fire_event(atom!("change")); + let mql = mql.root().unwrap(); + if let MediaQueryListMatchState::Changed(_) = mql.evaluate_changes() { + let event = MediaQueryListEvent::new(&mql.global(), + atom!("change"), + false, false, + mql.Media(), + mql.Matches()); + event.upcast::<Event>().fire(mql.upcast::<EventTarget>()); } } } diff --git a/components/script/dom/mediaquerylistevent.rs b/components/script/dom/mediaquerylistevent.rs new file mode 100644 index 00000000000..8edd2fa3ab2 --- /dev/null +++ b/components/script/dom/mediaquerylistevent.rs @@ -0,0 +1,76 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +use dom::bindings::codegen::Bindings::EventBinding::EventMethods; +use dom::bindings::codegen::Bindings::MediaQueryListEventBinding; +use dom::bindings::codegen::Bindings::MediaQueryListEventBinding::MediaQueryListEventInit; +use dom::bindings::codegen::Bindings::MediaQueryListEventBinding::MediaQueryListEventMethods; +use dom::bindings::error::Fallible; +use dom::bindings::inheritance::Castable; +use dom::bindings::js::Root; +use dom::bindings::reflector::reflect_dom_object; +use dom::bindings::str::DOMString; +use dom::event::Event; +use dom::globalscope::GlobalScope; +use dom::window::Window; +use servo_atoms::Atom; +use std::cell::Cell; + +// https://drafts.csswg.org/cssom-view/#dom-mediaquerylistevent-mediaquerylistevent +#[dom_struct] +pub struct MediaQueryListEvent { + event: Event, + media: DOMString, + matches: Cell<bool> +} + +impl MediaQueryListEvent { + pub fn new_initialized(global: &GlobalScope, + media: DOMString, + matches: bool) -> Root<MediaQueryListEvent> { + let ev = box MediaQueryListEvent { + event: Event::new_inherited(), + media: media, + matches: Cell::new(matches) + }; + reflect_dom_object(ev, global, MediaQueryListEventBinding::Wrap) + } + + pub fn new(global: &GlobalScope, type_: Atom, + bubbles: bool, cancelable: bool, + media: DOMString, matches: bool) -> Root<MediaQueryListEvent> { + let ev = MediaQueryListEvent::new_initialized(global, media, matches); + { + let event = ev.upcast::<Event>(); + event.init_event(type_, bubbles, cancelable); + } + ev + } + + pub fn Constructor(window: &Window, type_: DOMString, + init: &MediaQueryListEventInit) + -> Fallible<Root<MediaQueryListEvent>> { + let global = window.upcast::<GlobalScope>(); + Ok(MediaQueryListEvent::new(global, Atom::from(type_), + init.parent.bubbles, init.parent.cancelable, + init.media.clone(), init.matches)) + } +} + +impl MediaQueryListEventMethods for MediaQueryListEvent { + // https://drafts.csswg.org/cssom-view/#dom-mediaquerylistevent-media + fn Media(&self) -> DOMString { + self.media.clone() + } + + // https://drafts.csswg.org/cssom-view/#dom-mediaquerylistevent-matches + fn Matches(&self) -> bool { + self.matches.get() + } + + // https://dom.spec.whatwg.org/#dom-event-istrusted + fn IsTrusted(&self) -> bool { + self.upcast::<Event>().IsTrusted() + } +} diff --git a/components/script/dom/mod.rs b/components/script/dom/mod.rs index 5bc19eab627..4f94ac8309f 100644 --- a/components/script/dom/mod.rs +++ b/components/script/dom/mod.rs @@ -32,8 +32,8 @@ //! * rooting pointers on the stack: //! the [`Root`](bindings/js/struct.Root.html) smart pointer; //! * tracing pointers in member fields: the [`JS`](bindings/js/struct.JS.html), -//! [`MutNullableHeap`](bindings/js/struct.MutNullableHeap.html) and -//! [`MutHeap`](bindings/js/struct.MutHeap.html) smart pointers and +//! [`MutNullableJS`](bindings/js/struct.MutNullableJS.html) and +//! [`MutJS`](bindings/js/struct.MutJS.html) smart pointers and //! [the tracing implementation](bindings/trace/index.html); //! * rooting pointers from across thread boundaries or in channels: the //! [`Trusted`](bindings/refcounted/struct.Trusted.html) smart pointer; @@ -217,13 +217,10 @@ pub mod abstractworkerglobalscope; pub mod activation; pub mod attr; pub mod beforeunloadevent; -mod create; -#[allow(unsafe_code)] -#[deny(missing_docs, non_snake_case)] pub mod bindings; pub mod blob; pub mod bluetooth; -pub mod bluetoothadvertisingdata; +pub mod bluetoothadvertisingevent; pub mod bluetoothcharacteristicproperties; pub mod bluetoothdevice; pub mod bluetoothremotegattcharacteristic; @@ -240,10 +237,12 @@ pub mod client; pub mod closeevent; pub mod comment; pub mod console; +mod create; pub mod crypto; pub mod css; pub mod cssfontfacerule; pub mod cssgroupingrule; +pub mod cssimportrule; pub mod csskeyframerule; pub mod csskeyframesrule; pub mod cssmediarule; @@ -370,6 +369,7 @@ pub mod location; pub mod mediaerror; pub mod medialist; pub mod mediaquerylist; +pub mod mediaquerylistevent; pub mod messageevent; pub mod mimetype; pub mod mimetypearray; diff --git a/components/script/dom/mouseevent.rs b/components/script/dom/mouseevent.rs index 2b39d555204..3b0e3fb1710 100644 --- a/components/script/dom/mouseevent.rs +++ b/components/script/dom/mouseevent.rs @@ -7,16 +7,16 @@ use dom::bindings::codegen::Bindings::MouseEventBinding::MouseEventMethods; use dom::bindings::codegen::Bindings::UIEventBinding::UIEventMethods; use dom::bindings::error::Fallible; use dom::bindings::inheritance::Castable; -use dom::bindings::js::{JS, MutNullableHeap, Root, RootedReference}; +use dom::bindings::js::{MutNullableJS, Root, RootedReference}; use dom::bindings::reflector::reflect_dom_object; use dom::bindings::str::DOMString; use dom::event::{Event, EventBubbles, EventCancelable}; use dom::eventtarget::EventTarget; use dom::uievent::UIEvent; use dom::window::Window; +use servo_config::prefs::PREFS; use std::cell::Cell; use std::default::Default; -use util::prefs::PREFS; #[dom_struct] pub struct MouseEvent { @@ -30,7 +30,7 @@ pub struct MouseEvent { alt_key: Cell<bool>, meta_key: Cell<bool>, button: Cell<i16>, - related_target: MutNullableHeap<JS<EventTarget>>, + related_target: MutNullableJS<EventTarget>, } impl MouseEvent { diff --git a/components/script/dom/navigator.rs b/components/script/dom/navigator.rs index 9318e437ad5..b7d781f5eb0 100644 --- a/components/script/dom/navigator.rs +++ b/components/script/dom/navigator.rs @@ -4,7 +4,7 @@ use dom::bindings::codegen::Bindings::NavigatorBinding; use dom::bindings::codegen::Bindings::NavigatorBinding::NavigatorMethods; -use dom::bindings::js::{JS, MutNullableHeap, Root}; +use dom::bindings::js::{MutNullableJS, Root}; use dom::bindings::reflector::{Reflector, DomObject, reflect_dom_object}; use dom::bindings::str::DOMString; use dom::bluetooth::Bluetooth; @@ -17,10 +17,10 @@ use dom::window::Window; #[dom_struct] pub struct Navigator { reflector_: Reflector, - bluetooth: MutNullableHeap<JS<Bluetooth>>, - plugins: MutNullableHeap<JS<PluginArray>>, - mime_types: MutNullableHeap<JS<MimeTypeArray>>, - service_worker: MutNullableHeap<JS<ServiceWorkerContainer>>, + bluetooth: MutNullableJS<Bluetooth>, + plugins: MutNullableJS<PluginArray>, + mime_types: MutNullableJS<MimeTypeArray>, + service_worker: MutNullableJS<ServiceWorkerContainer>, } impl Navigator { diff --git a/components/script/dom/navigatorinfo.rs b/components/script/dom/navigatorinfo.rs index 54200e7be20..f0b331c49e6 100644 --- a/components/script/dom/navigatorinfo.rs +++ b/components/script/dom/navigatorinfo.rs @@ -3,7 +3,7 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ use dom::bindings::str::DOMString; -use util::opts; +use servo_config::opts; pub fn Product() -> DOMString { DOMString::from("Gecko") diff --git a/components/script/dom/node.rs b/components/script/dom/node.rs index 983f11f478c..d6bc301955d 100644 --- a/components/script/dom/node.rs +++ b/components/script/dom/node.rs @@ -21,7 +21,7 @@ use dom::bindings::error::{Error, ErrorResult, Fallible}; use dom::bindings::inheritance::{Castable, CharacterDataTypeId, ElementTypeId}; use dom::bindings::inheritance::{EventTargetTypeId, HTMLElementTypeId, NodeTypeId}; use dom::bindings::inheritance::{SVGElementTypeId, SVGGraphicsElementTypeId}; -use dom::bindings::js::{JS, LayoutJS, MutNullableHeap}; +use dom::bindings::js::{JS, LayoutJS, MutNullableJS}; use dom::bindings::js::Root; use dom::bindings::js::RootedReference; use dom::bindings::reflector::{DomObject, reflect_dom_object}; @@ -57,7 +57,6 @@ use euclid::point::Point2D; use euclid::rect::Rect; use euclid::size::Size2D; use heapsize::{HeapSizeOf, heap_size_of}; -use html5ever::tree_builder::QuirksMode; use html5ever_atoms::{Prefix, Namespace, QualName}; use js::jsapi::{JSContext, JSObject, JSRuntime}; use libc::{self, c_void, uintptr_t}; @@ -78,6 +77,7 @@ use std::iter; use std::mem; use std::ops::Range; use std::sync::Arc; +use style::context::QuirksMode; use style::dom::OpaqueNode; use style::selector_parser::{SelectorImpl, SelectorParser}; use style::stylesheets::Stylesheet; @@ -95,25 +95,25 @@ pub struct Node { eventtarget: EventTarget, /// The parent of this node. - parent_node: MutNullableHeap<JS<Node>>, + parent_node: MutNullableJS<Node>, /// The first child of this node. - first_child: MutNullableHeap<JS<Node>>, + first_child: MutNullableJS<Node>, /// The last child of this node. - last_child: MutNullableHeap<JS<Node>>, + last_child: MutNullableJS<Node>, /// The next sibling of this node. - next_sibling: MutNullableHeap<JS<Node>>, + next_sibling: MutNullableJS<Node>, /// The previous sibling of this node. - prev_sibling: MutNullableHeap<JS<Node>>, + prev_sibling: MutNullableJS<Node>, /// The document that this node belongs to. - owner_doc: MutNullableHeap<JS<Document>>, + owner_doc: MutNullableJS<Document>, /// The live list of children return by .childNodes. - child_list: MutNullableHeap<JS<NodeList>>, + child_list: MutNullableJS<NodeList>, /// The live count of children of this node. children_count: Cell<u32>, @@ -426,10 +426,6 @@ impl Node { self.get_flag(HAS_DIRTY_DESCENDANTS) } - pub fn set_has_dirty_descendants(&self, state: bool) { - self.set_flag(HAS_DIRTY_DESCENDANTS, state) - } - pub fn rev_version(&self) { // The new version counter is 1 plus the max of the node's current version counter, // its descendants version, and the document's version. Normally, this will just be @@ -1370,7 +1366,7 @@ impl Node { last_child: Default::default(), next_sibling: Default::default(), prev_sibling: Default::default(), - owner_doc: MutNullableHeap::new(doc), + owner_doc: MutNullableJS::new(doc), child_list: Default::default(), children_count: Cell::new(0u32), flags: Cell::new(flags), @@ -1788,12 +1784,16 @@ impl Node { copy } + /// https://html.spec.whatwg.org/multipage/#child-text-content + pub fn child_text_content(&self) -> DOMString { + Node::collect_text_contents(self.children()) + } + pub fn collect_text_contents<T: Iterator<Item=Root<Node>>>(iterator: T) -> DOMString { let mut content = String::new(); for node in iterator { - match node.downcast::<Text>() { - Some(ref text) => content.push_str(&text.upcast::<CharacterData>().data()), - None => (), + if let Some(ref text) = node.downcast::<Text>() { + content.push_str(&text.upcast::<CharacterData>().data()); } } DOMString::from(content) diff --git a/components/script/dom/nodeiterator.rs b/components/script/dom/nodeiterator.rs index d9e46a5ea44..920d94d635c 100644 --- a/components/script/dom/nodeiterator.rs +++ b/components/script/dom/nodeiterator.rs @@ -9,7 +9,7 @@ use dom::bindings::codegen::Bindings::NodeFilterBinding::NodeFilterConstants; use dom::bindings::codegen::Bindings::NodeIteratorBinding; use dom::bindings::codegen::Bindings::NodeIteratorBinding::NodeIteratorMethods; use dom::bindings::error::Fallible; -use dom::bindings::js::{JS, MutHeap, Root}; +use dom::bindings::js::{JS, MutJS, Root}; use dom::bindings::reflector::{Reflector, reflect_dom_object}; use dom::document::Document; use dom::node::Node; @@ -21,7 +21,7 @@ pub struct NodeIterator { reflector_: Reflector, root_node: JS<Node>, #[ignore_heap_size_of = "Defined in rust-mozjs"] - reference_node: MutHeap<JS<Node>>, + reference_node: MutJS<Node>, pointer_before_reference_node: Cell<bool>, what_to_show: u32, #[ignore_heap_size_of = "Can't measure due to #6870"] @@ -35,7 +35,7 @@ impl NodeIterator { NodeIterator { reflector_: Reflector::new(), root_node: JS::from_ref(root_node), - reference_node: MutHeap::new(root_node), + reference_node: MutJS::new(root_node), pointer_before_reference_node: Cell::new(true), what_to_show: what_to_show, filter: filter @@ -79,7 +79,6 @@ impl NodeIteratorMethods for NodeIterator { match self.filter { Filter::None => None, Filter::Callback(ref nf) => Some((*nf).clone()), - Filter::Native(_) => panic!("Cannot convert native node filter to DOM NodeFilter") } } @@ -200,7 +199,6 @@ impl NodeIterator { // Step 3-5. match self.filter { Filter::None => Ok(NodeFilterConstants::FILTER_ACCEPT), - Filter::Native(f) => Ok((f)(node)), Filter::Callback(ref callback) => callback.AcceptNode_(self, node, Rethrow) } } @@ -210,6 +208,5 @@ impl NodeIterator { #[derive(JSTraceable)] pub enum Filter { None, - Native(fn (node: &Node) -> u16), Callback(Rc<NodeFilter>) } diff --git a/components/script/dom/nodelist.rs b/components/script/dom/nodelist.rs index 391d21d5865..21e05fc7dcc 100644 --- a/components/script/dom/nodelist.rs +++ b/components/script/dom/nodelist.rs @@ -5,7 +5,7 @@ use dom::bindings::codegen::Bindings::NodeBinding::NodeMethods; use dom::bindings::codegen::Bindings::NodeListBinding; use dom::bindings::codegen::Bindings::NodeListBinding::NodeListMethods; -use dom::bindings::js::{JS, MutNullableHeap, Root, RootedReference}; +use dom::bindings::js::{JS, MutNullableJS, Root, RootedReference}; use dom::bindings::reflector::{Reflector, reflect_dom_object}; use dom::node::{ChildrenMutation, Node}; use dom::window::Window; @@ -111,7 +111,7 @@ impl NodeList { pub struct ChildrenList { node: JS<Node>, #[ignore_heap_size_of = "Defined in rust-mozjs"] - last_visited: MutNullableHeap<JS<Node>>, + last_visited: MutNullableJS<Node>, last_index: Cell<u32>, } @@ -120,7 +120,7 @@ impl ChildrenList { let last_visited = node.GetFirstChild(); ChildrenList { node: JS::from_ref(node), - last_visited: MutNullableHeap::new(last_visited.r()), + last_visited: MutNullableJS::new(last_visited.r()), last_index: Cell::new(0u32), } } diff --git a/components/script/dom/radionodelist.rs b/components/script/dom/radionodelist.rs index 5cf05cb872a..b8078aa6670 100644 --- a/components/script/dom/radionodelist.rs +++ b/components/script/dom/radionodelist.rs @@ -40,10 +40,6 @@ impl RadioNodeList { RadioNodeList::new(window, NodeListType::Simple(iter.map(|r| JS::from_ref(&*r)).collect())) } - pub fn empty(window: &Window) -> Root<RadioNodeList> { - RadioNodeList::new(window, NodeListType::Simple(vec![])) - } - // FIXME: This shouldn't need to be implemented here since NodeList (the parent of // RadioNodeList) implements Length // https://github.com/servo/servo/issues/5875 diff --git a/components/script/dom/range.rs b/components/script/dom/range.rs index 723239ea3d3..e9e3a484d41 100644 --- a/components/script/dom/range.rs +++ b/components/script/dom/range.rs @@ -13,7 +13,7 @@ use dom::bindings::codegen::Bindings::WindowBinding::WindowMethods; use dom::bindings::error::{Error, ErrorResult, Fallible}; use dom::bindings::inheritance::{CharacterDataTypeId, NodeTypeId}; use dom::bindings::inheritance::Castable; -use dom::bindings::js::{JS, MutHeap, Root, RootedReference}; +use dom::bindings::js::{JS, MutJS, Root, RootedReference}; use dom::bindings::reflector::{Reflector, reflect_dom_object}; use dom::bindings::str::DOMString; use dom::bindings::trace::JSTraceable; @@ -934,7 +934,7 @@ impl RangeMethods for Range { #[privatize] #[derive(HeapSizeOf)] pub struct BoundaryPoint { - node: MutHeap<JS<Node>>, + node: MutJS<Node>, offset: Cell<u32>, } @@ -943,7 +943,7 @@ impl BoundaryPoint { debug_assert!(!node.is_doctype()); debug_assert!(offset <= node.len()); BoundaryPoint { - node: MutHeap::new(node), + node: MutJS::new(node), offset: Cell::new(offset), } } diff --git a/components/script/dom/request.rs b/components/script/dom/request.rs index cb338d65b29..8ca9104b945 100644 --- a/components/script/dom/request.rs +++ b/components/script/dom/request.rs @@ -17,7 +17,7 @@ use dom::bindings::codegen::Bindings::RequestBinding::RequestMode; use dom::bindings::codegen::Bindings::RequestBinding::RequestRedirect; use dom::bindings::codegen::Bindings::RequestBinding::RequestType; use dom::bindings::error::{Error, Fallible}; -use dom::bindings::js::{JS, MutNullableHeap, Root}; +use dom::bindings::js::{MutNullableJS, Root}; use dom::bindings::reflector::{DomObject, Reflector, reflect_dom_object}; use dom::bindings::str::{ByteString, DOMString, USVString}; use dom::globalscope::GlobalScope; @@ -45,7 +45,7 @@ pub struct Request { reflector_: Reflector, request: DOMRefCell<NetTraitsRequest>, body_used: Cell<bool>, - headers: MutNullableHeap<JS<Headers>>, + headers: MutNullableJS<Headers>, mime_type: DOMRefCell<Vec<u8>>, #[ignore_heap_size_of = "Rc"] body_promise: DOMRefCell<Option<(Rc<Promise>, BodyType)>>, @@ -92,8 +92,7 @@ impl Request { let mut fallback_credentials: Option<NetTraitsRequestCredentials> = None; // Step 4 - // TODO: `entry settings object` is not implemented in Servo yet. - let base_url = global.get_url(); + let base_url = global.api_base_url(); match input { // Step 5 diff --git a/components/script/dom/response.rs b/components/script/dom/response.rs index 278ead3c36d..1d9d62c079a 100644 --- a/components/script/dom/response.rs +++ b/components/script/dom/response.rs @@ -10,7 +10,7 @@ use dom::bindings::codegen::Bindings::ResponseBinding; use dom::bindings::codegen::Bindings::ResponseBinding::{ResponseMethods, ResponseType as DOMResponseType}; use dom::bindings::codegen::Bindings::XMLHttpRequestBinding::BodyInit; use dom::bindings::error::{Error, Fallible}; -use dom::bindings::js::{JS, MutNullableHeap, Root}; +use dom::bindings::js::{MutNullableJS, Root}; use dom::bindings::reflector::{DomObject, Reflector, reflect_dom_object}; use dom::bindings::str::{ByteString, USVString}; use dom::globalscope::GlobalScope; @@ -32,7 +32,7 @@ use url::Position; #[dom_struct] pub struct Response { reflector_: Reflector, - headers_reflector: MutNullableHeap<JS<Headers>>, + headers_reflector: MutNullableJS<Headers>, mime_type: DOMRefCell<Vec<u8>>, body_used: Cell<bool>, /// `None` can be considered a StatusCode of `0`. @@ -149,8 +149,7 @@ impl Response { // https://fetch.spec.whatwg.org/#dom-response-redirect pub fn Redirect(global: &GlobalScope, url: USVString, status: u16) -> Fallible<Root<Response>> { // Step 1 - // TODO: `entry settings object` is not implemented in Servo yet. - let base_url = global.get_url(); + let base_url = global.api_base_url(); let parsed_url = base_url.join(&url.0); // Step 2 diff --git a/components/script/dom/serviceworkercontainer.rs b/components/script/dom/serviceworkercontainer.rs index e5662f56dee..6757fc0179d 100644 --- a/components/script/dom/serviceworkercontainer.rs +++ b/components/script/dom/serviceworkercontainer.rs @@ -5,7 +5,7 @@ use dom::bindings::codegen::Bindings::ServiceWorkerContainerBinding::{ServiceWorkerContainerMethods, Wrap}; use dom::bindings::codegen::Bindings::ServiceWorkerContainerBinding::RegistrationOptions; use dom::bindings::error::Error; -use dom::bindings::js::{JS, MutNullableHeap, Root}; +use dom::bindings::js::{JS, MutNullableJS, Root}; use dom::bindings::reflector::{DomObject, reflect_dom_object}; use dom::bindings::str::USVString; use dom::client::Client; @@ -22,7 +22,7 @@ use std::rc::Rc; #[dom_struct] pub struct ServiceWorkerContainer { eventtarget: EventTarget, - controller: MutNullableHeap<JS<ServiceWorker>>, + controller: MutNullableJS<ServiceWorker>, client: JS<Client> } diff --git a/components/script/dom/serviceworkerglobalscope.rs b/components/script/dom/serviceworkerglobalscope.rs index 4daf07fff20..8dd3da01671 100644 --- a/components/script/dom/serviceworkerglobalscope.rs +++ b/components/script/dom/serviceworkerglobalscope.rs @@ -28,13 +28,12 @@ use net_traits::request::{CredentialsMode, Destination, RequestInit, Type as Req use rand::random; use script_runtime::{CommonScriptMsg, StackRootTLS, get_reports, new_rt_and_cx, ScriptChan}; use script_traits::{TimerEvent, WorkerGlobalScopeInit, ScopeThings, ServiceWorkerMsg, WorkerScriptLoadOrigin}; +use servo_config::prefs::PREFS; use servo_url::ServoUrl; use std::sync::mpsc::{Receiver, RecvError, Select, Sender, channel}; use std::thread; use std::time::Duration; use style::thread_state::{self, IN_WORKER, SCRIPT}; -use util::prefs::PREFS; -use util::thread::spawn_named; /// Messages used to control service worker event loop pub enum ServiceWorkerScriptMsg { @@ -151,7 +150,7 @@ impl ServiceWorkerGlobalScope { .. } = scope_things; let serialized_worker_url = script_url.to_string(); - spawn_named(format!("ServiceWorker for {}", serialized_worker_url), move || { + thread::Builder::new().name(format!("ServiceWorker for {}", serialized_worker_url)).spawn(move || { thread_state::initialize(SCRIPT | IN_WORKER); let roots = RootCollection::new(); let _stack_roots_tls = StackRootTLS::new(&roots); @@ -202,11 +201,11 @@ impl ServiceWorkerGlobalScope { scope.execute_script(DOMString::from(source)); // Service workers are time limited - spawn_named("SWTimeoutThread".to_owned(), move || { + thread::Builder::new().name("SWTimeoutThread".to_owned()).spawn(move || { let sw_lifetime_timeout = PREFS.get("dom.serviceworker.timeout_seconds").as_u64().unwrap(); thread::sleep(Duration::new(sw_lifetime_timeout, 0)); let _ = timer_chan.send(()); - }); + }).expect("Thread spawning failed"); global.dispatch_activate(); let reporter_name = format!("service-worker-reporter-{}", random::<u64>()); @@ -217,7 +216,7 @@ impl ServiceWorkerGlobalScope { } } }, reporter_name, scope.script_chan(), CommonScriptMsg::CollectReports); - }); + }).expect("Thread spawning failed"); } fn handle_event(&self, event: MixedMessage) -> bool { diff --git a/components/script/dom/servoparser/html.rs b/components/script/dom/servoparser/html.rs index ac6330c3ca2..28f8735891e 100644 --- a/components/script/dom/servoparser/html.rs +++ b/components/script/dom/servoparser/html.rs @@ -34,6 +34,7 @@ use js::jsapi::JSTracer; use servo_url::ServoUrl; use std::borrow::Cow; use std::io::{self, Write}; +use style::context::QuirksMode as ServoQuirksMode; #[derive(HeapSizeOf, JSTraceable)] #[must_root] @@ -187,6 +188,11 @@ impl<'a> TreeSink for Sink { } fn set_quirks_mode(&mut self, mode: QuirksMode) { + let mode = match mode { + QuirksMode::Quirks => ServoQuirksMode::Quirks, + QuirksMode::LimitedQuirks => ServoQuirksMode::LimitedQuirks, + QuirksMode::NoQuirks => ServoQuirksMode::NoQuirks, + }; self.document.set_quirks_mode(mode); } diff --git a/components/script/dom/servoparser/mod.rs b/components/script/dom/servoparser/mod.rs index c6f4364925b..2f4f485be12 100644 --- a/components/script/dom/servoparser/mod.rs +++ b/components/script/dom/servoparser/mod.rs @@ -32,10 +32,10 @@ use network_listener::PreInvoke; use profile_traits::time::{TimerMetadata, TimerMetadataFrameType}; use profile_traits::time::{TimerMetadataReflowType, ProfilerCategory, profile}; use script_thread::ScriptThread; +use servo_config::resource_files::read_resource_file; use servo_url::ServoUrl; use std::cell::Cell; use std::mem; -use util::resource_files::read_resource_file; mod html; mod xml; diff --git a/components/script/dom/servoparser/xml.rs b/components/script/dom/servoparser/xml.rs index bcbfa6c4169..616263651c3 100644 --- a/components/script/dom/servoparser/xml.rs +++ b/components/script/dom/servoparser/xml.rs @@ -6,7 +6,7 @@ use dom::bindings::codegen::Bindings::NodeBinding::NodeMethods; use dom::bindings::inheritance::Castable; -use dom::bindings::js::{JS, MutNullableHeap, Root}; +use dom::bindings::js::{JS, MutNullableJS, Root}; use dom::bindings::str::DOMString; use dom::bindings::trace::JSTraceable; use dom::comment::Comment; @@ -97,7 +97,7 @@ unsafe impl JSTraceable for XmlTokenizer<XmlTreeBuilder<JS<Node>, Sink>> { struct Sink { base_url: ServoUrl, document: JS<Document>, - script: MutNullableHeap<JS<HTMLScriptElement>>, + script: MutNullableJS<HTMLScriptElement>, } impl<'a> TreeSink for Sink { diff --git a/components/script/dom/storageevent.rs b/components/script/dom/storageevent.rs index 172a7be9ed8..9778976dc0f 100644 --- a/components/script/dom/storageevent.rs +++ b/components/script/dom/storageevent.rs @@ -7,7 +7,7 @@ use dom::bindings::codegen::Bindings::StorageEventBinding; use dom::bindings::codegen::Bindings::StorageEventBinding::StorageEventMethods; use dom::bindings::error::Fallible; use dom::bindings::inheritance::Castable; -use dom::bindings::js::{JS, MutNullableHeap, Root, RootedReference}; +use dom::bindings::js::{MutNullableJS, Root, RootedReference}; use dom::bindings::reflector::reflect_dom_object; use dom::bindings::str::DOMString; use dom::event::{Event, EventBubbles, EventCancelable}; @@ -23,7 +23,7 @@ pub struct StorageEvent { old_value: Option<DOMString>, new_value: Option<DOMString>, url: DOMString, - storage_area: MutNullableHeap<JS<Storage>> + storage_area: MutNullableJS<Storage> } @@ -39,7 +39,7 @@ impl StorageEvent { old_value: old_value, new_value: new_value, url: url, - storage_area: MutNullableHeap::new(storage_area) + storage_area: MutNullableJS::new(storage_area) } } diff --git a/components/script/dom/svgelement.rs b/components/script/dom/svgelement.rs index c89bab166ee..3a18f965ecc 100644 --- a/components/script/dom/svgelement.rs +++ b/components/script/dom/svgelement.rs @@ -2,13 +2,10 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -use dom::bindings::codegen::Bindings::SVGElementBinding; use dom::bindings::inheritance::Castable; -use dom::bindings::js::Root; use dom::bindings::str::DOMString; use dom::document::Document; use dom::element::Element; -use dom::node::Node; use dom::virtualmethods::VirtualMethods; use html5ever_atoms::LocalName; use style::element_state::ElementState; @@ -19,11 +16,6 @@ pub struct SVGElement { } impl SVGElement { - pub fn new_inherited(tag_name: LocalName, prefix: Option<DOMString>, - document: &Document) -> SVGElement { - SVGElement::new_inherited_with_state(ElementState::empty(), tag_name, prefix, document) - } - pub fn new_inherited_with_state(state: ElementState, tag_name: LocalName, prefix: Option<DOMString>, document: &Document) -> SVGElement { @@ -32,13 +24,6 @@ impl SVGElement { Element::new_inherited_with_state(state, tag_name, ns!(svg), prefix, document), } } - - #[allow(unrooted_must_root)] - pub fn new(local_name: LocalName, prefix: Option<DOMString>, document: &Document) -> Root<SVGElement> { - Node::reflect_node(box SVGElement::new_inherited(local_name, prefix, document), - document, - SVGElementBinding::Wrap) - } } impl VirtualMethods for SVGElement { diff --git a/components/script/dom/svggraphicselement.rs b/components/script/dom/svggraphicselement.rs index 9435cc6d6b7..b8e8aced371 100644 --- a/components/script/dom/svggraphicselement.rs +++ b/components/script/dom/svggraphicselement.rs @@ -2,12 +2,9 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -use dom::bindings::codegen::Bindings::SVGGraphicsElementBinding; use dom::bindings::inheritance::Castable; -use dom::bindings::js::Root; use dom::bindings::str::DOMString; use dom::document::Document; -use dom::node::Node; use dom::svgelement::SVGElement; use dom::virtualmethods::VirtualMethods; use html5ever_atoms::LocalName; @@ -32,13 +29,6 @@ impl SVGGraphicsElement { SVGElement::new_inherited_with_state(state, tag_name, prefix, document), } } - - #[allow(unrooted_must_root)] - pub fn new(local_name: LocalName, prefix: Option<DOMString>, document: &Document) -> Root<SVGGraphicsElement> { - Node::reflect_node(box SVGGraphicsElement::new_inherited(local_name, prefix, document), - document, - SVGGraphicsElementBinding::Wrap) - } } impl VirtualMethods for SVGGraphicsElement { diff --git a/components/script/dom/testbinding.rs b/components/script/dom/testbinding.rs index 6b0c619749a..9f65d04bbfa 100644 --- a/components/script/dom/testbinding.rs +++ b/components/script/dom/testbinding.rs @@ -37,11 +37,11 @@ use js::jsapi::{HandleObject, HandleValue, JSContext, JSObject, JSAutoCompartmen use js::jsapi::{JS_NewPlainObject, JS_NewUint8ClampedArray}; use js::jsval::{JSVal, NullValue}; use script_traits::MsDuration; +use servo_config::prefs::PREFS; use std::borrow::ToOwned; use std::ptr; use std::rc::Rc; use timers::OneshotTimerCallback; -use util::prefs::PREFS; #[dom_struct] pub struct TestBinding { diff --git a/components/script/dom/touch.rs b/components/script/dom/touch.rs index 32eeb24b6e1..9b4e61788d3 100644 --- a/components/script/dom/touch.rs +++ b/components/script/dom/touch.rs @@ -4,7 +4,7 @@ use dom::bindings::codegen::Bindings::TouchBinding; use dom::bindings::codegen::Bindings::TouchBinding::TouchMethods; -use dom::bindings::js::{JS, MutHeap, Root}; +use dom::bindings::js::{MutJS, Root}; use dom::bindings::num::Finite; use dom::bindings::reflector::{Reflector, reflect_dom_object}; use dom::eventtarget::EventTarget; @@ -14,7 +14,7 @@ use dom::window::Window; pub struct Touch { reflector_: Reflector, identifier: i32, - target: MutHeap<JS<EventTarget>>, + target: MutJS<EventTarget>, screen_x: f64, screen_y: f64, client_x: f64, @@ -31,7 +31,7 @@ impl Touch { Touch { reflector_: Reflector::new(), identifier: identifier, - target: MutHeap::new(target), + target: MutJS::new(target), screen_x: *screen_x, screen_y: *screen_y, client_x: *client_x, diff --git a/components/script/dom/touchevent.rs b/components/script/dom/touchevent.rs index 9b4b3a250d5..f20dc4dc012 100644 --- a/components/script/dom/touchevent.rs +++ b/components/script/dom/touchevent.rs @@ -6,7 +6,7 @@ use dom::bindings::codegen::Bindings::TouchEventBinding; use dom::bindings::codegen::Bindings::TouchEventBinding::TouchEventMethods; use dom::bindings::codegen::Bindings::UIEventBinding::UIEventMethods; use dom::bindings::inheritance::Castable; -use dom::bindings::js::{JS, MutHeap, Root}; +use dom::bindings::js::{MutJS, Root}; use dom::bindings::reflector::reflect_dom_object; use dom::bindings::str::DOMString; use dom::event::{EventBubbles, EventCancelable}; @@ -18,9 +18,9 @@ use std::cell::Cell; #[dom_struct] pub struct TouchEvent { uievent: UIEvent, - touches: MutHeap<JS<TouchList>>, - target_touches: MutHeap<JS<TouchList>>, - changed_touches: MutHeap<JS<TouchList>>, + touches: MutJS<TouchList>, + target_touches: MutJS<TouchList>, + changed_touches: MutJS<TouchList>, alt_key: Cell<bool>, meta_key: Cell<bool>, ctrl_key: Cell<bool>, @@ -33,9 +33,9 @@ impl TouchEvent { target_touches: &TouchList) -> TouchEvent { TouchEvent { uievent: UIEvent::new_inherited(), - touches: MutHeap::new(touches), - target_touches: MutHeap::new(target_touches), - changed_touches: MutHeap::new(changed_touches), + touches: MutJS::new(touches), + target_touches: MutJS::new(target_touches), + changed_touches: MutJS::new(changed_touches), ctrl_key: Cell::new(false), shift_key: Cell::new(false), alt_key: Cell::new(false), diff --git a/components/script/dom/treewalker.rs b/components/script/dom/treewalker.rs index 1dc3d22f1cf..2a3367b3393 100644 --- a/components/script/dom/treewalker.rs +++ b/components/script/dom/treewalker.rs @@ -9,7 +9,7 @@ use dom::bindings::codegen::Bindings::NodeFilterBinding::NodeFilterConstants; use dom::bindings::codegen::Bindings::TreeWalkerBinding; use dom::bindings::codegen::Bindings::TreeWalkerBinding::TreeWalkerMethods; use dom::bindings::error::Fallible; -use dom::bindings::js::{JS, MutHeap}; +use dom::bindings::js::{JS, MutJS}; use dom::bindings::js::Root; use dom::bindings::reflector::{Reflector, reflect_dom_object}; use dom::document::Document; @@ -21,7 +21,7 @@ use std::rc::Rc; pub struct TreeWalker { reflector_: Reflector, root_node: JS<Node>, - current_node: MutHeap<JS<Node>>, + current_node: MutJS<Node>, what_to_show: u32, #[ignore_heap_size_of = "function pointers and Rc<T> are hard"] filter: Filter @@ -34,7 +34,7 @@ impl TreeWalker { TreeWalker { reflector_: Reflector::new(), root_node: JS::from_ref(root_node), - current_node: MutHeap::new(root_node), + current_node: MutJS::new(root_node), what_to_show: what_to_show, filter: filter } @@ -251,9 +251,6 @@ impl TreeWalkerMethods for TreeWalker { } } -type NodeAdvancer<'a> = Fn(&Node) -> Option<Root<Node>> + 'a; - - impl TreeWalker { // https://dom.spec.whatwg.org/#concept-traverse-children fn traverse_children<F, G>(&self, diff --git a/components/script/dom/uievent.rs b/components/script/dom/uievent.rs index 289088b2977..b8c09a48994 100644 --- a/components/script/dom/uievent.rs +++ b/components/script/dom/uievent.rs @@ -7,8 +7,7 @@ use dom::bindings::codegen::Bindings::UIEventBinding; use dom::bindings::codegen::Bindings::UIEventBinding::UIEventMethods; use dom::bindings::error::Fallible; use dom::bindings::inheritance::Castable; -use dom::bindings::js::{JS, MutNullableHeap, RootedReference}; -use dom::bindings::js::Root; +use dom::bindings::js::{MutNullableJS, Root, RootedReference}; use dom::bindings::reflector::reflect_dom_object; use dom::bindings::str::DOMString; use dom::event::{Event, EventBubbles, EventCancelable}; @@ -21,7 +20,7 @@ use std::default::Default; #[dom_struct] pub struct UIEvent { event: Event, - view: MutNullableHeap<JS<Window>>, + view: MutNullableJS<Window>, detail: Cell<i32> } diff --git a/components/script/dom/url.rs b/components/script/dom/url.rs index 2f3e3c3f923..cea4c898119 100644 --- a/components/script/dom/url.rs +++ b/components/script/dom/url.rs @@ -6,7 +6,7 @@ use dom::bindings::cell::DOMRefCell; use dom::bindings::codegen::Bindings::BlobBinding::BlobMethods; use dom::bindings::codegen::Bindings::URLBinding::{self, URLMethods}; use dom::bindings::error::{Error, ErrorResult, Fallible}; -use dom::bindings::js::{JS, MutNullableHeap, Root}; +use dom::bindings::js::{MutNullableJS, Root}; use dom::bindings::reflector::{DomObject, Reflector, reflect_dom_object}; use dom::bindings::str::{DOMString, USVString}; use dom::blob::Blob; @@ -30,7 +30,7 @@ pub struct URL { url: DOMRefCell<ServoUrl>, // https://url.spec.whatwg.org/#dom-url-searchparams - search_params: MutNullableHeap<JS<URLSearchParams>>, + search_params: MutNullableJS<URLSearchParams>, } impl URL { diff --git a/components/script/dom/userscripts.rs b/components/script/dom/userscripts.rs index a4051f44581..66758afaa98 100644 --- a/components/script/dom/userscripts.rs +++ b/components/script/dom/userscripts.rs @@ -9,11 +9,11 @@ use dom::bindings::js::RootedReference; use dom::bindings::str::DOMString; use dom::htmlheadelement::HTMLHeadElement; use dom::node::Node; +use servo_config::opts; +use servo_config::resource_files::resources_dir_path; use std::borrow::ToOwned; use std::fs::read_dir; use std::path::PathBuf; -use util::opts; -use util::resource_files::resources_dir_path; pub fn load_script(head: &HTMLHeadElement) { diff --git a/components/script/dom/validitystate.rs b/components/script/dom/validitystate.rs index 10801120871..f5b6501a82d 100755 --- a/components/script/dom/validitystate.rs +++ b/components/script/dom/validitystate.rs @@ -10,8 +10,8 @@ use dom::element::Element; use dom::window::Window; // https://html.spec.whatwg.org/multipage/#validity-states -#[derive(JSTraceable)] -#[derive(HeapSizeOf)] +#[derive(JSTraceable, HeapSizeOf)] +#[allow(dead_code)] pub enum ValidityStatus { ValueMissing, TypeMismatch, diff --git a/components/script/dom/webglframebuffer.rs b/components/script/dom/webglframebuffer.rs index 02a767958e2..2f18362122d 100644 --- a/components/script/dom/webglframebuffer.rs +++ b/components/script/dom/webglframebuffer.rs @@ -7,7 +7,7 @@ use canvas_traits::CanvasMsg; use dom::bindings::cell::DOMRefCell; use dom::bindings::codegen::Bindings::WebGLFramebufferBinding; use dom::bindings::codegen::Bindings::WebGLRenderingContextBinding::WebGLRenderingContextConstants as constants; -use dom::bindings::js::{HeapGCValue, JS, Root}; +use dom::bindings::js::{JS, Root}; use dom::bindings::reflector::reflect_dom_object; use dom::webglobject::WebGLObject; use dom::webglrenderbuffer::WebGLRenderbuffer; @@ -25,8 +25,6 @@ enum WebGLFramebufferAttachment { Texture { texture: JS<WebGLTexture>, level: i32 }, } -impl HeapGCValue for WebGLFramebufferAttachment {} - #[dom_struct] pub struct WebGLFramebuffer { webgl_object: WebGLObject, diff --git a/components/script/dom/webglobject.rs b/components/script/dom/webglobject.rs index 9c7382ce5b5..3ebbf8fb017 100644 --- a/components/script/dom/webglobject.rs +++ b/components/script/dom/webglobject.rs @@ -3,10 +3,7 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ // https://www.khronos.org/registry/webgl/specs/latest/1.0/webgl.idl -use dom::bindings::codegen::Bindings::WebGLObjectBinding; -use dom::bindings::js::Root; -use dom::bindings::reflector::{Reflector, reflect_dom_object}; -use dom::window::Window; +use dom::bindings::reflector::Reflector; #[dom_struct] pub struct WebGLObject { @@ -19,8 +16,4 @@ impl WebGLObject { reflector_: Reflector::new(), } } - - pub fn new(window: &Window) -> Root<WebGLObject> { - reflect_dom_object(box WebGLObject::new_inherited(), window, WebGLObjectBinding::Wrap) - } } diff --git a/components/script/dom/webglprogram.rs b/components/script/dom/webglprogram.rs index 3f18c0e313b..ad33fc2f22f 100644 --- a/components/script/dom/webglprogram.rs +++ b/components/script/dom/webglprogram.rs @@ -6,7 +6,7 @@ use canvas_traits::CanvasMsg; use dom::bindings::codegen::Bindings::WebGLProgramBinding; use dom::bindings::codegen::Bindings::WebGLRenderingContextBinding::WebGLRenderingContextConstants as constants; -use dom::bindings::js::{JS, MutNullableHeap, Root}; +use dom::bindings::js::{MutNullableJS, Root}; use dom::bindings::reflector::{DomObject, reflect_dom_object}; use dom::bindings::str::DOMString; use dom::webglactiveinfo::WebGLActiveInfo; @@ -27,8 +27,8 @@ pub struct WebGLProgram { is_deleted: Cell<bool>, link_called: Cell<bool>, linked: Cell<bool>, - fragment_shader: MutNullableHeap<JS<WebGLShader>>, - vertex_shader: MutNullableHeap<JS<WebGLShader>>, + fragment_shader: MutNullableJS<WebGLShader>, + vertex_shader: MutNullableJS<WebGLShader>, #[ignore_heap_size_of = "Defined in ipc-channel"] renderer: IpcSender<CanvasMsg>, } diff --git a/components/script/dom/webglrenderingcontext.rs b/components/script/dom/webglrenderingcontext.rs index 98b160095d5..81dfe804278 100644 --- a/components/script/dom/webglrenderingcontext.rs +++ b/components/script/dom/webglrenderingcontext.rs @@ -13,7 +13,7 @@ use dom::bindings::conversions::{array_buffer_to_vec, array_buffer_view_data, ar use dom::bindings::conversions::{array_buffer_view_to_vec, array_buffer_view_to_vec_checked}; use dom::bindings::error::{Error, Fallible}; use dom::bindings::inheritance::Castable; -use dom::bindings::js::{JS, LayoutJS, MutNullableHeap, Root}; +use dom::bindings::js::{JS, LayoutJS, MutNullableJS, Root}; use dom::bindings::reflector::{DomObject, Reflector, reflect_dom_object}; use dom::bindings::str::DOMString; use dom::event::{Event, EventBubbles, EventCancelable}; @@ -124,13 +124,13 @@ pub struct WebGLRenderingContext { #[ignore_heap_size_of = "Defined in webrender_traits"] last_error: Cell<Option<WebGLError>>, texture_unpacking_settings: Cell<TextureUnpacking>, - bound_framebuffer: MutNullableHeap<JS<WebGLFramebuffer>>, - bound_renderbuffer: MutNullableHeap<JS<WebGLRenderbuffer>>, - bound_texture_2d: MutNullableHeap<JS<WebGLTexture>>, - bound_texture_cube_map: MutNullableHeap<JS<WebGLTexture>>, - bound_buffer_array: MutNullableHeap<JS<WebGLBuffer>>, - bound_buffer_element_array: MutNullableHeap<JS<WebGLBuffer>>, - current_program: MutNullableHeap<JS<WebGLProgram>>, + bound_framebuffer: MutNullableJS<WebGLFramebuffer>, + bound_renderbuffer: MutNullableJS<WebGLRenderbuffer>, + bound_texture_2d: MutNullableJS<WebGLTexture>, + bound_texture_cube_map: MutNullableJS<WebGLTexture>, + bound_buffer_array: MutNullableJS<WebGLBuffer>, + bound_buffer_element_array: MutNullableJS<WebGLBuffer>, + current_program: MutNullableJS<WebGLProgram>, #[ignore_heap_size_of = "Because it's small"] current_vertex_attrib_0: Cell<(f32, f32, f32, f32)>, #[ignore_heap_size_of = "Because it's small"] @@ -159,13 +159,13 @@ impl WebGLRenderingContext { canvas: JS::from_ref(canvas), last_error: Cell::new(None), texture_unpacking_settings: Cell::new(CONVERT_COLORSPACE), - bound_framebuffer: MutNullableHeap::new(None), - bound_texture_2d: MutNullableHeap::new(None), - bound_texture_cube_map: MutNullableHeap::new(None), - bound_buffer_array: MutNullableHeap::new(None), - bound_buffer_element_array: MutNullableHeap::new(None), - bound_renderbuffer: MutNullableHeap::new(None), - current_program: MutNullableHeap::new(None), + bound_framebuffer: MutNullableJS::new(None), + bound_texture_2d: MutNullableJS::new(None), + bound_texture_cube_map: MutNullableJS::new(None), + bound_buffer_array: MutNullableJS::new(None), + bound_buffer_element_array: MutNullableJS::new(None), + bound_renderbuffer: MutNullableJS::new(None), + current_program: MutNullableJS::new(None), current_vertex_attrib_0: Cell::new((0f32, 0f32, 0f32, 1f32)), current_scissor: Cell::new((0, 0, size.width, size.height)), current_clear_color: Cell::new((0.0, 0.0, 0.0, 0.0)) @@ -2829,39 +2829,4 @@ impl UniformSetterType { UniformSetterType::FloatMat4 => 16, } } - - pub fn is_compatible_with(&self, gl_type: u32) -> bool { - gl_type == self.as_gl_constant() || match *self { - // Sampler uniform variables have an index value (the index of the - // texture), and as such they have to be set as ints - UniformSetterType::Int => gl_type == constants::SAMPLER_2D || - gl_type == constants::SAMPLER_CUBE, - // Don't ask me why, but it seems we must allow setting bool - // uniforms with uniform1f. - // - // See the WebGL conformance test - // conformance/uniforms/gl-uniform-bool.html - UniformSetterType::Float => gl_type == constants::BOOL, - UniformSetterType::FloatVec2 => gl_type == constants::BOOL_VEC2, - UniformSetterType::FloatVec3 => gl_type == constants::BOOL_VEC3, - UniformSetterType::FloatVec4 => gl_type == constants::BOOL_VEC4, - _ => false, - } - } - - fn as_gl_constant(&self) -> u32 { - match *self { - UniformSetterType::Int => constants::INT, - UniformSetterType::IntVec2 => constants::INT_VEC2, - UniformSetterType::IntVec3 => constants::INT_VEC3, - UniformSetterType::IntVec4 => constants::INT_VEC4, - UniformSetterType::Float => constants::FLOAT, - UniformSetterType::FloatVec2 => constants::FLOAT_VEC2, - UniformSetterType::FloatVec3 => constants::FLOAT_VEC3, - UniformSetterType::FloatVec4 => constants::FLOAT_VEC4, - UniformSetterType::FloatMat2 => constants::FLOAT_MAT2, - UniformSetterType::FloatMat3 => constants::FLOAT_MAT3, - UniformSetterType::FloatMat4 => constants::FLOAT_MAT4, - } - } } diff --git a/components/script/dom/webglshaderprecisionformat.rs b/components/script/dom/webglshaderprecisionformat.rs index c0f954c8d4d..87ab7490e3a 100644 --- a/components/script/dom/webglshaderprecisionformat.rs +++ b/components/script/dom/webglshaderprecisionformat.rs @@ -2,6 +2,8 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ +#![allow(dead_code)] + // https://www.khronos.org/registry/webgl/specs/latest/1.0/webgl.idl use dom::bindings::codegen::Bindings::WebGLShaderPrecisionFormatBinding; use dom::bindings::codegen::Bindings::WebGLShaderPrecisionFormatBinding::WebGLShaderPrecisionFormatMethods; diff --git a/components/script/dom/webidls/BluetoothAdvertisingData.webidl b/components/script/dom/webidls/BluetoothAdvertisingEvent.webidl index 27583a95e4e..2bb88b6f9de 100644 --- a/components/script/dom/webidls/BluetoothAdvertisingData.webidl +++ b/components/script/dom/webidls/BluetoothAdvertisingEvent.webidl @@ -2,21 +2,32 @@ * 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/. */ -//https://webbluetoothcg.github.io/web-bluetooth/#bluetoothadvertisingdata +// https://webbluetoothcg.github.io/web-bluetooth/#advertising-events /*interface BluetoothManufacturerDataMap { readonly maplike<unsigned short, DataView>; }; - interface BluetoothServiceDataMap { readonly maplike<UUID, DataView>; };*/ - -[Pref="dom.bluetooth.enabled"] -interface BluetoothAdvertisingData { +[Pref="dom.bluetooth.enabled", Constructor(DOMString type, BluetoothAdvertisingEventInit init)] +interface BluetoothAdvertisingEvent : Event { + readonly attribute BluetoothDevice device; + // readonly attribute FrozenArray<UUID> uuids; + readonly attribute DOMString? name; readonly attribute unsigned short? appearance; readonly attribute byte? txPower; readonly attribute byte? rssi; // readonly attribute BluetoothManufacturerDataMap manufacturerData; // readonly attribute BluetoothServiceDataMap serviceData; }; +dictionary BluetoothAdvertisingEventInit : EventInit { + required BluetoothDevice device; + // sequence<(DOMString or unsigned long)> uuids; + DOMString name; + unsigned short appearance; + byte txPower; + byte rssi; + // Map manufacturerData; + // Map serviceData; +}; diff --git a/components/script/dom/webidls/BluetoothDevice.webidl b/components/script/dom/webidls/BluetoothDevice.webidl index 0e7843db109..a68049dd08b 100644 --- a/components/script/dom/webidls/BluetoothDevice.webidl +++ b/components/script/dom/webidls/BluetoothDevice.webidl @@ -8,13 +8,11 @@ interface BluetoothDevice : EventTarget { readonly attribute DOMString id; readonly attribute DOMString? name; - // TODO: remove this after BluetoothAdvertisingEvent implemented. - readonly attribute BluetoothAdvertisingData adData; readonly attribute BluetoothRemoteGATTServer gatt; - // Promise<void> watchAdvertisements(); - // void unwatchAdvertisements(); - // readonly attribute boolean watchingAdvertisements; + Promise<void> watchAdvertisements(); + void unwatchAdvertisements(); + readonly attribute boolean watchingAdvertisements; }; [NoInterfaceObject] diff --git a/components/script/dom/webidls/CSSGroupingRule.webidl b/components/script/dom/webidls/CSSGroupingRule.webidl index 9f8347a17d5..41ac5e8dd57 100644 --- a/components/script/dom/webidls/CSSGroupingRule.webidl +++ b/components/script/dom/webidls/CSSGroupingRule.webidl @@ -3,7 +3,7 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ // https://drafts.csswg.org/cssom/#the-cssgroupingrule-interface -[Exposed=Window] +[Abstract, Exposed=Window] interface CSSGroupingRule : CSSRule { [SameObject] readonly attribute CSSRuleList cssRules; [Throws] unsigned long insertRule(DOMString rule, unsigned long index); diff --git a/components/script/dom/webidls/CSSImportRule.webidl b/components/script/dom/webidls/CSSImportRule.webidl new file mode 100644 index 00000000000..b8131a7bb87 --- /dev/null +++ b/components/script/dom/webidls/CSSImportRule.webidl @@ -0,0 +1,11 @@ +/* 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/. */ + +// https://drafts.csswg.org/cssom/#cssimportrule +[Exposed=Window] +interface CSSImportRule : CSSRule { + // readonly attribute DOMString href; + // [SameObject, PutForwards=mediaText] readonly attribute MediaList media; + // [SameObject] readonly attribute CSSStyleSheet styleSheet; +}; diff --git a/components/script/dom/webidls/CSSKeyframesRule.webidl b/components/script/dom/webidls/CSSKeyframesRule.webidl index 34d45e1a357..fc31fc62406 100644 --- a/components/script/dom/webidls/CSSKeyframesRule.webidl +++ b/components/script/dom/webidls/CSSKeyframesRule.webidl @@ -5,7 +5,8 @@ // https://drafts.csswg.org/css-animations/#interface-csskeyframesrule [Exposed=Window] interface CSSKeyframesRule : CSSRule { - // attribute DOMString name; + [SetterThrows] + attribute DOMString name; readonly attribute CSSRuleList cssRules; void appendRule(DOMString rule); diff --git a/components/script/dom/webidls/CSSRule.webidl b/components/script/dom/webidls/CSSRule.webidl index 462943430e6..cda06ab1254 100644 --- a/components/script/dom/webidls/CSSRule.webidl +++ b/components/script/dom/webidls/CSSRule.webidl @@ -3,7 +3,7 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ // https://drafts.csswg.org/cssom/#the-cssrule-interface -[Exposed=Window] +[Abstract, Exposed=Window] interface CSSRule { const unsigned short STYLE_RULE = 1; const unsigned short CHARSET_RULE = 2; // historical diff --git a/components/script/dom/webidls/CSSStyleDeclaration.webidl b/components/script/dom/webidls/CSSStyleDeclaration.webidl index 4314eca74f9..c32e9afddfc 100644 --- a/components/script/dom/webidls/CSSStyleDeclaration.webidl +++ b/components/script/dom/webidls/CSSStyleDeclaration.webidl @@ -38,6 +38,10 @@ partial interface CSSStyleDeclaration { [SetterThrows, TreatNullAs=EmptyString] attribute DOMString background-color; [SetterThrows, TreatNullAs=EmptyString] attribute DOMString backgroundPosition; [SetterThrows, TreatNullAs=EmptyString] attribute DOMString background-position; + [SetterThrows, TreatNullAs=EmptyString] attribute DOMString backgroundPositionX; + [SetterThrows, TreatNullAs=EmptyString] attribute DOMString background-position-x; + [SetterThrows, TreatNullAs=EmptyString] attribute DOMString backgroundPositionY; + [SetterThrows, TreatNullAs=EmptyString] attribute DOMString background-position-y; [SetterThrows, TreatNullAs=EmptyString] attribute DOMString backgroundRepeat; [SetterThrows, TreatNullAs=EmptyString] attribute DOMString background-repeat; [SetterThrows, TreatNullAs=EmptyString] attribute DOMString backgroundImage; diff --git a/components/script/dom/webidls/CSSStyleRule.webidl b/components/script/dom/webidls/CSSStyleRule.webidl index faee525e7ff..145650a916c 100644 --- a/components/script/dom/webidls/CSSStyleRule.webidl +++ b/components/script/dom/webidls/CSSStyleRule.webidl @@ -6,5 +6,5 @@ [Exposed=Window] interface CSSStyleRule : CSSRule { // attribute DOMString selectorText; - // [SameObject, PutForwards=cssText] readonly attribute CSSStyleDeclaration style; + [SameObject, PutForwards=cssText] readonly attribute CSSStyleDeclaration style; }; diff --git a/components/script/dom/webidls/MediaQueryListEvent.webidl b/components/script/dom/webidls/MediaQueryListEvent.webidl new file mode 100644 index 00000000000..877ca17b60b --- /dev/null +++ b/components/script/dom/webidls/MediaQueryListEvent.webidl @@ -0,0 +1,15 @@ +/* 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/. */ + +// https://drafts.csswg.org/cssom-view/#dom-mediaquerylistevent-mediaquerylistevent +[Constructor(DOMString type, optional MediaQueryListEventInit eventInitDict), Exposed=(Window)] +interface MediaQueryListEvent : Event { + readonly attribute DOMString media; + readonly attribute boolean matches; +}; + +dictionary MediaQueryListEventInit : EventInit { + DOMString media = ""; + boolean matches = false; +}; diff --git a/components/script/dom/webidls/SVGElement.webidl b/components/script/dom/webidls/SVGElement.webidl index 02f673a420e..529e9e67f06 100644 --- a/components/script/dom/webidls/SVGElement.webidl +++ b/components/script/dom/webidls/SVGElement.webidl @@ -3,7 +3,7 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ // https://svgwg.org/svg2-draft/types.html#InterfaceSVGElement -[Pref="dom.svg.enabled"] +[Abstract, Pref="dom.svg.enabled"] interface SVGElement : Element { //[SameObject] readonly attribute SVGAnimatedString className; diff --git a/components/script/dom/webidls/SVGGraphicsElement.webidl b/components/script/dom/webidls/SVGGraphicsElement.webidl index d8f90e639ea..cf6c315d917 100644 --- a/components/script/dom/webidls/SVGGraphicsElement.webidl +++ b/components/script/dom/webidls/SVGGraphicsElement.webidl @@ -3,7 +3,6 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ // https://svgwg.org/svg2-draft/types.html#InterfaceSVGGraphicsElement -[Pref="dom.svg.enabled"] //dictionary SVGBoundingBoxOptions { // boolean fill = true; // boolean stroke = false; @@ -11,6 +10,7 @@ // boolean clipped = false; //}; +[Abstract, Pref="dom.svg.enabled"] interface SVGGraphicsElement : SVGElement { //[SameObject] readonly attribute SVGAnimatedTransformList transform; diff --git a/components/script/dom/webidls/WebGLObject.webidl b/components/script/dom/webidls/WebGLObject.webidl index 3ac7514830a..3e8f1f54cca 100644 --- a/components/script/dom/webidls/WebGLObject.webidl +++ b/components/script/dom/webidls/WebGLObject.webidl @@ -6,6 +6,6 @@ // https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.3 // -[Exposed=Window] +[Abstract, Exposed=Window] interface WebGLObject { }; diff --git a/components/script/dom/websocket.rs b/components/script/dom/websocket.rs index 0953f7898a2..b2057e7effe 100644 --- a/components/script/dom/websocket.rs +++ b/components/script/dom/websocket.rs @@ -22,6 +22,8 @@ use dom::eventtarget::EventTarget; use dom::globalscope::GlobalScope; use dom::messageevent::MessageEvent; use dom::urlhelper::UrlHelper; +use hyper; +use hyper_serde::Serde; use ipc_channel::ipc::{self, IpcReceiver, IpcSender}; use js::jsapi::{JS_GetArrayBufferData, JS_NewArrayBuffer}; use js::jsapi::JSAutoCompartment; @@ -496,13 +498,10 @@ impl Runnable for ConnectionEstablishedTask { }; // Step 5: Cookies. - if let Some(cookies) = self.headers.get_raw("set-cookie") { - for cookie in cookies.iter() { - if let Ok(cookie_value) = String::from_utf8(cookie.clone()) { - let _ = ws.global().core_resource_thread().send( - SetCookiesForUrl(ws.url.clone(), cookie_value, HTTP)); - } - } + if let Some(cookies) = self.headers.get::<hyper::header::SetCookie>() { + let cookies = cookies.iter().map(|c| Serde(c.clone())).collect(); + let _ = ws.global().core_resource_thread().send( + SetCookiesForUrl(ws.url.clone(), cookies, HTTP)); } // Step 6. diff --git a/components/script/dom/window.rs b/components/script/dom/window.rs index 282979dc7bf..7dd8d71e9c8 100644 --- a/components/script/dom/window.rs +++ b/components/script/dom/window.rs @@ -19,7 +19,7 @@ use dom::bindings::codegen::Bindings::WindowBinding::{ScrollBehavior, ScrollToOp use dom::bindings::codegen::UnionTypes::RequestOrUSVString; use dom::bindings::error::{Error, ErrorResult, Fallible}; use dom::bindings::inheritance::Castable; -use dom::bindings::js::{JS, MutNullableHeap, Root}; +use dom::bindings::js::{JS, MutNullableJS, Root}; use dom::bindings::num::Finite; use dom::bindings::refcounted::Trusted; use dom::bindings::reflector::DomObject; @@ -28,7 +28,7 @@ use dom::bindings::structuredclone::StructuredCloneData; use dom::bindings::utils::{GlobalStaticData, WindowProxyHandler}; use dom::browsingcontext::BrowsingContext; use dom::crypto::Crypto; -use dom::cssstyledeclaration::{CSSModificationAccess, CSSStyleDeclaration}; +use dom::cssstyledeclaration::{CSSModificationAccess, CSSStyleDeclaration, CSSStyleOwner}; use dom::document::{AnimationFrameCallback, Document}; use dom::element::Element; use dom::event::Event; @@ -77,6 +77,9 @@ use script_traits::{DocumentState, TimerEvent, TimerEventId}; use script_traits::{ScriptMsg as ConstellationMsg, TimerEventRequest, WindowSizeData, WindowSizeType}; use script_traits::webdriver_msg::{WebDriverJSError, WebDriverJSResult}; use servo_atoms::Atom; +use servo_config::opts; +use servo_config::prefs::PREFS; +use servo_geometry::{f32_rect_to_au_rect, max_rect}; use servo_url::ServoUrl; use std::ascii::AsciiExt; use std::borrow::ToOwned; @@ -92,6 +95,7 @@ use std::sync::mpsc::TryRecvError::{Disconnected, Empty}; use style::context::ReflowGoal; use style::error_reporting::ParseErrorReporter; use style::media_queries; +use style::properties::PropertyId; use style::properties::longhands::overflow_x; use style::selector_parser::PseudoElement; use style::str::HTML_SPACE_CHARACTERS; @@ -105,9 +109,6 @@ use timers::{IsInterval, TimerCallback}; #[cfg(any(target_os = "macos", target_os = "linux", target_os = "windows"))] use tinyfiledialogs::{self, MessageBoxIcon}; use url::Position; -use util::geometry::{self, max_rect}; -use util::opts; -use util::prefs::PREFS; use webdriver_handlers::jsval_to_webdriver; /// Current state of the window object @@ -141,8 +142,6 @@ pub enum ReflowReason { ElementStateChanged, } -pub type ScrollPoint = Point2D<Au>; - #[dom_struct] pub struct Window { globalscope: GlobalScope, @@ -158,19 +157,19 @@ pub struct Window { history_traversal_task_source: HistoryTraversalTaskSource, #[ignore_heap_size_of = "task sources are hard"] file_reading_task_source: FileReadingTaskSource, - navigator: MutNullableHeap<JS<Navigator>>, + navigator: MutNullableJS<Navigator>, #[ignore_heap_size_of = "channels are hard"] image_cache_thread: ImageCacheThread, #[ignore_heap_size_of = "channels are hard"] image_cache_chan: ImageCacheChan, - browsing_context: MutNullableHeap<JS<BrowsingContext>>, - history: MutNullableHeap<JS<History>>, - performance: MutNullableHeap<JS<Performance>>, + browsing_context: MutNullableJS<BrowsingContext>, + history: MutNullableJS<History>, + performance: MutNullableJS<Performance>, navigation_start: u64, navigation_start_precise: f64, - screen: MutNullableHeap<JS<Screen>>, - session_storage: MutNullableHeap<JS<Storage>>, - local_storage: MutNullableHeap<JS<Storage>>, + screen: MutNullableJS<Screen>, + session_storage: MutNullableJS<Storage>, + local_storage: MutNullableJS<Storage>, status: DOMRefCell<DOMString>, /// For sending timeline markers. Will be ignored if @@ -240,7 +239,7 @@ pub struct Window { /// All the MediaQueryLists we need to update media_query_lists: WeakMediaQueryListVec, - test_runner: MutNullableHeap<JS<TestRunner>>, + test_runner: MutNullableJS<TestRunner>, } impl Window { @@ -700,7 +699,10 @@ impl WindowMethods for Window { }; // Step 5. - CSSStyleDeclaration::new(self, element, pseudo, CSSModificationAccess::Readonly) + CSSStyleDeclaration::new(self, + CSSStyleOwner::Element(JS::from_ref(element)), + pseudo, + CSSModificationAccess::Readonly) } // https://drafts.csswg.org/cssom-view/#dom-window-innerheight @@ -1295,16 +1297,16 @@ impl Window { } pub fn resolved_style_query(&self, - element: TrustedNodeAddress, - pseudo: Option<PseudoElement>, - property: &Atom) -> Option<DOMString> { + element: TrustedNodeAddress, + pseudo: Option<PseudoElement>, + property: PropertyId) -> DOMString { if !self.reflow(ReflowGoal::ForScriptQuery, - ReflowQueryType::ResolvedStyleQuery(element, pseudo, property.clone()), + ReflowQueryType::ResolvedStyleQuery(element, pseudo, property), ReflowReason::Query) { - return None; + return DOMString::new(); } let ResolvedStyleResponse(resolved) = self.layout_rpc.resolved_style(); - resolved.map(DOMString::from) + DOMString::from(resolved) } pub fn offset_parent_query(&self, node: TrustedNodeAddress) -> (Option<Root<Element>>, Rect<Au>) { @@ -1412,13 +1414,13 @@ impl Window { } pub fn set_page_clip_rect_with_new_viewport(&self, viewport: Rect<f32>) -> bool { - let rect = geometry::f32_rect_to_au_rect(viewport.clone()); + let rect = f32_rect_to_au_rect(viewport.clone()); self.current_viewport.set(rect); // We use a clipping rectangle that is five times the size of the of the viewport, // so that we don't collect display list items for areas too far outside the viewport, // but also don't trigger reflows every time the viewport changes. static VIEWPORT_EXPANSION: f32 = 2.0; // 2 lengths on each side plus original length is 5 total. - let proposed_clip_rect = geometry::f32_rect_to_au_rect( + let proposed_clip_rect = f32_rect_to_au_rect( viewport.inflate(viewport.size.width * VIEWPORT_EXPANSION, viewport.size.height * VIEWPORT_EXPANSION)); let clip_rect = self.page_clip_rect.get(); diff --git a/components/script/dom/workerglobalscope.rs b/components/script/dom/workerglobalscope.rs index 430757bce53..221d60c1570 100644 --- a/components/script/dom/workerglobalscope.rs +++ b/components/script/dom/workerglobalscope.rs @@ -10,7 +10,7 @@ use dom::bindings::codegen::Bindings::WorkerGlobalScopeBinding::WorkerGlobalScop use dom::bindings::codegen::UnionTypes::RequestOrUSVString; use dom::bindings::error::{Error, ErrorResult, Fallible, report_pending_exception}; use dom::bindings::inheritance::Castable; -use dom::bindings::js::{JS, MutNullableHeap, Root}; +use dom::bindings::js::{MutNullableJS, Root}; use dom::bindings::refcounted::Trusted; use dom::bindings::reflector::DomObject; use dom::bindings::str::DOMString; @@ -73,8 +73,8 @@ pub struct WorkerGlobalScope { closing: Option<Arc<AtomicBool>>, #[ignore_heap_size_of = "Defined in js"] runtime: Runtime, - location: MutNullableHeap<JS<WorkerLocation>>, - navigator: MutNullableHeap<JS<WorkerNavigator>>, + location: MutNullableJS<WorkerLocation>, + navigator: MutNullableJS<WorkerNavigator>, #[ignore_heap_size_of = "Defined in ipc-channel"] /// Optional `IpcSender` for sending the `DevtoolScriptControlMsg` diff --git a/components/script/dom/xmlhttprequest.rs b/components/script/dom/xmlhttprequest.rs index 2e1fcd465e8..f676eac3b64 100644 --- a/components/script/dom/xmlhttprequest.rs +++ b/components/script/dom/xmlhttprequest.rs @@ -14,7 +14,7 @@ use dom::bindings::codegen::Bindings::XMLHttpRequestBinding::XMLHttpRequestRespo use dom::bindings::conversions::ToJSValConvertible; use dom::bindings::error::{Error, ErrorResult, Fallible}; use dom::bindings::inheritance::Castable; -use dom::bindings::js::{JS, MutHeapJSVal, MutNullableHeap, Root}; +use dom::bindings::js::{JS, MutHeapJSVal, MutNullableJS, Root}; use dom::bindings::refcounted::Trusted; use dom::bindings::reflector::{DomObject, reflect_dom_object}; use dom::bindings::str::{ByteString, DOMString, USVString, is_token}; @@ -53,6 +53,7 @@ use net_traits::request::{CredentialsMode, Destination, RequestInit, RequestMode use net_traits::trim_http_whitespace; use network_listener::{NetworkListener, PreInvoke}; use servo_atoms::Atom; +use servo_config::prefs::PREFS; use servo_url::ServoUrl; use std::ascii::AsciiExt; use std::borrow::ToOwned; @@ -64,7 +65,6 @@ use task_source::networking::NetworkingTaskSource; use time; use timers::{OneshotTimerCallback, OneshotTimerHandle}; use url::Position; -use util::prefs::PREFS; #[derive(JSTraceable, PartialEq, Copy, Clone, HeapSizeOf)] enum XMLHttpRequestState { @@ -122,8 +122,8 @@ pub struct XMLHttpRequest { status_text: DOMRefCell<ByteString>, response: DOMRefCell<ByteString>, response_type: Cell<XMLHttpRequestResponseType>, - response_xml: MutNullableHeap<JS<Document>>, - response_blob: MutNullableHeap<JS<Blob>>, + response_xml: MutNullableJS<Document>, + response_blob: MutNullableJS<Blob>, #[ignore_heap_size_of = "Defined in rust-mozjs"] response_json: MutHeapJSVal, #[ignore_heap_size_of = "Defined in hyper"] diff --git a/components/script/layout_wrapper.rs b/components/script/layout_wrapper.rs index 290ebeb2312..e6c38aa1fb3 100644 --- a/components/script/layout_wrapper.rs +++ b/components/script/layout_wrapper.rs @@ -61,7 +61,7 @@ use std::sync::atomic::Ordering; use style::atomic_refcell::AtomicRefCell; use style::attr::AttrValue; use style::computed_values::display; -use style::context::SharedStyleContext; +use style::context::{QuirksMode, SharedStyleContext}; use style::data::ElementData; use style::dom::{LayoutIterator, NodeInfo, OpaqueNode, PresentationalHintsSynthetizer, TElement, TNode}; use style::dom::UnsafeNode; @@ -86,7 +86,11 @@ impl<'ln> Debug for ServoLayoutNode<'ln> { if let Some(el) = self.as_element() { el.fmt(f) } else { - write!(f, "{:?} ({:#x})", self.type_id(), self.opaque().0) + if self.is_text_node() { + write!(f, "<text node> ({:#x})", self.opaque().0) + } else { + write!(f, "<non-text node> ({:#x})", self.opaque().0) + } } } } @@ -156,15 +160,6 @@ impl<'ln> TNode for ServoLayoutNode<'ln> { transmute(node) } - fn dump(self) { - self.dump_indent(0); - } - - fn dump_style(self) { - println!("\nDOM with computed styles:"); - self.dump_style_indent(0); - } - fn children(self) -> LayoutIterator<ServoChildrenIterator<'ln>> { LayoutIterator(ServoChildrenIterator { current: self.first_child(), @@ -290,54 +285,6 @@ impl<'le> GetLayoutData for ServoThreadSafeLayoutElement<'le> { } impl<'ln> ServoLayoutNode<'ln> { - fn dump_indent(self, indent: u32) { - let mut s = String::new(); - for _ in 0..indent { - s.push_str(" "); - } - - s.push_str(&self.debug_str()); - println!("{}", s); - - for kid in self.children() { - kid.dump_indent(indent + 1); - } - } - - fn dump_style_indent(self, indent: u32) { - if self.is_element() { - let mut s = String::new(); - for _ in 0..indent { - s.push_str(" "); - } - s.push_str(&self.debug_style_str()); - println!("{}", s); - } - - for kid in self.children() { - kid.dump_style_indent(indent + 1); - } - } - - fn debug_str(self) -> String { - format!("{:?}: dirty_descendants={}", - self.script_type_id(), - self.as_element().map_or(false, |el| el.has_dirty_descendants())) - } - - fn debug_style_str(self) -> String { - let maybe_element = self.as_element(); - let maybe_data = match maybe_element { - Some(ref el) => el.borrow_data(), - None => None, - }; - if let Some(data) = maybe_data { - format!("{:?}: {:?}", self.script_type_id(), &*data) - } else { - format!("{:?}: style_data=None", self.script_type_id()) - } - } - /// Returns the interior of this node as a `LayoutJS`. This is highly unsafe for layout to /// call and as such is marked `unsafe`. pub unsafe fn get_jsmanaged(&self) -> &LayoutJS<Node> { @@ -374,6 +321,10 @@ impl<'ld> ServoLayoutDocument<'ld> { unsafe { self.document.will_paint(); } } + pub fn quirks_mode(&self) -> QuirksMode { + unsafe { self.document.quirks_mode() } + } + pub fn from_layout_js(doc: LayoutJS<Document>) -> ServoLayoutDocument<'ld> { ServoLayoutDocument { document: doc, @@ -816,7 +767,7 @@ impl<'ln> ThreadSafeLayoutNode for ServoThreadSafeLayoutNode<'ln> { debug_assert!(self.is_text_node()); let parent = self.node.parent_node().unwrap().as_element().unwrap(); let parent_data = parent.get_data().unwrap().borrow(); - parent_data.current_styles().primary.values.clone() + parent_data.styles().primary.values.clone() } fn debug_id(self) -> usize { diff --git a/components/script/lib.rs b/components/script/lib.rs index e80e9553956..52c0cd6f358 100644 --- a/components/script/lib.rs +++ b/components/script/lib.rs @@ -83,6 +83,8 @@ extern crate script_traits; extern crate selectors; extern crate serde; #[macro_use] extern crate servo_atoms; +#[macro_use] extern crate servo_config; +extern crate servo_geometry; extern crate servo_url; extern crate smallvec; #[macro_use] @@ -93,7 +95,6 @@ extern crate time; extern crate tinyfiledialogs; extern crate url; #[macro_use] -extern crate util; extern crate uuid; extern crate webrender_traits; extern crate websocket; @@ -104,7 +105,7 @@ pub mod clipboard_provider; mod devtools; pub mod document_loader; #[macro_use] -pub mod dom; +mod dom; pub mod fetch; pub mod layout_wrapper; mod mem; @@ -115,7 +116,9 @@ pub mod script_runtime; pub mod script_thread; mod serviceworker_manager; mod serviceworkerjob; +mod stylesheet_loader; mod task_source; +pub mod test; pub mod textinput; mod timers; mod unpremultiplytable; diff --git a/components/script/network_listener.rs b/components/script/network_listener.rs index 5a96317fb18..fc7b4635756 100644 --- a/components/script/network_listener.rs +++ b/components/script/network_listener.rs @@ -2,7 +2,6 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -use bluetooth_traits::{BluetoothResponseListener, BluetoothResponseResult}; use net_traits::{Action, FetchResponseListener, FetchResponseMsg}; use script_thread::{Runnable, RunnableWrapper}; use std::sync::{Arc, Mutex}; @@ -41,13 +40,6 @@ impl<Listener: FetchResponseListener + PreInvoke + Send + 'static> NetworkListen } } -// helps type inference -impl<Listener: BluetoothResponseListener + PreInvoke + Send + 'static> NetworkListener<Listener> { - pub fn notify_response(&self, action: BluetoothResponseResult) { - self.notify(action); - } -} - /// A gating mechanism that runs before invoking the runnable on the target thread. /// If the `should_invoke` method returns false, the runnable is discarded without /// being invoked. diff --git a/components/script/script_runtime.rs b/components/script/script_runtime.rs index 00e7d3a198e..a21f96c5890 100644 --- a/components/script/script_runtime.rs +++ b/components/script/script_runtime.rs @@ -25,6 +25,8 @@ use js::rust::Runtime; use msg::constellation_msg::PipelineId; use profile_traits::mem::{Report, ReportKind, ReportsChan}; use script_thread::{Runnable, STACK_ROOTS, trace_thread}; +use servo_config::opts; +use servo_config::prefs::PREFS; use std::cell::Cell; use std::io::{Write, stdout}; use std::marker::PhantomData; @@ -35,8 +37,6 @@ use std::ptr; use std::rc::Rc; use style::thread_state; use time::{Tm, now}; -use util::opts; -use util::prefs::PREFS; /// Common messages used to control the event loops in both the script and the worker pub enum CommonScriptMsg { diff --git a/components/script/script_thread.rs b/components/script/script_thread.rs index f55d9279138..447b6775bdc 100644 --- a/components/script/script_thread.rs +++ b/components/script/script_thread.rs @@ -32,7 +32,7 @@ use dom::bindings::codegen::Bindings::TransitionEventBinding::TransitionEventIni use dom::bindings::codegen::Bindings::WindowBinding::WindowMethods; use dom::bindings::conversions::{ConversionResult, FromJSValConvertible, StringificationBehavior}; use dom::bindings::inheritance::Castable; -use dom::bindings::js::{JS, MutNullableHeap, Root, RootCollection}; +use dom::bindings::js::{JS, MutNullableJS, Root, RootCollection}; use dom::bindings::js::{RootCollectionPtr, RootedReference}; use dom::bindings::num::Finite; use dom::bindings::refcounted::Trusted; @@ -91,6 +91,7 @@ use script_traits::CompositorEvent::{KeyEvent, MouseButtonEvent, MouseMoveEvent, use script_traits::CompositorEvent::{TouchEvent, TouchpadPressureEvent}; use script_traits::webdriver_msg::WebDriverScriptCommand; use serviceworkerjob::{Job, JobQueue, AsyncJobHandler, FinishJobHandler, InvokeType, SettleType}; +use servo_config::opts; use servo_url::ServoUrl; use std::cell::Cell; use std::collections::{hash_map, HashMap, HashSet}; @@ -101,6 +102,7 @@ use std::result::Result; use std::sync::{Arc, Mutex}; use std::sync::atomic::{AtomicBool, Ordering}; use std::sync::mpsc::{Receiver, Select, Sender, channel}; +use std::thread; use style::context::ReflowGoal; use style::dom::{TNode, UnsafeNode}; use style::thread_state; @@ -112,8 +114,6 @@ use task_source::networking::NetworkingTaskSource; use task_source::user_interaction::{UserInteractionTask, UserInteractionTaskSource}; use time::Tm; use url::Position; -use util::opts; -use util::thread; use webdriver_handlers; thread_local!(pub static STACK_ROOTS: Cell<Option<RootCollectionPtr>> = Cell::new(None)); @@ -461,7 +461,7 @@ pub struct ScriptThread { js_runtime: Rc<Runtime>, /// The topmost element over the mouse. - topmost_mouse_over_target: MutNullableHeap<JS<Element>>, + topmost_mouse_over_target: MutNullableJS<Element>, /// List of pipelines that have been owned and closed by this script thread. closed_pipelines: DOMRefCell<HashSet<PipelineId>>, @@ -498,13 +498,10 @@ impl<'a> ScriptMemoryFailsafe<'a> { impl<'a> Drop for ScriptMemoryFailsafe<'a> { #[allow(unrooted_must_root)] fn drop(&mut self) { - match self.owner { - Some(owner) => { - for (_, document) in owner.documents.borrow().iter() { - document.window().clear_js_runtime_for_script_deallocation(); - } + if let Some(owner) = self.owner { + for (_, document) in owner.documents.borrow().iter() { + document.window().clear_js_runtime_for_script_deallocation(); } - None => (), } } } @@ -519,8 +516,7 @@ impl ScriptThreadFactory for ScriptThread { let (sender, receiver) = channel(); let layout_chan = sender.clone(); - thread::spawn_named(format!("ScriptThread {:?}", state.id), - move || { + thread::Builder::new().name(format!("ScriptThread {:?}", state.id)).spawn(move || { thread_state::initialize(thread_state::SCRIPT); PipelineNamespace::install(state.pipeline_namespace_id); FrameId::install(state.top_level_frame_id); @@ -553,7 +549,7 @@ impl ScriptThreadFactory for ScriptThread { // This must always be the very last operation performed before the thread completes failsafe.neuter(); - }); + }).expect("Thread spawning failed"); (sender, receiver) } @@ -686,7 +682,7 @@ impl ScriptThread { devtools_sender: ipc_devtools_sender, js_runtime: Rc::new(runtime), - topmost_mouse_over_target: MutNullableHeap::new(Default::default()), + topmost_mouse_over_target: MutNullableJS::new(Default::default()), closed_pipelines: DOMRefCell::new(HashSet::new()), scheduler_chan: state.scheduler_chan, @@ -726,10 +722,8 @@ impl ScriptThread { for (id, document) in self.documents.borrow().iter() { // Only process a resize if layout is idle. - let resize_event = document.window().steal_resize_event(); - match resize_event { - Some((size, size_type)) => resizes.push((id, size, size_type)), - None => () + if let Some((size, size_type)) = document.window().steal_resize_event() { + resizes.push((id, size, size_type)); } } @@ -1050,8 +1044,11 @@ impl ScriptThread { TimerSource::FromWorker => panic!("Worker timeouts must not be sent to script thread"), }; - let window = self.documents.borrow().find_window(pipeline_id) - .expect("ScriptThread: received fire timer msg for a pipeline not in this script thread. This is a bug."); + let window = self.documents.borrow().find_window(pipeline_id); + let window = match window { + Some(w) => w, + None => return warn!("Received fire timer msg for a closed pipeline {}.", pipeline_id), + }; window.handle_fire_timer(id); } @@ -1143,7 +1140,8 @@ impl ScriptThread { } fn handle_resize(&self, id: PipelineId, size: WindowSizeData, size_type: WindowSizeType) { - if let Some(ref window) = self.documents.borrow().find_window(id) { + let window = self.documents.borrow().find_window(id); + if let Some(ref window) = window { window.set_resize_event(size, size_type); return; } @@ -1156,7 +1154,8 @@ impl ScriptThread { } fn handle_viewport(&self, id: PipelineId, rect: Rect<f32>) { - if let Some(document) = self.documents.borrow().find_document(id) { + let document = self.documents.borrow().find_document(id); + if let Some(document) = document { if document.window().set_page_clip_rect_with_new_viewport(rect) { self.rebuild_and_force_reflow(&document, ReflowReason::Viewport); } @@ -1173,7 +1172,7 @@ impl ScriptThread { fn handle_set_scroll_state(&self, id: PipelineId, scroll_states: &[(UntrustedNodeAddress, Point2D<f32>)]) { - let window = match self.documents.borrow().find_window(id) { + let window = match { self.documents.borrow().find_window(id) } { Some(window) => window, None => return warn!("Set scroll state message sent to nonexistent pipeline: {:?}", id), }; @@ -1241,7 +1240,7 @@ impl ScriptThread { } fn handle_loads_complete(&self, pipeline: PipelineId) { - let doc = match self.documents.borrow().find_document(pipeline) { + let doc = match { self.documents.borrow().find_document(pipeline) } { Some(doc) => doc, None => return warn!("Message sent to closed pipeline {}.", pipeline), }; @@ -1296,7 +1295,8 @@ impl ScriptThread { /// To slow/speed up timers and manage any other script thread resource based on visibility. /// Returns true if successful. fn alter_resource_utilization(&self, id: PipelineId, visible: bool) -> bool { - if let Some(window) = self.documents.borrow().find_window(id) { + let window = self.documents.borrow().find_window(id); + if let Some(window) = window { if visible { window.upcast::<GlobalScope>().speed_up_timers(); } else { @@ -1309,7 +1309,8 @@ impl ScriptThread { /// Updates iframe element after a change in visibility fn handle_visibility_change_complete_msg(&self, parent_pipeline_id: PipelineId, id: FrameId, visible: bool) { - if let Some(iframe) = self.documents.borrow().find_iframe(parent_pipeline_id, id) { + let iframe = self.documents.borrow().find_iframe(parent_pipeline_id, id); + if let Some(iframe) = iframe { iframe.change_visibility_status(visible); } } @@ -1337,7 +1338,8 @@ impl ScriptThread { /// Handles freeze message fn handle_freeze_msg(&self, id: PipelineId) { - if let Some(window) = self.documents.borrow().find_window(id) { + let window = self.documents.borrow().find_window(id); + if let Some(window) = window { window.upcast::<GlobalScope>().suspend(); return; } @@ -1351,7 +1353,8 @@ impl ScriptThread { /// Handles thaw message fn handle_thaw_msg(&self, id: PipelineId) { - if let Some(document) = self.documents.borrow().find_document(id) { + let document = self.documents.borrow().find_document(id); + if let Some(document) = document { if let Some(context) = document.browsing_context() { let needed_reflow = context.set_reflow_status(false); if needed_reflow { @@ -1402,14 +1405,16 @@ impl ScriptThread { parent_pipeline_id: PipelineId, frame_id: Option<FrameId>, event: MozBrowserEvent) { - match self.documents.borrow().find_document(parent_pipeline_id) { - None => warn!("Mozbrowser event after pipeline {:?} closed.", parent_pipeline_id), - Some(doc) => match frame_id { - None => doc.window().dispatch_mozbrowser_event(event), - Some(frame_id) => match doc.find_iframe(frame_id) { - None => warn!("Mozbrowser event after iframe {:?}/{:?} closed.", parent_pipeline_id, frame_id), - Some(frame_element) => frame_element.dispatch_mozbrowser_event(event), - }, + let doc = match { self.documents.borrow().find_document(parent_pipeline_id) } { + None => return warn!("Mozbrowser event after pipeline {:?} closed.", parent_pipeline_id), + Some(doc) => doc, + }; + + match frame_id { + None => doc.window().dispatch_mozbrowser_event(event), + Some(frame_id) => match doc.find_iframe(frame_id) { + None => warn!("Mozbrowser event after iframe {:?}/{:?} closed.", parent_pipeline_id, frame_id), + Some(frame_element) => frame_element.dispatch_mozbrowser_event(event), }, } } @@ -1418,7 +1423,8 @@ impl ScriptThread { parent_pipeline_id: PipelineId, frame_id: FrameId, new_pipeline_id: PipelineId) { - if let Some(frame_element) = self.documents.borrow().find_iframe(parent_pipeline_id, frame_id) { + let frame_element = self.documents.borrow().find_iframe(parent_pipeline_id, frame_id); + if let Some(frame_element) = frame_element { frame_element.update_pipeline_id(new_pipeline_id); } } @@ -1487,13 +1493,14 @@ impl ScriptThread { Some(r) => r, None => return }; - if let Some(window) = self.documents.borrow().find_window(pipeline_id) { - let script_url = maybe_registration.get_installed().get_script_url(); - let scope_things = ServiceWorkerRegistration::create_scope_things(window.upcast(), script_url); - let _ = self.constellation_chan.send(ConstellationMsg::RegisterServiceWorker(scope_things, scope.clone())); - } else { - warn!("Registration failed for {}", scope); - } + let window = match { self.documents.borrow().find_window(pipeline_id) } { + Some(window) => window, + None => return warn!("Registration failed for {}", scope), + }; + + let script_url = maybe_registration.get_installed().get_script_url(); + let scope_things = ServiceWorkerRegistration::create_scope_things(window.upcast(), script_url); + let _ = self.constellation_chan.send(ConstellationMsg::RegisterServiceWorker(scope_things, scope.clone())); } pub fn dispatch_job_queue(&self, job_handler: Box<AsyncJobHandler>) { @@ -1544,7 +1551,7 @@ impl ScriptThread { /// Handles a request for the window title. fn handle_get_title_msg(&self, pipeline_id: PipelineId) { - let document = match self.documents.borrow().find_document(pipeline_id) { + let document = match { self.documents.borrow().find_document(pipeline_id) } { Some(document) => document, None => return warn!("Message sent to closed pipeline {}.", pipeline_id), }; @@ -1601,7 +1608,7 @@ impl ScriptThread { /// Handles when layout thread finishes all animation in one tick fn handle_tick_all_animations(&self, id: PipelineId) { - let document = match self.documents.borrow().find_document(id) { + let document = match { self.documents.borrow().find_document(id) } { Some(document) => document, None => return warn!("Message sent to closed pipeline {}.", id), }; @@ -1642,7 +1649,8 @@ impl ScriptThread { /// Handles a Web font being loaded. Does nothing if the page no longer exists. fn handle_web_font_loaded(&self, pipeline_id: PipelineId) { - if let Some(document) = self.documents.borrow().find_document(pipeline_id) { + let document = self.documents.borrow().find_document(pipeline_id); + if let Some(document) = document { self.rebuild_and_force_reflow(&document, ReflowReason::WebFontLoaded); } } @@ -1650,12 +1658,14 @@ impl ScriptThread { /// Notify a window of a storage event fn handle_storage_event(&self, pipeline_id: PipelineId, storage_type: StorageType, url: ServoUrl, key: Option<String>, old_value: Option<String>, new_value: Option<String>) { - let storage = match self.documents.borrow().find_window(pipeline_id) { + let window = match { self.documents.borrow().find_window(pipeline_id) } { None => return warn!("Storage event sent to closed pipeline {}.", pipeline_id), - Some(window) => match storage_type { - StorageType::Local => window.LocalStorage(), - StorageType::Session => window.SessionStorage(), - }, + Some(window) => window, + }; + + let storage = match storage_type { + StorageType::Local => window.LocalStorage(), + StorageType::Session => window.SessionStorage(), }; storage.queue_storage_event(url, key, old_value, new_value); @@ -1908,7 +1918,7 @@ impl ScriptThread { } MouseMoveEvent(point) => { - let document = match self.documents.borrow().find_document(pipeline_id) { + let document = match { self.documents.borrow().find_document(pipeline_id) } { Some(document) => document, None => return warn!("Message sent to closed pipeline {}.", pipeline_id), }; @@ -1980,17 +1990,19 @@ impl ScriptThread { } TouchpadPressureEvent(point, pressure, phase) => { - match self.documents.borrow().find_document(pipeline_id) { - Some(doc) => doc.handle_touchpad_pressure_event(self.js_runtime.rt(), point, pressure, phase), - None => warn!("Message sent to closed pipeline {}.", pipeline_id), - } + let doc = match { self.documents.borrow().find_document(pipeline_id) } { + Some(doc) => doc, + None => return warn!("Message sent to closed pipeline {}.", pipeline_id), + }; + doc.handle_touchpad_pressure_event(self.js_runtime.rt(), point, pressure, phase); } KeyEvent(ch, key, state, modifiers) => { - match self.documents.borrow().find_document(pipeline_id) { - Some(document) => document.dispatch_key_event(ch, key, state, modifiers, &self.constellation_chan), - None => warn!("Message sent to closed pipeline {}.", pipeline_id), - } + let document = match { self.documents.borrow().find_document(pipeline_id) } { + Some(document) => document, + None => return warn!("Message sent to closed pipeline {}.", pipeline_id), + }; + document.dispatch_key_event(ch, key, state, modifiers, &self.constellation_chan); } } } @@ -2000,10 +2012,11 @@ impl ScriptThread { mouse_event_type: MouseEventType, button: MouseButton, point: Point2D<f32>) { - match self.documents.borrow().find_document(pipeline_id) { - Some(document) => document.handle_mouse_event(self.js_runtime.rt(), button, point, mouse_event_type), - None => warn!("Message sent to closed pipeline {}.", pipeline_id), - } + let document = match { self.documents.borrow().find_document(pipeline_id) } { + Some(document) => document, + None => return warn!("Message sent to closed pipeline {}.", pipeline_id), + }; + document.handle_mouse_event(self.js_runtime.rt(), button, point, mouse_event_type); } fn handle_touch_event(&self, @@ -2012,13 +2025,14 @@ impl ScriptThread { identifier: TouchId, point: Point2D<f32>) -> TouchEventResult { - match self.documents.borrow().find_document(pipeline_id) { - Some(document) => document.handle_touch_event(self.js_runtime.rt(), event_type, identifier, point), + let document = match { self.documents.borrow().find_document(pipeline_id) } { + Some(document) => document, None => { warn!("Message sent to closed pipeline {}.", pipeline_id); - TouchEventResult::Processed(true) + return TouchEventResult::Processed(true); }, - } + }; + document.handle_touch_event(self.js_runtime.rt(), event_type, identifier, point) } /// https://html.spec.whatwg.org/multipage/#navigating-across-documents @@ -2044,7 +2058,7 @@ impl ScriptThread { } fn handle_resize_event(&self, pipeline_id: PipelineId, new_size: WindowSizeData, size_type: WindowSizeType) { - let document = match self.documents.borrow().find_document(pipeline_id) { + let document = match { self.documents.borrow().find_document(pipeline_id) } { Some(document) => document, None => return warn!("Message sent to closed pipeline {}.", pipeline_id), }; @@ -2127,7 +2141,7 @@ impl ScriptThread { } fn handle_parsing_complete(&self, id: PipelineId) { - let document = match self.documents.borrow().find_document(id) { + let document = match { self.documents.borrow().find_document(id) } { Some(document) => document, None => return, }; @@ -2175,7 +2189,8 @@ impl ScriptThread { } fn handle_reload(&self, pipeline_id: PipelineId) { - if let Some(window) = self.documents.borrow().find_window(pipeline_id) { + let window = self.documents.borrow().find_window(pipeline_id); + if let Some(window) = window { window.Location().Reload(); } } diff --git a/components/script/serviceworker_manager.rs b/components/script/serviceworker_manager.rs index ac3c2ab4109..793d7ccf370 100644 --- a/components/script/serviceworker_manager.rs +++ b/components/script/serviceworker_manager.rs @@ -16,11 +16,11 @@ use ipc_channel::ipc::{self, IpcSender}; use ipc_channel::router::ROUTER; use net_traits::{CustomResponseMediator, CoreResourceMsg}; use script_traits::{ServiceWorkerMsg, ScopeThings, SWManagerMsg, SWManagerSenders, DOMMessage}; +use servo_config::prefs::PREFS; use servo_url::ServoUrl; use std::collections::HashMap; use std::sync::mpsc::{channel, Sender, Receiver, RecvError}; -use util::prefs::PREFS; -use util::thread::spawn_named; +use std::thread; enum Message { FromResource(CustomResponseMediator), @@ -60,11 +60,11 @@ impl ServiceWorkerManager { let resource_port = ROUTER.route_ipc_receiver_to_new_mpsc_receiver(resource_port); let _ = sw_senders.resource_sender.send(CoreResourceMsg::NetworkMediator(resource_chan)); let _ = sw_senders.swmanager_sender.send(SWManagerMsg::OwnSender(own_sender.clone())); - spawn_named("ServiceWorkerManager".to_owned(), move || { + thread::Builder::new().name("ServiceWorkerManager".to_owned()).spawn(move || { ServiceWorkerManager::new(own_sender, from_constellation, resource_port).handle_message(); - }); + }).expect("Thread spawning failed"); } pub fn get_matching_scope(&self, load_url: &ServoUrl) -> Option<ServoUrl> { diff --git a/components/script/stylesheet_loader.rs b/components/script/stylesheet_loader.rs new file mode 100644 index 00000000000..427593c8500 --- /dev/null +++ b/components/script/stylesheet_loader.rs @@ -0,0 +1,245 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +use document_loader::LoadType; +use dom::bindings::inheritance::Castable; +use dom::bindings::refcounted::Trusted; +use dom::bindings::reflector::DomObject; +use dom::element::Element; +use dom::eventtarget::EventTarget; +use dom::htmlelement::HTMLElement; +use dom::htmllinkelement::HTMLLinkElement; +use dom::node::{document_from_node, window_from_node}; +use encoding::EncodingRef; +use encoding::all::UTF_8; +use hyper::header::ContentType; +use hyper::mime::{Mime, TopLevel, SubLevel}; +use hyper_serde::Serde; +use ipc_channel::ipc; +use ipc_channel::router::ROUTER; +use net_traits::{FetchResponseListener, FetchMetadata, Metadata, NetworkError, ReferrerPolicy}; +use net_traits::request::{CredentialsMode, Destination, RequestInit, Type as RequestType}; +use network_listener::{NetworkListener, PreInvoke}; +use parking_lot::RwLock; +use script_layout_interface::message::Msg; +use servo_url::ServoUrl; +use std::mem; +use std::sync::{Arc, Mutex}; +use style::media_queries::MediaList; +use style::parser::ParserContextExtraData; +use style::stylesheets::{ImportRule, Stylesheet, Origin}; +use style::stylesheets::StylesheetLoader as StyleStylesheetLoader; + +pub trait StylesheetOwner { + /// Returns whether this element was inserted by the parser (i.e., it should + /// trigger a document-load-blocking load). + fn parser_inserted(&self) -> bool; + + /// Which referrer policy should loads triggered by this owner follow, or + /// `None` for the default. + fn referrer_policy(&self) -> Option<ReferrerPolicy>; + + /// Notes that a new load is pending to finish. + fn increment_pending_loads_count(&self); + + /// Returns None if there are still pending loads, or whether any load has + /// failed since the loads started. + fn load_finished(&self, successful: bool) -> Option<bool>; +} + +pub enum StylesheetContextSource { + // NB: `media` is just an option so we avoid cloning it. + LinkElement { media: Option<MediaList>, url: ServoUrl }, + Import(Arc<RwLock<ImportRule>>), +} + +impl StylesheetContextSource { + fn url(&self) -> ServoUrl { + match *self { + StylesheetContextSource::LinkElement { ref url, .. } => url.clone(), + StylesheetContextSource::Import(ref import) => { + let import = import.read(); + // Look at the parser in style::stylesheets, where we don't + // trigger a load if the url is invalid. + import.url.url() + .expect("Invalid urls shouldn't enter the loader") + .clone() + } + } + } +} + +/// The context required for asynchronously loading an external stylesheet. +pub struct StylesheetContext { + /// The element that initiated the request. + elem: Trusted<HTMLElement>, + source: StylesheetContextSource, + metadata: Option<Metadata>, + /// The response body received to date. + data: Vec<u8>, +} + +impl PreInvoke for StylesheetContext {} + +impl FetchResponseListener for StylesheetContext { + fn process_request_body(&mut self) {} + + fn process_request_eof(&mut self) {} + + fn process_response(&mut self, + metadata: Result<FetchMetadata, NetworkError>) { + self.metadata = metadata.ok().map(|m| { + match m { + FetchMetadata::Unfiltered(m) => m, + FetchMetadata::Filtered { unsafe_, .. } => unsafe_ + } + }); + } + + fn process_response_chunk(&mut self, mut payload: Vec<u8>) { + self.data.append(&mut payload); + } + + fn process_response_eof(&mut self, status: Result<(), NetworkError>) { + let elem = self.elem.root(); + let document = document_from_node(&*elem); + let mut successful = false; + + if status.is_ok() { + let metadata = match self.metadata.take() { + Some(meta) => meta, + None => return, + }; + let is_css = metadata.content_type.map_or(false, |Serde(ContentType(Mime(top, sub, _)))| + top == TopLevel::Text && sub == SubLevel::Css); + + let data = if is_css { mem::replace(&mut self.data, vec![]) } else { vec![] }; + + // TODO: Get the actual value. http://dev.w3.org/csswg/css-syntax/#environment-encoding + let environment_encoding = UTF_8 as EncodingRef; + let protocol_encoding_label = metadata.charset.as_ref().map(|s| &**s); + let final_url = metadata.final_url; + + let win = window_from_node(&*elem); + + let loader = StylesheetLoader::for_element(&elem); + match self.source { + StylesheetContextSource::LinkElement { ref mut media, .. } => { + let sheet = + Arc::new(Stylesheet::from_bytes(&data, final_url, + protocol_encoding_label, + Some(environment_encoding), + Origin::Author, + media.take().unwrap(), + Some(&loader), + win.css_error_reporter(), + ParserContextExtraData::default())); + elem.downcast::<HTMLLinkElement>() + .unwrap() + .set_stylesheet(sheet.clone()); + + let win = window_from_node(&*elem); + win.layout_chan().send(Msg::AddStylesheet(sheet)).unwrap(); + } + StylesheetContextSource::Import(ref import) => { + let import = import.read(); + Stylesheet::update_from_bytes(&import.stylesheet, + &data, + protocol_encoding_label, + Some(environment_encoding), + Some(&loader), + win.css_error_reporter(), + ParserContextExtraData::default()); + } + } + + document.invalidate_stylesheets(); + + // FIXME: Revisit once consensus is reached at: + // https://github.com/whatwg/html/issues/1142 + successful = metadata.status.map_or(false, |(code, _)| code == 200); + } + + let owner = elem.upcast::<Element>().as_stylesheet_owner() + .expect("Stylesheet not loaded by <style> or <link> element!"); + if owner.parser_inserted() { + document.decrement_script_blocking_stylesheet_count(); + } + + let url = self.source.url(); + document.finish_load(LoadType::Stylesheet(url)); + + if let Some(any_failed) = owner.load_finished(successful) { + let event = if any_failed { atom!("error") } else { atom!("load") }; + elem.upcast::<EventTarget>().fire_event(event); + } + } +} + +pub struct StylesheetLoader<'a> { + elem: &'a HTMLElement, +} + +impl<'a> StylesheetLoader<'a> { + pub fn for_element(element: &'a HTMLElement) -> Self { + StylesheetLoader { + elem: element, + } + } +} + +impl<'a> StylesheetLoader<'a> { + pub fn load(&self, source: StylesheetContextSource) { + let url = source.url(); + let context = Arc::new(Mutex::new(StylesheetContext { + elem: Trusted::new(&*self.elem), + source: source, + metadata: None, + data: vec![], + })); + + let document = document_from_node(self.elem); + + let (action_sender, action_receiver) = ipc::channel().unwrap(); + let listener = NetworkListener { + context: context, + task_source: document.window().networking_task_source(), + wrapper: Some(document.window().get_runnable_wrapper()) + }; + ROUTER.add_route(action_receiver.to_opaque(), box move |message| { + listener.notify_fetch(message.to().unwrap()); + }); + + + let owner = self.elem.upcast::<Element>().as_stylesheet_owner() + .expect("Stylesheet not loaded by <style> or <link> element!"); + let referrer_policy = owner.referrer_policy() + .or_else(|| document.get_referrer_policy()); + owner.increment_pending_loads_count(); + if owner.parser_inserted() { + document.increment_script_blocking_stylesheet_count(); + } + + let request = RequestInit { + url: url.clone(), + type_: RequestType::Style, + destination: Destination::Style, + credentials_mode: CredentialsMode::Include, + use_url_credentials: true, + origin: document.url(), + pipeline_id: Some(self.elem.global().pipeline_id()), + referrer_url: Some(document.url()), + referrer_policy: referrer_policy, + .. RequestInit::default() + }; + + document.fetch_async(LoadType::Stylesheet(url), request, action_sender); + } +} + +impl<'a> StyleStylesheetLoader for StylesheetLoader<'a> { + fn request_stylesheet(&self, import: &Arc<RwLock<ImportRule>>) { + self.load(StylesheetContextSource::Import(import.clone())) + } +} diff --git a/components/script/test.rs b/components/script/test.rs new file mode 100644 index 00000000000..31353b5ffa3 --- /dev/null +++ b/components/script/test.rs @@ -0,0 +1,68 @@ +/* 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/. */ + +pub use dom::bindings::str::{ByteString, DOMString}; +pub use dom::headers::normalize_value; + +// For compile-fail tests only. +pub use dom::bindings::cell::DOMRefCell; +pub use dom::bindings::js::JS; +pub use dom::node::Node; + +pub mod size_of { + use dom::characterdata::CharacterData; + use dom::element::Element; + use dom::eventtarget::EventTarget; + use dom::htmldivelement::HTMLDivElement; + use dom::htmlelement::HTMLElement; + use dom::htmlspanelement::HTMLSpanElement; + use dom::node::Node; + use dom::text::Text; + use layout_wrapper::{ServoLayoutElement, ServoLayoutNode, ServoThreadSafeLayoutNode}; + use std::mem::size_of; + + pub fn CharacterData() -> usize { + size_of::<CharacterData>() + } + + pub fn Element() -> usize { + size_of::<Element>() + } + + pub fn EventTarget() -> usize { + size_of::<EventTarget>() + } + + pub fn HTMLDivElement() -> usize { + size_of::<HTMLDivElement>() + } + + pub fn HTMLElement() -> usize { + size_of::<HTMLElement>() + } + + pub fn HTMLSpanElement() -> usize { + size_of::<HTMLSpanElement>() + } + + pub fn Node() -> usize { + size_of::<Node>() + } + + pub fn SendElement() -> usize { + size_of::<::style::dom::SendElement<ServoLayoutElement>>() + } + + pub fn SendNode() -> usize { + size_of::<::style::dom::SendNode<ServoLayoutNode>>() + } + + pub fn ServoThreadSafeLayoutNode() -> usize { + size_of::<ServoThreadSafeLayoutNode>() + } + + pub fn Text() -> usize { + size_of::<Text>() + } +} diff --git a/components/script/timers.rs b/components/script/timers.rs index db0adfa9557..14c4eb89c13 100644 --- a/components/script/timers.rs +++ b/components/script/timers.rs @@ -18,12 +18,12 @@ use js::jsapi::{HandleValue, Heap}; use js::jsval::{JSVal, UndefinedValue}; use script_traits::{MsDuration, precise_time_ms}; use script_traits::{TimerEvent, TimerEventId, TimerEventRequest, TimerSource}; +use servo_config::prefs::PREFS; use std::cell::Cell; use std::cmp::{self, Ord, Ordering}; use std::collections::HashMap; use std::default::Default; use std::rc::Rc; -use util::prefs::PREFS; #[derive(JSTraceable, PartialEq, Eq, Copy, Clone, HeapSizeOf, Hash, PartialOrd, Ord, Debug)] pub struct OneshotTimerHandle(i32); diff --git a/components/script/webdriver_handlers.rs b/components/script/webdriver_handlers.rs index e0818347c56..e1599d7caef 100644 --- a/components/script/webdriver_handlers.rs +++ b/components/script/webdriver_handlers.rs @@ -31,7 +31,7 @@ use js::jsapi::{HandleValue, JSContext}; use js::jsval::UndefinedValue; use msg::constellation_msg::PipelineId; use net_traits::CookieSource::{HTTP, NonHTTP}; -use net_traits::CoreResourceMsg::{GetCookiesDataForUrl, SetCookiesForUrlWithData}; +use net_traits::CoreResourceMsg::{GetCookiesDataForUrl, SetCookieForUrl}; use net_traits::IpcSend; use script_thread::Documents; use script_traits::webdriver_msg::{WebDriverFrameId, WebDriverJSError, WebDriverJSResult, WebDriverJSValue}; @@ -243,14 +243,14 @@ pub fn handle_add_cookie(documents: &Documents, (true, _) => Err(WebDriverCookieError::InvalidDomain), (false, Some(ref domain)) if url.host_str().map(|x| { x == &**domain }).unwrap_or(false) => { let _ = document.window().upcast::<GlobalScope>().resource_threads().send( - SetCookiesForUrlWithData(url, cookie, method) - ); + SetCookieForUrl(url, cookie, method) + ); Ok(()) }, (false, None) => { let _ = document.window().upcast::<GlobalScope>().resource_threads().send( - SetCookiesForUrlWithData(url, cookie, method) - ); + SetCookieForUrl(url, cookie, method) + ); Ok(()) }, (_, _) => { diff --git a/components/script_layout_interface/message.rs b/components/script_layout_interface/message.rs index 581adbb45bc..3d0e00c46cc 100644 --- a/components/script_layout_interface/message.rs +++ b/components/script_layout_interface/message.rs @@ -14,11 +14,11 @@ use profile_traits::mem::ReportsChan; use rpc::LayoutRPC; use script_traits::{ConstellationControlMsg, LayoutControlMsg}; use script_traits::{LayoutMsg as ConstellationMsg, StackingContextScrollState, WindowSizeData}; -use servo_atoms::Atom; use servo_url::ServoUrl; use std::sync::Arc; use std::sync::mpsc::{Receiver, Sender}; use style::context::ReflowGoal; +use style::properties::PropertyId; use style::selector_parser::PseudoElement; use style::stylesheets::Stylesheet; @@ -97,7 +97,7 @@ pub enum ReflowQueryType { NodeScrollRootIdQuery(TrustedNodeAddress), NodeGeometryQuery(TrustedNodeAddress), NodeScrollGeometryQuery(TrustedNodeAddress), - ResolvedStyleQuery(TrustedNodeAddress, Option<PseudoElement>, Atom), + ResolvedStyleQuery(TrustedNodeAddress, Option<PseudoElement>, PropertyId), OffsetParentQuery(TrustedNodeAddress), MarginStyleQuery(TrustedNodeAddress), } diff --git a/components/script_layout_interface/rpc.rs b/components/script_layout_interface/rpc.rs index 6e19b3f3bcf..7bc58dbf334 100644 --- a/components/script_layout_interface/rpc.rs +++ b/components/script_layout_interface/rpc.rs @@ -57,7 +57,7 @@ pub struct HitTestResponse { pub node_address: Option<UntrustedNodeAddress>, } -pub struct ResolvedStyleResponse(pub Option<String>); +pub struct ResolvedStyleResponse(pub String); #[derive(Clone)] pub struct OffsetParentResponse { diff --git a/components/script_layout_interface/wrapper_traits.rs b/components/script_layout_interface/wrapper_traits.rs index cf3e3e4c7c5..e141cb581c3 100644 --- a/components/script_layout_interface/wrapper_traits.rs +++ b/components/script_layout_interface/wrapper_traits.rs @@ -319,7 +319,7 @@ pub trait ThreadSafeLayoutElement: Clone + Copy + Sized + Debug + if self.get_style_data() .unwrap() .borrow() - .current_styles().pseudos + .styles().pseudos .contains_key(&PseudoElement::Before) { Some(self.with_pseudo(PseudoElementType::Before(None))) } else { @@ -332,7 +332,7 @@ pub trait ThreadSafeLayoutElement: Clone + Copy + Sized + Debug + if self.get_style_data() .unwrap() .borrow() - .current_styles().pseudos + .styles().pseudos .contains_key(&PseudoElement::After) { Some(self.with_pseudo(PseudoElementType::After(None))) } else { @@ -373,7 +373,7 @@ pub trait ThreadSafeLayoutElement: Clone + Copy + Sized + Debug + fn style(&self, context: &SharedStyleContext) -> Arc<ServoComputedValues> { match self.get_pseudo_element_type() { PseudoElementType::Normal => self.get_style_data().unwrap().borrow() - .current_styles().primary.values.clone(), + .styles().primary.values.clone(), other => { // Precompute non-eagerly-cascaded pseudo-element styles if not // cached before. @@ -385,14 +385,14 @@ pub trait ThreadSafeLayoutElement: Clone + Copy + Sized + Debug + if !self.get_style_data() .unwrap() .borrow() - .current_styles().pseudos.contains_key(&style_pseudo) { + .styles().pseudos.contains_key(&style_pseudo) { let mut data = self.get_style_data().unwrap().borrow_mut(); let new_style = context.stylist.precomputed_values_for_pseudo( &style_pseudo, - Some(&data.current_styles().primary.values), + Some(&data.styles().primary.values), false); - data.current_styles_mut().pseudos + data.styles_mut().pseudos .insert(style_pseudo.clone(), new_style.unwrap()); } } @@ -400,22 +400,22 @@ pub trait ThreadSafeLayoutElement: Clone + Copy + Sized + Debug + if !self.get_style_data() .unwrap() .borrow() - .current_styles().pseudos.contains_key(&style_pseudo) { + .styles().pseudos.contains_key(&style_pseudo) { let mut data = self.get_style_data().unwrap().borrow_mut(); let new_style = context.stylist .lazily_compute_pseudo_element_style( self, &style_pseudo, - &data.current_styles().primary.values); - data.current_styles_mut().pseudos + &data.styles().primary.values); + data.styles_mut().pseudos .insert(style_pseudo.clone(), new_style.unwrap()); } } } self.get_style_data().unwrap().borrow() - .current_styles().pseudos.get(&style_pseudo) + .styles().pseudos.get(&style_pseudo) .unwrap().values.clone() } } @@ -424,9 +424,9 @@ pub trait ThreadSafeLayoutElement: Clone + Copy + Sized + Debug + #[inline] fn selected_style(&self) -> Arc<ServoComputedValues> { let data = self.get_style_data().unwrap().borrow(); - data.current_styles().pseudos + data.styles().pseudos .get(&PseudoElement::Selection).map(|s| s) - .unwrap_or(&data.current_styles().primary) + .unwrap_or(&data.styles().primary) .values.clone() } @@ -442,9 +442,9 @@ pub trait ThreadSafeLayoutElement: Clone + Copy + Sized + Debug + let data = self.get_style_data().unwrap().borrow(); match self.get_pseudo_element_type() { PseudoElementType::Normal - => data.current_styles().primary.values.clone(), + => data.styles().primary.values.clone(), other - => data.current_styles().pseudos + => data.styles().pseudos .get(&other.style_pseudo_element()).unwrap().values.clone(), } } diff --git a/components/script_traits/lib.rs b/components/script_traits/lib.rs index 0494f44c70d..56d4406f1ce 100644 --- a/components/script_traits/lib.rs +++ b/components/script_traits/lib.rs @@ -686,7 +686,7 @@ pub enum ConstellationMsg { /// Request that the constellation send the current pipeline id for the provided frame /// id, or for the root frame if this is None, over a provided channel. /// Also returns a boolean saying whether the document has finished loading or not. - GetPipeline(Option<FrameId>, IpcSender<Option<(PipelineId, bool)>>), + GetPipeline(Option<FrameId>, IpcSender<Option<PipelineId>>), /// Requests that the constellation inform the compositor of the title of the pipeline /// immediately. GetPipelineTitle(PipelineId), diff --git a/components/servo/Cargo.toml b/components/servo/Cargo.toml index 724ba36214b..759082970d7 100644 --- a/components/servo/Cargo.toml +++ b/components/servo/Cargo.toml @@ -50,10 +50,10 @@ profile_traits = {path = "../profile_traits"} script = {path = "../script"} script_layout_interface = {path = "../script_layout_interface"} script_traits = {path = "../script_traits"} +servo_config = {path = "../config"} servo_url = {path = "../url"} style = {path = "../style", features = ["servo"]} url = "1.2" -util = {path = "../util"} webdriver_server = {path = "../webdriver_server", optional = true} [dependencies.webrender] diff --git a/components/servo/lib.rs b/components/servo/lib.rs index 3cc549f102f..afb7f88b7ae 100644 --- a/components/servo/lib.rs +++ b/components/servo/lib.rs @@ -45,10 +45,9 @@ pub extern crate profile_traits; pub extern crate script; pub extern crate script_traits; pub extern crate script_layout_interface; +pub extern crate servo_config; pub extern crate servo_url; pub extern crate style; -pub extern crate url; -pub extern crate util; #[cfg(feature = "webdriver")] extern crate webdriver_server; @@ -88,17 +87,19 @@ use profile::time as profile_time; use profile_traits::mem; use profile_traits::time; use script_traits::{ConstellationMsg, SWManagerSenders, ScriptMsg}; +use servo_config::opts; +use servo_config::prefs::PREFS; +use servo_config::resource_files::resources_dir_path; use servo_url::ServoUrl; use std::borrow::Cow; use std::cmp::max; use std::path::PathBuf; use std::rc::Rc; use std::sync::mpsc::Sender; -use util::opts; -use util::prefs::PREFS; -use util::resource_files::resources_dir_path; pub use gleam::gl; +pub use servo_config as config; +pub use servo_url as url; /// The in-process interface to Servo. /// @@ -163,7 +164,6 @@ impl<Window> Browser<Window> where Window: WindowMethods + 'static { device_pixel_ratio: device_pixel_ratio, resource_override_path: Some(resource_path), enable_aa: opts.enable_text_antialiasing, - enable_msaa: opts.use_msaa, enable_profiler: opts.webrender_stats, debug: opts.webrender_debug, enable_recording: opts.webrender_record, @@ -171,6 +171,9 @@ impl<Window> Browser<Window> where Window: WindowMethods + 'static { enable_scrollbars: opts.output_file.is_none(), renderer_kind: renderer_kind, enable_subpixel_aa: opts.enable_subpixel_text_antialiasing, + clear_empty_tiles: true, + clear_framebuffer: true, + clear_color: webrender_traits::ColorF::new(1.0, 1.0, 1.0, 1.0), }) }; diff --git a/components/style/Cargo.toml b/components/style/Cargo.toml index 5a1b854ca4d..3cc56f23711 100644 --- a/components/style/Cargo.toml +++ b/components/style/Cargo.toml @@ -14,10 +14,11 @@ doctest = false [features] gecko = ["nsstring_vendor", "num_cpus", "rayon/unstable"] +bindgen = ["libbindgen", "regex"] servo = ["serde/unstable", "serde", "serde_derive", "heapsize_derive", "style_traits/servo", "app_units/plugins", "servo_atoms", "html5ever-atoms", "cssparser/heap_size", "cssparser/serde-serialization", - "plugins", "rayon/unstable", "servo_url/servo"] + "rayon/unstable", "servo_url/servo"] testing = [] [dependencies] @@ -40,21 +41,21 @@ num-traits = "0.1.32" ordered-float = "0.2.2" owning_ref = "0.2.2" parking_lot = "0.3.3" +phf = "0.7.20" quickersort = "2.0.0" rand = "0.3" -rayon = "0.5" +rayon = "0.6" rustc-serialize = "0.3" selectors = "0.15" serde = {version = "0.8", optional = true} serde_derive = {version = "0.8", optional = true} servo_atoms = {path = "../atoms", optional = true} +servo_config = {path = "../config"} smallvec = "0.1" style_traits = {path = "../style_traits"} servo_url = {path = "../url"} time = "0.1" unicode-segmentation = "0.1.2" -util = {path = "../util"} -plugins = {path = "../plugins", optional = true} [dependencies.num_cpus] optional = true @@ -64,4 +65,8 @@ version = "1.0" kernel32-sys = "0.2" [build-dependencies] +lazy_static = "0.2" +libbindgen = {version = "0.1.1", optional = true} +phf_codegen = "0.7.20" +regex = {version = "0.1", optional = true} walkdir = "0.1" diff --git a/components/style/binding_tools/README.md b/components/style/binding_tools/README.md index 5b23c7a57bb..e1465143e32 100644 --- a/components/style/binding_tools/README.md +++ b/components/style/binding_tools/README.md @@ -5,8 +5,3 @@ This directory contains simple tools for generating the Rust bindings for [stylo ## `setup_bindgen.sh` This clones Servo's version of bindgen, and uses `llvm-3.8` library to build it. It will then be used to generate the Rust bindings. - -## `regen.sh` - -This will regenerate the bindings for the `ServoBindings.h` file in your gecko -build. The generated bindings live in `components/style/gecko_bindings/bindings.rs`. For structs, the bindings are in `components/style/gecko_bindings/structs_*` diff --git a/components/style/binding_tools/regen.py b/components/style/binding_tools/regen.py deleted file mode 100755 index 248d50ea9ea..00000000000 --- a/components/style/binding_tools/regen.py +++ /dev/null @@ -1,820 +0,0 @@ -#!/usr/bin/env python - -# 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 print_function - -import re -import os -import sys -import argparse -import platform -import copy -import subprocess -import fileinput - -import regen_atoms - -DESCRIPTION = 'Regenerate the rust version of the structs or the bindings file.' -TOOLS_DIR = os.path.dirname(os.path.abspath(__file__)) -COMMON_BUILD_KEY = "__common__" - -COMPILATION_TARGETS = { - # Flags common for all the targets. - COMMON_BUILD_KEY: { - "flags": [ - "--no-unstable-rust", - ], - "clang_flags": [ - "-x", "c++", "-std=c++14", - "-DTRACING=1", "-DIMPL_LIBXUL", "-DMOZ_STYLO_BINDINGS=1", - "-DMOZILLA_INTERNAL_API", "-DRUST_BINDGEN", "-DMOZ_STYLO" - ], - "search_dirs": [ - "{}/dist/include", - "{}/dist/include/nspr", - "{}/../nsprpub/pr/include" - ], - "includes": [ - "{}/mozilla-config.h", - ], - }, - # Generation of style structs. - "structs": { - "target_dir": "../gecko_bindings", - "flags": [ - "--enable-cxx-namespaces", - # FIXME(emilio): Incrementally remove these. Probably mozilla::css - # and mozilla::dom are easier. - "--raw-line", "pub use self::root::*;", - "--raw-line", "pub use self::root::mozilla::*;", - "--raw-line", "pub use self::root::mozilla::css::*;", - "--raw-line", "pub use self::root::mozilla::dom::*;", - "--generate", "types,vars", - ], - "includes": [ - "{}/dist/include/gfxFontConstants.h", - "{}/dist/include/nsThemeConstants.h", - "{}/dist/include/mozilla/dom/AnimationEffectReadOnlyBinding.h", - "{}/dist/include/mozilla/ServoElementSnapshot.h", - "{}/dist/include/mozilla/dom/Element.h", - "{}/dist/include/mozilla/ServoBindings.h", - ], - "files": [ - "{}/dist/include/nsStyleStruct.h", - ], - "build_kinds": { - "debug": { - "clang_flags": [ - "-DDEBUG=1", - "-DJS_DEBUG=1", - ] - }, - "release": { - } - }, - "raw_lines": [ - "use atomic_refcell::AtomicRefCell;", - "use data::ElementData;", - ], - "blacklist_types": [ - "nsString", - ], - "whitelist_vars": [ - "NS_THEME_.*", - "NODE_.*", - "NS_FONT_.*", - "NS_STYLE_.*", - "NS_CORNER_.*", - "NS_RADIUS_.*", - "BORDER_COLOR_.*", - "BORDER_STYLE_.*" - ], - "whitelist": [ - "RawGecko.*", - "mozilla::ServoElementSnapshot.*", - "mozilla::ConsumeStyleBehavior", - "mozilla::LazyComputeBehavior", - "mozilla::css::SheetParsingMode", - "mozilla::SkipRootBehavior", - "mozilla::DisplayItemClip", # Needed because bindgen generates - # specialization tests for this even - # though it shouldn't. - ".*ThreadSafe.*Holder", - "AnonymousContent", - "AudioContext", - "CapturingContentInfo", - "ConsumeStyleBehavior", - "DefaultDelete", - "DOMIntersectionObserverEntry", - "Element", - "FontFamilyList", - "FontFamilyListRefCnt", - "FontFamilyName", - "FontFamilyType", - "FragmentOrURL", - "FrameRequestCallback", - "gfxAlternateValue", - "gfxFontFeature", - "gfxFontVariation", - "GridNamedArea", - "Image", - "ImageURL", - "LazyComputeBehavior", - "nsAttrName", - "nsAttrValue", - "nsBorderColors", - "nscolor", - "nsChangeHint", - "nsCSSKeyword", - "nsCSSPropertyID", - "nsCSSRect", - "nsCSSRect_heap", - "nsCSSShadowArray", - "nsCSSValue", - "nsCSSValueFloatColor", - "nsCSSValueGradient", - "nsCSSValueGradientStop", - "nsCSSValueList", - "nsCSSValueList_heap", - "nsCSSValuePair_heap", - "nsCSSValuePairList", - "nsCSSValuePairList_heap", - "nsCSSValueTokenStream", - "nsCSSValueTriplet_heap", - "nsCursorImage", - "nsFont", - "nsIAtom", - "nsMainThreadPtrHandle", - "nsMainThreadPtrHolder", - "nsMargin", - "nsRect", - "nsRestyleHint", - "nsresult", - "nsSize", - "nsStyleBackground", - "nsStyleBorder", - "nsStyleColor", - "nsStyleColumn", - "nsStyleContent", - "nsStyleContentData", - "nsStyleContext", - "nsStyleCoord", - "nsStyleCounterData", - "nsStyleDisplay", - "nsStyleEffects", - "nsStyleFilter", - "nsStyleFont", - "nsStyleGradient", - "nsStyleGradientStop", - "nsStyleImage", - "nsStyleImageLayers", - "nsStyleList", - "nsStyleMargin", - "nsStyleOutline", - "nsStylePadding", - "nsStylePosition", - "nsStyleSVG", - "nsStyleSVGReset", - "nsStyleTable", - "nsStyleTableBorder", - "nsStyleText", - "nsStyleTextReset", - "nsStyleUIReset", - "nsStyleUnion", - "nsStyleUnit", - "nsStyleUserInterface", - "nsStyleVariables", - "nsStyleVisibility", - "nsStyleXUL", - "nsTArray", - "nsTArrayHeader", - "pair", - "Position", - "Runnable", - "ServoAttrSnapshot", - "ServoElementSnapshot", - "SheetParsingMode", - "Side", - "StaticRefPtr", - "StyleAnimation", - "StyleBasicShape", - "StyleBasicShapeType", - "StyleClipPath", - "StyleClipPathGeometryBox", - "StyleTransition", - "mozilla::UniquePtr", - "mozilla::DefaultDelete", - ], - "bitfield_enum_types": ["nsChangeHint", "nsRestyleHint"], - "opaque_types": [ - "atomic___base", - "nsAString_internal_char_traits", - "nsAString_internal_incompatible_char_type", - "nsACString_internal_char_traits", - "nsACString_internal_incompatible_char_type", - "RefPtr_Proxy", - "RefPtr_Proxy_member_function", - "nsAutoPtr_Proxy", - "nsAutoPtr_Proxy_member_function", - "mozilla::detail::PointerType", - "mozilla::Pair_Base", - "mozilla::SupportsWeakPtr", - "SupportsWeakPtr", - "mozilla::detail::WeakReference", - "mozilla::WeakPtr", - "nsWritingIterator_reference", "nsReadingIterator_reference", - "nsTObserverArray", # <- Inherits from nsAutoTObserverArray<T, 0> - "nsTHashtable", # <- Inheriting from inner typedefs that clang - # doesn't expose properly. - "nsRefPtrHashtable", "nsDataHashtable", "nsClassHashtable", # <- Ditto - "nsIDocument_SelectorCache", # <- Inherits from nsExpirationTracker<.., 4> - "nsIPresShell_ScrollAxis", # <- For some reason the alignment of this is 4 - # for clang. - "nsPIDOMWindow", # <- Takes the vtable from a template parameter, and we can't - # generate it conditionally. - "JS::Rooted", - "mozilla::Maybe", - "gfxSize", # <- union { struct { T width; T height; }; T components[2] }; - "gfxSize_Super", # Ditto. - "mozilla::ErrorResult", # Causes JSWhyMagic to be included & handled incorrectly. - ], - "manual_fixups": [ - ["root::nsString", "::nsstring::nsStringRepr"] - ], - "servo_mapped_generic_types": [ - { - "generic": True, - "gecko": "mozilla::ServoUnsafeCell", - "servo": "::std::cell::UnsafeCell" - }, { - "generic": True, - "gecko": "mozilla::ServoCell", - "servo": "::std::cell::Cell" - }, { - "generic": False, - "gecko": "ServoNodeData", - "servo": "AtomicRefCell<ElementData>", - } - ], - }, - # Generation of the ffi bindings. - "bindings": { - "target_dir": "../gecko_bindings", - "raw_lines": [ - "pub use nsstring::{nsACString, nsAString};", - "type nsACString_internal = nsACString;", - "type nsAString_internal = nsAString;" - ], - "flags": [ - "--generate", "functions", - "--disable-name-namespacing", - ], - "match_headers": [ - "ServoBindingList.h", - "ServoBindings.h", - "ServoTypes.h", - "nsStyleStructList.h", - ], - "files": [ - "{}/dist/include/mozilla/ServoBindings.h", - ], - # Types to just use from the `structs` target. - "structs_types": [ - "RawGeckoDocument", - "RawGeckoElement", - "RawGeckoNode", - "ThreadSafeURIHolder", - "ThreadSafePrincipalHolder", - "ConsumeStyleBehavior", - "LazyComputeBehavior", - "SkipRootBehavior", - "FontFamilyList", - "FontFamilyType", - "ServoElementSnapshot", - "SheetParsingMode", - "StyleBasicShape", - "StyleBasicShapeType", - "StyleClipPath", - "nsCSSKeyword", - "nsCSSShadowArray", - "nsCSSValue", - "nsCSSValueSharedList", - "nsChangeHint", - "nsCursorImage", - "nsFont", - "nsIAtom", - "nsRestyleHint", - "nsStyleBackground", - "nsStyleBorder", - "nsStyleColor", - "nsStyleColumn", - "nsStyleContent", - "nsStyleContext", - "nsStyleCoord", - "nsStyleCoord_Calc", - "nsStyleCoord_CalcValue", - "nsStyleDisplay", - "nsStyleEffects", - "nsStyleFont", - "nsStyleGradient", - "nsStyleGradientStop", - "nsStyleImage", - "nsStyleImageLayers", - "nsStyleImageLayers_Layer", - "nsStyleImageLayers_LayerType", - "nsStyleImageRequest", - "nsStyleList", - "nsStyleMargin", - "nsStyleOutline", - "nsStylePadding", - "nsStylePosition", - "nsStyleQuoteValues", - "nsStyleSVG", - "nsStyleSVGReset", - "nsStyleTable", - "nsStyleTableBorder", - "nsStyleText", - "nsStyleTextReset", - "nsStyleUIReset", - "nsStyleUnion", - "nsStyleUnit", - "nsStyleUserInterface", - "nsStyleVariables", - "nsStyleVisibility", - "nsStyleXUL", - "nscoord", - "nsresult", - ], - "array_types": { - "uintptr_t": "usize", - }, - "servo_nullable_arc_types": [ - "ServoComputedValues", - "ServoCssRules", - "RawServoStyleSheet", - "RawServoDeclarationBlock", - "RawServoStyleRule", - ], - "servo_owned_types": [ - { - "name": "RawServoStyleSet", - "opaque": True, - }, { - "name": "StyleChildrenIterator", - "opaque": True, - }, { - "name": "ServoElementSnapshot", - "opaque": False, - }, - ], - "servo_immutable_borrow_types": [ - "RawGeckoNode", - "RawGeckoElement", - "RawGeckoDocument", - "RawServoDeclarationBlockStrong", - ], - "servo_borrow_types": [ - "nsCSSValue", - ], - "whitelist_functions": [ - "Servo_.*", - "Gecko_.*" - ] - }, - - "atoms": { - "custom_build": regen_atoms.build, - } -} - - -def platform_dependent_defines(): - ret = [] - - if os.name == "posix": - ret.append("-DOS_POSIX=1") - - system = platform.system() - if system == "Linux": - ret.append("-DOS_LINUX=1") - elif system == "Darwin": - ret.append("-DOS_MACOSX=1") - elif system == "Windows": - ret.append("-DOS_WIN=1") - ret.append("-DWIN32=1") - msvc_platform = os.environ["PLATFORM"] - if msvc_platform == "X86": - ret.append("--target=i686-pc-win32") - elif msvc_platform == "X64": - ret.append("--target=x86_64-pc-win32") - else: - raise Exception("Only MSVC builds are supported on Windows") - # For compatibility with MSVC 2015 - ret.append("-fms-compatibility-version=19") - # To enable the builtin __builtin_offsetof so that CRT wouldn't - # use reinterpret_cast in offsetof() which is not allowed inside - # static_assert(). - ret.append("-D_CRT_USE_BUILTIN_OFFSETOF") - # Enable hidden attribute (which is not supported by MSVC and - # thus not enabled by default with a MSVC-compatibile build) - # to exclude hidden symbols from the generated file. - ret.append("-DHAVE_VISIBILITY_HIDDEN_ATTRIBUTE=1") - else: - raise Exception("Unknown platform") - - return ret - - -def extend_object(obj, other): - if not obj or not other: - return obj - - if isinstance(obj, list) and isinstance(other, list): - obj.extend(other) - return - - assert isinstance(obj, dict) and isinstance(other, dict) - - for key in other.keys(): - if key in obj: - extend_object(obj[key], other[key]) - else: - obj[key] = copy.deepcopy(other[key]) - - -def build(objdir, target_name, debug, debugger, kind_name=None, - output_filename=None, bindgen=None, skip_test=False, - verbose=False): - assert target_name in COMPILATION_TARGETS - - current_target = COMPILATION_TARGETS[target_name] - if COMMON_BUILD_KEY in COMPILATION_TARGETS: - current_target = copy.deepcopy(COMPILATION_TARGETS[COMMON_BUILD_KEY]) - extend_object(current_target, COMPILATION_TARGETS[target_name]) - - assert ((kind_name is None and "build_kinds" not in current_target) or - (kind_name in current_target["build_kinds"])) - - if "custom_build" in current_target: - print("[CUSTOM] {}::{} in \"{}\"... ".format(target_name, kind_name, objdir), end='') - sys.stdout.flush() - ret = current_target["custom_build"](objdir, verbose=True) - if ret != 0: - print("FAIL") - else: - print("OK") - - return ret - - if bindgen is None: - bindgen = os.path.join(TOOLS_DIR, "rust-bindgen") - - if os.path.isdir(bindgen): - bindgen = ["cargo", "run", "--manifest-path", - os.path.join(bindgen, "Cargo.toml"), "--features", "llvm_stable", "--release", "--"] - else: - bindgen = [bindgen] - - if kind_name is not None: - current_target = copy.deepcopy(current_target) - extend_object(current_target, current_target["build_kinds"][kind_name]) - - target_dir = None - if output_filename is None and "target_dir" in current_target: - target_dir = current_target["target_dir"] - - if output_filename is None: - output_filename = "{}.rs".format(target_name) - - if kind_name is not None: - output_filename = "{}_{}.rs".format(target_name, kind_name) - - if target_dir: - output_filename = "{}/{}".format(target_dir, output_filename) - - print("[BINDGEN] {}::{} in \"{}\"... ".format(target_name, kind_name, objdir), end='') - sys.stdout.flush() - - flags = [] - - # Types we have to fixup since we insert them manually. - # - # Bindgen only allows us to add stuff outside of the root module. This - # wasn't intended to add new types, but we do so, so we postprocess the - # bindgen output to fixup the path to these types. - fixups = [] - - if "manual_fixups" in current_target: - fixups = current_target["manual_fixups"] - - # This makes an FFI-safe void type that can't be matched on - # &VoidType is UB to have, because you can match on it - # to produce a reachable unreachable. If it's wrapped in - # a struct as a private field it becomes okay again - # - # Not 100% sure of how safe this is, but it's what we're using - # in the XPCOM ffi too - # https://github.com/nikomatsakis/rust-memory-model/issues/2 - def zero_size_type(ty, flags): - flags.append("--blacklist-type") - flags.append(ty) - flags.append("--raw-line") - flags.append("enum {0}Void{{ }}".format(ty)) - flags.append("--raw-line") - flags.append("pub struct {0}({0}Void);".format(ty)) - - if "flags" in current_target: - flags.extend(current_target["flags"]) - - clang_flags = [] - - if "clang_flags" in current_target: - clang_flags.extend(current_target["clang_flags"]) - - clang_flags.extend(platform_dependent_defines()) - - if platform.system() == "Windows": - flags.append("--use-msvc-mangling") - - if "raw_lines" in current_target: - for raw_line in current_target["raw_lines"]: - flags.append("--raw-line") - flags.append(raw_line) - - if "search_dirs" in current_target: - for dir_name in current_target["search_dirs"]: - clang_flags.append("-I") - clang_flags.append(dir_name.format(objdir)) - - if "includes" in current_target: - for file_name in current_target["includes"]: - clang_flags.append("-include") - clang_flags.append(file_name.format(objdir)) - - if "whitelist" in current_target: - for header in current_target["whitelist"]: - flags.append("--whitelist-type") - flags.append(header) - - if "whitelist_functions" in current_target: - for header in current_target["whitelist_functions"]: - flags.append("--whitelist-function") - flags.append(header) - - if "whitelist_vars" in current_target: - for header in current_target["whitelist_vars"]: - flags.append("--whitelist-var") - flags.append(header) - - if "bitfield_enum_types" in current_target: - for ty in current_target["bitfield_enum_types"]: - flags.append("--bitfield-enum") - flags.append(ty) - - if "opaque_types" in current_target: - for ty in current_target["opaque_types"]: - flags.append("--opaque-type") - flags.append(ty) - - if "array_types" in current_target: - for cpp_type, rust_type in current_target["array_types"].items(): - flags.append("--blacklist-type") - flags.append("nsTArrayBorrowed_{}".format(cpp_type)) - flags.append("--raw-line") - flags.append("pub type nsTArrayBorrowed_{0}<'a> = &'a mut ::gecko_bindings::structs::nsTArray<{1}>;" - .format(cpp_type, rust_type)) - - if "blacklist_types" in current_target: - for ty in current_target["blacklist_types"]: - flags.append("--blacklist-type") - flags.append(ty) - - if "servo_nullable_arc_types" in current_target: - for ty in current_target["servo_nullable_arc_types"]: - flags.append("--blacklist-type") - flags.append("{}Strong".format(ty)) - flags.append("--raw-line") - flags.append("pub type {0}Strong = ::gecko_bindings::sugar::ownership::Strong<{0}>;" - .format(ty)) - flags.append("--blacklist-type") - flags.append("{}BorrowedOrNull".format(ty)) - flags.append("--raw-line") - flags.append("pub type {0}BorrowedOrNull<'a> = \ -Option<&'a {0}>;".format(ty)) - flags.append("--blacklist-type") - flags.append("{}Borrowed".format(ty)) - flags.append("--raw-line") - flags.append("pub type {0}Borrowed<'a> = &'a {0};".format(ty)) - zero_size_type(ty, flags) - - if "servo_immutable_borrow_types" in current_target: - for ty in current_target.get("servo_immutable_borrow_types", []) + current_target.get("servo_borrow_types", []): - flags.append("--blacklist-type") - flags.append("{}Borrowed".format(ty)) - flags.append("--raw-line") - flags.append("pub type {0}Borrowed<'a> = &'a {0};".format(ty)) - flags.append("--blacklist-type") - flags.append("{}BorrowedOrNull".format(ty)) - flags.append("--raw-line") - flags.append("pub type {0}BorrowedOrNull<'a> = Option<&'a {0}>;".format(ty)) - if "servo_borrow_types" in current_target: - for ty in current_target["servo_borrow_types"]: - flags.append("--blacklist-type") - flags.append("{}BorrowedMut".format(ty)) - flags.append("--raw-line") - flags.append("pub type {0}BorrowedMut<'a> = &'a mut {0};".format(ty)) - flags.append("--blacklist-type") - flags.append("{}BorrowedMutOrNull".format(ty)) - flags.append("--raw-line") - flags.append("pub type {0}BorrowedMutOrNull<'a> = \ -Option<&'a mut {0}>;".format(ty)) - # Right now the only immutable borrow types are ones which we import - # from the |structs| module. As such, we don't need to create an opaque - # type with zero_size_type. If we ever introduce immutable borrow types - # which _do_ need to be opaque, we'll need a separate mode. - - if "servo_mapped_generic_types" in current_target: - for ty in current_target["servo_mapped_generic_types"]: - flags.append("--blacklist-type") - flags.append(ty["gecko"]) - - gecko_name = ty["gecko"].split("::")[-1] - flags.append("--raw-line") - flags.append("pub type {0}{2} = {1}{2};".format(gecko_name, ty["servo"], "<T>" if ty["generic"] else "")) - fixups.append(["root::{}".format(ty["gecko"]), "::gecko_bindings::structs::{}".format(gecko_name)]) - - if "servo_owned_types" in current_target: - for entry in current_target["servo_owned_types"]: - ty = entry["name"] - flags.append("--blacklist-type") - flags.append("{}Borrowed".format(ty)) - flags.append("--raw-line") - flags.append("pub type {0}Borrowed<'a> = &'a {0};".format(ty)) - flags.append("--blacklist-type") - flags.append("{}BorrowedMut".format(ty)) - flags.append("--raw-line") - flags.append("pub type {0}BorrowedMut<'a> = &'a mut {0};".format(ty)) - flags.append("--blacklist-type") - flags.append("{}Owned".format(ty)) - flags.append("--raw-line") - flags.append("pub type {0}Owned = ::gecko_bindings::sugar::ownership::Owned<{0}>;".format(ty)) - flags.append("--blacklist-type") - flags.append("{}BorrowedOrNull".format(ty)) - flags.append("--raw-line") - flags.append("pub type {0}BorrowedOrNull<'a> = Option<&'a {0}>;" - .format(ty)) - flags.append("--blacklist-type") - flags.append("{}BorrowedMutOrNull".format(ty)) - flags.append("--raw-line") - flags.append("pub type {0}BorrowedMutOrNull<'a> = Option<&'a mut {0}>;" - .format(ty)) - flags.append("--blacklist-type") - flags.append("{}OwnedOrNull".format(ty)) - flags.append("--raw-line") - flags.append("pub type {0}OwnedOrNull = ::gecko_bindings::sugar::ownership::OwnedOrNull<{0}>;".format(ty)) - if entry["opaque"]: - zero_size_type(ty, flags) - - if "structs_types" in current_target: - for ty in current_target["structs_types"]: - flags.append("--blacklist-type") - flags.append(ty) - flags.append("--raw-line") - flags.append("use gecko_bindings::structs::{};".format(ty)) - - # TODO: this is hacky, figure out a better way to do it without - # hardcoding everything... - if ty.startswith("nsStyle"): - flags.extend([ - "--raw-line", - "unsafe impl Send for {} {{}}".format(ty), - "--raw-line", - "unsafe impl Sync for {} {{}}".format(ty), - ]) - - flags.append("-o") - flags.append(output_filename) - - assert len(current_target["files"]) == 1 - flags.append(current_target["files"][0].format(objdir)) - - flags = bindgen + flags + ["--"] + clang_flags - - if verbose: - print(flags) - - output = "" - try: - if debug: - flags = [debugger, "--args"] + flags - subprocess.check_call(flags) - else: - output = subprocess.check_output(flags, stderr=subprocess.STDOUT, - universal_newlines=True) - except subprocess.CalledProcessError as e: - print("FAIL\n", e.output) - return 1 - - generated = fileinput.input(output_filename, inplace=True) - for line in generated: - for fixup in fixups: - line = re.sub("\\b{}\\b".format(fixup[0]), fixup[1], line) - print(line, end='') - generated.close() - - print("OK") - print("(please test with ./mach test-stylo)") - - if verbose: - print(output) - - return 0 - - -def builds_for(target_name, kind): - if target_name == "all": - for target in COMPILATION_TARGETS.keys(): - if target == COMMON_BUILD_KEY: - continue - - if "build_kinds" in COMPILATION_TARGETS[target]: - for kind in COMPILATION_TARGETS[target]["build_kinds"].keys(): - yield (target, kind) - else: - yield (target, None) - return - - target = COMPILATION_TARGETS[target_name] - if "build_kinds" in target: - if kind is None: - for kind in target["build_kinds"].keys(): - yield(target_name, kind) - else: - yield (target_name, kind) - return - - yield (target_name, None) - - -def main(): - parser = argparse.ArgumentParser(description=DESCRIPTION) - parser.add_argument('--target', default='all', - help='The target to build, either "structs" or "bindings"') - parser.add_argument('--kind', - help='Kind of build') - parser.add_argument('--bindgen', - help='Override bindgen binary') - parser.add_argument('--output', '-o', - help='Output of the script') - parser.add_argument('--skip-test', - action='store_true', - help='Skip automatic tests, useful for debugging') - parser.add_argument('--verbose', '-v', - action='store_true', - help='Be... verbose') - parser.add_argument('--debug', - action='store_true', - help='Try to use a debugger to debug bindgen commands (default: gdb)') - parser.add_argument('--debugger', default='gdb', - help='Debugger to use. Only used if --debug is passed.') - parser.add_argument('objdir') - - args = parser.parse_args() - - if not os.path.isdir(args.objdir): - print("\"{}\" doesn't seem to be a directory".format(args.objdir)) - return 1 - - if (args.target != "all" and args.target not in COMPILATION_TARGETS) or args.target == COMMON_BUILD_KEY: - print("{} is not a valid compilation target.".format(args.target)) - print("Valid compilation targets are:") - for target in COMPILATION_TARGETS.keys(): - if target != COMMON_BUILD_KEY: - print("\t * {}".format(target)) - return 1 - - current_target = COMPILATION_TARGETS.get(args.target, {}) - if args.kind and "build_kinds" in current_target and args.kind not in current_target["build_kinds"]: - print("{} is not a valid build kind.".format(args.kind)) - print("Valid build kinds are:") - for kind in current_target["build_kinds"].keys(): - print("\t * {}".format(kind)) - return 1 - - for target, kind in builds_for(args.target, args.kind): - ret = build(args.objdir, target, kind_name=kind, - debug=args.debug, debugger=args.debugger, - bindgen=args.bindgen, skip_test=args.skip_test, - output_filename=args.output, - verbose=args.verbose) - if ret != 0: - print("{}::{} failed".format(target, kind)) - return ret - - return 0 - -if __name__ == '__main__': - sys.exit(main()) diff --git a/components/style/binding_tools/regen.sh b/components/style/binding_tools/regen.sh deleted file mode 100755 index d08e17116b0..00000000000 --- a/components/style/binding_tools/regen.sh +++ /dev/null @@ -1,37 +0,0 @@ -#!/usr/bin/env bash - -# 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/. - -set -o errexit -set -o nounset -set -o pipefail - -TOOLS_DIR="$(dirname ${0})" - -if [[ ${#} -eq 0 ]]; then - echo "Usage: ${0} /path/to/gecko/objdir [other-regen.py-flags]" - exit 1 -fi - -# Check for rust-bindgen -if [[ ! -d "${TOOLS_DIR}/rust-bindgen" ]]; then - echo "rust-bindgen not found. Run setup_bindgen.sh first." - exit 1 -fi - -# Check for /usr/include -if [[ ! -d /usr/include ]]; then - echo "/usr/include doesn't exist." \ - "Mac users may need to run 'xcode-select --install.'" - exit 1 -fi - -if [[ "$(uname)" == "Linux" ]]; then - LIBCLANG_PATH=/usr/lib/llvm-3.8/lib -else - LIBCLANG_PATH="$(brew --prefix llvm38)/lib/llvm-3.8/lib" -fi - -"./${TOOLS_DIR}/regen.py" --target all "${@}" diff --git a/components/style/binding_tools/regen_atoms.py b/components/style/binding_tools/regen_atoms.py index 5af58417b3d..a12ccd39899 100755 --- a/components/style/binding_tools/regen_atoms.py +++ b/components/style/binding_tools/regen_atoms.py @@ -6,6 +6,7 @@ import re import os +import sys PRELUDE = """ @@ -32,15 +33,15 @@ def msvc32_symbolify(source, ident): class GkAtomSource: - PATTERN = re.compile('^GK_ATOM\((?P<ident>.+),\s*"(?P<value>.*)"\)', re.M) - FILE = "dist/include/nsGkAtomList.h" + PATTERN = re.compile('^GK_ATOM\((.+),\s*"(.*)"\)') + FILE = "include/nsGkAtomList.h" CLASS = "nsGkAtoms" TYPE = "nsIAtom" class CSSPseudoElementsAtomSource: - PATTERN = re.compile('^CSS_PSEUDO_ELEMENT\((?P<ident>.+),\s*"(?P<value>.*)",', re.M) - FILE = "dist/include/nsCSSPseudoElementList.h" + PATTERN = re.compile('^CSS_PSEUDO_ELEMENT\((.+),\s*"(.*)",') + FILE = "include/nsCSSPseudoElementList.h" CLASS = "nsCSSPseudoElements" # NB: nsICSSPseudoElement is effectively the same as a nsIAtom, but we need # this for MSVC name mangling. @@ -48,24 +49,16 @@ class CSSPseudoElementsAtomSource: class CSSAnonBoxesAtomSource: - PATTERN = re.compile('^CSS_ANON_BOX\((?P<ident>.+),\s*"(?P<value>.*)"\)', re.M) - FILE = "dist/include/nsCSSAnonBoxList.h" + PATTERN = re.compile('^CSS_ANON_BOX\((.+),\s*"(.*)"\)') + FILE = "include/nsCSSAnonBoxList.h" CLASS = "nsCSSAnonBoxes" TYPE = "nsICSSAnonBoxPseudo" -class CSSPropsAtomSource: - PATTERN = re.compile('^CSS_PROP_[A-Z]+\(\s*(?P<value>[^,]+),\s*(?P<ident>[^,]+)', re.M) - FILE = "dist/include/nsCSSPropList.h" - CLASS = "nsCSSProps" - TYPE = "nsICSSProperty" - - SOURCES = [ GkAtomSource, CSSPseudoElementsAtomSource, CSSAnonBoxesAtomSource, - CSSPropsAtomSource, ] @@ -103,14 +96,10 @@ def collect_atoms(objdir): atoms = [] for source in SOURCES: with open(os.path.join(objdir, source.FILE)) as f: - content = f.read() - found = set() - for match in source.PATTERN.finditer(content): - ident = match.group('ident') - if ident in found: - continue - found.add(ident) - atoms.append(Atom(source, ident, match.group('value'))) + for line in f.readlines(): + result = re.match(source.PATTERN, line) + if result: + atoms.append(Atom(source, result.group(1), result.group(2))) return atoms @@ -231,8 +220,15 @@ def write_pseudo_element_helper(atoms, target_filename): f.write("}\n") -def build(objdir, verbose=False): - atoms = collect_atoms(objdir) - write_atom_macro(atoms, "../gecko_string_cache/atom_macro.rs") - write_pseudo_element_helper(atoms, "../gecko/generated/gecko_pseudo_element_helper.rs") - return 0 +def generate_atoms(dist): + style_path = os.path.dirname(os.path.dirname(__file__)) + atoms = collect_atoms(dist) + write_atom_macro(atoms, os.path.join(style_path, "gecko_string_cache/atom_macro.rs")) + write_pseudo_element_helper(atoms, os.path.join(style_path, "gecko/generated/gecko_pseudo_element_helper.rs")) + + +if __name__ == "__main__": + if len(sys.argv) != 2: + print("Usage: {} objdir".format(sys.argv[0])) + exit(2) + generate_atoms(os.path.join(sys.argv[1], "dist")) diff --git a/components/style/binding_tools/setup_bindgen.sh b/components/style/binding_tools/setup_bindgen.sh index feb788d4bab..4447b2ccda3 100755 --- a/components/style/binding_tools/setup_bindgen.sh +++ b/components/style/binding_tools/setup_bindgen.sh @@ -28,11 +28,3 @@ fi export LD_LIBRARY_PATH="${LIBCLANG_PATH}" export DYLD_LIBRARY_PATH="${LIBCLANG_PATH}" - -# Don't try to clone twice. -if [[ ! -d rust-bindgen ]]; then - git clone https://github.com/servo/rust-bindgen.git -fi - -cd rust-bindgen -cargo build --features llvm_stable --release diff --git a/components/style/bloom.rs b/components/style/bloom.rs index 4dd880d8ea7..e2f45bb6233 100644 --- a/components/style/bloom.rs +++ b/components/style/bloom.rs @@ -5,32 +5,23 @@ //! The style bloom filter is used as an optimization when matching deep //! descendant selectors. -use dom::{TNode, TElement, UnsafeNode}; +use dom::{SendElement, TElement}; use matching::MatchMethods; use selectors::bloom::BloomFilter; -pub struct StyleBloom { +pub struct StyleBloom<E: TElement> { /// The bloom filter per se. filter: Box<BloomFilter>, - /// The stack of elements that this bloom filter contains. These unsafe - /// nodes are guaranteed to be elements. - /// - /// Note that the use we do for them is safe, since the data we access from - /// them is completely read-only during restyling. - elements: Vec<UnsafeNode>, - - /// A monotonic counter incremented which each reflow in order to invalidate - /// the bloom filter if appropriate. - generation: u32, + /// The stack of elements that this bloom filter contains. + elements: Vec<SendElement<E>>, } -impl StyleBloom { - pub fn new(generation: u32) -> Self { +impl<E: TElement> StyleBloom<E> { + pub fn new() -> Self { StyleBloom { filter: Box::new(BloomFilter::new()), elements: vec![], - generation: generation, } } @@ -38,43 +29,27 @@ impl StyleBloom { &*self.filter } - pub fn generation(&self) -> u32 { - self.generation - } - - pub fn maybe_pop<E>(&mut self, element: E) - where E: TElement + MatchMethods - { - if self.elements.last() == Some(&element.as_node().to_unsafe()) { - self.pop::<E>().unwrap(); + pub fn maybe_pop(&mut self, element: E) { + if self.elements.last().map(|el| **el) == Some(element) { + self.pop().unwrap(); } } /// Push an element to the bloom filter, knowing that it's a child of the /// last element parent. - pub fn push<E>(&mut self, element: E) - where E: TElement + MatchMethods, - { + pub fn push(&mut self, element: E) { if cfg!(debug_assertions) { if self.elements.is_empty() { assert!(element.parent_element().is_none()); } } element.insert_into_bloom_filter(&mut *self.filter); - self.elements.push(element.as_node().to_unsafe()); + self.elements.push(unsafe { SendElement::new(element) }); } /// Pop the last element in the bloom filter and return it. - fn pop<E>(&mut self) -> Option<E> - where E: TElement + MatchMethods, - { - let popped = - self.elements.pop().map(|unsafe_node| { - let parent = unsafe { - E::ConcreteNode::from_unsafe(&unsafe_node) - }; - parent.as_element().unwrap() - }); + fn pop(&mut self) -> Option<E> { + let popped = self.elements.pop().map(|el| *el); if let Some(popped) = popped { popped.remove_from_bloom_filter(&mut self.filter); } @@ -87,14 +62,12 @@ impl StyleBloom { self.elements.clear(); } - fn rebuild<E>(&mut self, mut element: E) -> usize - where E: TElement + MatchMethods, - { + fn rebuild(&mut self, mut element: E) -> usize { self.clear(); while let Some(parent) = element.parent_element() { parent.insert_into_bloom_filter(&mut *self.filter); - self.elements.push(parent.as_node().to_unsafe()); + self.elements.push(unsafe { SendElement::new(parent) }); element = parent; } @@ -105,14 +78,11 @@ impl StyleBloom { /// In debug builds, asserts that all the parents of `element` are in the /// bloom filter. - pub fn assert_complete<E>(&self, mut element: E) - where E: TElement, - { + pub fn assert_complete(&self, mut element: E) { if cfg!(debug_assertions) { let mut checked = 0; while let Some(parent) = element.parent_element() { - assert_eq!(parent.as_node().to_unsafe(), - self.elements[self.elements.len() - 1 - checked]); + assert_eq!(parent, *self.elements[self.elements.len() - 1 - checked]); element = parent; checked += 1; } @@ -127,16 +97,13 @@ impl StyleBloom { /// provided always rebuilds the filter from scratch. /// /// Returns the new bloom filter depth. - pub fn insert_parents_recovering<E>(&mut self, - element: E, - element_depth: Option<usize>, - generation: u32) - -> usize - where E: TElement, + pub fn insert_parents_recovering(&mut self, + element: E, + element_depth: Option<usize>) + -> usize { // Easy case, we're in a different restyle, or we're empty. - if self.generation != generation || self.elements.is_empty() { - self.generation = generation; + if self.elements.is_empty() { return self.rebuild(element); } @@ -149,8 +116,7 @@ impl StyleBloom { } }; - let unsafe_parent = parent_element.as_node().to_unsafe(); - if self.elements.last() == Some(&unsafe_parent) { + if self.elements.last().map(|el| **el) == Some(parent_element) { // Ta da, cache hit, we're all done. return self.elements.len(); } @@ -182,7 +148,7 @@ impl StyleBloom { // If the filter represents an element too deep in the dom, we need to // pop ancestors. while current_depth > element_depth - 1 { - self.pop::<E>().expect("Emilio is bad at math"); + self.pop().expect("Emilio is bad at math"); current_depth -= 1; } @@ -219,9 +185,9 @@ impl StyleBloom { // off the document (such as scrollbars) as a separate subtree from the // document root. Thus it's possible with Gecko that we do not find any // common ancestor. - while *self.elements.last().unwrap() != common_parent.as_node().to_unsafe() { + while **self.elements.last().unwrap() != common_parent { parents_to_insert.push(common_parent); - self.pop::<E>().unwrap(); + self.pop().unwrap(); common_parent = match common_parent.parent_element() { Some(parent) => parent, None => { diff --git a/components/style/build.rs b/components/style/build.rs index b8d46348b94..fb8d4a5e5f9 100644 --- a/components/style/build.rs +++ b/components/style/build.rs @@ -2,13 +2,30 @@ * 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/. */ +#[macro_use] +extern crate lazy_static; +#[cfg(feature = "bindgen")] +extern crate libbindgen; +#[cfg(feature = "bindgen")] +extern crate regex; extern crate walkdir; +extern crate phf_codegen; use std::env; +use std::fs::File; +use std::io::{BufWriter, BufReader, BufRead, Write}; use std::path::Path; use std::process::{Command, exit}; use walkdir::WalkDir; +#[cfg(feature = "gecko")] +mod build_gecko; + +#[cfg(not(feature = "gecko"))] +mod build_gecko { + pub fn generate() {} +} + #[cfg(windows)] fn find_python() -> String { if Command::new("python2.7.exe").arg("--version").output().is_ok() { @@ -36,8 +53,7 @@ fn find_python() -> String { }.to_owned() } -fn main() { - println!("cargo:rerun-if-changed=build.rs"); +fn generate_properties() { for entry in WalkDir::new("properties") { let entry = entry.unwrap(); match entry.path().extension().and_then(|e| e.to_str()) { @@ -61,4 +77,27 @@ fn main() { if !status.success() { exit(1) } + + let path = Path::new(&env::var("OUT_DIR").unwrap()).join("static_ids.rs"); + let static_ids = Path::new(&env::var("OUT_DIR").unwrap()).join("static_ids.txt"); + let mut file = BufWriter::new(File::create(&path).unwrap()); + let static_ids = BufReader::new(File::open(&static_ids).unwrap()); + + write!(&mut file, "static STATIC_IDS: ::phf::Map<&'static str, StaticId> = ").unwrap(); + let mut map = phf_codegen::Map::new(); + for result in static_ids.lines() { + let line = result.unwrap(); + let mut split = line.split('\t'); + let key = split.next().unwrap().to_owned(); + let value = split.next().unwrap(); + map.entry(key, value); + } + map.build(&mut file).unwrap(); + write!(&mut file, ";\n").unwrap(); +} + +fn main() { + println!("cargo:rerun-if-changed=build.rs"); + generate_properties(); + build_gecko::generate(); } diff --git a/components/style/build_gecko.rs b/components/style/build_gecko.rs new file mode 100644 index 00000000000..81c49fa5909 --- /dev/null +++ b/components/style/build_gecko.rs @@ -0,0 +1,632 @@ +/* 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/. */ + +mod common { + use std::env; + use std::path::PathBuf; + + lazy_static! { + pub static ref OUTDIR_PATH: PathBuf = PathBuf::from(env::var("OUT_DIR").unwrap()).join("gecko"); + } + + pub const STRUCTS_DEBUG_FILE: &'static str = "structs_debug.rs"; + pub const STRUCTS_RELEASE_FILE: &'static str = "structs_release.rs"; + pub const BINDINGS_FILE: &'static str = "bindings.rs"; + + #[derive(Clone, Copy, PartialEq)] + pub enum BuildType { + Debug, + Release, + } + + pub fn structs_file(build_type: BuildType) -> &'static str { + match build_type { + BuildType::Debug => STRUCTS_DEBUG_FILE, + BuildType::Release => STRUCTS_RELEASE_FILE + } + } +} + +#[cfg(feature = "bindgen")] +mod bindings { + use libbindgen::{Builder, CodegenConfig}; + use regex::Regex; + use std::collections::HashSet; + use std::env; + use std::fs::File; + use std::io::{BufWriter, Read, Write}; + use std::path::PathBuf; + use std::sync::Mutex; + use super::common::*; + + lazy_static! { + static ref INCLUDE_RE: Regex = Regex::new(r#"#include\s*"(.+?)""#).unwrap(); + static ref DISTDIR_PATH: PathBuf = { + let path = PathBuf::from(env::var("MOZ_DIST").unwrap()); + if !path.is_absolute() || !path.is_dir() { + panic!("MOZ_DIST must be an absolute directory, was: {}", path.display()); + } + path + }; + static ref SEARCH_PATHS: Vec<PathBuf> = vec![ + DISTDIR_PATH.join("include"), + DISTDIR_PATH.join("include/nspr"), + ]; + static ref ADDED_PATHS: Mutex<HashSet<PathBuf>> = Mutex::new(HashSet::new()); + } + + fn search_include(name: &str) -> Option<PathBuf> { + for path in SEARCH_PATHS.iter() { + let file = path.join(name); + if file.is_file() { + return Some(file); + } + } + None + } + + fn add_headers_recursively(path: PathBuf, added_paths: &mut HashSet<PathBuf>) { + if added_paths.contains(&path) { + return; + } + let mut file = File::open(&path).unwrap(); + let mut content = String::new(); + file.read_to_string(&mut content).unwrap(); + println!("cargo:rerun-if-changed={}", path.to_str().unwrap()); + added_paths.insert(path); + // Find all includes and add them recursively + for cap in INCLUDE_RE.captures_iter(&content) { + if let Some(path) = search_include(cap.at(1).unwrap()) { + add_headers_recursively(path, added_paths); + } + } + } + + fn add_include(name: &str) -> String { + let mut added_paths = ADDED_PATHS.lock().unwrap(); + let file = search_include(name).unwrap(); + let result = String::from(file.to_str().unwrap()); + add_headers_recursively(file, &mut *added_paths); + result + } + + trait BuilderExt { + fn get_initial_builder(build_type: BuildType) -> Builder; + fn include<T: Into<String>>(self, file: T) -> Builder; + fn zero_size_type(self, ty: &str) -> Builder; + fn borrowed_type(self, ty: &str) -> Builder; + fn mutable_borrowed_type(self, ty: &str) -> Builder; + } + + impl BuilderExt for Builder { + fn get_initial_builder(build_type: BuildType) -> Builder { + let mut builder = Builder::default().no_unstable_rust(); + let args = [ + "-x", "c++", "-std=c++14", + "-DTRACING=1", "-DIMPL_LIBXUL", "-DMOZ_STYLO_BINDINGS=1", + "-DMOZILLA_INTERNAL_API", "-DRUST_BINDGEN", "-DMOZ_STYLO" + ]; + for &arg in args.iter() { + builder = builder.clang_arg(arg); + } + for dir in SEARCH_PATHS.iter() { + builder = builder.clang_arg("-I").clang_arg(dir.to_str().unwrap()); + } + builder = builder.include(add_include("mozilla-config.h")); + + if build_type == BuildType::Debug { + builder = builder.clang_arg("-DDEBUG=1").clang_arg("-DJS_DEBUG=1"); + } + if cfg!(target_family = "unix") { + builder = builder.clang_arg("-DOS_POSIX=1"); + } + if cfg!(target_os = "linux") { + builder = builder.clang_arg("-DOS_LINUX=1"); + } else if cfg!(target_os = "macos") { + builder = builder.clang_arg("-DOS_MACOSX=1"); + } else if cfg!(target_env = "msvc") { + builder = builder.clang_arg("-DOS_WIN=1").clang_arg("-DWIN32=1") + // For compatibility with MSVC 2015 + .clang_arg("-fms-compatibility-version=19") + // To enable the builtin __builtin_offsetof so that CRT wouldn't + // use reinterpret_cast in offsetof() which is not allowed inside + // static_assert(). + .clang_arg("-D_CRT_USE_BUILTIN_OFFSETOF") + // Enable hidden attribute (which is not supported by MSVC and + // thus not enabled by default with a MSVC-compatibile build) + // to exclude hidden symbols from the generated file. + .clang_arg("-DHAVE_VISIBILITY_HIDDEN_ATTRIBUTE=1"); + if cfg!(target_pointer_width = "32") { + builder = builder.clang_arg("--target=i686-pc-win32"); + } else { + builder = builder.clang_arg("--target=x86_64-pc-win32"); + } + } else { + panic!("Unknown platform"); + } + builder + } + fn include<T: Into<String>>(self, file: T) -> Builder { + self.clang_arg("-include").clang_arg(file) + } + // This makes an FFI-safe void type that can't be matched on + // &VoidType is UB to have, because you can match on it + // to produce a reachable unreachable. If it's wrapped in + // a struct as a private field it becomes okay again + // + // Not 100% sure of how safe this is, but it's what we're using + // in the XPCOM ffi too + // https://github.com/nikomatsakis/rust-memory-model/issues/2 + fn zero_size_type(self, ty: &str) -> Builder { + self.hide_type(ty) + .raw_line(format!("enum {}Void {{ }}", ty)) + .raw_line(format!("pub struct {0}({0}Void);", ty)) + } + fn borrowed_type(self, ty: &str) -> Builder { + self.hide_type(format!("{}Borrowed", ty)) + .raw_line(format!("pub type {0}Borrowed<'a> = &'a {0};", ty)) + .hide_type(format!("{}BorrowedOrNull", ty)) + .raw_line(format!("pub type {0}BorrowedOrNull<'a> = Option<&'a {0}>;", ty)) + } + fn mutable_borrowed_type(self, ty: &str) -> Builder { + self.borrowed_type(ty) + .hide_type(format!("{}BorrowedMut", ty)) + .raw_line(format!("pub type {0}BorrowedMut<'a> = &'a mut {0};", ty)) + .hide_type(format!("{}BorrowedMutOrNull", ty)) + .raw_line(format!("pub type {0}BorrowedMutOrNull<'a> = Option<&'a mut {0}>;", ty)) + } + } + + fn write_binding_file(builder: Builder, file: &str) { + let bindings = builder.generate().expect("Unable to generate bindings"); + let binding_file = File::create(&OUTDIR_PATH.join(file)).unwrap(); + bindings.write(Box::new(BufWriter::new(binding_file))).expect("Unable to write output"); + } + + pub fn generate_structs(build_type: BuildType) { + let mut builder = Builder::get_initial_builder(build_type) + .enable_cxx_namespaces() + .with_codegen_config(CodegenConfig { + types: true, + vars: true, + ..CodegenConfig::nothing() + }) + .header(add_include("nsStyleStruct.h")) + .include(add_include("gfxFontConstants.h")) + .include(add_include("nsThemeConstants.h")) + .include(add_include("mozilla/dom/AnimationEffectReadOnlyBinding.h")) + .include(add_include("mozilla/ServoElementSnapshot.h")) + .include(add_include("mozilla/dom/Element.h")) + .include(add_include("mozilla/ServoBindings.h")) + // FIXME(emilio): Incrementally remove these "pub use"s. Probably + // mozilla::css and mozilla::dom are easier. + .raw_line("pub use self::root::*;") + .raw_line("pub use self::root::mozilla::*;") + .raw_line("pub use self::root::mozilla::css::*;") + .raw_line("pub use self::root::mozilla::dom::*;") + .raw_line("use atomic_refcell::AtomicRefCell;") + .raw_line("use data::ElementData;") + .hide_type("nsString") + .bitfield_enum("nsChangeHint") + .bitfield_enum("nsRestyleHint"); + let whitelist_vars = [ + "NS_THEME_.*", + "NODE_.*", + "NS_FONT_.*", + "NS_STYLE_.*", + "NS_CORNER_.*", + "NS_RADIUS_.*", + "BORDER_COLOR_.*", + "BORDER_STYLE_.*" + ]; + let whitelist = [ + "RawGecko.*", + "mozilla::ServoElementSnapshot.*", + "mozilla::ConsumeStyleBehavior", + "mozilla::LazyComputeBehavior", + "mozilla::css::SheetParsingMode", + "mozilla::TraversalRootBehavior", + "mozilla::DisplayItemClip", // Needed because bindgen generates + // specialization tests for this even + // though it shouldn't. + "mozilla::StyleShapeRadius", + ".*ThreadSafe.*Holder", + "AnonymousContent", + "AudioContext", + "CapturingContentInfo", + "ConsumeStyleBehavior", + "DefaultDelete", + "DOMIntersectionObserverEntry", + "Element", + "FontFamilyList", + "FontFamilyListRefCnt", + "FontFamilyName", + "FontFamilyType", + "FragmentOrURL", + "FrameRequestCallback", + "gfxAlternateValue", + "gfxFontFeature", + "gfxFontVariation", + "GridNamedArea", + "Image", + "ImageURL", + "LazyComputeBehavior", + "nsAttrName", + "nsAttrValue", + "nsBorderColors", + "nscolor", + "nsChangeHint", + "nsCSSKeyword", + "nsCSSPropertyID", + "nsCSSRect", + "nsCSSRect_heap", + "nsCSSShadowArray", + "nsCSSValue", + "nsCSSValueFloatColor", + "nsCSSValueGradient", + "nsCSSValueGradientStop", + "nsCSSValueList", + "nsCSSValueList_heap", + "nsCSSValuePair_heap", + "nsCSSValuePairList", + "nsCSSValuePairList_heap", + "nsCSSValueTokenStream", + "nsCSSValueTriplet_heap", + "nsCursorImage", + "nsFont", + "nsIAtom", + "nsMainThreadPtrHandle", + "nsMainThreadPtrHolder", + "nsMargin", + "nsRect", + "nsRestyleHint", + "nsresult", + "nsSize", + "nsStyleBackground", + "nsStyleBorder", + "nsStyleColor", + "nsStyleColumn", + "nsStyleContent", + "nsStyleContentData", + "nsStyleContext", + "nsStyleCoord", + "nsStyleCounterData", + "nsStyleDisplay", + "nsStyleEffects", + "nsStyleFilter", + "nsStyleFont", + "nsStyleGradient", + "nsStyleGradientStop", + "nsStyleImage", + "nsStyleImageLayers", + "nsStyleList", + "nsStyleMargin", + "nsStyleOutline", + "nsStylePadding", + "nsStylePosition", + "nsStyleSVG", + "nsStyleSVGReset", + "nsStyleTable", + "nsStyleTableBorder", + "nsStyleText", + "nsStyleTextReset", + "nsStyleUIReset", + "nsStyleUnion", + "nsStyleUnit", + "nsStyleUserInterface", + "nsStyleVariables", + "nsStyleVisibility", + "nsStyleXUL", + "nsTArray", + "nsTArrayHeader", + "pair", + "Position", + "Runnable", + "ServoAttrSnapshot", + "ServoElementSnapshot", + "SheetParsingMode", + "Side", // must be a rust-bindgen bug that requires both of these + "mozilla::Side", + "StaticRefPtr", + "StyleAnimation", + "StyleBasicShape", + "StyleBasicShapeType", + "StyleClipPath", + "StyleClipPathGeometryBox", + "StyleTransition", + "mozilla::UniquePtr", + "mozilla::DefaultDelete", + ]; + let opaque_types = [ + "std::namespace::atomic___base", "std::atomic__My_base", + "nsAString_internal_char_traits", + "nsAString_internal_incompatible_char_type", + "nsACString_internal_char_traits", + "nsACString_internal_incompatible_char_type", + "RefPtr_Proxy", + "RefPtr_Proxy_member_function", + "nsAutoPtr_Proxy", + "nsAutoPtr_Proxy_member_function", + "mozilla::detail::PointerType", + "mozilla::Pair_Base", + "mozilla::SupportsWeakPtr", + "SupportsWeakPtr", + "mozilla::detail::WeakReference", + "mozilla::WeakPtr", + "nsWritingIterator_reference", "nsReadingIterator_reference", + "nsTObserverArray", // <- Inherits from nsAutoTObserverArray<T, 0> + "nsTHashtable", // <- Inheriting from inner typedefs that clang + // doesn't expose properly. + "nsRefPtrHashtable", "nsDataHashtable", "nsClassHashtable", // <- Ditto + "nsIDocument_SelectorCache", // <- Inherits from nsExpirationTracker<.., 4> + "nsIPresShell_ScrollAxis", // <- For some reason the alignment of this is 4 + // for clang. + "nsPIDOMWindow", // <- Takes the vtable from a template parameter, and we can't + // generate it conditionally. + "JS::Rooted", + "mozilla::Maybe", + "gfxSize", // <- union { struct { T width; T height; }; T components[2] }; + "gfxSize_Super", // Ditto. + "mozilla::ErrorResult", // Causes JSWhyMagic to be included & handled incorrectly. + ]; + struct MappedGenericType { + generic: bool, + gecko: &'static str, + servo: &'static str, + } + let servo_mapped_generic_types = [ + MappedGenericType { + generic: true, + gecko: "mozilla::ServoUnsafeCell", + servo: "::std::cell::UnsafeCell" + }, + MappedGenericType { + generic: true, + gecko: "mozilla::ServoCell", + servo: "::std::cell::Cell" + }, + MappedGenericType { + generic: false, + gecko: "ServoNodeData", + servo: "AtomicRefCell<ElementData>", + } + ]; + struct Fixup { + pat: String, + rep: String + } + let mut fixups = vec![ + Fixup { + pat: "root::nsString".into(), + rep: "::nsstring::nsStringRepr".into() + }, + ]; + for &var in whitelist_vars.iter() { + builder = builder.whitelisted_var(var); + } + for &ty in whitelist.iter() { + builder = builder.whitelisted_type(ty); + } + for &ty in opaque_types.iter() { + builder = builder.opaque_type(ty); + } + for ty in servo_mapped_generic_types.iter() { + let gecko_name = ty.gecko.rsplit("::").next().unwrap(); + builder = builder.hide_type(ty.gecko) + .raw_line(format!("pub type {0}{2} = {1}{2};", gecko_name, ty.servo, + if ty.generic { "<T>" } else { "" })); + fixups.push(Fixup { + pat: format!("root::{}", ty.gecko), + rep: format!("::gecko_bindings::structs::{}", gecko_name) + }); + } + let mut result = builder.generate().expect("Unable to generate bindings").to_string(); + for fixup in fixups.iter() { + result = Regex::new(&format!(r"\b{}\b", fixup.pat)).unwrap().replace_all(&result, fixup.rep.as_str()); + } + File::create(&OUTDIR_PATH.join(structs_file(build_type))).unwrap() + .write_all(&result.into_bytes()).unwrap(); + } + + pub fn generate_bindings() { + let mut builder = Builder::get_initial_builder(BuildType::Release) + .disable_name_namespacing() + .with_codegen_config(CodegenConfig { + functions: true, + ..CodegenConfig::nothing() + }) + .header(add_include("mozilla/ServoBindings.h")) + .hide_type("nsACString_internal") + .hide_type("nsAString_internal") + .raw_line("pub use nsstring::{nsACString, nsAString};") + .raw_line("type nsACString_internal = nsACString;") + .raw_line("type nsAString_internal = nsAString;") + .whitelisted_function("Servo_.*") + .whitelisted_function("Gecko_.*"); + let structs_types = [ + "RawGeckoDocument", + "RawGeckoElement", + "RawGeckoNode", + "ThreadSafeURIHolder", + "ThreadSafePrincipalHolder", + "ConsumeStyleBehavior", + "LazyComputeBehavior", + "TraversalRootBehavior", + "FontFamilyList", + "FontFamilyType", + "ServoElementSnapshot", + "SheetParsingMode", + "StyleBasicShape", + "StyleBasicShapeType", + "StyleClipPath", + "nsCSSKeyword", + "nsCSSPropertyID", + "nsCSSShadowArray", + "nsCSSValue", + "nsCSSValueSharedList", + "nsChangeHint", + "nsCursorImage", + "nsFont", + "nsIAtom", + "nsRestyleHint", + "nsStyleBackground", + "nsStyleBorder", + "nsStyleColor", + "nsStyleColumn", + "nsStyleContent", + "nsStyleContext", + "nsStyleCoord", + "nsStyleCoord_Calc", + "nsStyleCoord_CalcValue", + "nsStyleDisplay", + "nsStyleEffects", + "nsStyleFont", + "nsStyleGradient", + "nsStyleGradientStop", + "nsStyleImage", + "nsStyleImageLayers", + "nsStyleImageLayers_Layer", + "nsStyleImageLayers_LayerType", + "nsStyleImageRequest", + "nsStyleList", + "nsStyleMargin", + "nsStyleOutline", + "nsStylePadding", + "nsStylePosition", + "nsStyleQuoteValues", + "nsStyleSVG", + "nsStyleSVGReset", + "nsStyleTable", + "nsStyleTableBorder", + "nsStyleText", + "nsStyleTextReset", + "nsStyleUIReset", + "nsStyleUnion", + "nsStyleUnit", + "nsStyleUserInterface", + "nsStyleVariables", + "nsStyleVisibility", + "nsStyleXUL", + "nscoord", + "nsresult", + ]; + struct ArrayType { + cpp_type: &'static str, + rust_type: &'static str + } + let array_types = [ + ArrayType { cpp_type: "uintptr_t", rust_type: "usize" }, + ]; + let servo_nullable_arc_types = [ + "ServoComputedValues", + "ServoCssRules", + "RawServoStyleSheet", + "RawServoDeclarationBlock", + "RawServoStyleRule", + ]; + struct ServoOwnedType { + name: &'static str, + opaque: bool, + } + let servo_owned_types = [ + ServoOwnedType { name: "RawServoStyleSet", opaque: true }, + ServoOwnedType { name: "StyleChildrenIterator", opaque: true }, + ServoOwnedType { name: "ServoElementSnapshot", opaque: false }, + ]; + let servo_immutable_borrow_types = [ + "RawGeckoNode", + "RawGeckoElement", + "RawGeckoDocument", + "RawServoDeclarationBlockStrong", + ]; + let servo_borrow_types = [ + "nsCSSValue", + ]; + for &ty in structs_types.iter() { + builder = builder.hide_type(ty) + .raw_line(format!("use gecko_bindings::structs::{};", ty)); + // TODO this is hacky, figure out a better way to do it without + // hardcoding everything... + if ty.starts_with("nsStyle") { + builder = builder + .raw_line(format!("unsafe impl Send for {} {{}}", ty)) + .raw_line(format!("unsafe impl Sync for {} {{}}", ty)); + } + } + for &ArrayType { cpp_type, rust_type } in array_types.iter() { + builder = builder.hide_type(format!("nsTArrayBorrowed_{}", cpp_type)) + .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() { + builder = builder + .hide_type(format!("{}Strong", ty)) + .raw_line(format!("pub type {0}Strong = ::gecko_bindings::sugar::ownership::Strong<{0}>;", ty)) + .borrowed_type(ty) + .zero_size_type(ty); + } + for &ServoOwnedType { name, opaque } in servo_owned_types.iter() { + builder = builder + .hide_type(format!("{}Owned", name)) + .raw_line(format!("pub type {0}Owned = ::gecko_bindings::sugar::ownership::Owned<{0}>;", name)) + .hide_type(format!("{}OwnedOrNull", name)) + .raw_line(format!("pub type {0}OwnedOrNull = ::gecko_bindings::sugar::ownership::OwnedOrNull<{0}>;", + name)) + .mutable_borrowed_type(name); + if opaque { + builder = builder.zero_size_type(name); + } + } + for &ty in servo_immutable_borrow_types.iter() { + builder = builder.borrowed_type(ty); + } + for &ty in servo_borrow_types.iter() { + builder = builder.mutable_borrowed_type(ty); + // Right now the only immutable borrow types are ones which we import + // from the |structs| module. As such, we don't need to create an opaque + // type with zero_size_type. If we ever introduce immutable borrow types + // which _do_ need to be opaque, we'll need a separate mode. + } + write_binding_file(builder, BINDINGS_FILE); + } +} + +#[cfg(not(feature = "bindgen"))] +mod bindings { + use std::fs; + use std::path::{Path, PathBuf}; + use super::common::*; + + lazy_static! { + static ref BINDINGS_PATH: PathBuf = Path::new(file!()).parent().unwrap().join("gecko_bindings"); + } + + pub fn generate_structs(build_type: BuildType) { + let file = structs_file(build_type); + let source = BINDINGS_PATH.join(file); + println!("cargo:rerun-if-changed={}", source.display()); + fs::copy(source, OUTDIR_PATH.join(file)).unwrap(); + } + + pub fn generate_bindings() { + let source = BINDINGS_PATH.join(BINDINGS_FILE); + println!("cargo:rerun-if-changed={}", source.display()); + fs::copy(source, OUTDIR_PATH.join(BINDINGS_FILE)).unwrap(); + } +} + +pub fn generate() { + use self::common::*; + use std::fs; + use std::thread; + fs::create_dir_all(&*OUTDIR_PATH).unwrap(); + let threads = vec![ + thread::spawn(|| bindings::generate_structs(BuildType::Debug)), + thread::spawn(|| bindings::generate_structs(BuildType::Release)), + thread::spawn(|| bindings::generate_bindings()), + ]; + for t in threads.into_iter() { + t.join().unwrap(); + } +} diff --git a/components/style/context.rs b/components/style/context.rs index 6785d752478..f649f64afbf 100644 --- a/components/style/context.rs +++ b/components/style/context.rs @@ -6,12 +6,12 @@ use animation::Animation; use app_units::Au; -use dom::OpaqueNode; +use bloom::StyleBloom; +use dom::{OpaqueNode, TElement}; use error_reporting::ParseErrorReporter; use euclid::Size2D; use matching::StyleSharingCandidateCache; use parking_lot::RwLock; -use std::cell::RefCell; use std::collections::HashMap; use std::sync::{Arc, Mutex}; use std::sync::mpsc::Sender; @@ -19,18 +19,26 @@ use stylist::Stylist; use timer::Timer; /// This structure is used to create a local style context from a shared one. -pub struct LocalStyleContextCreationInfo { +pub struct ThreadLocalStyleContextCreationInfo { new_animations_sender: Sender<Animation>, } -impl LocalStyleContextCreationInfo { +impl ThreadLocalStyleContextCreationInfo { pub fn new(animations_sender: Sender<Animation>) -> Self { - LocalStyleContextCreationInfo { + ThreadLocalStyleContextCreationInfo { new_animations_sender: animations_sender, } } } +#[derive(PartialEq, Eq, Copy, Clone, Hash, Debug)] +#[cfg_attr(feature = "servo", derive(HeapSizeOf))] +pub enum QuirksMode { + Quirks, + LimitedQuirks, + NoQuirks, +} + pub struct SharedStyleContext { /// The current viewport size. pub viewport_size: Size2D<Au>, @@ -38,21 +46,9 @@ pub struct SharedStyleContext { /// Screen sized changed? pub screen_size_changed: bool, - /// Skip the root during traversal? - /// - /// This is used in Gecko to style newly-appended children without restyling - /// the parent. It would be cleaner to add an API to allow us to enqueue the - /// children directly from glue.rs. - #[cfg(feature = "gecko")] - pub skip_root: bool, - /// The CSS selector stylist. pub stylist: Arc<Stylist>, - /// Starts at zero, and increased by one every time a layout completes. - /// This can be used to easily check for invalid stale data. - pub generation: u32, - /// Why is this reflow occurring pub goal: ReflowGoal, @@ -65,33 +61,38 @@ pub struct SharedStyleContext { ///The CSS error reporter for all CSS loaded in this layout thread pub error_reporter: Box<ParseErrorReporter + Sync>, - /// Data needed to create the local style context from the shared one. - pub local_context_creation_data: Mutex<LocalStyleContextCreationInfo>, + /// Data needed to create the thread-local style context from the shared one. + pub local_context_creation_data: Mutex<ThreadLocalStyleContextCreationInfo>, /// The current timer for transitions and animations. This is needed to test /// them. pub timer: Timer, + + /// The QuirksMode state which the document needs to be rendered with + pub quirks_mode: QuirksMode, } -pub struct LocalStyleContext { - pub style_sharing_candidate_cache: RefCell<StyleSharingCandidateCache>, +pub struct ThreadLocalStyleContext<E: TElement> { + pub style_sharing_candidate_cache: StyleSharingCandidateCache<E>, + pub bloom_filter: StyleBloom<E>, /// A channel on which new animations that have been triggered by style /// recalculation can be sent. pub new_animations_sender: Sender<Animation>, } -impl LocalStyleContext { - pub fn new(local_context_creation_data: &LocalStyleContextCreationInfo) -> Self { - LocalStyleContext { - style_sharing_candidate_cache: RefCell::new(StyleSharingCandidateCache::new()), - new_animations_sender: local_context_creation_data.new_animations_sender.clone(), +impl<E: TElement> ThreadLocalStyleContext<E> { + pub fn new(shared: &SharedStyleContext) -> Self { + ThreadLocalStyleContext { + style_sharing_candidate_cache: StyleSharingCandidateCache::new(), + bloom_filter: StyleBloom::new(), + new_animations_sender: shared.local_context_creation_data.lock().unwrap().new_animations_sender.clone(), } } } -pub trait StyleContext<'a> { - fn shared_context(&self) -> &'a SharedStyleContext; - fn local_context(&self) -> &LocalStyleContext; +pub struct StyleContext<'a, E: TElement + 'a> { + pub shared: &'a SharedStyleContext, + pub thread_local: &'a mut ThreadLocalStyleContext<E>, } /// Why we're doing reflow. diff --git a/components/style/custom_properties.rs b/components/style/custom_properties.rs index f9d3c77b1c4..d8e8913c41e 100644 --- a/components/style/custom_properties.rs +++ b/components/style/custom_properties.rs @@ -345,6 +345,7 @@ pub fn cascade<'a>(custom_properties: &mut Option<HashMap<&'a Name, BorrowedSpec DeclaredValue::Initial => { map.remove(&name); } + DeclaredValue::Unset | // Custom properties are inherited by default. DeclaredValue::Inherit => {} // The inherited value is what we already have. } } diff --git a/components/style/data.rs b/components/style/data.rs index b3049bba144..6aa68dc4ef2 100644 --- a/components/style/data.rs +++ b/components/style/data.rs @@ -4,10 +4,10 @@ //! Per-node data used in style calculation. -use dom::TRestyleDamage; +use dom::TElement; use properties::ComputedValues; use properties::longhands::display::computed_value as display; -use restyle_hints::RestyleHint; +use restyle_hints::{RESTYLE_LATER_SIBLINGS, RestyleHint}; use rule_tree::StrongRuleNode; use selector_parser::{PseudoElement, RestyleDamage, Snapshot}; use std::collections::HashMap; @@ -16,6 +16,8 @@ use std::hash::BuildHasherDefault; use std::mem; use std::ops::{Deref, DerefMut}; use std::sync::Arc; +use stylist::Stylist; +use thread_state; #[derive(Clone)] pub struct ComputedStyle { @@ -133,7 +135,7 @@ impl StoredRestyleHint { /// Propagates this restyle hint to a child element. pub fn propagate(&self) -> Self { StoredRestyleHint { - restyle_self: self.descendants == DescendantRestyleHint::Empty, + restyle_self: self.descendants != DescendantRestyleHint::Empty, descendants: self.descendants.propagate(), } } @@ -183,10 +185,50 @@ impl From<RestyleHint> for StoredRestyleHint { } } +// We really want to store an Option<Snapshot> here, but we can't drop Gecko +// Snapshots off-main-thread. So we make a convenient little wrapper to provide +// the semantics of Option<Snapshot>, while deferring the actual drop. +static NO_SNAPSHOT: Option<Snapshot> = None; + #[derive(Debug)] -pub enum RestyleDataStyles { - Previous(ElementStyles), - New(ElementStyles), +pub struct SnapshotOption { + snapshot: Option<Snapshot>, + destroyed: bool, +} + +impl SnapshotOption { + pub fn empty() -> Self { + SnapshotOption { + snapshot: None, + destroyed: false, + } + } + + pub fn destroy(&mut self) { + self.destroyed = true; + debug_assert!(self.is_none()); + } + + pub fn ensure<F: FnOnce() -> Snapshot>(&mut self, create: F) -> &mut Snapshot { + debug_assert!(thread_state::get().is_layout()); + if self.is_none() { + self.snapshot = Some(create()); + self.destroyed = false; + } + + self.snapshot.as_mut().unwrap() + } +} + +impl Deref for SnapshotOption { + type Target = Option<Snapshot>; + fn deref(&self) -> &Option<Snapshot> { + if self.destroyed { + &NO_SNAPSHOT + } else { + &self.snapshot + } + } } /// Transient data used by the restyle algorithm. This structure is instantiated @@ -194,54 +236,71 @@ pub enum RestyleDataStyles { /// processing. #[derive(Debug)] pub struct RestyleData { - pub styles: RestyleDataStyles, + pub styles: ElementStyles, pub hint: StoredRestyleHint, + pub recascade: bool, pub damage: RestyleDamage, - pub snapshot: Option<Snapshot>, + pub snapshot: SnapshotOption, } impl RestyleData { - fn new(previous: ElementStyles) -> Self { + fn new(styles: ElementStyles) -> Self { RestyleData { - styles: RestyleDataStyles::Previous(previous), + styles: styles, hint: StoredRestyleHint::default(), + recascade: false, damage: RestyleDamage::empty(), - snapshot: None, + snapshot: SnapshotOption::empty(), } } - pub fn get_current_styles(&self) -> Option<&ElementStyles> { - use self::RestyleDataStyles::*; - match self.styles { - Previous(_) => None, - New(ref x) => Some(x), + /// Expands the snapshot (if any) into a restyle hint. Returns true if later siblings + /// must be restyled. + pub fn expand_snapshot<E: TElement>(&mut self, element: E, stylist: &Stylist) -> bool { + if self.snapshot.is_none() { + return false; } + + // Compute the hint. + let state = element.get_state(); + let mut hint = stylist.compute_restyle_hint(&element, + self.snapshot.as_ref().unwrap(), + state); + + // If the hint includes a directive for later siblings, strip it out and + // notify the caller to modify the base hint for future siblings. + let later_siblings = hint.contains(RESTYLE_LATER_SIBLINGS); + hint.remove(RESTYLE_LATER_SIBLINGS); + + // Insert the hint. + self.hint.insert(&hint.into()); + + // Destroy the snapshot. + self.snapshot.destroy(); + + later_siblings } - pub fn current_styles(&self) -> &ElementStyles { - self.get_current_styles().unwrap() + pub fn has_current_styles(&self) -> bool { + !(self.hint.restyle_self || self.recascade || self.snapshot.is_some()) } - pub fn current_styles_mut(&mut self) -> &mut ElementStyles { - use self::RestyleDataStyles::*; - match self.styles { - New(ref mut x) => x, - Previous(_) => panic!("Calling current_styles_mut before styling"), - } + pub fn styles(&self) -> &ElementStyles { + &self.styles } - pub fn current_or_previous_styles(&self) -> &ElementStyles { - use self::RestyleDataStyles::*; - match self.styles { - Previous(ref x) => x, - New(ref x) => x, - } + pub fn styles_mut(&mut self) -> &mut ElementStyles { + &mut self.styles } fn finish_styling(&mut self, styles: ElementStyles, damage: RestyleDamage) { - debug_assert!(self.get_current_styles().is_none()); - self.styles = RestyleDataStyles::New(styles); + debug_assert!(!self.has_current_styles()); + debug_assert!(self.snapshot.is_none(), "Traversal should have expanded snapshots"); + self.styles = styles; self.damage |= damage; + // The hint and recascade bits get cleared by the traversal code. This + // is a bit confusing, and we should simplify it when we separate matching + // from cascading. } } @@ -363,10 +422,7 @@ impl ElementData { let old = mem::replace(self, ElementData::new(None)); let styles = match old { ElementData::Initial(i) => i.unwrap(), - ElementData::Restyle(r) => match r.styles { - RestyleDataStyles::New(n) => n, - RestyleDataStyles::Previous(_) => panic!("Never restyled element"), - }, + ElementData::Restyle(r) => r.styles, ElementData::Persistent(_) => unreachable!(), }; *self = ElementData::Persistent(styles); @@ -380,7 +436,7 @@ impl ElementData { RestyleDamage::rebuild_and_reflow() }, Restyle(ref r) => { - debug_assert!(r.get_current_styles().is_some()); + debug_assert!(r.has_current_styles()); r.damage }, Persistent(_) => RestyleDamage::empty(), @@ -400,7 +456,7 @@ impl ElementData { RestyleDamage::rebuild_and_reflow() }, Restyle(ref r) => { - if r.get_current_styles().is_none() { + if !r.has_current_styles() { error!("Accessing damage on dirty element"); } r.damage @@ -409,61 +465,41 @@ impl ElementData { } } - pub fn current_styles(&self) -> &ElementStyles { - self.get_current_styles().unwrap() - } - - pub fn get_current_styles(&self) -> Option<&ElementStyles> { + /// Returns true if this element's style is up-to-date and has no potential + /// invalidation. + pub fn has_current_styles(&self) -> bool { use self::ElementData::*; match *self { - Initial(ref x) => x.as_ref(), - Restyle(ref x) => x.get_current_styles(), - Persistent(ref x) => Some(x), + Initial(ref x) => x.is_some(), + Restyle(ref x) => x.has_current_styles(), + Persistent(_) => true, } } - pub fn current_styles_mut(&mut self) -> &mut ElementStyles { + pub fn get_styles(&self) -> Option<&ElementStyles> { use self::ElementData::*; match *self { - Initial(ref mut x) => x.as_mut().unwrap(), - Restyle(ref mut x) => x.current_styles_mut(), - Persistent(ref mut x) => x, + Initial(ref x) => x.as_ref(), + Restyle(ref x) => Some(x.styles()), + Persistent(ref x) => Some(x), } } - pub fn previous_styles(&self) -> Option<&ElementStyles> { - use self::ElementData::*; - use self::RestyleDataStyles::*; - match *self { - Initial(_) => None, - Restyle(ref x) => match x.styles { - Previous(ref styles) => Some(styles), - New(_) => panic!("Calling previous_styles after finish_styling"), - }, - Persistent(_) => panic!("Calling previous_styles on Persistent ElementData"), - } + pub fn styles(&self) -> &ElementStyles { + self.get_styles().expect("Calling styles() on unstyled ElementData") } - pub fn previous_styles_mut(&mut self) -> Option<&mut ElementStyles> { + pub fn get_styles_mut(&mut self) -> Option<&mut ElementStyles> { use self::ElementData::*; - use self::RestyleDataStyles::*; match *self { - Initial(_) => None, - Restyle(ref mut x) => match x.styles { - Previous(ref mut styles) => Some(styles), - New(_) => panic!("Calling previous_styles after finish_styling"), - }, - Persistent(_) => panic!("Calling previous_styles on Persistent ElementData"), + Initial(ref mut x) => x.as_mut(), + Restyle(ref mut x) => Some(x.styles_mut()), + Persistent(ref mut x) => Some(x), } } - pub fn current_or_previous_styles(&self) -> &ElementStyles { - use self::ElementData::*; - match *self { - Initial(ref x) => x.as_ref().unwrap(), - Restyle(ref x) => x.current_or_previous_styles(), - Persistent(ref x) => x, - } + pub fn styles_mut(&mut self) -> &mut ElementStyles { + self.get_styles_mut().expect("Calling styles_mut() on unstyled ElementData") } pub fn finish_styling(&mut self, styles: ElementStyles, damage: RestyleDamage) { diff --git a/components/style/dom.rs b/components/style/dom.rs index 5c66bbc0e0f..e9095ec0c9f 100644 --- a/components/style/dom.rs +++ b/components/style/dom.rs @@ -8,17 +8,17 @@ use {Atom, Namespace, LocalName}; use atomic_refcell::{AtomicRef, AtomicRefCell, AtomicRefMut}; -use data::{ElementStyles, ElementData}; +use data::ElementData; use element_state::ElementState; use parking_lot::RwLock; use properties::{ComputedValues, PropertyDeclarationBlock}; -use selector_parser::{ElementExt, PseudoElement, RestyleDamage}; +use selector_parser::{ElementExt, PreExistingComputedValues, PseudoElement}; use sink::Push; +use std::fmt; use std::fmt::Debug; -use std::ops::{BitOr, BitOrAssign}; +use std::ops::Deref; use std::sync::Arc; use stylist::ApplicableDeclarationBlock; -use util::opts; pub use style_traits::UnsafeNode; @@ -43,42 +43,6 @@ impl OpaqueNode { } } -#[derive(Clone, Copy, Debug, PartialEq)] -pub enum StylingMode { - /// The node has never been styled before, and needs a full style computation. - Initial, - /// The node has been styled before, but needs some amount of recomputation. - Restyle, - /// The node does not need any style processing, but one or more of its - /// descendants do. - Traverse, - /// No nodes in this subtree require style processing. - Stop, -} - -pub trait TRestyleDamage : BitOr<Output=Self> + BitOrAssign + Copy + Debug + PartialEq { - /// The source for our current computed values in the cascade. This is a - /// ComputedValues in Servo and a StyleContext in Gecko. - /// - /// This is needed because Gecko has a few optimisations for the calculation - /// of the difference depending on which values have been used during - /// layout. - /// - /// This should be obtained via TNode::existing_style_for_restyle_damage - type PreExistingComputedValues; - - fn compute(old: &Self::PreExistingComputedValues, - new: &Arc<ComputedValues>) -> Self; - - fn empty() -> Self; - - fn rebuild_and_reflow() -> Self; - - fn is_empty(&self) -> bool { - *self == Self::empty() - } -} - /// Simple trait to provide basic information about the type of an element. /// /// We avoid exposing the full type id, since computing it in the general case @@ -105,17 +69,13 @@ impl<T, I> Iterator for LayoutIterator<T> where T: Iterator<Item=I>, I: NodeInfo } } -pub trait TNode : Sized + Copy + Clone + NodeInfo { +pub trait TNode : Sized + Copy + Clone + Debug + NodeInfo { type ConcreteElement: TElement<ConcreteNode = Self>; type ConcreteChildrenIterator: Iterator<Item = Self>; fn to_unsafe(&self) -> UnsafeNode; unsafe fn from_unsafe(n: &UnsafeNode) -> Self; - fn dump(self); - - fn dump_style(self); - /// Returns an iterator over this node's children. fn children(self) -> LayoutIterator<Self::ConcreteChildrenIterator>; @@ -141,6 +101,90 @@ pub trait TNode : Sized + Copy + Clone + NodeInfo { fn parent_node(&self) -> Option<Self>; } +/// Wrapper to output the ElementData along with the node when formatting for +/// Debug. +pub struct ShowData<N: TNode>(pub N); +impl<N: TNode> Debug for ShowData<N> { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + fmt_with_data(f, self.0) + } +} + +/// Wrapper to output the primary computed values along with the node when +/// formatting for Debug. This is very verbose. +pub struct ShowDataAndPrimaryValues<N: TNode>(pub N); +impl<N: TNode> Debug for ShowDataAndPrimaryValues<N> { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + fmt_with_data_and_primary_values(f, self.0) + } +} + +/// Wrapper to output the subtree rather than the single node when formatting +/// for Debug. +pub struct ShowSubtree<N: TNode>(pub N); +impl<N: TNode> Debug for ShowSubtree<N> { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + try!(writeln!(f, "DOM Subtree:")); + fmt_subtree(f, &|f, n| write!(f, "{:?}", n), self.0, 1) + } +} + +/// Wrapper to output the subtree along with the ElementData when formatting +/// for Debug. +pub struct ShowSubtreeData<N: TNode>(pub N); +impl<N: TNode> Debug for ShowSubtreeData<N> { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + try!(writeln!(f, "DOM Subtree:")); + fmt_subtree(f, &|f, n| fmt_with_data(f, n), self.0, 1) + } +} + +/// Wrapper to output the subtree along with the ElementData and primary +/// ComputedValues when formatting for Debug. This is extremely verbose. +pub struct ShowSubtreeDataAndPrimaryValues<N: TNode>(pub N); +impl<N: TNode> Debug for ShowSubtreeDataAndPrimaryValues<N> { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + try!(writeln!(f, "DOM Subtree:")); + fmt_subtree(f, &|f, n| fmt_with_data_and_primary_values(f, n), self.0, 1) + } +} + +fn fmt_with_data<N: TNode>(f: &mut fmt::Formatter, n: N) -> fmt::Result { + if let Some(el) = n.as_element() { + write!(f, "{:?} dd={} data={:?}", el, el.has_dirty_descendants(), el.borrow_data()) + } else { + write!(f, "{:?}", n) + } +} + +fn fmt_with_data_and_primary_values<N: TNode>(f: &mut fmt::Formatter, n: N) -> fmt::Result { + if let Some(el) = n.as_element() { + let dd = el.has_dirty_descendants(); + let data = el.borrow_data(); + let styles = data.as_ref().and_then(|d| d.get_styles()); + let values = styles.map(|s| &s.primary.values); + write!(f, "{:?} dd={} data={:?} values={:?}", el, dd, &data, values) + } else { + write!(f, "{:?}", n) + } +} + +fn fmt_subtree<F, N: TNode>(f: &mut fmt::Formatter, stringify: &F, n: N, indent: u32) + -> fmt::Result + where F: Fn(&mut fmt::Formatter, N) -> fmt::Result +{ + for _ in 0..indent { + try!(write!(f, " ")); + } + try!(stringify(f, n)); + for kid in n.children() { + try!(writeln!(f, "")); + try!(fmt_subtree(f, stringify, kid, indent + 1)); + } + + Ok(()) +} + pub trait PresentationalHintsSynthetizer { fn synthesize_presentational_hints_for_legacy_attributes<V>(&self, hints: &mut V) where V: Push<ApplicableDeclarationBlock>; @@ -174,7 +218,7 @@ pub trait TElement : PartialEq + Debug + Sized + Copy + Clone + ElementExt + Pre fn existing_style_for_restyle_damage<'a>(&'a self, current_computed_values: Option<&'a Arc<ComputedValues>>, pseudo: Option<&PseudoElement>) - -> Option<&'a <RestyleDamage as TRestyleDamage>::PreExistingComputedValues>; + -> Option<&'a PreExistingComputedValues>; /// Returns true if this element may have a descendant needing style processing. /// @@ -201,62 +245,6 @@ pub trait TElement : PartialEq + Debug + Sized + Copy + Clone + ElementExt + Pre /// traversal. Returns the number of children left to process. fn did_process_child(&self) -> isize; - /// Returns true if this element's current style is display:none. Only valid - /// to call after styling. - fn is_display_none(&self) -> bool { - self.borrow_data().unwrap().current_styles().is_display_none() - } - - /// Returns true if this node has a styled layout frame that owns the style. - fn frame_has_style(&self) -> bool { false } - - /// Returns the styles from the layout frame that owns them, if any. - /// - /// FIXME(bholley): Once we start dropping ElementData from nodes when - /// creating frames, we'll want to teach this method to actually get - /// style data from the frame. - fn get_styles_from_frame(&self) -> Option<ElementStyles> { None } - - /// Returns the styling mode for this node. This is only valid to call before - /// and during restyling, before finish_styling is invoked. - /// - /// See the comments around StylingMode. - fn styling_mode(&self) -> StylingMode { - use self::StylingMode::*; - - // Non-incremental layout impersonates Initial. - if opts::get().nonincremental_layout { - return Initial; - } - - // Compute the default result if this node doesn't require processing. - let mode_for_descendants = if self.has_dirty_descendants() { - Traverse - } else { - Stop - }; - - match self.borrow_data() { - // No element data, no style on the frame. - None if !self.frame_has_style() => Initial, - // No element data, style on the frame. - None => mode_for_descendants, - // We have element data. Decide below. - Some(d) => match *d { - ElementData::Restyle(_) => Restyle, - ElementData::Persistent(_) => mode_for_descendants, - ElementData::Initial(None) => Initial, - // We previously computed the initial style for this element - // and then never consumed it. This is arguably a bug, since - // it means we either styled an element unnecessarily, or missed - // an opportunity to coalesce style traversals. However, this - // happens now for various reasons, so we just let it slide and - // treat it as persistent for now. - ElementData::Initial(Some(_)) => mode_for_descendants, - }, - } - } - /// Gets a reference to the ElementData container. fn get_data(&self) -> Option<&AtomicRefCell<ElementData>>; @@ -275,3 +263,38 @@ pub trait TElement : PartialEq + Debug + Sized + Copy + Clone + ElementExt + Pre /// native anonymous content can opt out of this style fixup.) fn skip_root_and_item_based_display_fixup(&self) -> bool; } + +/// TNode and TElement aren't Send because we want to be careful and explicit +/// about our parallel traversal. However, there are certain situations +/// (including but not limited to the traversal) where we need to send DOM +/// objects to other threads. + +#[derive(Clone, Debug, PartialEq)] +pub struct SendNode<N: TNode>(N); +unsafe impl<N: TNode> Send for SendNode<N> {} +impl<N: TNode> SendNode<N> { + pub unsafe fn new(node: N) -> Self { + SendNode(node) + } +} +impl<N: TNode> Deref for SendNode<N> { + type Target = N; + fn deref(&self) -> &N { + &self.0 + } +} + +#[derive(Debug, PartialEq)] +pub struct SendElement<E: TElement>(E); +unsafe impl<E: TElement> Send for SendElement<E> {} +impl<E: TElement> SendElement<E> { + pub unsafe fn new(el: E) -> Self { + SendElement(el) + } +} +impl<E: TElement> Deref for SendElement<E> { + type Target = E; + fn deref(&self) -> &E { + &self.0 + } +} diff --git a/components/style/gecko/context.rs b/components/style/gecko/context.rs deleted file mode 100644 index 1313030f3dc..00000000000 --- a/components/style/gecko/context.rs +++ /dev/null @@ -1,52 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -use context::{LocalStyleContext, StyleContext, SharedStyleContext}; -use std::cell::RefCell; -use std::rc::Rc; - -thread_local!(static LOCAL_CONTEXT_KEY: RefCell<Option<Rc<LocalStyleContext>>> = RefCell::new(None)); - -// Keep this implementation in sync with the one in components/layout/context.rs. -fn create_or_get_local_context(shared: &SharedStyleContext) -> Rc<LocalStyleContext> { - LOCAL_CONTEXT_KEY.with(|r| { - let mut r = r.borrow_mut(); - if let Some(context) = r.clone() { - context - } else { - let context = Rc::new(LocalStyleContext::new(&shared.local_context_creation_data.lock().unwrap())); - *r = Some(context.clone()); - context - } - }) -} - -pub fn clear_local_context() { - LOCAL_CONTEXT_KEY.with(|r| *r.borrow_mut() = None); -} - -pub struct StandaloneStyleContext<'a> { - pub shared: &'a SharedStyleContext, - cached_local_context: Rc<LocalStyleContext>, -} - -impl<'a> StandaloneStyleContext<'a> { - pub fn new(shared: &'a SharedStyleContext) -> Self { - let local_context = create_or_get_local_context(shared); - StandaloneStyleContext { - shared: shared, - cached_local_context: local_context, - } - } -} - -impl<'a> StyleContext<'a> for StandaloneStyleContext<'a> { - fn shared_context(&self) -> &'a SharedStyleContext { - &self.shared - } - - fn local_context(&self) -> &LocalStyleContext { - &self.cached_local_context - } -} diff --git a/components/style/gecko/conversions.rs b/components/style/gecko/conversions.rs index e32168a436d..9c2df76aabf 100644 --- a/components/style/gecko/conversions.rs +++ b/components/style/gecko/conversions.rs @@ -133,7 +133,9 @@ impl nsStyleImage { self.set_gradient(gradient) }, Image::Url(ref url) if with_url => { - let (ptr, len) = url.as_slice_components(); + let (ptr, len) = match url.as_slice_components() { + Ok(value) | Err(value) => value + }; let extra_data = url.extra_data(); unsafe { Gecko_SetUrlImageValue(self, @@ -160,10 +162,9 @@ impl nsStyleImage { use gecko_bindings::structs::{NS_STYLE_GRADIENT_SIZE_CLOSEST_SIDE, NS_STYLE_GRADIENT_SIZE_EXPLICIT_SIZE}; use gecko_bindings::structs::{NS_STYLE_GRADIENT_SIZE_FARTHEST_CORNER, NS_STYLE_GRADIENT_SIZE_FARTHEST_SIDE}; use gecko_bindings::structs::nsStyleCoord; - use values::computed::{GradientKind, GradientShape, LengthOrKeyword}; + use values::computed::{AngleOrCorner, GradientKind, GradientShape, LengthOrKeyword}; use values::computed::LengthOrPercentageOrKeyword; - use values::specified::{AngleOrCorner, HorizontalDirection}; - use values::specified::{SizeKeyword, VerticalDirection}; + use values::specified::{HorizontalDirection, SizeKeyword, VerticalDirection}; let stop_count = gradient.stops.len(); if stop_count >= ::std::u32::MAX as usize { diff --git a/components/style/gecko/mod.rs b/components/style/gecko/mod.rs index 2e1e653f88e..7f227f154dc 100644 --- a/components/style/gecko/mod.rs +++ b/components/style/gecko/mod.rs @@ -3,7 +3,6 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -pub mod context; pub mod data; pub mod restyle_damage; pub mod snapshot; diff --git a/components/style/gecko/restyle_damage.rs b/components/style/gecko/restyle_damage.rs index 53523cac04a..a1c7fc2c4e9 100644 --- a/components/style/gecko/restyle_damage.rs +++ b/components/style/gecko/restyle_damage.rs @@ -2,7 +2,6 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -use dom::TRestyleDamage; use gecko_bindings::bindings; use gecko_bindings::structs; use gecko_bindings::structs::{nsChangeHint, nsStyleContext}; @@ -22,17 +21,17 @@ impl GeckoRestyleDamage { pub fn as_change_hint(&self) -> nsChangeHint { self.0 } -} - -impl TRestyleDamage for GeckoRestyleDamage { - type PreExistingComputedValues = nsStyleContext; - fn empty() -> Self { + pub fn empty() -> Self { GeckoRestyleDamage(nsChangeHint(0)) } - fn compute(source: &nsStyleContext, - new_style: &Arc<ComputedValues>) -> Self { + pub fn is_empty(&self) -> bool { + self.0 == nsChangeHint(0) + } + + pub fn compute(source: &nsStyleContext, + new_style: &Arc<ComputedValues>) -> Self { let context = source as *const nsStyleContext as *mut nsStyleContext; let hint = unsafe { bindings::Gecko_CalcStyleDifference(context, @@ -41,7 +40,7 @@ impl TRestyleDamage for GeckoRestyleDamage { GeckoRestyleDamage(hint) } - fn rebuild_and_reflow() -> Self { + pub fn rebuild_and_reflow() -> Self { GeckoRestyleDamage(structs::nsChangeHint_nsChangeHint_ReconstructFrame) } } diff --git a/components/style/gecko/snapshot.rs b/components/style/gecko/snapshot.rs index bcb0874c853..08d5288a8d0 100644 --- a/components/style/gecko/snapshot.rs +++ b/components/style/gecko/snapshot.rs @@ -17,6 +17,10 @@ use string_cache::Atom; #[derive(Debug)] pub struct GeckoElementSnapshot(bindings::ServoElementSnapshotOwned); +// FIXME(bholley): Add support for *OwnedConst type, and then we get Sync +// automatically. +unsafe impl Sync for GeckoElementSnapshot {} + impl Drop for GeckoElementSnapshot { fn drop(&mut self) { unsafe { diff --git a/components/style/gecko/traversal.rs b/components/style/gecko/traversal.rs index cc6bed8f79b..7f83fbe5426 100644 --- a/components/style/gecko/traversal.rs +++ b/components/style/gecko/traversal.rs @@ -3,52 +3,48 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ use atomic_refcell::AtomicRefCell; -use context::{LocalStyleContext, SharedStyleContext, StyleContext}; +use context::{SharedStyleContext, StyleContext, ThreadLocalStyleContext}; use data::ElementData; -use dom::{NodeInfo, OpaqueNode, StylingMode, TElement, TNode}; -use gecko::context::StandaloneStyleContext; +use dom::{NodeInfo, TNode}; use gecko::wrapper::{GeckoElement, GeckoNode}; -use std::mem; -use traversal::{DomTraversalContext, PerLevelTraversalData, recalc_style_at}; +use traversal::{DomTraversal, PerLevelTraversalData, recalc_style_at}; -pub struct RecalcStyleOnly<'lc> { - context: StandaloneStyleContext<'lc>, - root: OpaqueNode, +pub struct RecalcStyleOnly { + shared: SharedStyleContext, } -impl<'lc, 'ln> DomTraversalContext<GeckoNode<'ln>> for RecalcStyleOnly<'lc> { - type SharedContext = SharedStyleContext; - #[allow(unsafe_code)] - fn new<'a>(shared: &'a Self::SharedContext, root: OpaqueNode) -> Self { - // See the comment in RecalcStyleAndConstructFlows::new for an explanation of why this is - // necessary. - let shared_lc: &'lc Self::SharedContext = unsafe { mem::transmute(shared) }; +impl RecalcStyleOnly { + pub fn new(shared: SharedStyleContext) -> Self { RecalcStyleOnly { - context: StandaloneStyleContext::new(shared_lc), - root: root, + shared: shared, } } +} + +impl<'ln> DomTraversal<GeckoNode<'ln>> for RecalcStyleOnly { + type ThreadLocalContext = ThreadLocalStyleContext<GeckoElement<'ln>>; - fn process_preorder(&self, node: GeckoNode<'ln>, data: &mut PerLevelTraversalData) { - if node.is_element() && (!self.context.shared_context().skip_root || node.opaque() != self.root) { + fn process_preorder(&self, traversal_data: &mut PerLevelTraversalData, + thread_local: &mut Self::ThreadLocalContext, + node: GeckoNode<'ln>) + { + if node.is_element() { let el = node.as_element().unwrap(); - recalc_style_at::<_, _, Self>(&self.context, data, el); + let mut data = unsafe { el.ensure_data() }.borrow_mut(); + let mut context = StyleContext { + shared: &self.shared, + thread_local: thread_local, + }; + recalc_style_at(self, traversal_data, &mut context, el, &mut data); } } - fn process_postorder(&self, _: GeckoNode<'ln>) { + fn process_postorder(&self, _: &mut Self::ThreadLocalContext, _: GeckoNode<'ln>) { unreachable!(); } /// We don't use the post-order traversal for anything. - fn needs_postorder_traversal(&self) -> bool { false } - - fn should_traverse_child(child: GeckoNode<'ln>) -> bool { - match child.as_element() { - Some(el) => el.styling_mode() != StylingMode::Stop, - None => false, // Gecko restyle doesn't need to traverse text nodes. - } - } + fn needs_postorder_traversal() -> bool { false } unsafe fn ensure_element_data<'a>(element: &'a GeckoElement<'ln>) -> &'a AtomicRefCell<ElementData> { element.ensure_data() @@ -58,7 +54,11 @@ impl<'lc, 'ln> DomTraversalContext<GeckoNode<'ln>> for RecalcStyleOnly<'lc> { element.clear_data() } - fn local_context(&self) -> &LocalStyleContext { - self.context.local_context() + fn shared_context(&self) -> &SharedStyleContext { + &self.shared + } + + fn create_thread_local_context(&self) -> Self::ThreadLocalContext { + ThreadLocalStyleContext::new(&self.shared) } } diff --git a/components/style/gecko/values.rs b/components/style/gecko/values.rs index cf5b90c71fc..6cbe4242e62 100644 --- a/components/style/gecko/values.rs +++ b/components/style/gecko/values.rs @@ -6,8 +6,7 @@ use app_units::Au; use cssparser::RGBA; -use gecko_bindings::structs::{NS_RADIUS_CLOSEST_SIDE, NS_RADIUS_FARTHEST_SIDE}; -use gecko_bindings::structs::nsStyleCoord; +use gecko_bindings::structs::{nsStyleCoord, StyleShapeRadius}; use gecko_bindings::sugar::ns_style_coord::{CoordData, CoordDataMut, CoordDataValue}; use std::cmp::max; use values::{Auto, Either}; @@ -140,10 +139,10 @@ impl GeckoStyleCoordConvertible for ShapeRadius { fn to_gecko_style_coord<T: CoordDataMut>(&self, coord: &mut T) { match *self { ShapeRadius::ClosestSide => { - coord.set_value(CoordDataValue::Enumerated(NS_RADIUS_CLOSEST_SIDE)) + coord.set_value(CoordDataValue::Enumerated(StyleShapeRadius::ClosestSide as u32)) } ShapeRadius::FarthestSide => { - coord.set_value(CoordDataValue::Enumerated(NS_RADIUS_FARTHEST_SIDE)) + coord.set_value(CoordDataValue::Enumerated(StyleShapeRadius::FarthestSide as u32)) } ShapeRadius::Length(lop) => lop.to_gecko_style_coord(coord), } @@ -151,8 +150,15 @@ impl GeckoStyleCoordConvertible for ShapeRadius { fn from_gecko_style_coord<T: CoordData>(coord: &T) -> Option<Self> { match coord.as_value() { - CoordDataValue::Enumerated(NS_RADIUS_CLOSEST_SIDE) => Some(ShapeRadius::ClosestSide), - CoordDataValue::Enumerated(NS_RADIUS_FARTHEST_SIDE) => Some(ShapeRadius::FarthestSide), + CoordDataValue::Enumerated(v) => { + if v == StyleShapeRadius::ClosestSide as u32 { + Some(ShapeRadius::ClosestSide) + } else if v == StyleShapeRadius::FarthestSide as u32 { + Some(ShapeRadius::FarthestSide) + } else { + None + } + } _ => LengthOrPercentage::from_gecko_style_coord(coord).map(ShapeRadius::Length), } } diff --git a/components/style/gecko/wrapper.rs b/components/style/gecko/wrapper.rs index 4d9683241a8..45dc1bb8cdf 100644 --- a/components/style/gecko/wrapper.rs +++ b/components/style/gecko/wrapper.rs @@ -50,6 +50,20 @@ use stylist::ApplicableDeclarationBlock; #[derive(Clone, Copy)] pub struct GeckoNode<'ln>(pub &'ln RawGeckoNode); +impl<'ln> fmt::Debug for GeckoNode<'ln> { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + if let Some(el) = self.as_element() { + el.fmt(f) + } else { + if self.is_text_node() { + write!(f, "<text node> ({:#x})", self.opaque().0) + } else { + write!(f, "<non-text node> ({:#x})", self.opaque().0) + } + } + } +} + impl<'ln> GeckoNode<'ln> { fn from_content(content: &'ln nsIContent) -> Self { GeckoNode(&content._base) @@ -102,19 +116,6 @@ impl<'ln> TNode for GeckoNode<'ln> { GeckoNode(&*(n.0 as *mut RawGeckoNode)) } - fn dump(self) { - if self.is_text_node() { - println!("Text ({:?})", &self.0 as *const _); - } else { - let el = self.as_element().unwrap(); - println!("Element {} ({:?})", el.get_local_name(), &el.0 as *const _); - } - } - - fn dump_style(self) { - unimplemented!() - } - fn children(self) -> LayoutIterator<GeckoChildrenIterator<'ln>> { let maybe_iter = unsafe { Gecko_MaybeCreateStyleChildrenIterator(self.0) }; if let Some(iter) = maybe_iter.into_owned_opt() { @@ -211,7 +212,7 @@ impl<'le> fmt::Debug for GeckoElement<'le> { if let Some(id) = self.get_id() { try!(write!(f, " id={}", id)); } - write!(f, "> ({:?})", self.0 as *const _) + write!(f, "> ({:#x})", self.as_node().opaque().0) } } @@ -260,10 +261,10 @@ impl<'le> GeckoElement<'le> { } pub fn get_pseudo_style(&self, pseudo: &PseudoElement) -> Option<Arc<ComputedValues>> { - // NB: Gecko sometimes resolves pseudos after an element has already been - // marked for restyle. We should consider fixing this, but for now just allow - // it with current_or_previous_styles. - self.borrow_data().and_then(|data| data.current_or_previous_styles().pseudos + // FIXME(bholley): Gecko sometimes resolves pseudos after an element has + // already been marked for restyle. We should consider fixing this, and + // then assert has_current_styles here. + self.borrow_data().and_then(|data| data.styles().pseudos .get(pseudo).map(|c| c.values.clone())) } @@ -273,8 +274,7 @@ impl<'le> GeckoElement<'le> { Some(x) => x, None => { debug!("Creating ElementData for {:?}", self); - let existing = self.get_styles_from_frame(); - let ptr = Box::into_raw(Box::new(AtomicRefCell::new(ElementData::new(existing)))); + let ptr = Box::into_raw(Box::new(AtomicRefCell::new(ElementData::new(None)))); self.0.mServoData.set(ptr); unsafe { &* ptr } }, @@ -353,6 +353,7 @@ impl<'le> TElement for GeckoElement<'le> { } unsafe fn set_dirty_descendants(&self) { + debug!("Setting dirty descendants: {:?}", self); self.set_flags(NODE_HAS_DIRTY_DESCENDANTS_FOR_SERVO as u32) } diff --git a/components/style/gecko_bindings/bindings.rs b/components/style/gecko_bindings/bindings.rs index d7ad23ff955..b9dc050143b 100644 --- a/components/style/gecko_bindings/bindings.rs +++ b/components/style/gecko_bindings/bindings.rs @@ -3,66 +3,6 @@ pub use nsstring::{nsACString, nsAString}; type nsACString_internal = nsACString; type nsAString_internal = nsAString; -pub type nsTArrayBorrowed_uintptr_t<'a> = &'a mut ::gecko_bindings::structs::nsTArray<usize>; -pub type ServoComputedValuesStrong = ::gecko_bindings::sugar::ownership::Strong<ServoComputedValues>; -pub type ServoComputedValuesBorrowedOrNull<'a> = Option<&'a ServoComputedValues>; -pub type ServoComputedValuesBorrowed<'a> = &'a ServoComputedValues; -enum ServoComputedValuesVoid{ } -pub struct ServoComputedValues(ServoComputedValuesVoid); -pub type ServoCssRulesStrong = ::gecko_bindings::sugar::ownership::Strong<ServoCssRules>; -pub type ServoCssRulesBorrowedOrNull<'a> = Option<&'a ServoCssRules>; -pub type ServoCssRulesBorrowed<'a> = &'a ServoCssRules; -enum ServoCssRulesVoid{ } -pub struct ServoCssRules(ServoCssRulesVoid); -pub type RawServoStyleSheetStrong = ::gecko_bindings::sugar::ownership::Strong<RawServoStyleSheet>; -pub type RawServoStyleSheetBorrowedOrNull<'a> = Option<&'a RawServoStyleSheet>; -pub type RawServoStyleSheetBorrowed<'a> = &'a RawServoStyleSheet; -enum RawServoStyleSheetVoid{ } -pub struct RawServoStyleSheet(RawServoStyleSheetVoid); -pub type RawServoDeclarationBlockStrong = ::gecko_bindings::sugar::ownership::Strong<RawServoDeclarationBlock>; -pub type RawServoDeclarationBlockBorrowedOrNull<'a> = Option<&'a RawServoDeclarationBlock>; -pub type RawServoDeclarationBlockBorrowed<'a> = &'a RawServoDeclarationBlock; -enum RawServoDeclarationBlockVoid{ } -pub struct RawServoDeclarationBlock(RawServoDeclarationBlockVoid); -pub type RawServoStyleRuleStrong = ::gecko_bindings::sugar::ownership::Strong<RawServoStyleRule>; -pub type RawServoStyleRuleBorrowedOrNull<'a> = Option<&'a RawServoStyleRule>; -pub type RawServoStyleRuleBorrowed<'a> = &'a RawServoStyleRule; -enum RawServoStyleRuleVoid{ } -pub struct RawServoStyleRule(RawServoStyleRuleVoid); -pub type RawGeckoNodeBorrowed<'a> = &'a RawGeckoNode; -pub type RawGeckoNodeBorrowedOrNull<'a> = Option<&'a RawGeckoNode>; -pub type RawGeckoElementBorrowed<'a> = &'a RawGeckoElement; -pub type RawGeckoElementBorrowedOrNull<'a> = Option<&'a RawGeckoElement>; -pub type RawGeckoDocumentBorrowed<'a> = &'a RawGeckoDocument; -pub type RawGeckoDocumentBorrowedOrNull<'a> = Option<&'a RawGeckoDocument>; -pub type RawServoDeclarationBlockStrongBorrowed<'a> = &'a RawServoDeclarationBlockStrong; -pub type RawServoDeclarationBlockStrongBorrowedOrNull<'a> = Option<&'a RawServoDeclarationBlockStrong>; -pub type nsCSSValueBorrowed<'a> = &'a nsCSSValue; -pub type nsCSSValueBorrowedOrNull<'a> = Option<&'a nsCSSValue>; -pub type nsCSSValueBorrowedMut<'a> = &'a mut nsCSSValue; -pub type nsCSSValueBorrowedMutOrNull<'a> = Option<&'a mut nsCSSValue>; -pub type RawServoStyleSetBorrowed<'a> = &'a RawServoStyleSet; -pub type RawServoStyleSetBorrowedMut<'a> = &'a mut RawServoStyleSet; -pub type RawServoStyleSetOwned = ::gecko_bindings::sugar::ownership::Owned<RawServoStyleSet>; -pub type RawServoStyleSetBorrowedOrNull<'a> = Option<&'a RawServoStyleSet>; -pub type RawServoStyleSetBorrowedMutOrNull<'a> = Option<&'a mut RawServoStyleSet>; -pub type RawServoStyleSetOwnedOrNull = ::gecko_bindings::sugar::ownership::OwnedOrNull<RawServoStyleSet>; -enum RawServoStyleSetVoid{ } -pub struct RawServoStyleSet(RawServoStyleSetVoid); -pub type StyleChildrenIteratorBorrowed<'a> = &'a StyleChildrenIterator; -pub type StyleChildrenIteratorBorrowedMut<'a> = &'a mut StyleChildrenIterator; -pub type StyleChildrenIteratorOwned = ::gecko_bindings::sugar::ownership::Owned<StyleChildrenIterator>; -pub type StyleChildrenIteratorBorrowedOrNull<'a> = Option<&'a StyleChildrenIterator>; -pub type StyleChildrenIteratorBorrowedMutOrNull<'a> = Option<&'a mut StyleChildrenIterator>; -pub type StyleChildrenIteratorOwnedOrNull = ::gecko_bindings::sugar::ownership::OwnedOrNull<StyleChildrenIterator>; -enum StyleChildrenIteratorVoid{ } -pub struct StyleChildrenIterator(StyleChildrenIteratorVoid); -pub type ServoElementSnapshotBorrowed<'a> = &'a ServoElementSnapshot; -pub type ServoElementSnapshotBorrowedMut<'a> = &'a mut ServoElementSnapshot; -pub type ServoElementSnapshotOwned = ::gecko_bindings::sugar::ownership::Owned<ServoElementSnapshot>; -pub type ServoElementSnapshotBorrowedOrNull<'a> = Option<&'a ServoElementSnapshot>; -pub type ServoElementSnapshotBorrowedMutOrNull<'a> = Option<&'a mut ServoElementSnapshot>; -pub type ServoElementSnapshotOwnedOrNull = ::gecko_bindings::sugar::ownership::OwnedOrNull<ServoElementSnapshot>; use gecko_bindings::structs::RawGeckoDocument; use gecko_bindings::structs::RawGeckoElement; use gecko_bindings::structs::RawGeckoNode; @@ -70,7 +10,7 @@ use gecko_bindings::structs::ThreadSafeURIHolder; use gecko_bindings::structs::ThreadSafePrincipalHolder; use gecko_bindings::structs::ConsumeStyleBehavior; use gecko_bindings::structs::LazyComputeBehavior; -use gecko_bindings::structs::SkipRootBehavior; +use gecko_bindings::structs::TraversalRootBehavior; use gecko_bindings::structs::FontFamilyList; use gecko_bindings::structs::FontFamilyType; use gecko_bindings::structs::ServoElementSnapshot; @@ -79,6 +19,7 @@ use gecko_bindings::structs::StyleBasicShape; use gecko_bindings::structs::StyleBasicShapeType; use gecko_bindings::structs::StyleClipPath; use gecko_bindings::structs::nsCSSKeyword; +use gecko_bindings::structs::nsCSSPropertyID; use gecko_bindings::structs::nsCSSShadowArray; use gecko_bindings::structs::nsCSSValue; use gecko_bindings::structs::nsCSSValueSharedList; @@ -203,6 +144,66 @@ unsafe impl Send for nsStyleXUL {} unsafe impl Sync for nsStyleXUL {} use gecko_bindings::structs::nscoord; use gecko_bindings::structs::nsresult; +pub type nsTArrayBorrowed_uintptr_t<'a> = &'a mut ::gecko_bindings::structs::nsTArray<usize>; +pub type ServoComputedValuesStrong = ::gecko_bindings::sugar::ownership::Strong<ServoComputedValues>; +pub type ServoComputedValuesBorrowed<'a> = &'a ServoComputedValues; +pub type ServoComputedValuesBorrowedOrNull<'a> = Option<&'a ServoComputedValues>; +enum ServoComputedValuesVoid { } +pub struct ServoComputedValues(ServoComputedValuesVoid); +pub type ServoCssRulesStrong = ::gecko_bindings::sugar::ownership::Strong<ServoCssRules>; +pub type ServoCssRulesBorrowed<'a> = &'a ServoCssRules; +pub type ServoCssRulesBorrowedOrNull<'a> = Option<&'a ServoCssRules>; +enum ServoCssRulesVoid { } +pub struct ServoCssRules(ServoCssRulesVoid); +pub type RawServoStyleSheetStrong = ::gecko_bindings::sugar::ownership::Strong<RawServoStyleSheet>; +pub type RawServoStyleSheetBorrowed<'a> = &'a RawServoStyleSheet; +pub type RawServoStyleSheetBorrowedOrNull<'a> = Option<&'a RawServoStyleSheet>; +enum RawServoStyleSheetVoid { } +pub struct RawServoStyleSheet(RawServoStyleSheetVoid); +pub type RawServoDeclarationBlockStrong = ::gecko_bindings::sugar::ownership::Strong<RawServoDeclarationBlock>; +pub type RawServoDeclarationBlockBorrowed<'a> = &'a RawServoDeclarationBlock; +pub type RawServoDeclarationBlockBorrowedOrNull<'a> = Option<&'a RawServoDeclarationBlock>; +enum RawServoDeclarationBlockVoid { } +pub struct RawServoDeclarationBlock(RawServoDeclarationBlockVoid); +pub type RawServoStyleRuleStrong = ::gecko_bindings::sugar::ownership::Strong<RawServoStyleRule>; +pub type RawServoStyleRuleBorrowed<'a> = &'a RawServoStyleRule; +pub type RawServoStyleRuleBorrowedOrNull<'a> = Option<&'a RawServoStyleRule>; +enum RawServoStyleRuleVoid { } +pub struct RawServoStyleRule(RawServoStyleRuleVoid); +pub type RawServoStyleSetOwned = ::gecko_bindings::sugar::ownership::Owned<RawServoStyleSet>; +pub type RawServoStyleSetOwnedOrNull = ::gecko_bindings::sugar::ownership::OwnedOrNull<RawServoStyleSet>; +pub type RawServoStyleSetBorrowed<'a> = &'a RawServoStyleSet; +pub type RawServoStyleSetBorrowedOrNull<'a> = Option<&'a RawServoStyleSet>; +pub type RawServoStyleSetBorrowedMut<'a> = &'a mut RawServoStyleSet; +pub type RawServoStyleSetBorrowedMutOrNull<'a> = Option<&'a mut RawServoStyleSet>; +enum RawServoStyleSetVoid { } +pub struct RawServoStyleSet(RawServoStyleSetVoid); +pub type StyleChildrenIteratorOwned = ::gecko_bindings::sugar::ownership::Owned<StyleChildrenIterator>; +pub type StyleChildrenIteratorOwnedOrNull = ::gecko_bindings::sugar::ownership::OwnedOrNull<StyleChildrenIterator>; +pub type StyleChildrenIteratorBorrowed<'a> = &'a StyleChildrenIterator; +pub type StyleChildrenIteratorBorrowedOrNull<'a> = Option<&'a StyleChildrenIterator>; +pub type StyleChildrenIteratorBorrowedMut<'a> = &'a mut StyleChildrenIterator; +pub type StyleChildrenIteratorBorrowedMutOrNull<'a> = Option<&'a mut StyleChildrenIterator>; +enum StyleChildrenIteratorVoid { } +pub struct StyleChildrenIterator(StyleChildrenIteratorVoid); +pub type ServoElementSnapshotOwned = ::gecko_bindings::sugar::ownership::Owned<ServoElementSnapshot>; +pub type ServoElementSnapshotOwnedOrNull = ::gecko_bindings::sugar::ownership::OwnedOrNull<ServoElementSnapshot>; +pub type ServoElementSnapshotBorrowed<'a> = &'a ServoElementSnapshot; +pub type ServoElementSnapshotBorrowedOrNull<'a> = Option<&'a ServoElementSnapshot>; +pub type ServoElementSnapshotBorrowedMut<'a> = &'a mut ServoElementSnapshot; +pub type ServoElementSnapshotBorrowedMutOrNull<'a> = Option<&'a mut ServoElementSnapshot>; +pub type RawGeckoNodeBorrowed<'a> = &'a RawGeckoNode; +pub type RawGeckoNodeBorrowedOrNull<'a> = Option<&'a RawGeckoNode>; +pub type RawGeckoElementBorrowed<'a> = &'a RawGeckoElement; +pub type RawGeckoElementBorrowedOrNull<'a> = Option<&'a RawGeckoElement>; +pub type RawGeckoDocumentBorrowed<'a> = &'a RawGeckoDocument; +pub type RawGeckoDocumentBorrowedOrNull<'a> = Option<&'a RawGeckoDocument>; +pub type RawServoDeclarationBlockStrongBorrowed<'a> = &'a RawServoDeclarationBlockStrong; +pub type RawServoDeclarationBlockStrongBorrowedOrNull<'a> = Option<&'a RawServoDeclarationBlockStrong>; +pub type nsCSSValueBorrowed<'a> = &'a nsCSSValue; +pub type nsCSSValueBorrowedOrNull<'a> = Option<&'a nsCSSValue>; +pub type nsCSSValueBorrowedMut<'a> = &'a mut nsCSSValue; +pub type nsCSSValueBorrowedMutOrNull<'a> = Option<&'a mut nsCSSValue>; extern "C" { pub fn Servo_CssRules_AddRef(ptr: ServoCssRulesBorrowed); @@ -990,16 +991,18 @@ extern "C" { } extern "C" { pub fn Servo_StyleSet_AppendStyleSheet(set: RawServoStyleSetBorrowed, - sheet: RawServoStyleSheetBorrowed); + sheet: RawServoStyleSheetBorrowed, + flush: bool); } extern "C" { pub fn Servo_StyleSet_PrependStyleSheet(set: RawServoStyleSetBorrowed, - sheet: - RawServoStyleSheetBorrowed); + sheet: RawServoStyleSheetBorrowed, + flush: bool); } extern "C" { pub fn Servo_StyleSet_RemoveStyleSheet(set: RawServoStyleSetBorrowed, - sheet: RawServoStyleSheetBorrowed); + sheet: RawServoStyleSheetBorrowed, + flush: bool); } extern "C" { pub fn Servo_StyleSet_InsertStyleSheetBefore(set: @@ -1007,7 +1010,15 @@ extern "C" { sheet: RawServoStyleSheetBorrowed, reference: - RawServoStyleSheetBorrowed); + RawServoStyleSheetBorrowed, + flush: bool); +} +extern "C" { + pub fn Servo_StyleSet_FlushStyleSheets(set: RawServoStyleSetBorrowed); +} +extern "C" { + pub fn Servo_StyleSet_NoteStyleSheetsChanged(set: + RawServoStyleSetBorrowed); } extern "C" { pub fn Servo_CssRules_ListTypes(rules: ServoCssRulesBorrowed, @@ -1092,8 +1103,7 @@ extern "C" { extern "C" { pub fn Servo_DeclarationBlock_SerializeOneValue(declarations: RawServoDeclarationBlockBorrowed, - property: *mut nsIAtom, - is_custom: bool, + property: nsCSSPropertyID, buffer: *mut nsAString_internal); } @@ -1113,32 +1123,53 @@ extern "C" { extern "C" { pub fn Servo_DeclarationBlock_GetPropertyValue(declarations: RawServoDeclarationBlockBorrowed, - property: *mut nsIAtom, - is_custom: bool, + property: + *const nsACString_internal, value: *mut nsAString_internal); } extern "C" { + pub fn Servo_DeclarationBlock_GetPropertyValueById(declarations: + RawServoDeclarationBlockBorrowed, + property: + nsCSSPropertyID, + value: + *mut nsAString_internal); +} +extern "C" { pub fn Servo_DeclarationBlock_GetPropertyIsImportant(declarations: RawServoDeclarationBlockBorrowed, property: - *mut nsIAtom, - is_custom: bool) + *const nsACString_internal) -> bool; } extern "C" { pub fn Servo_DeclarationBlock_SetProperty(declarations: RawServoDeclarationBlockBorrowed, - property: *mut nsIAtom, - is_custom: bool, + property: + *const nsACString_internal, value: *mut nsACString_internal, is_important: bool) -> bool; } extern "C" { + pub fn Servo_DeclarationBlock_SetPropertyById(declarations: + RawServoDeclarationBlockBorrowed, + property: nsCSSPropertyID, + value: + *mut nsACString_internal, + is_important: bool) -> bool; +} +extern "C" { pub fn Servo_DeclarationBlock_RemoveProperty(declarations: RawServoDeclarationBlockBorrowed, - property: *mut nsIAtom, - is_custom: bool); + property: + *const nsACString_internal); +} +extern "C" { + pub fn Servo_DeclarationBlock_RemovePropertyById(declarations: + RawServoDeclarationBlockBorrowed, + property: + nsCSSPropertyID); } extern "C" { pub fn Servo_CSSSupports(name: *const nsACString_internal, @@ -1153,17 +1184,6 @@ extern "C" { -> ServoComputedValuesStrong; } extern "C" { - pub fn Servo_ComputedValues_GetForPseudoElement(parent_style: - ServoComputedValuesBorrowed, - match_element: - RawGeckoElementBorrowed, - pseudo_tag: *mut nsIAtom, - set: - RawServoStyleSetBorrowed, - is_probe: bool) - -> ServoComputedValuesStrong; -} -extern "C" { pub fn Servo_ComputedValues_Inherit(parent_style: ServoComputedValuesBorrowedOrNull) -> ServoComputedValuesStrong; @@ -1195,9 +1215,15 @@ extern "C" { -> ServoComputedValuesStrong; } extern "C" { + pub fn Servo_ResolvePseudoStyle(element: RawGeckoElementBorrowed, + pseudo_tag: *mut nsIAtom, is_probe: bool, + set: RawServoStyleSetBorrowed) + -> ServoComputedValuesStrong; +} +extern "C" { pub fn Servo_TraverseSubtree(root: RawGeckoElementBorrowed, set: RawServoStyleSetBorrowed, - skip_root: SkipRootBehavior); + root_behavior: TraversalRootBehavior); } extern "C" { pub fn Servo_AssertTreeIsClean(root: RawGeckoElementBorrowed); diff --git a/components/style/gecko_bindings/mod.rs b/components/style/gecko_bindings/mod.rs index 7201bdb2668..d86bfb60484 100644 --- a/components/style/gecko_bindings/mod.rs +++ b/components/style/gecko_bindings/mod.rs @@ -3,22 +3,23 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #[allow(dead_code, improper_ctypes, non_camel_case_types)] -pub mod bindings; +pub mod bindings { + include!(concat!(env!("OUT_DIR"), "/gecko/bindings.rs")); +} // FIXME: We allow `improper_ctypes` (for now), because the lint doesn't allow // foreign structs to have `PhantomData`. We should remove this once the lint // ignores this case. -#[cfg(debug_assertions)] -#[allow(dead_code, improper_ctypes, non_camel_case_types, non_snake_case, non_upper_case_globals)] -pub mod structs { - include!("structs_debug.rs"); -} - -#[cfg(not(debug_assertions))] #[allow(dead_code, improper_ctypes, non_camel_case_types, non_snake_case, non_upper_case_globals)] pub mod structs { - include!("structs_release.rs"); + cfg_if! { + if #[cfg(debug_assertions)] { + include!(concat!(env!("OUT_DIR"), "/gecko/structs_debug.rs")); + } else { + include!(concat!(env!("OUT_DIR"), "/gecko/structs_release.rs")); + } + } } pub mod sugar; diff --git a/components/style/gecko_bindings/structs_debug.rs b/components/style/gecko_bindings/structs_debug.rs index 25960347510..7ed51c1e954 100644 --- a/components/style/gecko_bindings/structs_debug.rs +++ b/components/style/gecko_bindings/structs_debug.rs @@ -234,8 +234,6 @@ pub mod root { pub const NS_CORNER_BOTTOM_RIGHT_Y: ::std::os::raw::c_uint = 5; pub const NS_CORNER_BOTTOM_LEFT_X: ::std::os::raw::c_uint = 6; pub const NS_CORNER_BOTTOM_LEFT_Y: ::std::os::raw::c_uint = 7; - pub const NS_RADIUS_FARTHEST_SIDE: ::std::os::raw::c_uint = 0; - pub const NS_RADIUS_CLOSEST_SIDE: ::std::os::raw::c_uint = 1; pub const NS_STYLE_STACK_SIZING_IGNORE: ::std::os::raw::c_uint = 0; pub const NS_STYLE_STACK_SIZING_STRETCH_TO_FIT: ::std::os::raw::c_uint = 1; @@ -1014,6 +1012,7 @@ pub mod root { pub const NS_STYLE_DISPLAY_MODE_BROWSER: ::std::os::raw::c_uint = 0; pub const NS_STYLE_DISPLAY_MODE_MINIMAL_UI: ::std::os::raw::c_uint = 1; pub const NS_STYLE_DISPLAY_MODE_STANDALONE: ::std::os::raw::c_uint = 2; + pub const NS_STYLE_DISPLAY_MODE_FULLSCREEN: ::std::os::raw::c_uint = 3; pub const NS_STYLE_INHERIT_MASK: ::std::os::raw::c_uint = 16777215; pub const NS_STYLE_HAS_TEXT_DECORATION_LINES: ::std::os::raw::c_uint = 16777216; @@ -1175,10 +1174,7 @@ pub mod root { pub struct ThreadSafeAutoRefCnt { pub mValue: u64, } - extern "C" { - #[link_name = "_ZN7mozilla20ThreadSafeAutoRefCnt12isThreadSafeE"] - pub static ThreadSafeAutoRefCnt_isThreadSafe: bool; - } + pub const ThreadSafeAutoRefCnt_isThreadSafe: bool = true; #[test] fn bindgen_test_layout_ThreadSafeAutoRefCnt() { assert_eq!(::std::mem::size_of::<ThreadSafeAutoRefCnt>() , @@ -1295,6 +1291,112 @@ pub mod root { } #[repr(C)] #[derive(Debug)] + pub struct EventTarget { + pub _base: root::nsIDOMEventTarget, + pub _base_1: root::nsWrapperCache, + } + #[repr(C)] + #[derive(Debug, Copy, Clone)] + pub struct EventTarget_COMTypeInfo<T, U> { + pub _address: u8, + pub _phantom_0: ::std::marker::PhantomData<T>, + pub _phantom_1: ::std::marker::PhantomData<U>, + } + #[test] + fn bindgen_test_layout_EventTarget() { + assert_eq!(::std::mem::size_of::<EventTarget>() , 32usize); + assert_eq!(::std::mem::align_of::<EventTarget>() , 8usize); + } + #[repr(C)] + #[derive(Debug, Copy)] + pub struct AudioContext { + pub _address: u8, + } + impl Clone for AudioContext { + fn clone(&self) -> Self { *self } + } + #[repr(C)] + #[derive(Debug, Copy)] + pub struct DocGroup { + pub _address: u8, + } + impl Clone for DocGroup { + fn clone(&self) -> Self { *self } + } + pub const ReferrerPolicy_RP_Default: + root::mozilla::dom::ReferrerPolicy = + ReferrerPolicy::RP_No_Referrer_When_Downgrade; + #[repr(u32)] + #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] + pub enum ReferrerPolicy { + RP_No_Referrer = 2, + RP_Origin = 3, + RP_No_Referrer_When_Downgrade = 1, + RP_Origin_When_Crossorigin = 4, + RP_Unsafe_URL = 5, + RP_Same_Origin = 6, + RP_Strict_Origin = 7, + RP_Strict_Origin_When_Cross_Origin = 8, + RP_Unset = 0, + } + #[repr(C)] + #[derive(Debug)] + pub struct Element { + pub _base: root::mozilla::dom::FragmentOrElement, + pub mState: root::EventStates, + pub mServoData: ::gecko_bindings::structs::ServoCell<*mut ::gecko_bindings::structs::ServoNodeData>, + } + #[repr(C)] + #[derive(Debug, Copy, Clone)] + pub struct Element_COMTypeInfo<T, U> { + pub _address: u8, + pub _phantom_0: ::std::marker::PhantomData<T>, + pub _phantom_1: ::std::marker::PhantomData<U>, + } + #[repr(C)] + #[derive(Debug, Copy)] + pub struct Element_MappedAttributeEntry { + pub attribute: *mut *mut root::nsIAtom, + } + #[test] + fn bindgen_test_layout_Element_MappedAttributeEntry() { + assert_eq!(::std::mem::size_of::<Element_MappedAttributeEntry>() + , 8usize); + assert_eq!(::std::mem::align_of::<Element_MappedAttributeEntry>() + , 8usize); + } + impl Clone for Element_MappedAttributeEntry { + fn clone(&self) -> Self { *self } + } + pub const Element_kFireMutationEvent: bool = true; + pub const Element_kDontFireMutationEvent: bool = false; + pub const Element_kNotifyDocumentObservers: bool = true; + pub const Element_kDontNotifyDocumentObservers: bool = false; + pub const Element_kCallAfterSetAttr: bool = true; + pub const Element_kDontCallAfterSetAttr: bool = false; + #[test] + fn bindgen_test_layout_Element() { + assert_eq!(::std::mem::size_of::<Element>() , 136usize); + assert_eq!(::std::mem::align_of::<Element>() , 8usize); + } + #[repr(C)] + #[derive(Debug, Copy)] + pub struct TimeoutManager { + pub _address: u8, + } + impl Clone for TimeoutManager { + fn clone(&self) -> Self { *self } + } + #[repr(C)] + #[derive(Debug, Copy)] + pub struct PrefSetting { + pub _address: u8, + } + impl Clone for PrefSetting { + fn clone(&self) -> Self { *self } + } + #[repr(C)] + #[derive(Debug)] pub struct CallbackObject { pub _base: root::nsISupports, pub mRefCnt: root::nsCycleCollectingAutoRefCnt, @@ -1395,273 +1497,6 @@ pub mod root { assert_eq!(::std::mem::align_of::<CallbackFunction>() , 8usize); } - #[repr(C)] - #[derive(Debug, Copy)] - pub struct AudioContext { - pub _address: u8, - } - impl Clone for AudioContext { - fn clone(&self) -> Self { *self } - } - #[repr(C)] - #[derive(Debug, Copy)] - pub struct DocGroup { - pub _address: u8, - } - impl Clone for DocGroup { - fn clone(&self) -> Self { *self } - } - #[repr(C)] - #[derive(Debug)] - pub struct FragmentOrElement { - pub _base: root::nsIContent, - pub mRefCnt: root::nsCycleCollectingAutoRefCnt, - pub _mOwningThread: root::nsAutoOwningThread, - /** - * Array containing all attributes and children for this element - */ - pub mAttrsAndChildren: root::nsAttrAndChildArray, - } - pub type FragmentOrElement_HasThreadSafeRefCnt = - root::mozilla::FalseType; - #[repr(C)] - #[derive(Debug, Copy)] - pub struct FragmentOrElement_cycleCollection { - pub _base: root::nsXPCOMCycleCollectionParticipant, - } - #[test] - fn bindgen_test_layout_FragmentOrElement_cycleCollection() { - assert_eq!(::std::mem::size_of::<FragmentOrElement_cycleCollection>() - , 16usize); - assert_eq!(::std::mem::align_of::<FragmentOrElement_cycleCollection>() - , 8usize); - } - impl Clone for FragmentOrElement_cycleCollection { - fn clone(&self) -> Self { *self } - } - /** - * There are a set of DOM- and scripting-specific instance variables - * that may only be instantiated when a content object is accessed - * through the DOM. Rather than burn actual slots in the content - * objects for each of these instance variables, we put them off - * in a side structure that's only allocated when the content is - * accessed through the DOM. - */ - #[repr(C)] - #[derive(Debug)] - pub struct FragmentOrElement_nsDOMSlots { - pub _base: root::nsINode_nsSlots, - /** - * The .style attribute (an interface that forwards to the actual - * style rules) - * @see nsGenericHTMLElement::GetStyle - */ - pub mStyle: root::nsCOMPtr<root::nsICSSDeclaration>, - /** - * The .dataset attribute. - * @see nsGenericHTMLElement::GetDataset - */ - pub mDataset: *mut root::nsDOMStringMap, - /** - * SMIL Overridde style rules (for SMIL animation of CSS properties) - * @see nsIContent::GetSMILOverrideStyle - */ - pub mSMILOverrideStyle: root::nsCOMPtr<root::nsICSSDeclaration>, - /** - * Holds any SMIL override style declaration for this element. - */ - pub mSMILOverrideStyleDeclaration: root::RefPtr<root::mozilla::DeclarationBlock>, - /** - * An object implementing nsIDOMMozNamedAttrMap for this content (attributes) - * @see FragmentOrElement::GetAttributes - */ - pub mAttributeMap: root::RefPtr<root::nsDOMAttributeMap>, - pub __bindgen_anon_1: root::mozilla::dom::FragmentOrElement_nsDOMSlots__bindgen_ty_1, - /** - * An object implementing the .children property for this element. - */ - pub mChildrenList: root::RefPtr<root::nsContentList>, - /** - * An object implementing the .classList property for this element. - */ - pub mClassList: root::RefPtr<root::nsDOMTokenList>, - /** - * ShadowRoot bound to the element. - */ - pub mShadowRoot: root::RefPtr<root::mozilla::dom::ShadowRoot>, - /** - * The root ShadowRoot of this element if it is in a shadow tree. - */ - pub mContainingShadow: root::RefPtr<root::mozilla::dom::ShadowRoot>, - /** - * An array of web component insertion points to which this element - * is distributed. - */ - pub mDestInsertionPoints: root::nsTArray<*mut root::nsIContent>, - /** - * XBL binding installed on the element. - */ - pub mXBLBinding: root::RefPtr<root::nsXBLBinding>, - /** - * XBL binding installed on the lement. - */ - pub mXBLInsertionParent: root::nsCOMPtr<root::nsIContent>, - /** - * Web components custom element data. - */ - pub mCustomElementData: root::RefPtr<root::mozilla::dom::CustomElementData>, - pub mRegisteredIntersectionObservers: root::nsTArray<root::mozilla::dom::FragmentOrElement_nsDOMSlots_IntersectionObserverRegistration>, - } - #[repr(C)] - #[derive(Debug, Copy)] - pub struct FragmentOrElement_nsDOMSlots__bindgen_ty_1 { - /** - * The nearest enclosing content node with a binding that created us. - * @see FragmentOrElement::GetBindingParent - */ - pub mBindingParent: root::__BindgenUnionField<*mut root::nsIContent>, - /** - * The controllers of the XUL Element. - */ - pub mControllers: root::__BindgenUnionField<*mut root::nsIControllers>, - pub bindgen_union_field: u64, - } - #[test] - fn bindgen_test_layout_FragmentOrElement_nsDOMSlots__bindgen_ty_1() { - assert_eq!(::std::mem::size_of::<FragmentOrElement_nsDOMSlots__bindgen_ty_1>() - , 8usize); - assert_eq!(::std::mem::align_of::<FragmentOrElement_nsDOMSlots__bindgen_ty_1>() - , 8usize); - } - impl Clone for FragmentOrElement_nsDOMSlots__bindgen_ty_1 { - fn clone(&self) -> Self { *self } - } - /** - * Registered Intersection Observers on the element. - */ - #[repr(C)] - #[derive(Debug, Copy)] - pub struct FragmentOrElement_nsDOMSlots_IntersectionObserverRegistration { - pub observer: *mut root::mozilla::dom::DOMIntersectionObserver, - pub previousThreshold: i32, - } - #[test] - fn bindgen_test_layout_FragmentOrElement_nsDOMSlots_IntersectionObserverRegistration() { - assert_eq!(::std::mem::size_of::<FragmentOrElement_nsDOMSlots_IntersectionObserverRegistration>() - , 16usize); - assert_eq!(::std::mem::align_of::<FragmentOrElement_nsDOMSlots_IntersectionObserverRegistration>() - , 8usize); - } - impl Clone for - FragmentOrElement_nsDOMSlots_IntersectionObserverRegistration { - fn clone(&self) -> Self { *self } - } - #[test] - fn bindgen_test_layout_FragmentOrElement_nsDOMSlots() { - assert_eq!(::std::mem::size_of::<FragmentOrElement_nsDOMSlots>() - , 168usize); - assert_eq!(::std::mem::align_of::<FragmentOrElement_nsDOMSlots>() - , 8usize); - } - extern "C" { - #[link_name = - "_ZN7mozilla3dom17FragmentOrElement21_cycleCollectorGlobalE"] - pub static mut FragmentOrElement__cycleCollectorGlobal: - root::mozilla::dom::FragmentOrElement_cycleCollection; - } - #[test] - fn bindgen_test_layout_FragmentOrElement() { - assert_eq!(::std::mem::size_of::<FragmentOrElement>() , - 120usize); - assert_eq!(::std::mem::align_of::<FragmentOrElement>() , - 8usize); - } - pub const ReferrerPolicy_RP_Default: - root::mozilla::dom::ReferrerPolicy = - ReferrerPolicy::RP_No_Referrer_When_Downgrade; - #[repr(u32)] - #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] - pub enum ReferrerPolicy { - RP_No_Referrer = 2, - RP_Origin = 3, - RP_No_Referrer_When_Downgrade = 1, - RP_Origin_When_Crossorigin = 4, - RP_Unsafe_URL = 5, - RP_Same_Origin = 6, - RP_Strict_Origin = 7, - RP_Strict_Origin_When_Cross_Origin = 8, - RP_Unset = 0, - } - #[repr(C)] - #[derive(Debug)] - pub struct Element { - pub _base: root::mozilla::dom::FragmentOrElement, - pub mState: root::EventStates, - pub mServoData: ::gecko_bindings::structs::ServoCell<*mut ::gecko_bindings::structs::ServoNodeData>, - } - #[repr(C)] - #[derive(Debug, Copy, Clone)] - pub struct Element_COMTypeInfo<T, U> { - pub _address: u8, - pub _phantom_0: ::std::marker::PhantomData<T>, - pub _phantom_1: ::std::marker::PhantomData<U>, - } - #[repr(C)] - #[derive(Debug, Copy)] - pub struct Element_MappedAttributeEntry { - pub attribute: *mut *mut root::nsIAtom, - } - #[test] - fn bindgen_test_layout_Element_MappedAttributeEntry() { - assert_eq!(::std::mem::size_of::<Element_MappedAttributeEntry>() - , 8usize); - assert_eq!(::std::mem::align_of::<Element_MappedAttributeEntry>() - , 8usize); - } - impl Clone for Element_MappedAttributeEntry { - fn clone(&self) -> Self { *self } - } - extern "C" { - #[link_name = "_ZN7mozilla3dom7Element18kFireMutationEventE"] - pub static Element_kFireMutationEvent: bool; - } - extern "C" { - #[link_name = - "_ZN7mozilla3dom7Element22kDontFireMutationEventE"] - pub static Element_kDontFireMutationEvent: bool; - } - extern "C" { - #[link_name = - "_ZN7mozilla3dom7Element24kNotifyDocumentObserversE"] - pub static Element_kNotifyDocumentObservers: bool; - } - extern "C" { - #[link_name = - "_ZN7mozilla3dom7Element28kDontNotifyDocumentObserversE"] - pub static Element_kDontNotifyDocumentObservers: bool; - } - extern "C" { - #[link_name = "_ZN7mozilla3dom7Element17kCallAfterSetAttrE"] - pub static Element_kCallAfterSetAttr: bool; - } - extern "C" { - #[link_name = - "_ZN7mozilla3dom7Element21kDontCallAfterSetAttrE"] - pub static Element_kDontCallAfterSetAttr: bool; - } - #[test] - fn bindgen_test_layout_Element() { - assert_eq!(::std::mem::size_of::<Element>() , 136usize); - assert_eq!(::std::mem::align_of::<Element>() , 8usize); - } - #[repr(C)] - #[derive(Debug, Copy)] - pub struct PrefSetting { - pub _address: u8, - } - impl Clone for PrefSetting { - fn clone(&self) -> Self { *self } - } pub mod prototypes { #[allow(unused_imports)] use self::super::super::super::super::root; @@ -1863,6 +1698,14 @@ pub mod root { pub struct UnionMember<T> { pub mStorage: root::mozilla::AlignedStorage2<T>, } + #[repr(u32)] + #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] + pub enum VisibilityState { + Hidden = 0, + Visible = 1, + Prerender = 2, + EndGuard_ = 3, + } #[repr(C)] #[derive(Debug, Copy)] pub struct Animation { @@ -1881,26 +1724,8 @@ pub mod root { } #[repr(C)] #[derive(Debug)] - pub struct nsIAttribute { - pub _base: root::nsINode, - pub mAttrMap: root::RefPtr<root::nsDOMAttributeMap>, - } - #[repr(C)] - #[derive(Debug, Copy, Clone)] - pub struct nsIAttribute_COMTypeInfo<T, U> { - pub _address: u8, - pub _phantom_0: ::std::marker::PhantomData<T>, - pub _phantom_1: ::std::marker::PhantomData<U>, - } - #[test] - fn bindgen_test_layout_nsIAttribute() { - assert_eq!(::std::mem::size_of::<nsIAttribute>() , 104usize); - assert_eq!(::std::mem::align_of::<nsIAttribute>() , 8usize); - } - #[repr(C)] - #[derive(Debug)] pub struct Attr { - pub _base: root::mozilla::dom::nsIAttribute, + pub _base: root::nsIAttribute, pub _base_1: root::nsIDOMAttr, pub mRefCnt: root::nsCycleCollectingAutoRefCnt, pub _mOwningThread: root::nsAutoOwningThread, @@ -1937,59 +1762,6 @@ pub mod root { assert_eq!(::std::mem::align_of::<Attr>() , 8usize); } #[repr(C)] - #[derive(Debug)] - pub struct DOMIntersectionObserver { - pub _base: root::nsISupports, - pub _base_1: root::nsWrapperCache, - pub mRefCnt: root::nsCycleCollectingAutoRefCnt, - pub _mOwningThread: root::nsAutoOwningThread, - pub mOwner: root::nsCOMPtr<root::nsPIDOMWindowInner>, - pub mCallback: root::RefPtr<root::mozilla::dom::IntersectionCallback>, - pub mRoot: root::RefPtr<root::mozilla::dom::Element>, - pub mRootMargin: root::nsCSSRect, - pub mThresholds: root::nsTArray<f64>, - pub mObservationTargets: [u64; 6usize], - pub mQueuedEntries: root::nsTArray<root::RefPtr<root::mozilla::dom::DOMIntersectionObserverEntry>>, - pub mConnected: bool, - } - pub type DOMIntersectionObserver_HasThreadSafeRefCnt = - root::mozilla::FalseType; - #[repr(C)] - #[derive(Debug, Copy)] - pub struct DOMIntersectionObserver_cycleCollection { - pub _base: root::nsXPCOMCycleCollectionParticipant, - } - #[test] - fn bindgen_test_layout_DOMIntersectionObserver_cycleCollection() { - assert_eq!(::std::mem::size_of::<DOMIntersectionObserver_cycleCollection>() - , 16usize); - assert_eq!(::std::mem::align_of::<DOMIntersectionObserver_cycleCollection>() - , 8usize); - } - impl Clone for DOMIntersectionObserver_cycleCollection { - fn clone(&self) -> Self { *self } - } - #[repr(C)] - #[derive(Debug, Copy, Clone)] - pub struct DOMIntersectionObserver_COMTypeInfo<T, U> { - pub _address: u8, - pub _phantom_0: ::std::marker::PhantomData<T>, - pub _phantom_1: ::std::marker::PhantomData<U>, - } - extern "C" { - #[link_name = - "_ZN7mozilla3dom23DOMIntersectionObserver21_cycleCollectorGlobalE"] - pub static mut DOMIntersectionObserver__cycleCollectorGlobal: - root::mozilla::dom::DOMIntersectionObserver_cycleCollection; - } - #[test] - fn bindgen_test_layout_DOMIntersectionObserver() { - assert_eq!(::std::mem::size_of::<DOMIntersectionObserver>() , - 208usize); - assert_eq!(::std::mem::align_of::<DOMIntersectionObserver>() , - 8usize); - } - #[repr(C)] #[derive(Debug, Copy)] pub struct FontFaceSet { pub _address: u8, @@ -2070,6 +1842,154 @@ pub mod root { } #[repr(C)] #[derive(Debug)] + pub struct FragmentOrElement { + pub _base: root::nsIContent, + pub mRefCnt: root::nsCycleCollectingAutoRefCnt, + pub _mOwningThread: root::nsAutoOwningThread, + /** + * Array containing all attributes and children for this element + */ + pub mAttrsAndChildren: root::nsAttrAndChildArray, + } + pub type FragmentOrElement_HasThreadSafeRefCnt = + root::mozilla::FalseType; + #[repr(C)] + #[derive(Debug, Copy)] + pub struct FragmentOrElement_cycleCollection { + pub _base: root::nsXPCOMCycleCollectionParticipant, + } + #[test] + fn bindgen_test_layout_FragmentOrElement_cycleCollection() { + assert_eq!(::std::mem::size_of::<FragmentOrElement_cycleCollection>() + , 16usize); + assert_eq!(::std::mem::align_of::<FragmentOrElement_cycleCollection>() + , 8usize); + } + impl Clone for FragmentOrElement_cycleCollection { + fn clone(&self) -> Self { *self } + } + /** + * There are a set of DOM- and scripting-specific instance variables + * that may only be instantiated when a content object is accessed + * through the DOM. Rather than burn actual slots in the content + * objects for each of these instance variables, we put them off + * in a side structure that's only allocated when the content is + * accessed through the DOM. + */ + #[repr(C)] + #[derive(Debug)] + pub struct FragmentOrElement_nsDOMSlots { + pub _base: root::nsINode_nsSlots, + /** + * The .style attribute (an interface that forwards to the actual + * style rules) + * @see nsGenericHTMLElement::GetStyle + */ + pub mStyle: root::nsCOMPtr<root::nsICSSDeclaration>, + /** + * The .dataset attribute. + * @see nsGenericHTMLElement::GetDataset + */ + pub mDataset: *mut root::nsDOMStringMap, + /** + * SMIL Overridde style rules (for SMIL animation of CSS properties) + * @see nsIContent::GetSMILOverrideStyle + */ + pub mSMILOverrideStyle: root::nsCOMPtr<root::nsICSSDeclaration>, + /** + * Holds any SMIL override style declaration for this element. + */ + pub mSMILOverrideStyleDeclaration: root::RefPtr<root::mozilla::DeclarationBlock>, + /** + * An object implementing nsIDOMMozNamedAttrMap for this content (attributes) + * @see FragmentOrElement::GetAttributes + */ + pub mAttributeMap: root::RefPtr<root::nsDOMAttributeMap>, + pub __bindgen_anon_1: root::mozilla::dom::FragmentOrElement_nsDOMSlots__bindgen_ty_1, + /** + * An object implementing the .children property for this element. + */ + pub mChildrenList: root::RefPtr<root::nsContentList>, + /** + * An object implementing the .classList property for this element. + */ + pub mClassList: root::RefPtr<root::nsDOMTokenList>, + /** + * ShadowRoot bound to the element. + */ + pub mShadowRoot: root::RefPtr<root::mozilla::dom::ShadowRoot>, + /** + * The root ShadowRoot of this element if it is in a shadow tree. + */ + pub mContainingShadow: root::RefPtr<root::mozilla::dom::ShadowRoot>, + /** + * An array of web component insertion points to which this element + * is distributed. + */ + pub mDestInsertionPoints: root::nsTArray<*mut root::nsIContent>, + /** + * XBL binding installed on the element. + */ + pub mXBLBinding: root::RefPtr<root::nsXBLBinding>, + /** + * XBL binding installed on the lement. + */ + pub mXBLInsertionParent: root::nsCOMPtr<root::nsIContent>, + /** + * Web components custom element data. + */ + pub mCustomElementData: root::RefPtr<root::mozilla::dom::CustomElementData>, + /** + * Registered Intersection Observers on the element. + */ + pub mRegisteredIntersectionObservers: [u64; 6usize], + } + #[repr(C)] + #[derive(Debug, Copy)] + pub struct FragmentOrElement_nsDOMSlots__bindgen_ty_1 { + /** + * The nearest enclosing content node with a binding that created us. + * @see FragmentOrElement::GetBindingParent + */ + pub mBindingParent: root::__BindgenUnionField<*mut root::nsIContent>, + /** + * The controllers of the XUL Element. + */ + pub mControllers: root::__BindgenUnionField<*mut root::nsIControllers>, + pub bindgen_union_field: u64, + } + #[test] + fn bindgen_test_layout_FragmentOrElement_nsDOMSlots__bindgen_ty_1() { + assert_eq!(::std::mem::size_of::<FragmentOrElement_nsDOMSlots__bindgen_ty_1>() + , 8usize); + assert_eq!(::std::mem::align_of::<FragmentOrElement_nsDOMSlots__bindgen_ty_1>() + , 8usize); + } + impl Clone for FragmentOrElement_nsDOMSlots__bindgen_ty_1 { + fn clone(&self) -> Self { *self } + } + #[test] + fn bindgen_test_layout_FragmentOrElement_nsDOMSlots() { + assert_eq!(::std::mem::size_of::<FragmentOrElement_nsDOMSlots>() + , 208usize); + assert_eq!(::std::mem::align_of::<FragmentOrElement_nsDOMSlots>() + , 8usize); + } + extern "C" { + #[link_name = + "_ZN7mozilla3dom17FragmentOrElement21_cycleCollectorGlobalE"] + pub static mut FragmentOrElement__cycleCollectorGlobal: + root::mozilla::dom::FragmentOrElement_cycleCollection; + } + #[test] + fn bindgen_test_layout_FragmentOrElement() { + assert_eq!(::std::mem::size_of::<FragmentOrElement>() , + 120usize); + assert_eq!(::std::mem::align_of::<FragmentOrElement>() , + 8usize); + } + #[repr(C)] + #[derive(Debug)] pub struct DOMRect { pub _base: root::mozilla::dom::DOMRectReadOnly, pub _base_1: root::nsIDOMClientRect, @@ -2130,18 +2050,6 @@ pub mod root { , 8usize); } #[repr(C)] - #[derive(Debug)] - pub struct IntersectionCallback { - pub _base: root::mozilla::dom::CallbackFunction, - } - #[test] - fn bindgen_test_layout_IntersectionCallback() { - assert_eq!(::std::mem::size_of::<IntersectionCallback>() , - 56usize); - assert_eq!(::std::mem::align_of::<IntersectionCallback>() , - 8usize); - } - #[repr(C)] #[derive(Debug, Copy)] pub struct Grid { pub _address: u8, @@ -2158,6 +2066,62 @@ pub mod root { impl Clone for ShortcutKeyCandidate { fn clone(&self) -> Self { *self } } + /** + * Instances of this class represent moments in time, or a special + * "null" moment. We do not use the non-monotonic system clock or + * local time, since they can be reset, causing apparent backward + * travel in time, which can confuse algorithms. Instead we measure + * elapsed time according to the system. This time can never go + * backwards (i.e. it never wraps around, at least not in less than + * five million years of system elapsed time). It might not advance + * while the system is sleeping. If TimeStamp::SetNow() is not called + * at all for hours or days, we might not notice the passage of some + * of that time. + * + * We deliberately do not expose a way to convert TimeStamps to some + * particular unit. All you can do is compute a difference between two + * TimeStamps to get a TimeDuration. You can also add a TimeDuration + * to a TimeStamp to get a new TimeStamp. You can't do something + * meaningless like add two TimeStamps. + * + * Internally this is implemented as either a wrapper around + * - high-resolution, monotonic, system clocks if they exist on this + * platform + * - PRIntervalTime otherwise. We detect wraparounds of + * PRIntervalTime and work around them. + * + * This class is similar to C++11's time_point, however it is + * explicitly nullable and provides an IsNull() method. time_point + * is initialized to the clock's epoch and provides a + * time_since_epoch() method that functions similiarly. i.e. + * t.IsNull() is equivalent to t.time_since_epoch() == decltype(t)::duration::zero(); + */ + #[repr(C)] + #[derive(Debug, Copy)] + pub struct TimeStamp { + /** + * When built with PRIntervalTime, a value of 0 means this instance + * is "null". Otherwise, the low 32 bits represent a PRIntervalTime, + * and the high 32 bits represent a counter of the number of + * rollovers of PRIntervalTime that we've seen. This counter starts + * at 1 to avoid a real time colliding with the "null" value. + * + * PR_INTERVAL_MAX is set at 100,000 ticks per second. So the minimum + * time to wrap around is about 2^64/100000 seconds, i.e. about + * 5,849,424 years. + * + * When using a system clock, a value is system dependent. + */ + pub mValue: root::mozilla::TimeStampValue, + } + #[test] + fn bindgen_test_layout_TimeStamp() { + assert_eq!(::std::mem::size_of::<TimeStamp>() , 8usize); + assert_eq!(::std::mem::align_of::<TimeStamp>() , 8usize); + } + impl Clone for TimeStamp { + fn clone(&self) -> Self { *self } + } pub type TimeStampValue = u64; #[repr(C)] #[derive(Debug)] @@ -2222,6 +2186,28 @@ pub mod root { fn clone(&self) -> Self { *self } } #[repr(C)] + #[derive(Debug)] + pub struct URLValue { + pub _base: root::mozilla::css::URLValueData, + } + #[test] + fn bindgen_test_layout_URLValue() { + assert_eq!(::std::mem::size_of::<URLValue>() , 64usize); + assert_eq!(::std::mem::align_of::<URLValue>() , 8usize); + } + #[repr(C)] + #[derive(Debug)] + pub struct ImageValue { + pub _base: root::mozilla::css::URLValueData, + pub mRequests: [u64; 6usize], + pub mInitialized: bool, + } + #[test] + fn bindgen_test_layout_ImageValue() { + assert_eq!(::std::mem::size_of::<ImageValue>() , 120usize); + assert_eq!(::std::mem::align_of::<ImageValue>() , 8usize); + } + #[repr(C)] pub struct URLValueData__bindgen_vtable { } #[repr(C)] @@ -2246,28 +2232,6 @@ pub mod root { } #[repr(C)] #[derive(Debug)] - pub struct URLValue { - pub _base: root::mozilla::css::URLValueData, - } - #[test] - fn bindgen_test_layout_URLValue() { - assert_eq!(::std::mem::size_of::<URLValue>() , 64usize); - assert_eq!(::std::mem::align_of::<URLValue>() , 8usize); - } - #[repr(C)] - #[derive(Debug)] - pub struct ImageValue { - pub _base: root::mozilla::css::URLValueData, - pub mRequests: [u64; 6usize], - pub mInitialized: bool, - } - #[test] - fn bindgen_test_layout_ImageValue() { - assert_eq!(::std::mem::size_of::<ImageValue>() , 120usize); - assert_eq!(::std::mem::align_of::<ImageValue>() , 8usize); - } - #[repr(C)] - #[derive(Debug)] pub struct GridNamedArea { pub mName: ::nsstring::nsStringRepr, pub mColumnStart: u32, @@ -2406,6 +2370,14 @@ pub mod root { assert_eq!(::std::mem::size_of::<StyleSheet>() , 88usize); assert_eq!(::std::mem::align_of::<StyleSheet>() , 8usize); } + #[repr(u32)] + #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] + pub enum Side { + eSideTop = 0, + eSideRight = 1, + eSideBottom = 2, + eSideLeft = 3, + } #[repr(C)] #[derive(Debug, Copy)] pub struct SVGAttrAnimationRuleProcessor { @@ -2493,7 +2465,32 @@ pub mod root { } #[repr(i32)] #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] - pub enum SkipRootBehavior { Skip = 0, DontSkip = 1, } + pub enum ConsumeStyleBehavior { Consume = 0, DontConsume = 1, } + #[repr(i32)] + #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] + pub enum LazyComputeBehavior { Allow = 0, Assert = 1, } + #[repr(i32)] + #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] + pub enum TraversalRootBehavior { + Normal = 0, + UnstyledChildrenOnly = 1, + } + #[repr(u8)] + #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] + pub enum SheetType { + Agent = 0, + User = 1, + PresHint = 2, + SVGAttrAnimation = 3, + Doc = 4, + ScopedDoc = 5, + StyleAttr = 6, + Override = 7, + Animation = 8, + Transition = 9, + Count = 10, + Unknown = 255, + } pub mod a11y { #[allow(unused_imports)] use self::super::super::super::root; @@ -2600,13 +2597,6 @@ pub mod root { impl Clone for FramePropertyDescriptorUntyped { fn clone(&self) -> Self { *self } } - #[test] - fn __bindgen_test_layout_template_1() { - assert_eq!(::std::mem::size_of::<root::nsPtrHashKey<root::nsIFrame>>() - , 16usize); - assert_eq!(::std::mem::align_of::<root::nsPtrHashKey<root::nsIFrame>>() - , 8usize); - } /** * The FramePropertyTable is optimized for storing 0 or 1 properties on * a given frame. Storing very large numbers of properties on a single @@ -2776,6 +2766,9 @@ pub mod root { } #[repr(u8)] #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] + pub enum StyleShapeRadius { FarthestSide = 0, ClosestSide = 1, } + #[repr(u8)] + #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] pub enum StyleShapeSourceType { None = 0, URL = 1, @@ -2888,6 +2881,42 @@ pub mod root { pub struct HandleRefPtr<T> { pub mHandle: T, } + /** + * Smart pointer class that can hold a pointer to either a RestyleManager + * or a ServoRestyleManager. + */ + #[repr(C)] + #[derive(Debug, Copy)] + pub struct RestyleManagerHandle { + pub mPtr: root::mozilla::RestyleManagerHandle_Ptr, + } + pub type RestyleManagerHandle_RefPtr = + root::mozilla::HandleRefPtr<root::mozilla::RestyleManagerHandle>; + #[repr(C)] + #[derive(Debug, Copy)] + pub struct RestyleManagerHandle_Ptr { + pub mValue: usize, + } + #[test] + fn bindgen_test_layout_RestyleManagerHandle_Ptr() { + assert_eq!(::std::mem::size_of::<RestyleManagerHandle_Ptr>() , + 8usize); + assert_eq!(::std::mem::align_of::<RestyleManagerHandle_Ptr>() , + 8usize); + } + impl Clone for RestyleManagerHandle_Ptr { + fn clone(&self) -> Self { *self } + } + #[test] + fn bindgen_test_layout_RestyleManagerHandle() { + assert_eq!(::std::mem::size_of::<RestyleManagerHandle>() , + 8usize); + assert_eq!(::std::mem::align_of::<RestyleManagerHandle>() , + 8usize); + } + impl Clone for RestyleManagerHandle { + fn clone(&self) -> Self { *self } + } #[repr(C)] #[derive(Debug)] pub struct LangGroupFontPrefs { @@ -3018,7 +3047,7 @@ pub mod root { fn clone(&self) -> Self { *self } } #[test] - fn __bindgen_test_layout_template_2() { + fn __bindgen_test_layout_template_1() { assert_eq!(::std::mem::size_of::<root::mozilla::DefaultDelete<root::RawServoStyleSet>>() , 1usize); assert_eq!(::std::mem::align_of::<root::mozilla::DefaultDelete<root::RawServoStyleSet>>() @@ -3101,6 +3130,34 @@ pub mod root { impl Clone for ProgressTracker { fn clone(&self) -> Self { *self } } + #[repr(C)] + pub struct IProgressObserver__bindgen_vtable { + } + /** + * An interface for observing changes to image state, as reported by + * ProgressTracker. + * + * This is the ImageLib-internal version of imgINotificationObserver, + * essentially, with implementation details that code outside of ImageLib + * shouldn't see. + * + * XXX(seth): It's preferable to avoid adding anything to this interface if + * possible. In the long term, it would be ideal to get to a place where we can + * just use the imgINotificationObserver interface internally as well. + */ + #[repr(C)] + #[derive(Debug)] + pub struct IProgressObserver { + pub vtable_: *const IProgressObserver__bindgen_vtable, + pub _base: u64, + } + #[test] + fn bindgen_test_layout_IProgressObserver() { + assert_eq!(::std::mem::size_of::<IProgressObserver>() , + 16usize); + assert_eq!(::std::mem::align_of::<IProgressObserver>() , + 8usize); + } } #[repr(C)] #[derive(Debug, Copy)] @@ -3185,14 +3242,14 @@ pub mod root { pub type StyleShapeOutside = root::mozilla::StyleShapeSource<root::mozilla::StyleShapeOutsideShapeBox>; #[test] - fn __bindgen_test_layout_template_3() { + fn __bindgen_test_layout_template_2() { assert_eq!(::std::mem::size_of::<root::mozilla::StyleShapeSource<root::mozilla::StyleClipPathGeometryBox>>() , 16usize); assert_eq!(::std::mem::align_of::<root::mozilla::StyleShapeSource<root::mozilla::StyleClipPathGeometryBox>>() , 8usize); } #[test] - fn __bindgen_test_layout_template_4() { + fn __bindgen_test_layout_template_3() { assert_eq!(::std::mem::size_of::<root::mozilla::StyleShapeSource<root::mozilla::StyleShapeOutsideShapeBox>>() , 16usize); assert_eq!(::std::mem::align_of::<root::mozilla::StyleShapeSource<root::mozilla::StyleShapeOutsideShapeBox>>() @@ -3714,6 +3771,12 @@ pub mod root { NS_ERROR_DOM_MEDIA_CDM_ERR = 2154692621, NS_ERROR_DOM_MEDIA_NEED_NEW_DECODER = 2154692622, NS_ERROR_DOM_MEDIA_CUBEB_INITIALIZATION_ERR = 2154692709, + NS_ERROR_UC_UPDATE_UNKNOWN = 2154758145, + NS_ERROR_UC_UPDATE_DUPLICATE_PREFIX = 2154758146, + NS_ERROR_UC_UPDATE_INFINITE_LOOP = 2154758147, + NS_ERROR_UC_UPDATE_WRONG_REMOVAL_INDICES = 2154758148, + NS_ERROR_UC_UPDATE_CHECKSUM_MISMATCH = 2154758149, + NS_ERROR_UC_UPDATE_MISSING_CHECKSUM = 2154758150, NS_ERROR_DOWNLOAD_COMPLETE = 2155347969, NS_ERROR_DOWNLOAD_NOT_PARTIAL = 2155347970, NS_ERROR_UNORM_MOREOUTPUT = 2155348001, @@ -3815,12 +3878,6 @@ pub mod root { 8usize); } } - #[repr(C)] - #[derive(Debug, Copy, Clone)] - pub struct HeapBase<T> { - pub _address: u8, - pub _phantom_0: ::std::marker::PhantomData<T>, - } /** * The Heap<T> class is a heap-stored reference to a JS GC thing. All members of * heap classes that refer to GC things should use Heap<T> (or possibly @@ -3845,6 +3902,7 @@ pub mod root { pub struct Heap<T> { pub ptr: T, } + pub type Heap_ElementType<T> = T; /** * The TenuredHeap<T> class is similar to the Heap<T> class above in that it * encapsulates the GC concerns of an on-heap reference to a JS object. However, @@ -3880,15 +3938,16 @@ pub mod root { pub bits: usize, pub _phantom_0: ::std::marker::PhantomData<T>, } + pub type TenuredHeap_ElementType<T> = T; pub const TenuredHeap_maskBits: root::JS::TenuredHeap__bindgen_ty_1 = TenuredHeap__bindgen_ty_1::maskBits; - pub const flagsMask: root::JS::TenuredHeap__bindgen_ty_1 = + pub const TenuredHeap_flagsMask: root::JS::TenuredHeap__bindgen_ty_1 = TenuredHeap__bindgen_ty_1::maskBits; #[repr(i32)] #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] pub enum TenuredHeap__bindgen_ty_1 { maskBits = 0, } #[test] - fn __bindgen_test_layout_template_5() { + fn __bindgen_test_layout_template_4() { assert_eq!(::std::mem::size_of::<root::mozilla::UniquePtr<*mut ::std::os::raw::c_char, root::JS::FreePolicy>>() , 8usize); @@ -3913,6 +3972,12 @@ pub mod root { use self::super::super::super::root; } #[repr(C)] + #[derive(Debug, Copy, Clone)] + pub struct HeapBase<T> { + pub _address: u8, + pub _phantom_0: ::std::marker::PhantomData<T>, + } + #[repr(C)] pub struct SourceHook__bindgen_vtable { } /** @@ -4272,13 +4337,13 @@ pub mod root { pub _phantom_0: ::std::marker::PhantomData<CharT>, } #[test] - fn __bindgen_test_layout_template_6() { + fn __bindgen_test_layout_template_5() { assert_eq!(::std::mem::size_of::<root::nsCharTraits<u16>>() , 1usize); assert_eq!(::std::mem::align_of::<root::nsCharTraits<u16>>() , 1usize); } #[test] - fn __bindgen_test_layout_template_7() { + fn __bindgen_test_layout_template_6() { assert_eq!(::std::mem::size_of::<root::nsCharTraits<::std::os::raw::c_char>>() , 1usize); assert_eq!(::std::mem::align_of::<root::nsCharTraits<::std::os::raw::c_char>>() @@ -4416,10 +4481,7 @@ pub mod root { pub struct nsAutoRefCnt { pub mValue: root::nsrefcnt, } - extern "C" { - #[link_name = "_ZN12nsAutoRefCnt12isThreadSafeE"] - pub static nsAutoRefCnt_isThreadSafe: bool; - } + pub const nsAutoRefCnt_isThreadSafe: bool = false; #[test] fn bindgen_test_layout_nsAutoRefCnt() { assert_eq!(::std::mem::size_of::<nsAutoRefCnt>() , 8usize); @@ -4498,7 +4560,7 @@ pub mod root { pub mRawPtr: *mut root::nsISupports, } #[test] - fn __bindgen_test_layout_template_8() { + fn __bindgen_test_layout_template_7() { assert_eq!(::std::mem::size_of::<root::nsCOMPtr<root::nsISupports>>() , 8usize); assert_eq!(::std::mem::align_of::<root::nsCOMPtr<root::nsISupports>>() @@ -4606,26 +4668,6 @@ pub mod root { } #[repr(C)] #[derive(Debug, Copy)] - pub struct nsISerializable { - pub _base: root::nsISupports, - } - #[repr(C)] - #[derive(Debug, Copy, Clone)] - pub struct nsISerializable_COMTypeInfo<T, U> { - pub _address: u8, - pub _phantom_0: ::std::marker::PhantomData<T>, - pub _phantom_1: ::std::marker::PhantomData<U>, - } - #[test] - fn bindgen_test_layout_nsISerializable() { - assert_eq!(::std::mem::size_of::<nsISerializable>() , 8usize); - assert_eq!(::std::mem::align_of::<nsISerializable>() , 8usize); - } - impl Clone for nsISerializable { - fn clone(&self) -> Self { *self } - } - #[repr(C)] - #[derive(Debug, Copy)] pub struct nsIPrincipal { pub _base: root::nsISerializable, } @@ -4834,364 +4876,61 @@ pub mod root { } #[repr(C)] #[derive(Debug, Copy)] - pub struct nsIURI { + pub struct nsISerializable { pub _base: root::nsISupports, } #[repr(C)] #[derive(Debug, Copy, Clone)] - pub struct nsIURI_COMTypeInfo<T, U> { + pub struct nsISerializable_COMTypeInfo<T, U> { pub _address: u8, pub _phantom_0: ::std::marker::PhantomData<T>, pub _phantom_1: ::std::marker::PhantomData<U>, } #[test] - fn bindgen_test_layout_nsIURI() { - assert_eq!(::std::mem::size_of::<nsIURI>() , 8usize); - assert_eq!(::std::mem::align_of::<nsIURI>() , 8usize); + fn bindgen_test_layout_nsISerializable() { + assert_eq!(::std::mem::size_of::<nsISerializable>() , 8usize); + assert_eq!(::std::mem::align_of::<nsISerializable>() , 8usize); } - impl Clone for nsIURI { + impl Clone for nsISerializable { fn clone(&self) -> Self { *self } } - #[test] - fn __bindgen_test_layout_template_9() { - assert_eq!(::std::mem::size_of::<[u64; 29usize]>() , 232usize); - assert_eq!(::std::mem::align_of::<[u64; 29usize]>() , 8usize); - } - #[repr(C)] - #[derive(Debug)] - pub struct nsPIDOMWindowInner { - pub _base: [u64; 29usize], - } - #[repr(C)] - #[derive(Debug, Copy, Clone)] - pub struct nsPIDOMWindowInner_COMTypeInfo<T, U> { - pub _address: u8, - pub _phantom_0: ::std::marker::PhantomData<T>, - pub _phantom_1: ::std::marker::PhantomData<U>, - } - #[test] - fn bindgen_test_layout_nsPIDOMWindowInner() { - assert_eq!(::std::mem::size_of::<nsPIDOMWindowInner>() , 232usize); - assert_eq!(::std::mem::align_of::<nsPIDOMWindowInner>() , 8usize); - } #[repr(C)] #[derive(Debug, Copy)] - pub struct nsIDOMEventTarget { + pub struct nsIURI { pub _base: root::nsISupports, } #[repr(C)] #[derive(Debug, Copy, Clone)] - pub struct nsIDOMEventTarget_COMTypeInfo<T, U> { + pub struct nsIURI_COMTypeInfo<T, U> { pub _address: u8, pub _phantom_0: ::std::marker::PhantomData<T>, pub _phantom_1: ::std::marker::PhantomData<U>, } #[test] - fn bindgen_test_layout_nsIDOMEventTarget() { - assert_eq!(::std::mem::size_of::<nsIDOMEventTarget>() , 8usize); - assert_eq!(::std::mem::align_of::<nsIDOMEventTarget>() , 8usize); + fn bindgen_test_layout_nsIURI() { + assert_eq!(::std::mem::size_of::<nsIURI>() , 8usize); + assert_eq!(::std::mem::align_of::<nsIURI>() , 8usize); } - impl Clone for nsIDOMEventTarget { + impl Clone for nsIURI { fn clone(&self) -> Self { *self } } #[repr(C)] #[derive(Debug)] - pub struct EventTarget { - pub _base: root::nsIDOMEventTarget, - pub _base_1: root::nsWrapperCache, - } - #[repr(C)] - #[derive(Debug, Copy, Clone)] - pub struct EventTarget_COMTypeInfo<T, U> { - pub _address: u8, - pub _phantom_0: ::std::marker::PhantomData<T>, - pub _phantom_1: ::std::marker::PhantomData<U>, - } - #[test] - fn bindgen_test_layout_EventTarget() { - assert_eq!(::std::mem::size_of::<EventTarget>() , 32usize); - assert_eq!(::std::mem::align_of::<EventTarget>() , 8usize); - } - /** - * An internal interface that abstracts some DOMNode-related parts that both - * nsIContent and nsIDocument share. An instance of this interface has a list - * of nsIContent children and provides access to them. - */ - #[repr(C)] - #[derive(Debug)] - pub struct nsINode { - pub _base: root::EventTarget, - pub mNodeInfo: root::RefPtr<root::mozilla::dom::NodeInfo>, - pub mParent: *mut root::nsINode, - pub mBoolFlags: u32, - pub mNextSibling: *mut root::nsIContent, - pub mPreviousSibling: *mut root::nsIContent, - pub mFirstChild: *mut root::nsIContent, - pub __bindgen_anon_1: root::nsINode__bindgen_ty_1, - pub mSlots: *mut root::nsINode_nsSlots, + pub struct nsPIDOMWindowInner { + pub _base: [u64; 29usize], } - pub type nsINode_BoxQuadOptions = root::mozilla::dom::BoxQuadOptions; - pub type nsINode_ConvertCoordinateOptions = - root::mozilla::dom::ConvertCoordinateOptions; - pub type nsINode_DOMPoint = root::mozilla::dom::DOMPoint; - pub type nsINode_DOMPointInit = root::mozilla::dom::DOMPointInit; - pub type nsINode_DOMQuad = root::mozilla::dom::DOMQuad; - pub type nsINode_DOMRectReadOnly = root::mozilla::dom::DOMRectReadOnly; - pub type nsINode_OwningNodeOrString = - root::mozilla::dom::OwningNodeOrString; - pub type nsINode_TextOrElementOrDocument = - root::mozilla::dom::TextOrElementOrDocument; - pub type nsINode_ErrorResult = [u64; 4usize]; #[repr(C)] #[derive(Debug, Copy, Clone)] - pub struct nsINode_COMTypeInfo<T, U> { + pub struct nsPIDOMWindowInner_COMTypeInfo<T, U> { pub _address: u8, pub _phantom_0: ::std::marker::PhantomData<T>, pub _phantom_1: ::std::marker::PhantomData<U>, } - pub const nsINode_eCONTENT: root::nsINode__bindgen_ty_2 = - nsINode__bindgen_ty_2::eCONTENT; - pub const nsINode_eDOCUMENT: root::nsINode__bindgen_ty_2 = - nsINode__bindgen_ty_2::eDOCUMENT; - pub const nsINode_eATTRIBUTE: root::nsINode__bindgen_ty_2 = - nsINode__bindgen_ty_2::eATTRIBUTE; - pub const nsINode_eTEXT: root::nsINode__bindgen_ty_2 = - nsINode__bindgen_ty_2::eTEXT; - pub const nsINode_ePROCESSING_INSTRUCTION: root::nsINode__bindgen_ty_2 = - nsINode__bindgen_ty_2::ePROCESSING_INSTRUCTION; - pub const nsINode_eCOMMENT: root::nsINode__bindgen_ty_2 = - nsINode__bindgen_ty_2::eCOMMENT; - pub const nsINode_eHTML_FORM_CONTROL: root::nsINode__bindgen_ty_2 = - nsINode__bindgen_ty_2::eHTML_FORM_CONTROL; - pub const nsINode_eDOCUMENT_FRAGMENT: root::nsINode__bindgen_ty_2 = - nsINode__bindgen_ty_2::eDOCUMENT_FRAGMENT; - pub const nsINode_eDATA_NODE: root::nsINode__bindgen_ty_2 = - nsINode__bindgen_ty_2::eDATA_NODE; - pub const nsINode_eMEDIA: root::nsINode__bindgen_ty_2 = - nsINode__bindgen_ty_2::eMEDIA; - pub const nsINode_eANIMATION: root::nsINode__bindgen_ty_2 = - nsINode__bindgen_ty_2::eANIMATION; - pub const nsINode_eFILTER: root::nsINode__bindgen_ty_2 = - nsINode__bindgen_ty_2::eFILTER; - #[repr(u32)] - /** - * Bit-flags to pass (or'ed together) to IsNodeOfType() - */ - #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] - pub enum nsINode__bindgen_ty_2 { - eCONTENT = 1, - eDOCUMENT = 2, - eATTRIBUTE = 4, - eTEXT = 8, - ePROCESSING_INSTRUCTION = 16, - eCOMMENT = 32, - eHTML_FORM_CONTROL = 64, - eDOCUMENT_FRAGMENT = 128, - eDATA_NODE = 256, - eMEDIA = 512, - eANIMATION = 1024, - eFILTER = 2048, - } - #[repr(C)] - pub struct nsINode_nsSlots__bindgen_vtable { - } - #[repr(C)] - #[derive(Debug)] - pub struct nsINode_nsSlots { - pub vtable_: *const nsINode_nsSlots__bindgen_vtable, - /** - * A list of mutation observers - */ - pub mMutationObservers: [u64; 2usize], - /** - * An object implementing nsIDOMNodeList for this content (childNodes) - * @see nsIDOMNodeList - * @see nsGenericHTMLElement::GetChildNodes - */ - pub mChildNodes: root::RefPtr<root::nsChildContentList>, - /** - * Weak reference to this node. This is cleared by the destructor of - * nsNodeWeakReference. - */ - pub mWeakReference: *mut root::nsNodeWeakReference, - /** - * Number of descendant nodes in the uncomposed document that have been - * explicitly set as editable. - */ - pub mEditableDescendantCount: u32, - } - #[test] - fn bindgen_test_layout_nsINode_nsSlots() { - assert_eq!(::std::mem::size_of::<nsINode_nsSlots>() , 48usize); - assert_eq!(::std::mem::align_of::<nsINode_nsSlots>() , 8usize); - } - #[repr(u32)] - /** - * Boolean flags - */ - #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] - pub enum nsINode_BooleanFlag { - NodeHasRenderingObservers = 0, - IsInDocument = 1, - ParentIsContent = 2, - NodeIsElement = 3, - ElementHasID = 4, - ElementMayHaveStyle = 5, - ElementHasName = 6, - ElementMayHaveContentEditableAttr = 7, - NodeIsCommonAncestorForRangeInSelection = 8, - NodeIsDescendantOfCommonAncestorForRangeInSelection = 9, - NodeIsCCMarkedRoot = 10, - NodeIsCCBlackTree = 11, - NodeIsPurpleRoot = 12, - NodeHasExplicitBaseURI = 13, - ElementHasLockedStyleStates = 14, - ElementHasPointerLock = 15, - NodeMayHaveDOMMutationObserver = 16, - NodeIsContent = 17, - ElementHasAnimations = 18, - NodeHasValidDirAttribute = 19, - NodeHasFixedDir = 20, - NodeHasDirAutoSet = 21, - NodeHasTextNodeDirectionalityMap = 22, - NodeHasDirAuto = 23, - NodeAncestorHasDirAuto = 24, - ElementIsInStyleScope = 25, - ElementIsScopedStyleRoot = 26, - NodeHandlingClick = 27, - NodeHasRelevantHoverRules = 28, - ElementHasWeirdParserInsertionMode = 29, - ParserHasNotified = 30, - MayBeApzAware = 31, - BooleanFlagCount = 32, - } - #[repr(C)] - #[derive(Debug, Copy)] - pub struct nsINode__bindgen_ty_1 { - pub mPrimaryFrame: root::__BindgenUnionField<*mut root::nsIFrame>, - pub mSubtreeRoot: root::__BindgenUnionField<*mut root::nsINode>, - pub bindgen_union_field: u64, - } #[test] - fn bindgen_test_layout_nsINode__bindgen_ty_1() { - assert_eq!(::std::mem::size_of::<nsINode__bindgen_ty_1>() , 8usize); - assert_eq!(::std::mem::align_of::<nsINode__bindgen_ty_1>() , 8usize); - } - impl Clone for nsINode__bindgen_ty_1 { - fn clone(&self) -> Self { *self } - } - #[test] - fn bindgen_test_layout_nsINode() { - assert_eq!(::std::mem::size_of::<nsINode>() , 96usize); - assert_eq!(::std::mem::align_of::<nsINode>() , 8usize); - } - #[repr(u8)] - /** - * Enumeration that represents one of the two supported style system backends. - */ - #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] - pub enum StyleBackendType { Gecko = 1, Servo = 2, } - #[repr(i32)] - #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] - pub enum ConsumeStyleBehavior { Consume = 0, DontConsume = 1, } - #[repr(i32)] - #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] - pub enum LazyComputeBehavior { Allow = 0, Assert = 1, } - #[repr(u8)] - #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] - pub enum SheetType { - Agent = 0, - User = 1, - PresHint = 2, - SVGAttrAnimation = 3, - Doc = 4, - ScopedDoc = 5, - StyleAttr = 6, - Override = 7, - Animation = 8, - Transition = 9, - Count = 10, - Unknown = 255, - } - /** - * EventStates is the class used to represent the event states of nsIContent - * instances. These states are calculated by IntrinsicState() and - * ContentStatesChanged() has to be called when one of them changes thus - * informing the layout/style engine of the change. - * Event states are associated with pseudo-classes. - */ - #[repr(C)] - #[derive(Debug, Copy)] - pub struct EventStates { - pub mStates: root::EventStates_InternalType, - } - pub type EventStates_InternalType = u64; - pub type EventStates_ServoType = u8; - #[test] - fn bindgen_test_layout_EventStates() { - assert_eq!(::std::mem::size_of::<EventStates>() , 8usize); - assert_eq!(::std::mem::align_of::<EventStates>() , 8usize); - } - impl Clone for EventStates { - fn clone(&self) -> Self { *self } - } - pub const nsRestyleHint_eRestyle_Self: root::nsRestyleHint = - nsRestyleHint(1); - pub const nsRestyleHint_eRestyle_SomeDescendants: root::nsRestyleHint = - nsRestyleHint(2); - pub const nsRestyleHint_eRestyle_Subtree: root::nsRestyleHint = - nsRestyleHint(4); - pub const nsRestyleHint_eRestyle_LaterSiblings: root::nsRestyleHint = - nsRestyleHint(8); - pub const nsRestyleHint_eRestyle_CSSTransitions: root::nsRestyleHint = - nsRestyleHint(16); - pub const nsRestyleHint_eRestyle_CSSAnimations: root::nsRestyleHint = - nsRestyleHint(32); - pub const nsRestyleHint_eRestyle_SVGAttrAnimations: root::nsRestyleHint = - nsRestyleHint(64); - pub const nsRestyleHint_eRestyle_StyleAttribute: root::nsRestyleHint = - nsRestyleHint(128); - pub const nsRestyleHint_eRestyle_StyleAttribute_Animations: - root::nsRestyleHint = - nsRestyleHint(256); - pub const nsRestyleHint_eRestyle_Force: root::nsRestyleHint = - nsRestyleHint(512); - pub const nsRestyleHint_eRestyle_ForceDescendants: root::nsRestyleHint = - nsRestyleHint(1024); - pub const nsRestyleHint_eRestyle_AllHintsWithAnimations: - root::nsRestyleHint = - nsRestyleHint(368); - impl ::std::ops::BitOr<root::nsRestyleHint> for root::nsRestyleHint { - type - Output - = - Self; - #[inline] - fn bitor(self, other: Self) -> Self { - nsRestyleHint(self.0 | other.0) - } + fn bindgen_test_layout_nsPIDOMWindowInner() { + assert_eq!(::std::mem::size_of::<nsPIDOMWindowInner>() , 232usize); + assert_eq!(::std::mem::align_of::<nsPIDOMWindowInner>() , 8usize); } - #[repr(C)] - /** - * |nsRestyleHint| is a bitfield for the result of - * |HasStateDependentStyle| and |HasAttributeDependentStyle|. When no - * restyling is necessary, use |nsRestyleHint(0)|. - * - * Without eRestyle_Force or eRestyle_ForceDescendants, the restyling process - * can stop processing at a frame when it detects no style changes and it is - * known that the styles of the subtree beneath it will not change, leaving - * the old style context on the frame. eRestyle_Force can be used to skip this - * optimization on a frame, and to force its new style context to be used. - * - * Similarly, eRestyle_ForceDescendants will cause the frame and all of its - * descendants to be traversed and for the new style contexts that are created - * to be set on the frames. - * - * NOTE: When adding new restyle hints, please also add them to - * RestyleManager::RestyleHintToString. - */ - #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] - pub struct nsRestyleHint(pub u32); /** * Smart pointer class that can hold a pointer to either an nsStyleSet * or a ServoStyleSet. @@ -5223,96 +4962,27 @@ pub mod root { fn clone(&self) -> Self { *self } } /** - * Instances of this class represent moments in time, or a special - * "null" moment. We do not use the non-monotonic system clock or - * local time, since they can be reset, causing apparent backward - * travel in time, which can confuse algorithms. Instead we measure - * elapsed time according to the system. This time can never go - * backwards (i.e. it never wraps around, at least not in less than - * five million years of system elapsed time). It might not advance - * while the system is sleeping. If TimeStamp::SetNow() is not called - * at all for hours or days, we might not notice the passage of some - * of that time. - * - * We deliberately do not expose a way to convert TimeStamps to some - * particular unit. All you can do is compute a difference between two - * TimeStamps to get a TimeDuration. You can also add a TimeDuration - * to a TimeStamp to get a new TimeStamp. You can't do something - * meaningless like add two TimeStamps. - * - * Internally this is implemented as either a wrapper around - * - high-resolution, monotonic, system clocks if they exist on this - * platform - * - PRIntervalTime otherwise. We detect wraparounds of - * PRIntervalTime and work around them. - * - * This class is similar to C++11's time_point, however it is - * explicitly nullable and provides an IsNull() method. time_point - * is initialized to the clock's epoch and provides a - * time_since_epoch() method that functions similiarly. i.e. - * t.IsNull() is equivalent to t.time_since_epoch() == decltype(t)::duration::zero(); + * EventStates is the class used to represent the event states of nsIContent + * instances. These states are calculated by IntrinsicState() and + * ContentStatesChanged() has to be called when one of them changes thus + * informing the layout/style engine of the change. + * Event states are associated with pseudo-classes. */ #[repr(C)] #[derive(Debug, Copy)] - pub struct TimeStamp { - /** - * When built with PRIntervalTime, a value of 0 means this instance - * is "null". Otherwise, the low 32 bits represent a PRIntervalTime, - * and the high 32 bits represent a counter of the number of - * rollovers of PRIntervalTime that we've seen. This counter starts - * at 1 to avoid a real time colliding with the "null" value. - * - * PR_INTERVAL_MAX is set at 100,000 ticks per second. So the minimum - * time to wrap around is about 2^64/100000 seconds, i.e. about - * 5,849,424 years. - * - * When using a system clock, a value is system dependent. - */ - pub mValue: root::mozilla::TimeStampValue, - } - #[test] - fn bindgen_test_layout_TimeStamp() { - assert_eq!(::std::mem::size_of::<TimeStamp>() , 8usize); - assert_eq!(::std::mem::align_of::<TimeStamp>() , 8usize); - } - impl Clone for TimeStamp { - fn clone(&self) -> Self { *self } - } - #[repr(C)] - #[derive(Debug, Copy)] - pub struct nsIObserver { - pub _base: root::nsISupports, - } - #[repr(C)] - #[derive(Debug, Copy, Clone)] - pub struct nsIObserver_COMTypeInfo<T, U> { - pub _address: u8, - pub _phantom_0: ::std::marker::PhantomData<T>, - pub _phantom_1: ::std::marker::PhantomData<U>, + pub struct EventStates { + pub mStates: root::EventStates_InternalType, } + pub type EventStates_InternalType = u64; + pub type EventStates_ServoType = u8; #[test] - fn bindgen_test_layout_nsIObserver() { - assert_eq!(::std::mem::size_of::<nsIObserver>() , 8usize); - assert_eq!(::std::mem::align_of::<nsIObserver>() , 8usize); + fn bindgen_test_layout_EventStates() { + assert_eq!(::std::mem::size_of::<EventStates>() , 8usize); + assert_eq!(::std::mem::align_of::<EventStates>() , 8usize); } - impl Clone for nsIObserver { + impl Clone for EventStates { fn clone(&self) -> Self { *self } } - #[repr(u32)] - #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] - pub enum nsCompatibility { - eCompatibility_FullStandards = 1, - eCompatibility_AlmostStandards = 2, - eCompatibility_NavQuirks = 3, - } - #[repr(u32)] - #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] - pub enum VisibilityState { - Hidden = 0, - Visible = 1, - Prerender = 2, - EndGuard_ = 3, - } #[repr(C)] #[derive(Debug)] pub struct nsIDocument { @@ -5358,7 +5028,7 @@ pub mod root { pub mCompatMode: root::nsCompatibility, pub mReadyState: root::nsIDocument_ReadyState, pub mStyleBackendType: root::StyleBackendType, - pub mVisibilityState: root::VisibilityState, + pub mVisibilityState: root::mozilla::dom::VisibilityState, pub _bitfield_1: u64, pub mType: root::nsIDocument_Type, pub mDefaultElementType: u8, @@ -5414,7 +5084,7 @@ pub mod root { pub mChildDocumentUseCounters: [u64; 2usize], pub mNotifiedPageForUseCounter: [u64; 2usize], pub mUserHasInteracted: bool, - pub mPageUnloadingEventTimeStamp: root::TimeStamp, + pub mPageUnloadingEventTimeStamp: root::mozilla::TimeStamp, pub mDocGroup: root::RefPtr<root::mozilla::dom::DocGroup>, pub mTrackingScripts: [u64; 6usize], } @@ -6280,6 +5950,26 @@ pub mod root { } #[repr(C)] #[derive(Debug, Copy)] + pub struct nsIObserver { + pub _base: root::nsISupports, + } + #[repr(C)] + #[derive(Debug, Copy, Clone)] + pub struct nsIObserver_COMTypeInfo<T, U> { + pub _address: u8, + pub _phantom_0: ::std::marker::PhantomData<T>, + pub _phantom_1: ::std::marker::PhantomData<U>, + } + #[test] + fn bindgen_test_layout_nsIObserver() { + assert_eq!(::std::mem::size_of::<nsIObserver>() , 8usize); + assert_eq!(::std::mem::align_of::<nsIObserver>() , 8usize); + } + impl Clone for nsIObserver { + fn clone(&self) -> Self { *self } + } + #[repr(C)] + #[derive(Debug, Copy)] pub struct nsIVariant { pub _base: root::nsISupports, } @@ -6321,6 +6011,26 @@ pub mod root { pub type DOMHighResTimeStamp = f64; #[repr(C)] #[derive(Debug, Copy)] + pub struct nsIDOMAttr { + pub _base: root::nsIDOMNode, + } + #[repr(C)] + #[derive(Debug, Copy, Clone)] + pub struct nsIDOMAttr_COMTypeInfo<T, U> { + pub _address: u8, + pub _phantom_0: ::std::marker::PhantomData<T>, + pub _phantom_1: ::std::marker::PhantomData<U>, + } + #[test] + fn bindgen_test_layout_nsIDOMAttr() { + assert_eq!(::std::mem::size_of::<nsIDOMAttr>() , 8usize); + assert_eq!(::std::mem::align_of::<nsIDOMAttr>() , 8usize); + } + impl Clone for nsIDOMAttr { + fn clone(&self) -> Self { *self } + } + #[repr(C)] + #[derive(Debug, Copy)] pub struct nsIDOMNode { pub _base: root::nsISupports, } @@ -6412,62 +6122,62 @@ pub mod root { } #[repr(C)] #[derive(Debug, Copy)] - pub struct nsIDOMAttr { - pub _base: root::nsIDOMNode, + pub struct nsIDOMClientRect { + pub _base: root::nsISupports, } #[repr(C)] #[derive(Debug, Copy, Clone)] - pub struct nsIDOMAttr_COMTypeInfo<T, U> { + pub struct nsIDOMClientRect_COMTypeInfo<T, U> { pub _address: u8, pub _phantom_0: ::std::marker::PhantomData<T>, pub _phantom_1: ::std::marker::PhantomData<U>, } #[test] - fn bindgen_test_layout_nsIDOMAttr() { - assert_eq!(::std::mem::size_of::<nsIDOMAttr>() , 8usize); - assert_eq!(::std::mem::align_of::<nsIDOMAttr>() , 8usize); + fn bindgen_test_layout_nsIDOMClientRect() { + assert_eq!(::std::mem::size_of::<nsIDOMClientRect>() , 8usize); + assert_eq!(::std::mem::align_of::<nsIDOMClientRect>() , 8usize); } - impl Clone for nsIDOMAttr { + impl Clone for nsIDOMClientRect { fn clone(&self) -> Self { *self } } #[repr(C)] #[derive(Debug, Copy)] - pub struct nsIDOMClientRect { + pub struct nsIDOMStyleSheet { pub _base: root::nsISupports, } #[repr(C)] #[derive(Debug, Copy, Clone)] - pub struct nsIDOMClientRect_COMTypeInfo<T, U> { + pub struct nsIDOMStyleSheet_COMTypeInfo<T, U> { pub _address: u8, pub _phantom_0: ::std::marker::PhantomData<T>, pub _phantom_1: ::std::marker::PhantomData<U>, } #[test] - fn bindgen_test_layout_nsIDOMClientRect() { - assert_eq!(::std::mem::size_of::<nsIDOMClientRect>() , 8usize); - assert_eq!(::std::mem::align_of::<nsIDOMClientRect>() , 8usize); + fn bindgen_test_layout_nsIDOMStyleSheet() { + assert_eq!(::std::mem::size_of::<nsIDOMStyleSheet>() , 8usize); + assert_eq!(::std::mem::align_of::<nsIDOMStyleSheet>() , 8usize); } - impl Clone for nsIDOMClientRect { + impl Clone for nsIDOMStyleSheet { fn clone(&self) -> Self { *self } } #[repr(C)] #[derive(Debug, Copy)] - pub struct nsIDOMStyleSheet { + pub struct nsIDOMEventTarget { pub _base: root::nsISupports, } #[repr(C)] #[derive(Debug, Copy, Clone)] - pub struct nsIDOMStyleSheet_COMTypeInfo<T, U> { + pub struct nsIDOMEventTarget_COMTypeInfo<T, U> { pub _address: u8, pub _phantom_0: ::std::marker::PhantomData<T>, pub _phantom_1: ::std::marker::PhantomData<U>, } #[test] - fn bindgen_test_layout_nsIDOMStyleSheet() { - assert_eq!(::std::mem::size_of::<nsIDOMStyleSheet>() , 8usize); - assert_eq!(::std::mem::align_of::<nsIDOMStyleSheet>() , 8usize); + fn bindgen_test_layout_nsIDOMEventTarget() { + assert_eq!(::std::mem::size_of::<nsIDOMEventTarget>() , 8usize); + assert_eq!(::std::mem::align_of::<nsIDOMEventTarget>() , 8usize); } - impl Clone for nsIDOMStyleSheet { + impl Clone for nsIDOMEventTarget { fn clone(&self) -> Self { *self } } #[repr(C)] @@ -6518,11 +6228,12 @@ pub mod root { impl Clone for nsIControllers { fn clone(&self) -> Self { *self } } - #[test] - fn __bindgen_test_layout_template_10() { - assert_eq!(::std::mem::size_of::<u64>() , 8usize); - assert_eq!(::std::mem::align_of::<u64>() , 8usize); - } + #[repr(u8)] + /** + * Enumeration that represents one of the two supported style system backends. + */ + #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] + pub enum StyleBackendType { Gecko = 1, Servo = 2, } pub const nsChangeHint_nsChangeHint_Empty: root::nsChangeHint = nsChangeHint(0); pub const nsChangeHint_nsChangeHint_RepaintFrame: root::nsChangeHint = @@ -6611,49 +6322,71 @@ pub mod root { #[repr(C)] #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] pub struct nsChangeHint(pub u32); - /** - * Smart pointer class that can hold a pointer to either a RestyleManager - * or a ServoRestyleManager. - */ - #[repr(C)] - #[derive(Debug, Copy)] - pub struct RestyleManagerHandle { - pub mPtr: root::RestyleManagerHandle_Ptr, + pub const nsRestyleHint_eRestyle_Self: root::nsRestyleHint = + nsRestyleHint(1); + pub const nsRestyleHint_eRestyle_SomeDescendants: root::nsRestyleHint = + nsRestyleHint(2); + pub const nsRestyleHint_eRestyle_Subtree: root::nsRestyleHint = + nsRestyleHint(4); + pub const nsRestyleHint_eRestyle_LaterSiblings: root::nsRestyleHint = + nsRestyleHint(8); + pub const nsRestyleHint_eRestyle_CSSTransitions: root::nsRestyleHint = + nsRestyleHint(16); + pub const nsRestyleHint_eRestyle_CSSAnimations: root::nsRestyleHint = + nsRestyleHint(32); + pub const nsRestyleHint_eRestyle_SVGAttrAnimations: root::nsRestyleHint = + nsRestyleHint(64); + pub const nsRestyleHint_eRestyle_StyleAttribute: root::nsRestyleHint = + nsRestyleHint(128); + pub const nsRestyleHint_eRestyle_StyleAttribute_Animations: + root::nsRestyleHint = + nsRestyleHint(256); + pub const nsRestyleHint_eRestyle_Force: root::nsRestyleHint = + nsRestyleHint(512); + pub const nsRestyleHint_eRestyle_ForceDescendants: root::nsRestyleHint = + nsRestyleHint(1024); + pub const nsRestyleHint_eRestyle_AllHintsWithAnimations: + root::nsRestyleHint = + nsRestyleHint(368); + impl ::std::ops::BitOr<root::nsRestyleHint> for root::nsRestyleHint { + type + Output + = + Self; + #[inline] + fn bitor(self, other: Self) -> Self { + nsRestyleHint(self.0 | other.0) + } } - pub type RestyleManagerHandle_RefPtr = - root::mozilla::HandleRefPtr<root::RestyleManagerHandle>; #[repr(C)] - #[derive(Debug, Copy)] - pub struct RestyleManagerHandle_Ptr { - pub mValue: usize, - } - #[test] - fn bindgen_test_layout_RestyleManagerHandle_Ptr() { - assert_eq!(::std::mem::size_of::<RestyleManagerHandle_Ptr>() , - 8usize); - assert_eq!(::std::mem::align_of::<RestyleManagerHandle_Ptr>() , - 8usize); - } - impl Clone for RestyleManagerHandle_Ptr { - fn clone(&self) -> Self { *self } - } - #[test] - fn bindgen_test_layout_RestyleManagerHandle() { - assert_eq!(::std::mem::size_of::<RestyleManagerHandle>() , 8usize); - assert_eq!(::std::mem::align_of::<RestyleManagerHandle>() , 8usize); - } - impl Clone for RestyleManagerHandle { - fn clone(&self) -> Self { *self } - } - pub type nscolor = u32; + /** + * |nsRestyleHint| is a bitfield for the result of + * |HasStateDependentStyle| and |HasAttributeDependentStyle|. When no + * restyling is necessary, use |nsRestyleHint(0)|. + * + * Without eRestyle_Force or eRestyle_ForceDescendants, the restyling process + * can stop processing at a frame when it detects no style changes and it is + * known that the styles of the subtree beneath it will not change, leaving + * the old style context on the frame. eRestyle_Force can be used to skip this + * optimization on a frame, and to force its new style context to be used. + * + * Similarly, eRestyle_ForceDescendants will cause the frame and all of its + * descendants to be traversed and for the new style contexts that are created + * to be set on the frames. + * + * NOTE: When adding new restyle hints, please also add them to + * RestyleManager::RestyleHintToString. + */ + #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] + pub struct nsRestyleHint(pub u32); #[repr(u32)] #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] - pub enum Side { - eSideTop = 0, - eSideRight = 1, - eSideBottom = 2, - eSideLeft = 3, + pub enum nsCompatibility { + eCompatibility_FullStandards = 1, + eCompatibility_AlmostStandards = 2, + eCompatibility_NavQuirks = 3, } + pub type nscolor = u32; #[repr(C)] #[derive(Debug)] pub struct nsPresContext { @@ -6670,7 +6403,7 @@ pub mod root { pub mEffectCompositor: root::RefPtr<root::mozilla::EffectCompositor>, pub mTransitionManager: root::RefPtr<root::nsTransitionManager>, pub mAnimationManager: root::RefPtr<root::nsAnimationManager>, - pub mRestyleManager: root::RestyleManagerHandle_RefPtr, + pub mRestyleManager: root::mozilla::RestyleManagerHandle_RefPtr, pub mCounterStyleManager: root::RefPtr<root::mozilla::CounterStyleManager>, pub mMedium: *mut root::nsIAtom, pub mMediaEmulated: root::nsCOMPtr<root::nsIAtom>, @@ -6717,8 +6450,8 @@ pub mod root { pub mElementsRestyled: u64, pub mFramesConstructed: u64, pub mFramesReflowed: u64, - pub mReflowStartTime: root::TimeStamp, - pub mLastStyleUpdateForAllAnimations: root::TimeStamp, + pub mReflowStartTime: root::mozilla::TimeStamp, + pub mLastStyleUpdateForAllAnimations: root::mozilla::TimeStamp, pub _bitfield_1: u64, pub mRestyleLoggingEnabled: bool, pub mInitialized: bool, @@ -7493,15 +7226,9 @@ pub mod root { #[repr(u32)] #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] pub enum PLDHashTable_SearchReason { ForSearchOrRemove = 0, ForAdd = 1, } - extern "C" { - #[link_name = "_ZN12PLDHashTable12kMaxCapacityE"] - pub static PLDHashTable_kMaxCapacity: u32; - } + pub const PLDHashTable_kMaxCapacity: u32 = 67108864; pub const PLDHashTable_kMinCapacity: u32 = 8; - extern "C" { - #[link_name = "_ZN12PLDHashTable17kMaxInitialLengthE"] - pub static PLDHashTable_kMaxInitialLength: u32; - } + pub const PLDHashTable_kMaxInitialLength: u32 = 33554432; pub const PLDHashTable_kDefaultInitialLength: u32 = 4; pub const PLDHashTable_kHashBits: u32 = 32; pub const PLDHashTable_kGoldenRatio: u32 = 2654435769; @@ -7745,73 +7472,6 @@ pub mod root { fn clone(&self) -> Self { *self } } pub type nsWeakPtr = root::nsCOMPtr<root::nsIWeakReference>; - pub type nsLoadFlags = u32; - #[repr(C)] - #[derive(Debug, Copy)] - pub struct nsIRequest { - pub _base: root::nsISupports, - } - #[repr(C)] - #[derive(Debug, Copy, Clone)] - pub struct nsIRequest_COMTypeInfo<T, U> { - pub _address: u8, - pub _phantom_0: ::std::marker::PhantomData<T>, - pub _phantom_1: ::std::marker::PhantomData<U>, - } - pub const nsIRequest_LOAD_REQUESTMASK: root::nsIRequest__bindgen_ty_1 = - nsIRequest__bindgen_ty_1::LOAD_REQUESTMASK; - pub const nsIRequest_LOAD_NORMAL: root::nsIRequest__bindgen_ty_1 = - nsIRequest__bindgen_ty_1::LOAD_NORMAL; - pub const nsIRequest_LOAD_BACKGROUND: root::nsIRequest__bindgen_ty_1 = - nsIRequest__bindgen_ty_1::LOAD_BACKGROUND; - pub const nsIRequest_INHIBIT_PIPELINE: root::nsIRequest__bindgen_ty_1 = - nsIRequest__bindgen_ty_1::INHIBIT_PIPELINE; - pub const nsIRequest_INHIBIT_CACHING: root::nsIRequest__bindgen_ty_1 = - nsIRequest__bindgen_ty_1::INHIBIT_CACHING; - pub const nsIRequest_INHIBIT_PERSISTENT_CACHING: - root::nsIRequest__bindgen_ty_1 = - nsIRequest__bindgen_ty_1::INHIBIT_PERSISTENT_CACHING; - pub const nsIRequest_LOAD_BYPASS_CACHE: root::nsIRequest__bindgen_ty_1 = - nsIRequest__bindgen_ty_1::LOAD_BYPASS_CACHE; - pub const nsIRequest_LOAD_FROM_CACHE: root::nsIRequest__bindgen_ty_1 = - nsIRequest__bindgen_ty_1::LOAD_FROM_CACHE; - pub const nsIRequest_VALIDATE_ALWAYS: root::nsIRequest__bindgen_ty_1 = - nsIRequest__bindgen_ty_1::VALIDATE_ALWAYS; - pub const nsIRequest_VALIDATE_NEVER: root::nsIRequest__bindgen_ty_1 = - nsIRequest__bindgen_ty_1::VALIDATE_NEVER; - pub const nsIRequest_VALIDATE_ONCE_PER_SESSION: - root::nsIRequest__bindgen_ty_1 = - nsIRequest__bindgen_ty_1::VALIDATE_ONCE_PER_SESSION; - pub const nsIRequest_LOAD_ANONYMOUS: root::nsIRequest__bindgen_ty_1 = - nsIRequest__bindgen_ty_1::LOAD_ANONYMOUS; - pub const nsIRequest_LOAD_FRESH_CONNECTION: root::nsIRequest__bindgen_ty_1 - = - nsIRequest__bindgen_ty_1::LOAD_FRESH_CONNECTION; - #[repr(u32)] - #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] - pub enum nsIRequest__bindgen_ty_1 { - LOAD_REQUESTMASK = 65535, - LOAD_NORMAL = 0, - LOAD_BACKGROUND = 1, - INHIBIT_PIPELINE = 64, - INHIBIT_CACHING = 128, - INHIBIT_PERSISTENT_CACHING = 256, - LOAD_BYPASS_CACHE = 512, - LOAD_FROM_CACHE = 1024, - VALIDATE_ALWAYS = 2048, - VALIDATE_NEVER = 4096, - VALIDATE_ONCE_PER_SESSION = 8192, - LOAD_ANONYMOUS = 16384, - LOAD_FRESH_CONNECTION = 32768, - } - #[test] - fn bindgen_test_layout_nsIRequest() { - assert_eq!(::std::mem::size_of::<nsIRequest>() , 8usize); - assert_eq!(::std::mem::align_of::<nsIRequest>() , 8usize); - } - impl Clone for nsIRequest { - fn clone(&self) -> Self { *self } - } #[repr(C)] #[derive(Debug, Copy)] pub struct nsIChannel { @@ -7883,6 +7543,7 @@ pub mod root { impl Clone for nsIChannel { fn clone(&self) -> Self { *self } } + pub type nsLoadFlags = u32; #[repr(C)] #[derive(Debug, Copy)] pub struct nsILoadGroup { @@ -7904,6 +7565,245 @@ pub mod root { fn clone(&self) -> Self { *self } } #[repr(C)] + #[derive(Debug, Copy)] + pub struct nsIRequest { + pub _base: root::nsISupports, + } + #[repr(C)] + #[derive(Debug, Copy, Clone)] + pub struct nsIRequest_COMTypeInfo<T, U> { + pub _address: u8, + pub _phantom_0: ::std::marker::PhantomData<T>, + pub _phantom_1: ::std::marker::PhantomData<U>, + } + pub const nsIRequest_LOAD_REQUESTMASK: root::nsIRequest__bindgen_ty_1 = + nsIRequest__bindgen_ty_1::LOAD_REQUESTMASK; + pub const nsIRequest_LOAD_NORMAL: root::nsIRequest__bindgen_ty_1 = + nsIRequest__bindgen_ty_1::LOAD_NORMAL; + pub const nsIRequest_LOAD_BACKGROUND: root::nsIRequest__bindgen_ty_1 = + nsIRequest__bindgen_ty_1::LOAD_BACKGROUND; + pub const nsIRequest_INHIBIT_PIPELINE: root::nsIRequest__bindgen_ty_1 = + nsIRequest__bindgen_ty_1::INHIBIT_PIPELINE; + pub const nsIRequest_INHIBIT_CACHING: root::nsIRequest__bindgen_ty_1 = + nsIRequest__bindgen_ty_1::INHIBIT_CACHING; + pub const nsIRequest_INHIBIT_PERSISTENT_CACHING: + root::nsIRequest__bindgen_ty_1 = + nsIRequest__bindgen_ty_1::INHIBIT_PERSISTENT_CACHING; + pub const nsIRequest_LOAD_BYPASS_CACHE: root::nsIRequest__bindgen_ty_1 = + nsIRequest__bindgen_ty_1::LOAD_BYPASS_CACHE; + pub const nsIRequest_LOAD_FROM_CACHE: root::nsIRequest__bindgen_ty_1 = + nsIRequest__bindgen_ty_1::LOAD_FROM_CACHE; + pub const nsIRequest_VALIDATE_ALWAYS: root::nsIRequest__bindgen_ty_1 = + nsIRequest__bindgen_ty_1::VALIDATE_ALWAYS; + pub const nsIRequest_VALIDATE_NEVER: root::nsIRequest__bindgen_ty_1 = + nsIRequest__bindgen_ty_1::VALIDATE_NEVER; + pub const nsIRequest_VALIDATE_ONCE_PER_SESSION: + root::nsIRequest__bindgen_ty_1 = + nsIRequest__bindgen_ty_1::VALIDATE_ONCE_PER_SESSION; + pub const nsIRequest_LOAD_ANONYMOUS: root::nsIRequest__bindgen_ty_1 = + nsIRequest__bindgen_ty_1::LOAD_ANONYMOUS; + pub const nsIRequest_LOAD_FRESH_CONNECTION: root::nsIRequest__bindgen_ty_1 + = + nsIRequest__bindgen_ty_1::LOAD_FRESH_CONNECTION; + #[repr(u32)] + #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] + pub enum nsIRequest__bindgen_ty_1 { + LOAD_REQUESTMASK = 65535, + LOAD_NORMAL = 0, + LOAD_BACKGROUND = 1, + INHIBIT_PIPELINE = 64, + INHIBIT_CACHING = 128, + INHIBIT_PERSISTENT_CACHING = 256, + LOAD_BYPASS_CACHE = 512, + LOAD_FROM_CACHE = 1024, + VALIDATE_ALWAYS = 2048, + VALIDATE_NEVER = 4096, + VALIDATE_ONCE_PER_SESSION = 8192, + LOAD_ANONYMOUS = 16384, + LOAD_FRESH_CONNECTION = 32768, + } + #[test] + fn bindgen_test_layout_nsIRequest() { + assert_eq!(::std::mem::size_of::<nsIRequest>() , 8usize); + assert_eq!(::std::mem::align_of::<nsIRequest>() , 8usize); + } + impl Clone for nsIRequest { + fn clone(&self) -> Self { *self } + } + /** + * An internal interface that abstracts some DOMNode-related parts that both + * nsIContent and nsIDocument share. An instance of this interface has a list + * of nsIContent children and provides access to them. + */ + #[repr(C)] + #[derive(Debug)] + pub struct nsINode { + pub _base: root::mozilla::dom::EventTarget, + pub mNodeInfo: root::RefPtr<root::mozilla::dom::NodeInfo>, + pub mParent: *mut root::nsINode, + pub mBoolFlags: u32, + pub mNextSibling: *mut root::nsIContent, + pub mPreviousSibling: *mut root::nsIContent, + pub mFirstChild: *mut root::nsIContent, + pub __bindgen_anon_1: root::nsINode__bindgen_ty_1, + pub mSlots: *mut root::nsINode_nsSlots, + } + pub type nsINode_BoxQuadOptions = root::mozilla::dom::BoxQuadOptions; + pub type nsINode_ConvertCoordinateOptions = + root::mozilla::dom::ConvertCoordinateOptions; + pub type nsINode_DOMPoint = root::mozilla::dom::DOMPoint; + pub type nsINode_DOMPointInit = root::mozilla::dom::DOMPointInit; + pub type nsINode_DOMQuad = root::mozilla::dom::DOMQuad; + pub type nsINode_DOMRectReadOnly = root::mozilla::dom::DOMRectReadOnly; + pub type nsINode_OwningNodeOrString = + root::mozilla::dom::OwningNodeOrString; + pub type nsINode_TextOrElementOrDocument = + root::mozilla::dom::TextOrElementOrDocument; + pub type nsINode_ErrorResult = [u64; 4usize]; + #[repr(C)] + #[derive(Debug, Copy, Clone)] + pub struct nsINode_COMTypeInfo<T, U> { + pub _address: u8, + pub _phantom_0: ::std::marker::PhantomData<T>, + pub _phantom_1: ::std::marker::PhantomData<U>, + } + pub const nsINode_eCONTENT: root::nsINode__bindgen_ty_2 = + nsINode__bindgen_ty_2::eCONTENT; + pub const nsINode_eDOCUMENT: root::nsINode__bindgen_ty_2 = + nsINode__bindgen_ty_2::eDOCUMENT; + pub const nsINode_eATTRIBUTE: root::nsINode__bindgen_ty_2 = + nsINode__bindgen_ty_2::eATTRIBUTE; + pub const nsINode_eTEXT: root::nsINode__bindgen_ty_2 = + nsINode__bindgen_ty_2::eTEXT; + pub const nsINode_ePROCESSING_INSTRUCTION: root::nsINode__bindgen_ty_2 = + nsINode__bindgen_ty_2::ePROCESSING_INSTRUCTION; + pub const nsINode_eCOMMENT: root::nsINode__bindgen_ty_2 = + nsINode__bindgen_ty_2::eCOMMENT; + pub const nsINode_eHTML_FORM_CONTROL: root::nsINode__bindgen_ty_2 = + nsINode__bindgen_ty_2::eHTML_FORM_CONTROL; + pub const nsINode_eDOCUMENT_FRAGMENT: root::nsINode__bindgen_ty_2 = + nsINode__bindgen_ty_2::eDOCUMENT_FRAGMENT; + pub const nsINode_eDATA_NODE: root::nsINode__bindgen_ty_2 = + nsINode__bindgen_ty_2::eDATA_NODE; + pub const nsINode_eMEDIA: root::nsINode__bindgen_ty_2 = + nsINode__bindgen_ty_2::eMEDIA; + pub const nsINode_eANIMATION: root::nsINode__bindgen_ty_2 = + nsINode__bindgen_ty_2::eANIMATION; + pub const nsINode_eFILTER: root::nsINode__bindgen_ty_2 = + nsINode__bindgen_ty_2::eFILTER; + #[repr(u32)] + /** + * Bit-flags to pass (or'ed together) to IsNodeOfType() + */ + #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] + pub enum nsINode__bindgen_ty_2 { + eCONTENT = 1, + eDOCUMENT = 2, + eATTRIBUTE = 4, + eTEXT = 8, + ePROCESSING_INSTRUCTION = 16, + eCOMMENT = 32, + eHTML_FORM_CONTROL = 64, + eDOCUMENT_FRAGMENT = 128, + eDATA_NODE = 256, + eMEDIA = 512, + eANIMATION = 1024, + eFILTER = 2048, + } + #[repr(C)] + pub struct nsINode_nsSlots__bindgen_vtable { + } + #[repr(C)] + #[derive(Debug)] + pub struct nsINode_nsSlots { + pub vtable_: *const nsINode_nsSlots__bindgen_vtable, + /** + * A list of mutation observers + */ + pub mMutationObservers: [u64; 2usize], + /** + * An object implementing nsIDOMNodeList for this content (childNodes) + * @see nsIDOMNodeList + * @see nsGenericHTMLElement::GetChildNodes + */ + pub mChildNodes: root::RefPtr<root::nsChildContentList>, + /** + * Weak reference to this node. This is cleared by the destructor of + * nsNodeWeakReference. + */ + pub mWeakReference: *mut root::nsNodeWeakReference, + /** + * Number of descendant nodes in the uncomposed document that have been + * explicitly set as editable. + */ + pub mEditableDescendantCount: u32, + } + #[test] + fn bindgen_test_layout_nsINode_nsSlots() { + assert_eq!(::std::mem::size_of::<nsINode_nsSlots>() , 48usize); + assert_eq!(::std::mem::align_of::<nsINode_nsSlots>() , 8usize); + } + #[repr(u32)] + /** + * Boolean flags + */ + #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] + pub enum nsINode_BooleanFlag { + NodeHasRenderingObservers = 0, + IsInDocument = 1, + ParentIsContent = 2, + NodeIsElement = 3, + ElementHasID = 4, + ElementMayHaveStyle = 5, + ElementHasName = 6, + ElementMayHaveContentEditableAttr = 7, + NodeIsCommonAncestorForRangeInSelection = 8, + NodeIsDescendantOfCommonAncestorForRangeInSelection = 9, + NodeIsCCMarkedRoot = 10, + NodeIsCCBlackTree = 11, + NodeIsPurpleRoot = 12, + NodeHasExplicitBaseURI = 13, + ElementHasLockedStyleStates = 14, + ElementHasPointerLock = 15, + NodeMayHaveDOMMutationObserver = 16, + NodeIsContent = 17, + ElementHasAnimations = 18, + NodeHasValidDirAttribute = 19, + NodeHasFixedDir = 20, + NodeHasDirAutoSet = 21, + NodeHasTextNodeDirectionalityMap = 22, + NodeHasDirAuto = 23, + NodeAncestorHasDirAuto = 24, + ElementIsInStyleScope = 25, + ElementIsScopedStyleRoot = 26, + NodeHandlingClick = 27, + NodeHasRelevantHoverRules = 28, + ElementHasWeirdParserInsertionMode = 29, + ParserHasNotified = 30, + MayBeApzAware = 31, + BooleanFlagCount = 32, + } + #[repr(C)] + #[derive(Debug, Copy)] + pub struct nsINode__bindgen_ty_1 { + pub mPrimaryFrame: root::__BindgenUnionField<*mut root::nsIFrame>, + pub mSubtreeRoot: root::__BindgenUnionField<*mut root::nsINode>, + pub bindgen_union_field: u64, + } + #[test] + fn bindgen_test_layout_nsINode__bindgen_ty_1() { + assert_eq!(::std::mem::size_of::<nsINode__bindgen_ty_1>() , 8usize); + assert_eq!(::std::mem::align_of::<nsINode__bindgen_ty_1>() , 8usize); + } + impl Clone for nsINode__bindgen_ty_1 { + fn clone(&self) -> Self { *self } + } + #[test] + fn bindgen_test_layout_nsINode() { + assert_eq!(::std::mem::size_of::<nsINode>() , 96usize); + assert_eq!(::std::mem::align_of::<nsINode>() , 8usize); + } + #[repr(C)] #[derive(Debug)] pub struct nsCOMArray_base { pub mArray: root::nsTArray<*mut root::nsISupports>, @@ -8171,26 +8071,6 @@ pub mod root { fn clone(&self) -> Self { *self } } #[repr(C)] - #[derive(Debug, Copy)] - pub struct nsIDOMMozNamedAttrMap { - pub _base: root::nsISupports, - } - #[repr(C)] - #[derive(Debug, Copy, Clone)] - pub struct nsIDOMMozNamedAttrMap_COMTypeInfo<T, U> { - pub _address: u8, - pub _phantom_0: ::std::marker::PhantomData<T>, - pub _phantom_1: ::std::marker::PhantomData<U>, - } - #[test] - fn bindgen_test_layout_nsIDOMMozNamedAttrMap() { - assert_eq!(::std::mem::size_of::<nsIDOMMozNamedAttrMap>() , 8usize); - assert_eq!(::std::mem::align_of::<nsIDOMMozNamedAttrMap>() , 8usize); - } - impl Clone for nsIDOMMozNamedAttrMap { - fn clone(&self) -> Self { *self } - } - #[repr(C)] #[derive(Debug)] pub struct nsDOMAttributeMap { pub _base: root::nsIDOMMozNamedAttrMap, @@ -8334,9 +8214,9 @@ pub mod root { nsIPresShell__bindgen_ty_1::SCROLL_TOP; pub const nsIPresShell_SCROLL_BOTTOM: root::nsIPresShell__bindgen_ty_1 = nsIPresShell__bindgen_ty_1::SCROLL_BOTTOM; - pub const SCROLL_LEFT: root::nsIPresShell__bindgen_ty_1 = + pub const nsIPresShell_SCROLL_LEFT: root::nsIPresShell__bindgen_ty_1 = nsIPresShell__bindgen_ty_1::SCROLL_TOP; - pub const SCROLL_RIGHT: root::nsIPresShell__bindgen_ty_1 = + pub const nsIPresShell_SCROLL_RIGHT: root::nsIPresShell__bindgen_ty_1 = nsIPresShell__bindgen_ty_1::SCROLL_BOTTOM; pub const nsIPresShell_SCROLL_CENTER: root::nsIPresShell__bindgen_ty_1 = nsIPresShell__bindgen_ty_1::SCROLL_CENTER; @@ -8748,63 +8628,63 @@ pub mod root { impl Clone for nsDOMMutationObserver { fn clone(&self) -> Self { *self } } - pub const NODE_HAS_LISTENERMANAGER: root::_bindgen_ty_68 = - _bindgen_ty_68::NODE_HAS_LISTENERMANAGER; - pub const NODE_HAS_PROPERTIES: root::_bindgen_ty_68 = - _bindgen_ty_68::NODE_HAS_PROPERTIES; - pub const NODE_IS_ANONYMOUS_ROOT: root::_bindgen_ty_68 = - _bindgen_ty_68::NODE_IS_ANONYMOUS_ROOT; - pub const NODE_IS_IN_NATIVE_ANONYMOUS_SUBTREE: root::_bindgen_ty_68 = - _bindgen_ty_68::NODE_IS_IN_NATIVE_ANONYMOUS_SUBTREE; - pub const NODE_IS_NATIVE_ANONYMOUS_ROOT: root::_bindgen_ty_68 = - _bindgen_ty_68::NODE_IS_NATIVE_ANONYMOUS_ROOT; - pub const NODE_FORCE_XBL_BINDINGS: root::_bindgen_ty_68 = - _bindgen_ty_68::NODE_FORCE_XBL_BINDINGS; - pub const NODE_MAY_BE_IN_BINDING_MNGR: root::_bindgen_ty_68 = - _bindgen_ty_68::NODE_MAY_BE_IN_BINDING_MNGR; - pub const NODE_IS_EDITABLE: root::_bindgen_ty_68 = - _bindgen_ty_68::NODE_IS_EDITABLE; - pub const NODE_MAY_HAVE_CLASS: root::_bindgen_ty_68 = - _bindgen_ty_68::NODE_MAY_HAVE_CLASS; - pub const NODE_IS_IN_SHADOW_TREE: root::_bindgen_ty_68 = - _bindgen_ty_68::NODE_IS_IN_SHADOW_TREE; - pub const NODE_HAS_EMPTY_SELECTOR: root::_bindgen_ty_68 = - _bindgen_ty_68::NODE_HAS_EMPTY_SELECTOR; - pub const NODE_HAS_SLOW_SELECTOR: root::_bindgen_ty_68 = - _bindgen_ty_68::NODE_HAS_SLOW_SELECTOR; - pub const NODE_HAS_EDGE_CHILD_SELECTOR: root::_bindgen_ty_68 = - _bindgen_ty_68::NODE_HAS_EDGE_CHILD_SELECTOR; - pub const NODE_HAS_SLOW_SELECTOR_LATER_SIBLINGS: root::_bindgen_ty_68 = - _bindgen_ty_68::NODE_HAS_SLOW_SELECTOR_LATER_SIBLINGS; - pub const NODE_ALL_SELECTOR_FLAGS: root::_bindgen_ty_68 = - _bindgen_ty_68::NODE_ALL_SELECTOR_FLAGS; - pub const NODE_NEEDS_FRAME: root::_bindgen_ty_68 = - _bindgen_ty_68::NODE_NEEDS_FRAME; - pub const NODE_DESCENDANTS_NEED_FRAMES: root::_bindgen_ty_68 = - _bindgen_ty_68::NODE_DESCENDANTS_NEED_FRAMES; - pub const NODE_HAS_ACCESSKEY: root::_bindgen_ty_68 = - _bindgen_ty_68::NODE_HAS_ACCESSKEY; - pub const NODE_HAS_DIRECTION_RTL: root::_bindgen_ty_68 = - _bindgen_ty_68::NODE_HAS_DIRECTION_RTL; - pub const NODE_HAS_DIRECTION_LTR: root::_bindgen_ty_68 = - _bindgen_ty_68::NODE_HAS_DIRECTION_LTR; - pub const NODE_ALL_DIRECTION_FLAGS: root::_bindgen_ty_68 = - _bindgen_ty_68::NODE_ALL_DIRECTION_FLAGS; - pub const NODE_CHROME_ONLY_ACCESS: root::_bindgen_ty_68 = - _bindgen_ty_68::NODE_CHROME_ONLY_ACCESS; - pub const NODE_IS_ROOT_OF_CHROME_ONLY_ACCESS: root::_bindgen_ty_68 = - _bindgen_ty_68::NODE_IS_ROOT_OF_CHROME_ONLY_ACCESS; - pub const NODE_SHARED_RESTYLE_BIT_1: root::_bindgen_ty_68 = - _bindgen_ty_68::NODE_SHARED_RESTYLE_BIT_1; - pub const NODE_SHARED_RESTYLE_BIT_2: root::_bindgen_ty_68 = - _bindgen_ty_68::NODE_SHARED_RESTYLE_BIT_2; - pub const NODE_HAS_DIRTY_DESCENDANTS_FOR_SERVO: root::_bindgen_ty_68 = - _bindgen_ty_68::NODE_SHARED_RESTYLE_BIT_1; - pub const NODE_TYPE_SPECIFIC_BITS_OFFSET: root::_bindgen_ty_68 = - _bindgen_ty_68::NODE_TYPE_SPECIFIC_BITS_OFFSET; + pub const NODE_HAS_LISTENERMANAGER: root::_bindgen_ty_137 = + _bindgen_ty_137::NODE_HAS_LISTENERMANAGER; + pub const NODE_HAS_PROPERTIES: root::_bindgen_ty_137 = + _bindgen_ty_137::NODE_HAS_PROPERTIES; + pub const NODE_IS_ANONYMOUS_ROOT: root::_bindgen_ty_137 = + _bindgen_ty_137::NODE_IS_ANONYMOUS_ROOT; + pub const NODE_IS_IN_NATIVE_ANONYMOUS_SUBTREE: root::_bindgen_ty_137 = + _bindgen_ty_137::NODE_IS_IN_NATIVE_ANONYMOUS_SUBTREE; + pub const NODE_IS_NATIVE_ANONYMOUS_ROOT: root::_bindgen_ty_137 = + _bindgen_ty_137::NODE_IS_NATIVE_ANONYMOUS_ROOT; + pub const NODE_FORCE_XBL_BINDINGS: root::_bindgen_ty_137 = + _bindgen_ty_137::NODE_FORCE_XBL_BINDINGS; + pub const NODE_MAY_BE_IN_BINDING_MNGR: root::_bindgen_ty_137 = + _bindgen_ty_137::NODE_MAY_BE_IN_BINDING_MNGR; + pub const NODE_IS_EDITABLE: root::_bindgen_ty_137 = + _bindgen_ty_137::NODE_IS_EDITABLE; + pub const NODE_MAY_HAVE_CLASS: root::_bindgen_ty_137 = + _bindgen_ty_137::NODE_MAY_HAVE_CLASS; + pub const NODE_IS_IN_SHADOW_TREE: root::_bindgen_ty_137 = + _bindgen_ty_137::NODE_IS_IN_SHADOW_TREE; + pub const NODE_HAS_EMPTY_SELECTOR: root::_bindgen_ty_137 = + _bindgen_ty_137::NODE_HAS_EMPTY_SELECTOR; + pub const NODE_HAS_SLOW_SELECTOR: root::_bindgen_ty_137 = + _bindgen_ty_137::NODE_HAS_SLOW_SELECTOR; + pub const NODE_HAS_EDGE_CHILD_SELECTOR: root::_bindgen_ty_137 = + _bindgen_ty_137::NODE_HAS_EDGE_CHILD_SELECTOR; + pub const NODE_HAS_SLOW_SELECTOR_LATER_SIBLINGS: root::_bindgen_ty_137 = + _bindgen_ty_137::NODE_HAS_SLOW_SELECTOR_LATER_SIBLINGS; + pub const NODE_ALL_SELECTOR_FLAGS: root::_bindgen_ty_137 = + _bindgen_ty_137::NODE_ALL_SELECTOR_FLAGS; + pub const NODE_NEEDS_FRAME: root::_bindgen_ty_137 = + _bindgen_ty_137::NODE_NEEDS_FRAME; + pub const NODE_DESCENDANTS_NEED_FRAMES: root::_bindgen_ty_137 = + _bindgen_ty_137::NODE_DESCENDANTS_NEED_FRAMES; + pub const NODE_HAS_ACCESSKEY: root::_bindgen_ty_137 = + _bindgen_ty_137::NODE_HAS_ACCESSKEY; + pub const NODE_HAS_DIRECTION_RTL: root::_bindgen_ty_137 = + _bindgen_ty_137::NODE_HAS_DIRECTION_RTL; + pub const NODE_HAS_DIRECTION_LTR: root::_bindgen_ty_137 = + _bindgen_ty_137::NODE_HAS_DIRECTION_LTR; + pub const NODE_ALL_DIRECTION_FLAGS: root::_bindgen_ty_137 = + _bindgen_ty_137::NODE_ALL_DIRECTION_FLAGS; + pub const NODE_CHROME_ONLY_ACCESS: root::_bindgen_ty_137 = + _bindgen_ty_137::NODE_CHROME_ONLY_ACCESS; + pub const NODE_IS_ROOT_OF_CHROME_ONLY_ACCESS: root::_bindgen_ty_137 = + _bindgen_ty_137::NODE_IS_ROOT_OF_CHROME_ONLY_ACCESS; + pub const NODE_SHARED_RESTYLE_BIT_1: root::_bindgen_ty_137 = + _bindgen_ty_137::NODE_SHARED_RESTYLE_BIT_1; + pub const NODE_SHARED_RESTYLE_BIT_2: root::_bindgen_ty_137 = + _bindgen_ty_137::NODE_SHARED_RESTYLE_BIT_2; + pub const NODE_HAS_DIRTY_DESCENDANTS_FOR_SERVO: root::_bindgen_ty_137 = + _bindgen_ty_137::NODE_SHARED_RESTYLE_BIT_1; + pub const NODE_TYPE_SPECIFIC_BITS_OFFSET: root::_bindgen_ty_137 = + _bindgen_ty_137::NODE_TYPE_SPECIFIC_BITS_OFFSET; #[repr(u32)] #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] - pub enum _bindgen_ty_68 { + pub enum _bindgen_ty_137 { NODE_HAS_LISTENERMANAGER = 4, NODE_HAS_PROPERTIES = 8, NODE_IS_ANONYMOUS_ROOT = 16, @@ -9164,6 +9044,26 @@ pub mod root { impl Clone for nsDOMStringMap { fn clone(&self) -> Self { *self } } + #[repr(C)] + #[derive(Debug, Copy)] + pub struct nsIDOMMozNamedAttrMap { + pub _base: root::nsISupports, + } + #[repr(C)] + #[derive(Debug, Copy, Clone)] + pub struct nsIDOMMozNamedAttrMap_COMTypeInfo<T, U> { + pub _address: u8, + pub _phantom_0: ::std::marker::PhantomData<T>, + pub _phantom_1: ::std::marker::PhantomData<U>, + } + #[test] + fn bindgen_test_layout_nsIDOMMozNamedAttrMap() { + assert_eq!(::std::mem::size_of::<nsIDOMMozNamedAttrMap>() , 8usize); + assert_eq!(::std::mem::align_of::<nsIDOMMozNamedAttrMap>() , 8usize); + } + impl Clone for nsIDOMMozNamedAttrMap { + fn clone(&self) -> Self { *self } + } /** * Interface used for handling clicks on links */ @@ -9188,6 +9088,24 @@ pub mod root { fn clone(&self) -> Self { *self } } #[repr(C)] + #[derive(Debug)] + pub struct nsIAttribute { + pub _base: root::nsINode, + pub mAttrMap: root::RefPtr<root::nsDOMAttributeMap>, + } + #[repr(C)] + #[derive(Debug, Copy, Clone)] + pub struct nsIAttribute_COMTypeInfo<T, U> { + pub _address: u8, + pub _phantom_0: ::std::marker::PhantomData<T>, + pub _phantom_1: ::std::marker::PhantomData<U>, + } + #[test] + fn bindgen_test_layout_nsIAttribute() { + assert_eq!(::std::mem::size_of::<nsIAttribute>() , 104usize); + assert_eq!(::std::mem::align_of::<nsIAttribute>() , 8usize); + } + #[repr(C)] #[derive(Debug, Copy)] pub struct nsStyleContext { pub _address: u8, @@ -9589,21 +9507,21 @@ pub mod root { } #[repr(C)] #[derive(Debug, Copy)] - pub struct _bindgen_ty_26 { + pub struct _bindgen_ty_25 { pub mInt: root::__BindgenUnionField<i32>, pub mFloat: root::__BindgenUnionField<f32>, pub mPointer: root::__BindgenUnionField<*mut ::std::os::raw::c_void>, pub bindgen_union_field: u64, } #[test] - fn bindgen_test_layout__bindgen_ty_26() { - assert_eq!(::std::mem::size_of::<_bindgen_ty_26>() , 8usize); - assert_eq!(::std::mem::align_of::<_bindgen_ty_26>() , 8usize); + fn bindgen_test_layout__bindgen_ty_25() { + assert_eq!(::std::mem::size_of::<_bindgen_ty_25>() , 8usize); + assert_eq!(::std::mem::align_of::<_bindgen_ty_25>() , 8usize); } - impl Clone for _bindgen_ty_26 { + impl Clone for _bindgen_ty_25 { fn clone(&self) -> Self { *self } } - pub type nsStyleUnion = root::_bindgen_ty_26; + pub type nsStyleUnion = root::_bindgen_ty_25; /** * Class that hold a single size specification used by the style * system. The size specification consists of two parts -- a number @@ -10702,7 +10620,7 @@ pub mod root { eCSSProperty_animation_name = 8, eCSSProperty_animation_play_state = 9, eCSSProperty_animation_timing_function = 10, - eCSSProperty_appearance = 11, + eCSSProperty__moz_appearance = 11, eCSSProperty_backface_visibility = 12, eCSSProperty_background_attachment = 13, eCSSProperty_background_blend_mode = 14, @@ -10714,7 +10632,7 @@ pub mod root { eCSSProperty_background_position_y = 20, eCSSProperty_background_repeat = 21, eCSSProperty_background_size = 22, - eCSSProperty_binding = 23, + eCSSProperty__moz_binding = 23, eCSSProperty_block_size = 24, eCSSProperty_border_block_end_color = 25, eCSSProperty_border_block_end_style = 26, @@ -10723,7 +10641,7 @@ pub mod root { eCSSProperty_border_block_start_style = 29, eCSSProperty_border_block_start_width = 30, eCSSProperty_border_bottom_color = 31, - eCSSProperty_border_bottom_colors = 32, + eCSSProperty__moz_border_bottom_colors = 32, eCSSProperty_border_bottom_left_radius = 33, eCSSProperty_border_bottom_right_radius = 34, eCSSProperty_border_bottom_style = 35, @@ -10741,28 +10659,28 @@ pub mod root { eCSSProperty_border_inline_start_style = 47, eCSSProperty_border_inline_start_width = 48, eCSSProperty_border_left_color = 49, - eCSSProperty_border_left_colors = 50, + eCSSProperty__moz_border_left_colors = 50, eCSSProperty_border_left_style = 51, eCSSProperty_border_left_width = 52, eCSSProperty_border_right_color = 53, - eCSSProperty_border_right_colors = 54, + eCSSProperty__moz_border_right_colors = 54, eCSSProperty_border_right_style = 55, eCSSProperty_border_right_width = 56, eCSSProperty_border_spacing = 57, eCSSProperty_border_top_color = 58, - eCSSProperty_border_top_colors = 59, + eCSSProperty__moz_border_top_colors = 59, eCSSProperty_border_top_left_radius = 60, eCSSProperty_border_top_right_radius = 61, eCSSProperty_border_top_style = 62, eCSSProperty_border_top_width = 63, eCSSProperty_bottom = 64, - eCSSProperty_box_align = 65, + eCSSProperty__moz_box_align = 65, eCSSProperty_box_decoration_break = 66, - eCSSProperty_box_direction = 67, - eCSSProperty_box_flex = 68, - eCSSProperty_box_ordinal_group = 69, - eCSSProperty_box_orient = 70, - eCSSProperty_box_pack = 71, + eCSSProperty__moz_box_direction = 67, + eCSSProperty__moz_box_flex = 68, + eCSSProperty__moz_box_ordinal_group = 69, + eCSSProperty__moz_box_orient = 70, + eCSSProperty__moz_box_pack = 71, eCSSProperty_box_shadow = 72, eCSSProperty_box_sizing = 73, eCSSProperty_caption_side = 74, @@ -10801,7 +10719,7 @@ pub mod root { eCSSProperty_flex_shrink = 107, eCSSProperty_flex_wrap = 108, eCSSProperty_float_ = 109, - eCSSProperty_float_edge = 110, + eCSSProperty__moz_float_edge = 110, eCSSProperty_flood_color = 111, eCSSProperty_flood_opacity = 112, eCSSProperty_font_family = 113, @@ -10821,7 +10739,7 @@ pub mod root { eCSSProperty_font_variant_position = 127, eCSSProperty_font_variation_settings = 128, eCSSProperty_font_weight = 129, - eCSSProperty_force_broken_image_icon = 130, + eCSSProperty__moz_force_broken_image_icon = 130, eCSSProperty_grid_auto_columns = 131, eCSSProperty_grid_auto_flow = 132, eCSSProperty_grid_auto_rows = 133, @@ -10838,7 +10756,7 @@ pub mod root { eCSSProperty_hyphens = 144, eCSSProperty_initial_letter = 145, eCSSProperty_image_orientation = 146, - eCSSProperty_image_region = 147, + eCSSProperty__moz_image_region = 147, eCSSProperty_image_rendering = 148, eCSSProperty_ime_mode = 149, eCSSProperty_inline_size = 150, @@ -10875,8 +10793,8 @@ pub mod root { eCSSProperty_mask_repeat = 181, eCSSProperty_mask_size = 182, eCSSProperty_mask_type = 183, - eCSSProperty_math_display = 184, - eCSSProperty_math_variant = 185, + eCSSProperty__moz_math_display = 184, + eCSSProperty__moz_math_variant = 185, eCSSProperty_max_block_size = 186, eCSSProperty_max_height = 187, eCSSProperty_max_inline_size = 188, @@ -10895,14 +10813,14 @@ pub mod root { eCSSProperty_offset_inline_start = 201, eCSSProperty_opacity = 202, eCSSProperty_order = 203, - eCSSProperty_orient = 204, - eCSSProperty_osx_font_smoothing = 205, + eCSSProperty__moz_orient = 204, + eCSSProperty__moz_osx_font_smoothing = 205, eCSSProperty_outline_color = 206, eCSSProperty_outline_offset = 207, - eCSSProperty__moz_outline_radius_bottomLeft = 208, - eCSSProperty__moz_outline_radius_bottomRight = 209, - eCSSProperty__moz_outline_radius_topLeft = 210, - eCSSProperty__moz_outline_radius_topRight = 211, + eCSSProperty__moz_outline_radius_bottomleft = 208, + eCSSProperty__moz_outline_radius_bottomright = 209, + eCSSProperty__moz_outline_radius_topleft = 210, + eCSSProperty__moz_outline_radius_topright = 211, eCSSProperty_outline_style = 212, eCSSProperty_outline_width = 213, eCSSProperty_overflow_clip_box = 214, @@ -10929,9 +10847,9 @@ pub mod root { eCSSProperty_right = 235, eCSSProperty_ruby_align = 236, eCSSProperty_ruby_position = 237, - eCSSProperty_script_level = 238, - eCSSProperty_script_min_size = 239, - eCSSProperty_script_size_multiplier = 240, + eCSSProperty__moz_script_level = 238, + eCSSProperty__moz_script_min_size = 239, + eCSSProperty__moz_script_size_multiplier = 240, eCSSProperty_scroll_behavior = 241, eCSSProperty_scroll_snap_coordinate = 242, eCSSProperty_scroll_snap_destination = 243, @@ -10942,7 +10860,7 @@ pub mod root { eCSSProperty_shape_outside = 248, eCSSProperty_shape_rendering = 249, eCSSProperty__x_span = 250, - eCSSProperty_stack_sizing = 251, + eCSSProperty__moz_stack_sizing = 251, eCSSProperty_stop_color = 252, eCSSProperty_stop_opacity = 253, eCSSProperty_stroke = 254, @@ -10972,7 +10890,7 @@ pub mod root { eCSSProperty_text_overflow = 278, eCSSProperty_text_rendering = 279, eCSSProperty_text_shadow = 280, - eCSSProperty_text_size_adjust = 281, + eCSSProperty__moz_text_size_adjust = 281, eCSSProperty__webkit_text_stroke_color = 282, eCSSProperty__webkit_text_stroke_width = 283, eCSSProperty_text_transform = 284, @@ -10989,10 +10907,10 @@ pub mod root { eCSSProperty_transition_property = 295, eCSSProperty_transition_timing_function = 296, eCSSProperty_unicode_bidi = 297, - eCSSProperty_user_focus = 298, - eCSSProperty_user_input = 299, - eCSSProperty_user_modify = 300, - eCSSProperty_user_select = 301, + eCSSProperty__moz_user_focus = 298, + eCSSProperty__moz_user_input = 299, + eCSSProperty__moz_user_modify = 300, + eCSSProperty__moz_user_select = 301, eCSSProperty_vector_effect = 302, eCSSProperty_vertical_align = 303, eCSSProperty_visibility = 304, @@ -11221,127 +11139,11 @@ pub mod root { pub struct nsMainThreadPtrHandle<T> { pub mPtr: root::RefPtr<T>, } - #[test] - fn __bindgen_test_layout_template_11() { - assert_eq!(::std::mem::size_of::<u64>() , 8usize); - assert_eq!(::std::mem::align_of::<u64>() , 8usize); - } - #[repr(C)] - pub struct IProgressObserver__bindgen_vtable { - } - /** - * An interface for observing changes to image state, as reported by - * ProgressTracker. - * - * This is the ImageLib-internal version of imgINotificationObserver, - * essentially, with implementation details that code outside of ImageLib - * shouldn't see. - * - * XXX(seth): It's preferable to avoid adding anything to this interface if - * possible. In the long term, it would be ideal to get to a place where we can - * just use the imgINotificationObserver interface internally as well. - */ - #[repr(C)] - #[derive(Debug)] - pub struct IProgressObserver { - pub vtable_: *const IProgressObserver__bindgen_vtable, - pub _base: u64, - } - #[test] - fn bindgen_test_layout_IProgressObserver() { - assert_eq!(::std::mem::size_of::<IProgressObserver>() , 16usize); - assert_eq!(::std::mem::align_of::<IProgressObserver>() , 8usize); - } - #[repr(C)] - #[derive(Debug, Copy)] - pub struct nsISupportsPriority { - pub _base: root::nsISupports, - } - #[repr(C)] - #[derive(Debug, Copy, Clone)] - pub struct nsISupportsPriority_COMTypeInfo<T, U> { - pub _address: u8, - pub _phantom_0: ::std::marker::PhantomData<T>, - pub _phantom_1: ::std::marker::PhantomData<U>, - } - pub const nsISupportsPriority_PRIORITY_HIGHEST: - root::nsISupportsPriority__bindgen_ty_1 = - nsISupportsPriority__bindgen_ty_1::PRIORITY_HIGHEST; - pub const nsISupportsPriority_PRIORITY_HIGH: - root::nsISupportsPriority__bindgen_ty_1 = - nsISupportsPriority__bindgen_ty_1::PRIORITY_HIGH; - pub const nsISupportsPriority_PRIORITY_NORMAL: - root::nsISupportsPriority__bindgen_ty_1 = - nsISupportsPriority__bindgen_ty_1::PRIORITY_NORMAL; - pub const nsISupportsPriority_PRIORITY_LOW: - root::nsISupportsPriority__bindgen_ty_1 = - nsISupportsPriority__bindgen_ty_1::PRIORITY_LOW; - pub const nsISupportsPriority_PRIORITY_LOWEST: - root::nsISupportsPriority__bindgen_ty_1 = - nsISupportsPriority__bindgen_ty_1::PRIORITY_LOWEST; - #[repr(i32)] - #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] - pub enum nsISupportsPriority__bindgen_ty_1 { - PRIORITY_HIGHEST = -20, - PRIORITY_HIGH = -10, - PRIORITY_NORMAL = 0, - PRIORITY_LOW = 10, - PRIORITY_LOWEST = 20, - } - #[test] - fn bindgen_test_layout_nsISupportsPriority() { - assert_eq!(::std::mem::size_of::<nsISupportsPriority>() , 8usize); - assert_eq!(::std::mem::align_of::<nsISupportsPriority>() , 8usize); - } - impl Clone for nsISupportsPriority { - fn clone(&self) -> Self { *self } - } - #[repr(C)] - #[derive(Debug, Copy)] - pub struct nsISecurityInfoProvider { - pub _base: root::nsISupports, - } - #[repr(C)] - #[derive(Debug, Copy, Clone)] - pub struct nsISecurityInfoProvider_COMTypeInfo<T, U> { - pub _address: u8, - pub _phantom_0: ::std::marker::PhantomData<T>, - pub _phantom_1: ::std::marker::PhantomData<U>, - } - #[test] - fn bindgen_test_layout_nsISecurityInfoProvider() { - assert_eq!(::std::mem::size_of::<nsISecurityInfoProvider>() , 8usize); - assert_eq!(::std::mem::align_of::<nsISecurityInfoProvider>() , - 8usize); - } - impl Clone for nsISecurityInfoProvider { - fn clone(&self) -> Self { *self } - } - #[repr(C)] - #[derive(Debug, Copy)] - pub struct nsITimedChannel { - pub _base: root::nsISupports, - } - #[repr(C)] - #[derive(Debug, Copy, Clone)] - pub struct nsITimedChannel_COMTypeInfo<T, U> { - pub _address: u8, - pub _phantom_0: ::std::marker::PhantomData<T>, - pub _phantom_1: ::std::marker::PhantomData<U>, - } - #[test] - fn bindgen_test_layout_nsITimedChannel() { - assert_eq!(::std::mem::size_of::<nsITimedChannel>() , 8usize); - assert_eq!(::std::mem::align_of::<nsITimedChannel>() , 8usize); - } - impl Clone for nsITimedChannel { - fn clone(&self) -> Self { *self } - } #[repr(C)] #[derive(Debug)] pub struct imgRequestProxy { pub _base: root::imgIRequest, - pub _base_1: root::IProgressObserver, + pub _base_1: root::mozilla::image::IProgressObserver, pub _base_2: root::nsISupportsPriority, pub _base_3: root::nsISecurityInfoProvider, pub _base_4: root::nsITimedChannel, @@ -11536,7 +11338,7 @@ pub mod root { pub mSheetPrincipal: root::nsCOMPtr<root::nsIPrincipal>, pub mLineNumber: u32, pub mLineOffset: u32, - pub mLevel: root::SheetType, + pub mLevel: root::mozilla::SheetType, } pub type nsCSSValueTokenStream_HasThreadSafeRefCnt = root::mozilla::FalseType; @@ -11826,6 +11628,91 @@ pub mod root { } #[repr(C)] #[derive(Debug, Copy)] + pub struct nsISecurityInfoProvider { + pub _base: root::nsISupports, + } + #[repr(C)] + #[derive(Debug, Copy, Clone)] + pub struct nsISecurityInfoProvider_COMTypeInfo<T, U> { + pub _address: u8, + pub _phantom_0: ::std::marker::PhantomData<T>, + pub _phantom_1: ::std::marker::PhantomData<U>, + } + #[test] + fn bindgen_test_layout_nsISecurityInfoProvider() { + assert_eq!(::std::mem::size_of::<nsISecurityInfoProvider>() , 8usize); + assert_eq!(::std::mem::align_of::<nsISecurityInfoProvider>() , + 8usize); + } + impl Clone for nsISecurityInfoProvider { + fn clone(&self) -> Self { *self } + } + #[repr(C)] + #[derive(Debug, Copy)] + pub struct nsISupportsPriority { + pub _base: root::nsISupports, + } + #[repr(C)] + #[derive(Debug, Copy, Clone)] + pub struct nsISupportsPriority_COMTypeInfo<T, U> { + pub _address: u8, + pub _phantom_0: ::std::marker::PhantomData<T>, + pub _phantom_1: ::std::marker::PhantomData<U>, + } + pub const nsISupportsPriority_PRIORITY_HIGHEST: + root::nsISupportsPriority__bindgen_ty_1 = + nsISupportsPriority__bindgen_ty_1::PRIORITY_HIGHEST; + pub const nsISupportsPriority_PRIORITY_HIGH: + root::nsISupportsPriority__bindgen_ty_1 = + nsISupportsPriority__bindgen_ty_1::PRIORITY_HIGH; + pub const nsISupportsPriority_PRIORITY_NORMAL: + root::nsISupportsPriority__bindgen_ty_1 = + nsISupportsPriority__bindgen_ty_1::PRIORITY_NORMAL; + pub const nsISupportsPriority_PRIORITY_LOW: + root::nsISupportsPriority__bindgen_ty_1 = + nsISupportsPriority__bindgen_ty_1::PRIORITY_LOW; + pub const nsISupportsPriority_PRIORITY_LOWEST: + root::nsISupportsPriority__bindgen_ty_1 = + nsISupportsPriority__bindgen_ty_1::PRIORITY_LOWEST; + #[repr(i32)] + #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] + pub enum nsISupportsPriority__bindgen_ty_1 { + PRIORITY_HIGHEST = -20, + PRIORITY_HIGH = -10, + PRIORITY_NORMAL = 0, + PRIORITY_LOW = 10, + PRIORITY_LOWEST = 20, + } + #[test] + fn bindgen_test_layout_nsISupportsPriority() { + assert_eq!(::std::mem::size_of::<nsISupportsPriority>() , 8usize); + assert_eq!(::std::mem::align_of::<nsISupportsPriority>() , 8usize); + } + impl Clone for nsISupportsPriority { + fn clone(&self) -> Self { *self } + } + #[repr(C)] + #[derive(Debug, Copy)] + pub struct nsITimedChannel { + pub _base: root::nsISupports, + } + #[repr(C)] + #[derive(Debug, Copy, Clone)] + pub struct nsITimedChannel_COMTypeInfo<T, U> { + pub _address: u8, + pub _phantom_0: ::std::marker::PhantomData<T>, + pub _phantom_1: ::std::marker::PhantomData<U>, + } + #[test] + fn bindgen_test_layout_nsITimedChannel() { + assert_eq!(::std::mem::size_of::<nsITimedChannel>() , 8usize); + assert_eq!(::std::mem::align_of::<nsITimedChannel>() , 8usize); + } + impl Clone for nsITimedChannel { + fn clone(&self) -> Self { *self } + } + #[repr(C)] + #[derive(Debug, Copy)] pub struct ProxyBehaviour { pub _address: u8, } @@ -11972,7 +11859,7 @@ pub mod root { assert_eq!(::std::mem::align_of::<CachedBorderImageData>() , 8usize); } #[test] - fn __bindgen_test_layout_template_12() { + fn __bindgen_test_layout_template_8() { assert_eq!(::std::mem::size_of::<root::mozilla::UniquePtr<root::nsStyleSides, root::mozilla::DefaultDelete<root::nsStyleSides>>>() , 8usize); @@ -13149,190 +13036,176 @@ pub mod root { root::nsMainThreadPtrHolder<root::nsIPrincipal>; pub type ThreadSafeURIHolder = root::nsMainThreadPtrHolder<root::nsIURI>; #[test] - fn __bindgen_test_layout_template_13() { + fn __bindgen_test_layout_template_9() { assert_eq!(::std::mem::size_of::<root::JS::TenuredHeap<*mut root::JSObject>>() , 8usize); assert_eq!(::std::mem::align_of::<root::JS::TenuredHeap<*mut root::JSObject>>() , 8usize); } #[test] - fn __bindgen_test_layout_template_14() { + fn __bindgen_test_layout_template_10() { assert_eq!(::std::mem::size_of::<root::JS::Heap<*mut root::JSObject>>() , 8usize); assert_eq!(::std::mem::align_of::<root::JS::Heap<*mut root::JSObject>>() , 8usize); } #[test] - fn __bindgen_test_layout_template_15() { + fn __bindgen_test_layout_template_11() { assert_eq!(::std::mem::size_of::<root::nsTArray<root::nsCString>>() , 8usize); assert_eq!(::std::mem::align_of::<root::nsTArray<root::nsCString>>() , 8usize); } #[test] - fn __bindgen_test_layout_template_16() { - assert_eq!(::std::mem::size_of::<root::nsTArray<::nsstring::nsStringRepr>>() , - 8usize); - assert_eq!(::std::mem::align_of::<root::nsTArray<::nsstring::nsStringRepr>>() , - 8usize); - } - #[test] - fn __bindgen_test_layout_template_17() { + fn __bindgen_test_layout_template_12() { assert_eq!(::std::mem::size_of::<root::nsCOMPtr<root::nsIPrincipal>>() , 8usize); assert_eq!(::std::mem::align_of::<root::nsCOMPtr<root::nsIPrincipal>>() , 8usize); } #[test] - fn __bindgen_test_layout_template_18() { - assert_eq!(::std::mem::size_of::<root::nsTArray<root::RefPtr<root::mozilla::dom::AnonymousContent>>>() - , 8usize); - assert_eq!(::std::mem::align_of::<root::nsTArray<root::RefPtr<root::mozilla::dom::AnonymousContent>>>() - , 8usize); - } - #[test] - fn __bindgen_test_layout_template_19() { + fn __bindgen_test_layout_template_13() { assert_eq!(::std::mem::size_of::<root::RefPtr<root::mozilla::dom::Element>>() , 8usize); assert_eq!(::std::mem::align_of::<root::RefPtr<root::mozilla::dom::Element>>() , 8usize); } #[test] - fn __bindgen_test_layout_template_20() { + fn __bindgen_test_layout_template_14() { assert_eq!(::std::mem::size_of::<root::nsTArray<root::RefPtr<root::mozilla::dom::Element>>>() , 8usize); assert_eq!(::std::mem::align_of::<root::nsTArray<root::RefPtr<root::mozilla::dom::Element>>>() , 8usize); } #[test] - fn __bindgen_test_layout_template_21() { + fn __bindgen_test_layout_template_15() { assert_eq!(::std::mem::size_of::<root::nsCOMPtr<root::nsIObserver>>() , 8usize); assert_eq!(::std::mem::align_of::<root::nsCOMPtr<root::nsIObserver>>() , 8usize); } #[test] - fn __bindgen_test_layout_template_22() { - assert_eq!(::std::mem::size_of::<root::nsTArray<root::nsCOMPtr<root::nsIObserver>>>() - , 8usize); - assert_eq!(::std::mem::align_of::<root::nsTArray<root::nsCOMPtr<root::nsIObserver>>>() - , 8usize); - } - #[test] - fn __bindgen_test_layout_template_23() { + fn __bindgen_test_layout_template_16() { assert_eq!(::std::mem::size_of::<root::nsCOMPtr<root::nsIWeakReference>>() , 8usize); assert_eq!(::std::mem::align_of::<root::nsCOMPtr<root::nsIWeakReference>>() , 8usize); } #[test] - fn __bindgen_test_layout_template_24() { + fn __bindgen_test_layout_template_17() { assert_eq!(::std::mem::size_of::<root::nsTArray<*mut root::nsIContent>>() , 8usize); assert_eq!(::std::mem::align_of::<root::nsTArray<*mut root::nsIContent>>() , 8usize); } #[test] - fn __bindgen_test_layout_template_25() { + fn __bindgen_test_layout_template_18() { + assert_eq!(::std::mem::size_of::<root::nsTArray<::nsstring::nsStringRepr>>() , + 8usize); + assert_eq!(::std::mem::align_of::<root::nsTArray<::nsstring::nsStringRepr>>() , + 8usize); + } + #[test] + fn __bindgen_test_layout_template_19() { + assert_eq!(::std::mem::size_of::<root::mozilla::DefaultDelete<root::mozilla::dom::TimeoutManager>>() + , 1usize); + assert_eq!(::std::mem::align_of::<root::mozilla::DefaultDelete<root::mozilla::dom::TimeoutManager>>() + , 1usize); + } + #[test] + fn __bindgen_test_layout_template_20() { assert_eq!(::std::mem::size_of::<root::nsCOMPtr<root::nsIRunnable>>() , 8usize); assert_eq!(::std::mem::align_of::<root::nsCOMPtr<root::nsIRunnable>>() , 8usize); } #[test] - fn __bindgen_test_layout_template_26() { + fn __bindgen_test_layout_template_21() { assert_eq!(::std::mem::size_of::<root::mozilla::OwningNonNull<root::nsINode>>() , 16usize); assert_eq!(::std::mem::align_of::<root::mozilla::OwningNonNull<root::nsINode>>() , 8usize); } #[test] - fn __bindgen_test_layout_template_27() { + fn __bindgen_test_layout_template_22() { assert_eq!(::std::mem::size_of::<root::nsTArray<f64>>() , 8usize); assert_eq!(::std::mem::align_of::<root::nsTArray<f64>>() , 8usize); } #[test] - fn __bindgen_test_layout_template_28() { + fn __bindgen_test_layout_template_23() { assert_eq!(::std::mem::size_of::<root::RefPtr<root::mozilla::dom::DOMIntersectionObserverEntry>>() , 8usize); assert_eq!(::std::mem::align_of::<root::RefPtr<root::mozilla::dom::DOMIntersectionObserverEntry>>() , 8usize); } #[test] - fn __bindgen_test_layout_template_29() { + fn __bindgen_test_layout_template_24() { assert_eq!(::std::mem::size_of::<root::nsTArray<root::RefPtr<root::mozilla::dom::DOMIntersectionObserverEntry>>>() , 8usize); assert_eq!(::std::mem::align_of::<root::nsTArray<root::RefPtr<root::mozilla::dom::DOMIntersectionObserverEntry>>>() , 8usize); } #[test] - fn __bindgen_test_layout_template_30() { - assert_eq!(::std::mem::size_of::<root::nsTArray<root::mozilla::FontFamilyName>>() - , 8usize); - assert_eq!(::std::mem::align_of::<root::nsTArray<root::mozilla::FontFamilyName>>() + fn __bindgen_test_layout_template_25() { + assert_eq!(::std::mem::size_of::<root::nsMainThreadPtrHolder<root::nsIURI>>() + , 24usize); + assert_eq!(::std::mem::align_of::<root::nsMainThreadPtrHolder<root::nsIURI>>() , 8usize); } #[test] - fn __bindgen_test_layout_template_31() { - assert_eq!(::std::mem::size_of::<root::nsTArray<root::mozilla::FramePropertyTable_PropertyValue>>() + fn __bindgen_test_layout_template_26() { + assert_eq!(::std::mem::size_of::<root::nsMainThreadPtrHolder<root::nsIPrincipal>>() + , 24usize); + assert_eq!(::std::mem::align_of::<root::nsMainThreadPtrHolder<root::nsIPrincipal>>() , 8usize); - assert_eq!(::std::mem::align_of::<root::nsTArray<root::mozilla::FramePropertyTable_PropertyValue>>() + } + #[test] + fn __bindgen_test_layout_template_27() { + assert_eq!(::std::mem::size_of::<root::nsPtrHashKey<root::nsIFrame>>() + , 16usize); + assert_eq!(::std::mem::align_of::<root::nsPtrHashKey<root::nsIFrame>>() , 8usize); } #[test] - fn __bindgen_test_layout_template_32() { + fn __bindgen_test_layout_template_28() { assert_eq!(::std::mem::size_of::<root::nsTArray<root::mozilla::DisplayItemClip_RoundedRect>>() , 8usize); assert_eq!(::std::mem::align_of::<root::nsTArray<root::mozilla::DisplayItemClip_RoundedRect>>() , 8usize); } #[test] - fn __bindgen_test_layout_template_33() { + fn __bindgen_test_layout_template_29() { assert_eq!(::std::mem::size_of::<root::RefPtr<root::mozilla::dom::DOMRect>>() , 8usize); assert_eq!(::std::mem::align_of::<root::RefPtr<root::mozilla::dom::DOMRect>>() , 8usize); } #[test] - fn __bindgen_test_layout_template_34() { + fn __bindgen_test_layout_template_30() { assert_eq!(::std::mem::size_of::<root::mozilla::DefaultDelete<root::ProxyBehaviour>>() , 1usize); assert_eq!(::std::mem::align_of::<root::mozilla::DefaultDelete<root::ProxyBehaviour>>() , 1usize); } #[test] - fn __bindgen_test_layout_template_35() { + fn __bindgen_test_layout_template_31() { assert_eq!(::std::mem::size_of::<root::mozilla::DefaultDelete<root::nsStyleSides>>() , 1usize); assert_eq!(::std::mem::align_of::<root::mozilla::DefaultDelete<root::nsStyleSides>>() , 1usize); } #[test] - fn __bindgen_test_layout_template_36() { + fn __bindgen_test_layout_template_32() { assert_eq!(::std::mem::size_of::<root::mozilla::DefaultDelete<root::CachedBorderImageData>>() , 1usize); assert_eq!(::std::mem::align_of::<root::mozilla::DefaultDelete<root::CachedBorderImageData>>() , 1usize); } #[test] - fn __bindgen_test_layout_template_37() { + fn __bindgen_test_layout_template_33() { assert_eq!(::std::mem::size_of::<root::std::pair<::nsstring::nsStringRepr, ::nsstring::nsStringRepr>>() , 32usize); assert_eq!(::std::mem::align_of::<root::std::pair<::nsstring::nsStringRepr, ::nsstring::nsStringRepr>>() , 8usize); } - #[test] - fn __bindgen_test_layout_template_38() { - assert_eq!(::std::mem::size_of::<root::nsMainThreadPtrHolder<root::nsIPrincipal>>() - , 24usize); - assert_eq!(::std::mem::align_of::<root::nsMainThreadPtrHolder<root::nsIPrincipal>>() - , 8usize); - } - #[test] - fn __bindgen_test_layout_template_39() { - assert_eq!(::std::mem::size_of::<root::nsMainThreadPtrHolder<root::nsIURI>>() - , 24usize); - assert_eq!(::std::mem::align_of::<root::nsMainThreadPtrHolder<root::nsIURI>>() - , 8usize); - } } diff --git a/components/style/gecko_bindings/structs_release.rs b/components/style/gecko_bindings/structs_release.rs index 587d932ba69..596345fa47c 100644 --- a/components/style/gecko_bindings/structs_release.rs +++ b/components/style/gecko_bindings/structs_release.rs @@ -234,8 +234,6 @@ pub mod root { pub const NS_CORNER_BOTTOM_RIGHT_Y: ::std::os::raw::c_uint = 5; pub const NS_CORNER_BOTTOM_LEFT_X: ::std::os::raw::c_uint = 6; pub const NS_CORNER_BOTTOM_LEFT_Y: ::std::os::raw::c_uint = 7; - pub const NS_RADIUS_FARTHEST_SIDE: ::std::os::raw::c_uint = 0; - pub const NS_RADIUS_CLOSEST_SIDE: ::std::os::raw::c_uint = 1; pub const NS_STYLE_STACK_SIZING_IGNORE: ::std::os::raw::c_uint = 0; pub const NS_STYLE_STACK_SIZING_STRETCH_TO_FIT: ::std::os::raw::c_uint = 1; @@ -1014,6 +1012,7 @@ pub mod root { pub const NS_STYLE_DISPLAY_MODE_BROWSER: ::std::os::raw::c_uint = 0; pub const NS_STYLE_DISPLAY_MODE_MINIMAL_UI: ::std::os::raw::c_uint = 1; pub const NS_STYLE_DISPLAY_MODE_STANDALONE: ::std::os::raw::c_uint = 2; + pub const NS_STYLE_DISPLAY_MODE_FULLSCREEN: ::std::os::raw::c_uint = 3; pub const NS_STYLE_INHERIT_MASK: ::std::os::raw::c_uint = 16777215; pub const NS_STYLE_HAS_TEXT_DECORATION_LINES: ::std::os::raw::c_uint = 16777216; @@ -1170,10 +1169,7 @@ pub mod root { pub struct ThreadSafeAutoRefCnt { pub mValue: u64, } - extern "C" { - #[link_name = "_ZN7mozilla20ThreadSafeAutoRefCnt12isThreadSafeE"] - pub static ThreadSafeAutoRefCnt_isThreadSafe: bool; - } + pub const ThreadSafeAutoRefCnt_isThreadSafe: bool = true; #[test] fn bindgen_test_layout_ThreadSafeAutoRefCnt() { assert_eq!(::std::mem::size_of::<ThreadSafeAutoRefCnt>() , @@ -1290,6 +1286,112 @@ pub mod root { } #[repr(C)] #[derive(Debug)] + pub struct EventTarget { + pub _base: root::nsIDOMEventTarget, + pub _base_1: root::nsWrapperCache, + } + #[repr(C)] + #[derive(Debug, Copy, Clone)] + pub struct EventTarget_COMTypeInfo<T, U> { + pub _address: u8, + pub _phantom_0: ::std::marker::PhantomData<T>, + pub _phantom_1: ::std::marker::PhantomData<U>, + } + #[test] + fn bindgen_test_layout_EventTarget() { + assert_eq!(::std::mem::size_of::<EventTarget>() , 32usize); + assert_eq!(::std::mem::align_of::<EventTarget>() , 8usize); + } + #[repr(C)] + #[derive(Debug, Copy)] + pub struct AudioContext { + pub _address: u8, + } + impl Clone for AudioContext { + fn clone(&self) -> Self { *self } + } + #[repr(C)] + #[derive(Debug, Copy)] + pub struct DocGroup { + pub _address: u8, + } + impl Clone for DocGroup { + fn clone(&self) -> Self { *self } + } + pub const ReferrerPolicy_RP_Default: + root::mozilla::dom::ReferrerPolicy = + ReferrerPolicy::RP_No_Referrer_When_Downgrade; + #[repr(u32)] + #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] + pub enum ReferrerPolicy { + RP_No_Referrer = 2, + RP_Origin = 3, + RP_No_Referrer_When_Downgrade = 1, + RP_Origin_When_Crossorigin = 4, + RP_Unsafe_URL = 5, + RP_Same_Origin = 6, + RP_Strict_Origin = 7, + RP_Strict_Origin_When_Cross_Origin = 8, + RP_Unset = 0, + } + #[repr(C)] + #[derive(Debug)] + pub struct Element { + pub _base: root::mozilla::dom::FragmentOrElement, + pub mState: root::EventStates, + pub mServoData: ::gecko_bindings::structs::ServoCell<*mut ::gecko_bindings::structs::ServoNodeData>, + } + #[repr(C)] + #[derive(Debug, Copy, Clone)] + pub struct Element_COMTypeInfo<T, U> { + pub _address: u8, + pub _phantom_0: ::std::marker::PhantomData<T>, + pub _phantom_1: ::std::marker::PhantomData<U>, + } + #[repr(C)] + #[derive(Debug, Copy)] + pub struct Element_MappedAttributeEntry { + pub attribute: *mut *mut root::nsIAtom, + } + #[test] + fn bindgen_test_layout_Element_MappedAttributeEntry() { + assert_eq!(::std::mem::size_of::<Element_MappedAttributeEntry>() + , 8usize); + assert_eq!(::std::mem::align_of::<Element_MappedAttributeEntry>() + , 8usize); + } + impl Clone for Element_MappedAttributeEntry { + fn clone(&self) -> Self { *self } + } + pub const Element_kFireMutationEvent: bool = true; + pub const Element_kDontFireMutationEvent: bool = false; + pub const Element_kNotifyDocumentObservers: bool = true; + pub const Element_kDontNotifyDocumentObservers: bool = false; + pub const Element_kCallAfterSetAttr: bool = true; + pub const Element_kDontCallAfterSetAttr: bool = false; + #[test] + fn bindgen_test_layout_Element() { + assert_eq!(::std::mem::size_of::<Element>() , 128usize); + assert_eq!(::std::mem::align_of::<Element>() , 8usize); + } + #[repr(C)] + #[derive(Debug, Copy)] + pub struct TimeoutManager { + pub _address: u8, + } + impl Clone for TimeoutManager { + fn clone(&self) -> Self { *self } + } + #[repr(C)] + #[derive(Debug, Copy)] + pub struct PrefSetting { + pub _address: u8, + } + impl Clone for PrefSetting { + fn clone(&self) -> Self { *self } + } + #[repr(C)] + #[derive(Debug)] pub struct CallbackObject { pub _base: root::nsISupports, pub mRefCnt: root::nsCycleCollectingAutoRefCnt, @@ -1389,272 +1491,6 @@ pub mod root { assert_eq!(::std::mem::align_of::<CallbackFunction>() , 8usize); } - #[repr(C)] - #[derive(Debug, Copy)] - pub struct AudioContext { - pub _address: u8, - } - impl Clone for AudioContext { - fn clone(&self) -> Self { *self } - } - #[repr(C)] - #[derive(Debug, Copy)] - pub struct DocGroup { - pub _address: u8, - } - impl Clone for DocGroup { - fn clone(&self) -> Self { *self } - } - #[repr(C)] - #[derive(Debug)] - pub struct FragmentOrElement { - pub _base: root::nsIContent, - pub mRefCnt: root::nsCycleCollectingAutoRefCnt, - /** - * Array containing all attributes and children for this element - */ - pub mAttrsAndChildren: root::nsAttrAndChildArray, - } - pub type FragmentOrElement_HasThreadSafeRefCnt = - root::mozilla::FalseType; - #[repr(C)] - #[derive(Debug, Copy)] - pub struct FragmentOrElement_cycleCollection { - pub _base: root::nsXPCOMCycleCollectionParticipant, - } - #[test] - fn bindgen_test_layout_FragmentOrElement_cycleCollection() { - assert_eq!(::std::mem::size_of::<FragmentOrElement_cycleCollection>() - , 16usize); - assert_eq!(::std::mem::align_of::<FragmentOrElement_cycleCollection>() - , 8usize); - } - impl Clone for FragmentOrElement_cycleCollection { - fn clone(&self) -> Self { *self } - } - /** - * There are a set of DOM- and scripting-specific instance variables - * that may only be instantiated when a content object is accessed - * through the DOM. Rather than burn actual slots in the content - * objects for each of these instance variables, we put them off - * in a side structure that's only allocated when the content is - * accessed through the DOM. - */ - #[repr(C)] - #[derive(Debug)] - pub struct FragmentOrElement_nsDOMSlots { - pub _base: root::nsINode_nsSlots, - /** - * The .style attribute (an interface that forwards to the actual - * style rules) - * @see nsGenericHTMLElement::GetStyle - */ - pub mStyle: root::nsCOMPtr<root::nsICSSDeclaration>, - /** - * The .dataset attribute. - * @see nsGenericHTMLElement::GetDataset - */ - pub mDataset: *mut root::nsDOMStringMap, - /** - * SMIL Overridde style rules (for SMIL animation of CSS properties) - * @see nsIContent::GetSMILOverrideStyle - */ - pub mSMILOverrideStyle: root::nsCOMPtr<root::nsICSSDeclaration>, - /** - * Holds any SMIL override style declaration for this element. - */ - pub mSMILOverrideStyleDeclaration: root::RefPtr<root::mozilla::DeclarationBlock>, - /** - * An object implementing nsIDOMMozNamedAttrMap for this content (attributes) - * @see FragmentOrElement::GetAttributes - */ - pub mAttributeMap: root::RefPtr<root::nsDOMAttributeMap>, - pub __bindgen_anon_1: root::mozilla::dom::FragmentOrElement_nsDOMSlots__bindgen_ty_1, - /** - * An object implementing the .children property for this element. - */ - pub mChildrenList: root::RefPtr<root::nsContentList>, - /** - * An object implementing the .classList property for this element. - */ - pub mClassList: root::RefPtr<root::nsDOMTokenList>, - /** - * ShadowRoot bound to the element. - */ - pub mShadowRoot: root::RefPtr<root::mozilla::dom::ShadowRoot>, - /** - * The root ShadowRoot of this element if it is in a shadow tree. - */ - pub mContainingShadow: root::RefPtr<root::mozilla::dom::ShadowRoot>, - /** - * An array of web component insertion points to which this element - * is distributed. - */ - pub mDestInsertionPoints: root::nsTArray<*mut root::nsIContent>, - /** - * XBL binding installed on the element. - */ - pub mXBLBinding: root::RefPtr<root::nsXBLBinding>, - /** - * XBL binding installed on the lement. - */ - pub mXBLInsertionParent: root::nsCOMPtr<root::nsIContent>, - /** - * Web components custom element data. - */ - pub mCustomElementData: root::RefPtr<root::mozilla::dom::CustomElementData>, - pub mRegisteredIntersectionObservers: root::nsTArray<root::mozilla::dom::FragmentOrElement_nsDOMSlots_IntersectionObserverRegistration>, - } - #[repr(C)] - #[derive(Debug, Copy)] - pub struct FragmentOrElement_nsDOMSlots__bindgen_ty_1 { - /** - * The nearest enclosing content node with a binding that created us. - * @see FragmentOrElement::GetBindingParent - */ - pub mBindingParent: root::__BindgenUnionField<*mut root::nsIContent>, - /** - * The controllers of the XUL Element. - */ - pub mControllers: root::__BindgenUnionField<*mut root::nsIControllers>, - pub bindgen_union_field: u64, - } - #[test] - fn bindgen_test_layout_FragmentOrElement_nsDOMSlots__bindgen_ty_1() { - assert_eq!(::std::mem::size_of::<FragmentOrElement_nsDOMSlots__bindgen_ty_1>() - , 8usize); - assert_eq!(::std::mem::align_of::<FragmentOrElement_nsDOMSlots__bindgen_ty_1>() - , 8usize); - } - impl Clone for FragmentOrElement_nsDOMSlots__bindgen_ty_1 { - fn clone(&self) -> Self { *self } - } - /** - * Registered Intersection Observers on the element. - */ - #[repr(C)] - #[derive(Debug, Copy)] - pub struct FragmentOrElement_nsDOMSlots_IntersectionObserverRegistration { - pub observer: *mut root::mozilla::dom::DOMIntersectionObserver, - pub previousThreshold: i32, - } - #[test] - fn bindgen_test_layout_FragmentOrElement_nsDOMSlots_IntersectionObserverRegistration() { - assert_eq!(::std::mem::size_of::<FragmentOrElement_nsDOMSlots_IntersectionObserverRegistration>() - , 16usize); - assert_eq!(::std::mem::align_of::<FragmentOrElement_nsDOMSlots_IntersectionObserverRegistration>() - , 8usize); - } - impl Clone for - FragmentOrElement_nsDOMSlots_IntersectionObserverRegistration { - fn clone(&self) -> Self { *self } - } - #[test] - fn bindgen_test_layout_FragmentOrElement_nsDOMSlots() { - assert_eq!(::std::mem::size_of::<FragmentOrElement_nsDOMSlots>() - , 168usize); - assert_eq!(::std::mem::align_of::<FragmentOrElement_nsDOMSlots>() - , 8usize); - } - extern "C" { - #[link_name = - "_ZN7mozilla3dom17FragmentOrElement21_cycleCollectorGlobalE"] - pub static mut FragmentOrElement__cycleCollectorGlobal: - root::mozilla::dom::FragmentOrElement_cycleCollection; - } - #[test] - fn bindgen_test_layout_FragmentOrElement() { - assert_eq!(::std::mem::size_of::<FragmentOrElement>() , - 112usize); - assert_eq!(::std::mem::align_of::<FragmentOrElement>() , - 8usize); - } - pub const ReferrerPolicy_RP_Default: - root::mozilla::dom::ReferrerPolicy = - ReferrerPolicy::RP_No_Referrer_When_Downgrade; - #[repr(u32)] - #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] - pub enum ReferrerPolicy { - RP_No_Referrer = 2, - RP_Origin = 3, - RP_No_Referrer_When_Downgrade = 1, - RP_Origin_When_Crossorigin = 4, - RP_Unsafe_URL = 5, - RP_Same_Origin = 6, - RP_Strict_Origin = 7, - RP_Strict_Origin_When_Cross_Origin = 8, - RP_Unset = 0, - } - #[repr(C)] - #[derive(Debug)] - pub struct Element { - pub _base: root::mozilla::dom::FragmentOrElement, - pub mState: root::EventStates, - pub mServoData: ::gecko_bindings::structs::ServoCell<*mut ::gecko_bindings::structs::ServoNodeData>, - } - #[repr(C)] - #[derive(Debug, Copy, Clone)] - pub struct Element_COMTypeInfo<T, U> { - pub _address: u8, - pub _phantom_0: ::std::marker::PhantomData<T>, - pub _phantom_1: ::std::marker::PhantomData<U>, - } - #[repr(C)] - #[derive(Debug, Copy)] - pub struct Element_MappedAttributeEntry { - pub attribute: *mut *mut root::nsIAtom, - } - #[test] - fn bindgen_test_layout_Element_MappedAttributeEntry() { - assert_eq!(::std::mem::size_of::<Element_MappedAttributeEntry>() - , 8usize); - assert_eq!(::std::mem::align_of::<Element_MappedAttributeEntry>() - , 8usize); - } - impl Clone for Element_MappedAttributeEntry { - fn clone(&self) -> Self { *self } - } - extern "C" { - #[link_name = "_ZN7mozilla3dom7Element18kFireMutationEventE"] - pub static Element_kFireMutationEvent: bool; - } - extern "C" { - #[link_name = - "_ZN7mozilla3dom7Element22kDontFireMutationEventE"] - pub static Element_kDontFireMutationEvent: bool; - } - extern "C" { - #[link_name = - "_ZN7mozilla3dom7Element24kNotifyDocumentObserversE"] - pub static Element_kNotifyDocumentObservers: bool; - } - extern "C" { - #[link_name = - "_ZN7mozilla3dom7Element28kDontNotifyDocumentObserversE"] - pub static Element_kDontNotifyDocumentObservers: bool; - } - extern "C" { - #[link_name = "_ZN7mozilla3dom7Element17kCallAfterSetAttrE"] - pub static Element_kCallAfterSetAttr: bool; - } - extern "C" { - #[link_name = - "_ZN7mozilla3dom7Element21kDontCallAfterSetAttrE"] - pub static Element_kDontCallAfterSetAttr: bool; - } - #[test] - fn bindgen_test_layout_Element() { - assert_eq!(::std::mem::size_of::<Element>() , 128usize); - assert_eq!(::std::mem::align_of::<Element>() , 8usize); - } - #[repr(C)] - #[derive(Debug, Copy)] - pub struct PrefSetting { - pub _address: u8, - } - impl Clone for PrefSetting { - fn clone(&self) -> Self { *self } - } pub mod prototypes { #[allow(unused_imports)] use self::super::super::super::super::root; @@ -1854,6 +1690,14 @@ pub mod root { pub struct UnionMember<T> { pub mStorage: root::mozilla::AlignedStorage2<T>, } + #[repr(u32)] + #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] + pub enum VisibilityState { + Hidden = 0, + Visible = 1, + Prerender = 2, + EndGuard_ = 3, + } #[repr(C)] #[derive(Debug, Copy)] pub struct Animation { @@ -1872,26 +1716,8 @@ pub mod root { } #[repr(C)] #[derive(Debug)] - pub struct nsIAttribute { - pub _base: root::nsINode, - pub mAttrMap: root::RefPtr<root::nsDOMAttributeMap>, - } - #[repr(C)] - #[derive(Debug, Copy, Clone)] - pub struct nsIAttribute_COMTypeInfo<T, U> { - pub _address: u8, - pub _phantom_0: ::std::marker::PhantomData<T>, - pub _phantom_1: ::std::marker::PhantomData<U>, - } - #[test] - fn bindgen_test_layout_nsIAttribute() { - assert_eq!(::std::mem::size_of::<nsIAttribute>() , 104usize); - assert_eq!(::std::mem::align_of::<nsIAttribute>() , 8usize); - } - #[repr(C)] - #[derive(Debug)] pub struct Attr { - pub _base: root::mozilla::dom::nsIAttribute, + pub _base: root::nsIAttribute, pub _base_1: root::nsIDOMAttr, pub mRefCnt: root::nsCycleCollectingAutoRefCnt, pub mValue: ::nsstring::nsStringRepr, @@ -1927,58 +1753,6 @@ pub mod root { assert_eq!(::std::mem::align_of::<Attr>() , 8usize); } #[repr(C)] - #[derive(Debug)] - pub struct DOMIntersectionObserver { - pub _base: root::nsISupports, - pub _base_1: root::nsWrapperCache, - pub mRefCnt: root::nsCycleCollectingAutoRefCnt, - pub mOwner: root::nsCOMPtr<root::nsPIDOMWindowInner>, - pub mCallback: root::RefPtr<root::mozilla::dom::IntersectionCallback>, - pub mRoot: root::RefPtr<root::mozilla::dom::Element>, - pub mRootMargin: root::nsCSSRect, - pub mThresholds: root::nsTArray<f64>, - pub mObservationTargets: [u64; 5usize], - pub mQueuedEntries: root::nsTArray<root::RefPtr<root::mozilla::dom::DOMIntersectionObserverEntry>>, - pub mConnected: bool, - } - pub type DOMIntersectionObserver_HasThreadSafeRefCnt = - root::mozilla::FalseType; - #[repr(C)] - #[derive(Debug, Copy)] - pub struct DOMIntersectionObserver_cycleCollection { - pub _base: root::nsXPCOMCycleCollectionParticipant, - } - #[test] - fn bindgen_test_layout_DOMIntersectionObserver_cycleCollection() { - assert_eq!(::std::mem::size_of::<DOMIntersectionObserver_cycleCollection>() - , 16usize); - assert_eq!(::std::mem::align_of::<DOMIntersectionObserver_cycleCollection>() - , 8usize); - } - impl Clone for DOMIntersectionObserver_cycleCollection { - fn clone(&self) -> Self { *self } - } - #[repr(C)] - #[derive(Debug, Copy, Clone)] - pub struct DOMIntersectionObserver_COMTypeInfo<T, U> { - pub _address: u8, - pub _phantom_0: ::std::marker::PhantomData<T>, - pub _phantom_1: ::std::marker::PhantomData<U>, - } - extern "C" { - #[link_name = - "_ZN7mozilla3dom23DOMIntersectionObserver21_cycleCollectorGlobalE"] - pub static mut DOMIntersectionObserver__cycleCollectorGlobal: - root::mozilla::dom::DOMIntersectionObserver_cycleCollection; - } - #[test] - fn bindgen_test_layout_DOMIntersectionObserver() { - assert_eq!(::std::mem::size_of::<DOMIntersectionObserver>() , - 192usize); - assert_eq!(::std::mem::align_of::<DOMIntersectionObserver>() , - 8usize); - } - #[repr(C)] #[derive(Debug, Copy)] pub struct FontFaceSet { pub _address: u8, @@ -2059,6 +1833,153 @@ pub mod root { } #[repr(C)] #[derive(Debug)] + pub struct FragmentOrElement { + pub _base: root::nsIContent, + pub mRefCnt: root::nsCycleCollectingAutoRefCnt, + /** + * Array containing all attributes and children for this element + */ + pub mAttrsAndChildren: root::nsAttrAndChildArray, + } + pub type FragmentOrElement_HasThreadSafeRefCnt = + root::mozilla::FalseType; + #[repr(C)] + #[derive(Debug, Copy)] + pub struct FragmentOrElement_cycleCollection { + pub _base: root::nsXPCOMCycleCollectionParticipant, + } + #[test] + fn bindgen_test_layout_FragmentOrElement_cycleCollection() { + assert_eq!(::std::mem::size_of::<FragmentOrElement_cycleCollection>() + , 16usize); + assert_eq!(::std::mem::align_of::<FragmentOrElement_cycleCollection>() + , 8usize); + } + impl Clone for FragmentOrElement_cycleCollection { + fn clone(&self) -> Self { *self } + } + /** + * There are a set of DOM- and scripting-specific instance variables + * that may only be instantiated when a content object is accessed + * through the DOM. Rather than burn actual slots in the content + * objects for each of these instance variables, we put them off + * in a side structure that's only allocated when the content is + * accessed through the DOM. + */ + #[repr(C)] + #[derive(Debug)] + pub struct FragmentOrElement_nsDOMSlots { + pub _base: root::nsINode_nsSlots, + /** + * The .style attribute (an interface that forwards to the actual + * style rules) + * @see nsGenericHTMLElement::GetStyle + */ + pub mStyle: root::nsCOMPtr<root::nsICSSDeclaration>, + /** + * The .dataset attribute. + * @see nsGenericHTMLElement::GetDataset + */ + pub mDataset: *mut root::nsDOMStringMap, + /** + * SMIL Overridde style rules (for SMIL animation of CSS properties) + * @see nsIContent::GetSMILOverrideStyle + */ + pub mSMILOverrideStyle: root::nsCOMPtr<root::nsICSSDeclaration>, + /** + * Holds any SMIL override style declaration for this element. + */ + pub mSMILOverrideStyleDeclaration: root::RefPtr<root::mozilla::DeclarationBlock>, + /** + * An object implementing nsIDOMMozNamedAttrMap for this content (attributes) + * @see FragmentOrElement::GetAttributes + */ + pub mAttributeMap: root::RefPtr<root::nsDOMAttributeMap>, + pub __bindgen_anon_1: root::mozilla::dom::FragmentOrElement_nsDOMSlots__bindgen_ty_1, + /** + * An object implementing the .children property for this element. + */ + pub mChildrenList: root::RefPtr<root::nsContentList>, + /** + * An object implementing the .classList property for this element. + */ + pub mClassList: root::RefPtr<root::nsDOMTokenList>, + /** + * ShadowRoot bound to the element. + */ + pub mShadowRoot: root::RefPtr<root::mozilla::dom::ShadowRoot>, + /** + * The root ShadowRoot of this element if it is in a shadow tree. + */ + pub mContainingShadow: root::RefPtr<root::mozilla::dom::ShadowRoot>, + /** + * An array of web component insertion points to which this element + * is distributed. + */ + pub mDestInsertionPoints: root::nsTArray<*mut root::nsIContent>, + /** + * XBL binding installed on the element. + */ + pub mXBLBinding: root::RefPtr<root::nsXBLBinding>, + /** + * XBL binding installed on the lement. + */ + pub mXBLInsertionParent: root::nsCOMPtr<root::nsIContent>, + /** + * Web components custom element data. + */ + pub mCustomElementData: root::RefPtr<root::mozilla::dom::CustomElementData>, + /** + * Registered Intersection Observers on the element. + */ + pub mRegisteredIntersectionObservers: [u64; 5usize], + } + #[repr(C)] + #[derive(Debug, Copy)] + pub struct FragmentOrElement_nsDOMSlots__bindgen_ty_1 { + /** + * The nearest enclosing content node with a binding that created us. + * @see FragmentOrElement::GetBindingParent + */ + pub mBindingParent: root::__BindgenUnionField<*mut root::nsIContent>, + /** + * The controllers of the XUL Element. + */ + pub mControllers: root::__BindgenUnionField<*mut root::nsIControllers>, + pub bindgen_union_field: u64, + } + #[test] + fn bindgen_test_layout_FragmentOrElement_nsDOMSlots__bindgen_ty_1() { + assert_eq!(::std::mem::size_of::<FragmentOrElement_nsDOMSlots__bindgen_ty_1>() + , 8usize); + assert_eq!(::std::mem::align_of::<FragmentOrElement_nsDOMSlots__bindgen_ty_1>() + , 8usize); + } + impl Clone for FragmentOrElement_nsDOMSlots__bindgen_ty_1 { + fn clone(&self) -> Self { *self } + } + #[test] + fn bindgen_test_layout_FragmentOrElement_nsDOMSlots() { + assert_eq!(::std::mem::size_of::<FragmentOrElement_nsDOMSlots>() + , 200usize); + assert_eq!(::std::mem::align_of::<FragmentOrElement_nsDOMSlots>() + , 8usize); + } + extern "C" { + #[link_name = + "_ZN7mozilla3dom17FragmentOrElement21_cycleCollectorGlobalE"] + pub static mut FragmentOrElement__cycleCollectorGlobal: + root::mozilla::dom::FragmentOrElement_cycleCollection; + } + #[test] + fn bindgen_test_layout_FragmentOrElement() { + assert_eq!(::std::mem::size_of::<FragmentOrElement>() , + 112usize); + assert_eq!(::std::mem::align_of::<FragmentOrElement>() , + 8usize); + } + #[repr(C)] + #[derive(Debug)] pub struct DOMRect { pub _base: root::mozilla::dom::DOMRectReadOnly, pub _base_1: root::nsIDOMClientRect, @@ -2118,18 +2039,6 @@ pub mod root { , 8usize); } #[repr(C)] - #[derive(Debug)] - pub struct IntersectionCallback { - pub _base: root::mozilla::dom::CallbackFunction, - } - #[test] - fn bindgen_test_layout_IntersectionCallback() { - assert_eq!(::std::mem::size_of::<IntersectionCallback>() , - 48usize); - assert_eq!(::std::mem::align_of::<IntersectionCallback>() , - 8usize); - } - #[repr(C)] #[derive(Debug, Copy)] pub struct Grid { pub _address: u8, @@ -2146,6 +2055,62 @@ pub mod root { impl Clone for ShortcutKeyCandidate { fn clone(&self) -> Self { *self } } + /** + * Instances of this class represent moments in time, or a special + * "null" moment. We do not use the non-monotonic system clock or + * local time, since they can be reset, causing apparent backward + * travel in time, which can confuse algorithms. Instead we measure + * elapsed time according to the system. This time can never go + * backwards (i.e. it never wraps around, at least not in less than + * five million years of system elapsed time). It might not advance + * while the system is sleeping. If TimeStamp::SetNow() is not called + * at all for hours or days, we might not notice the passage of some + * of that time. + * + * We deliberately do not expose a way to convert TimeStamps to some + * particular unit. All you can do is compute a difference between two + * TimeStamps to get a TimeDuration. You can also add a TimeDuration + * to a TimeStamp to get a new TimeStamp. You can't do something + * meaningless like add two TimeStamps. + * + * Internally this is implemented as either a wrapper around + * - high-resolution, monotonic, system clocks if they exist on this + * platform + * - PRIntervalTime otherwise. We detect wraparounds of + * PRIntervalTime and work around them. + * + * This class is similar to C++11's time_point, however it is + * explicitly nullable and provides an IsNull() method. time_point + * is initialized to the clock's epoch and provides a + * time_since_epoch() method that functions similiarly. i.e. + * t.IsNull() is equivalent to t.time_since_epoch() == decltype(t)::duration::zero(); + */ + #[repr(C)] + #[derive(Debug, Copy)] + pub struct TimeStamp { + /** + * When built with PRIntervalTime, a value of 0 means this instance + * is "null". Otherwise, the low 32 bits represent a PRIntervalTime, + * and the high 32 bits represent a counter of the number of + * rollovers of PRIntervalTime that we've seen. This counter starts + * at 1 to avoid a real time colliding with the "null" value. + * + * PR_INTERVAL_MAX is set at 100,000 ticks per second. So the minimum + * time to wrap around is about 2^64/100000 seconds, i.e. about + * 5,849,424 years. + * + * When using a system clock, a value is system dependent. + */ + pub mValue: root::mozilla::TimeStampValue, + } + #[test] + fn bindgen_test_layout_TimeStamp() { + assert_eq!(::std::mem::size_of::<TimeStamp>() , 8usize); + assert_eq!(::std::mem::align_of::<TimeStamp>() , 8usize); + } + impl Clone for TimeStamp { + fn clone(&self) -> Self { *self } + } pub type TimeStampValue = u64; #[repr(C)] #[derive(Debug)] @@ -2209,6 +2174,27 @@ pub mod root { fn clone(&self) -> Self { *self } } #[repr(C)] + #[derive(Debug)] + pub struct URLValue { + pub _base: root::mozilla::css::URLValueData, + } + #[test] + fn bindgen_test_layout_URLValue() { + assert_eq!(::std::mem::size_of::<URLValue>() , 64usize); + assert_eq!(::std::mem::align_of::<URLValue>() , 8usize); + } + #[repr(C)] + #[derive(Debug)] + pub struct ImageValue { + pub _base: root::mozilla::css::URLValueData, + pub mRequests: [u64; 5usize], + } + #[test] + fn bindgen_test_layout_ImageValue() { + assert_eq!(::std::mem::size_of::<ImageValue>() , 104usize); + assert_eq!(::std::mem::align_of::<ImageValue>() , 8usize); + } + #[repr(C)] pub struct URLValueData__bindgen_vtable { } #[repr(C)] @@ -2233,27 +2219,6 @@ pub mod root { } #[repr(C)] #[derive(Debug)] - pub struct URLValue { - pub _base: root::mozilla::css::URLValueData, - } - #[test] - fn bindgen_test_layout_URLValue() { - assert_eq!(::std::mem::size_of::<URLValue>() , 64usize); - assert_eq!(::std::mem::align_of::<URLValue>() , 8usize); - } - #[repr(C)] - #[derive(Debug)] - pub struct ImageValue { - pub _base: root::mozilla::css::URLValueData, - pub mRequests: [u64; 5usize], - } - #[test] - fn bindgen_test_layout_ImageValue() { - assert_eq!(::std::mem::size_of::<ImageValue>() , 104usize); - assert_eq!(::std::mem::align_of::<ImageValue>() , 8usize); - } - #[repr(C)] - #[derive(Debug)] pub struct GridNamedArea { pub mName: ::nsstring::nsStringRepr, pub mColumnStart: u32, @@ -2388,6 +2353,14 @@ pub mod root { assert_eq!(::std::mem::size_of::<StyleSheet>() , 80usize); assert_eq!(::std::mem::align_of::<StyleSheet>() , 8usize); } + #[repr(u32)] + #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] + pub enum Side { + eSideTop = 0, + eSideRight = 1, + eSideBottom = 2, + eSideLeft = 3, + } #[repr(C)] #[derive(Debug, Copy)] pub struct SVGAttrAnimationRuleProcessor { @@ -2475,7 +2448,32 @@ pub mod root { } #[repr(i32)] #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] - pub enum SkipRootBehavior { Skip = 0, DontSkip = 1, } + pub enum ConsumeStyleBehavior { Consume = 0, DontConsume = 1, } + #[repr(i32)] + #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] + pub enum LazyComputeBehavior { Allow = 0, Assert = 1, } + #[repr(i32)] + #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] + pub enum TraversalRootBehavior { + Normal = 0, + UnstyledChildrenOnly = 1, + } + #[repr(u8)] + #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] + pub enum SheetType { + Agent = 0, + User = 1, + PresHint = 2, + SVGAttrAnimation = 3, + Doc = 4, + ScopedDoc = 5, + StyleAttr = 6, + Override = 7, + Animation = 8, + Transition = 9, + Count = 10, + Unknown = 255, + } pub mod a11y { #[allow(unused_imports)] use self::super::super::super::root; @@ -2582,13 +2580,6 @@ pub mod root { impl Clone for FramePropertyDescriptorUntyped { fn clone(&self) -> Self { *self } } - #[test] - fn __bindgen_test_layout_template_1() { - assert_eq!(::std::mem::size_of::<root::nsPtrHashKey<root::nsIFrame>>() - , 16usize); - assert_eq!(::std::mem::align_of::<root::nsPtrHashKey<root::nsIFrame>>() - , 8usize); - } /** * The FramePropertyTable is optimized for storing 0 or 1 properties on * a given frame. Storing very large numbers of properties on a single @@ -2758,6 +2749,9 @@ pub mod root { } #[repr(u8)] #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] + pub enum StyleShapeRadius { FarthestSide = 0, ClosestSide = 1, } + #[repr(u8)] + #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] pub enum StyleShapeSourceType { None = 0, URL = 1, @@ -2870,6 +2864,42 @@ pub mod root { pub struct HandleRefPtr<T> { pub mHandle: T, } + /** + * Smart pointer class that can hold a pointer to either a RestyleManager + * or a ServoRestyleManager. + */ + #[repr(C)] + #[derive(Debug, Copy)] + pub struct RestyleManagerHandle { + pub mPtr: root::mozilla::RestyleManagerHandle_Ptr, + } + pub type RestyleManagerHandle_RefPtr = + root::mozilla::HandleRefPtr<root::mozilla::RestyleManagerHandle>; + #[repr(C)] + #[derive(Debug, Copy)] + pub struct RestyleManagerHandle_Ptr { + pub mValue: usize, + } + #[test] + fn bindgen_test_layout_RestyleManagerHandle_Ptr() { + assert_eq!(::std::mem::size_of::<RestyleManagerHandle_Ptr>() , + 8usize); + assert_eq!(::std::mem::align_of::<RestyleManagerHandle_Ptr>() , + 8usize); + } + impl Clone for RestyleManagerHandle_Ptr { + fn clone(&self) -> Self { *self } + } + #[test] + fn bindgen_test_layout_RestyleManagerHandle() { + assert_eq!(::std::mem::size_of::<RestyleManagerHandle>() , + 8usize); + assert_eq!(::std::mem::align_of::<RestyleManagerHandle>() , + 8usize); + } + impl Clone for RestyleManagerHandle { + fn clone(&self) -> Self { *self } + } #[repr(C)] #[derive(Debug)] pub struct LangGroupFontPrefs { @@ -2999,7 +3029,7 @@ pub mod root { fn clone(&self) -> Self { *self } } #[test] - fn __bindgen_test_layout_template_2() { + fn __bindgen_test_layout_template_1() { assert_eq!(::std::mem::size_of::<root::mozilla::DefaultDelete<root::RawServoStyleSet>>() , 1usize); assert_eq!(::std::mem::align_of::<root::mozilla::DefaultDelete<root::RawServoStyleSet>>() @@ -3082,6 +3112,34 @@ pub mod root { impl Clone for ProgressTracker { fn clone(&self) -> Self { *self } } + #[repr(C)] + pub struct IProgressObserver__bindgen_vtable { + } + /** + * An interface for observing changes to image state, as reported by + * ProgressTracker. + * + * This is the ImageLib-internal version of imgINotificationObserver, + * essentially, with implementation details that code outside of ImageLib + * shouldn't see. + * + * XXX(seth): It's preferable to avoid adding anything to this interface if + * possible. In the long term, it would be ideal to get to a place where we can + * just use the imgINotificationObserver interface internally as well. + */ + #[repr(C)] + #[derive(Debug)] + pub struct IProgressObserver { + pub vtable_: *const IProgressObserver__bindgen_vtable, + pub _base: u64, + } + #[test] + fn bindgen_test_layout_IProgressObserver() { + assert_eq!(::std::mem::size_of::<IProgressObserver>() , + 16usize); + assert_eq!(::std::mem::align_of::<IProgressObserver>() , + 8usize); + } } #[repr(C)] #[derive(Debug, Copy)] @@ -3166,14 +3224,14 @@ pub mod root { pub type StyleShapeOutside = root::mozilla::StyleShapeSource<root::mozilla::StyleShapeOutsideShapeBox>; #[test] - fn __bindgen_test_layout_template_3() { + fn __bindgen_test_layout_template_2() { assert_eq!(::std::mem::size_of::<root::mozilla::StyleShapeSource<root::mozilla::StyleClipPathGeometryBox>>() , 16usize); assert_eq!(::std::mem::align_of::<root::mozilla::StyleShapeSource<root::mozilla::StyleClipPathGeometryBox>>() , 8usize); } #[test] - fn __bindgen_test_layout_template_4() { + fn __bindgen_test_layout_template_3() { assert_eq!(::std::mem::size_of::<root::mozilla::StyleShapeSource<root::mozilla::StyleShapeOutsideShapeBox>>() , 16usize); assert_eq!(::std::mem::align_of::<root::mozilla::StyleShapeSource<root::mozilla::StyleShapeOutsideShapeBox>>() @@ -3695,6 +3753,12 @@ pub mod root { NS_ERROR_DOM_MEDIA_CDM_ERR = 2154692621, NS_ERROR_DOM_MEDIA_NEED_NEW_DECODER = 2154692622, NS_ERROR_DOM_MEDIA_CUBEB_INITIALIZATION_ERR = 2154692709, + NS_ERROR_UC_UPDATE_UNKNOWN = 2154758145, + NS_ERROR_UC_UPDATE_DUPLICATE_PREFIX = 2154758146, + NS_ERROR_UC_UPDATE_INFINITE_LOOP = 2154758147, + NS_ERROR_UC_UPDATE_WRONG_REMOVAL_INDICES = 2154758148, + NS_ERROR_UC_UPDATE_CHECKSUM_MISMATCH = 2154758149, + NS_ERROR_UC_UPDATE_MISSING_CHECKSUM = 2154758150, NS_ERROR_DOWNLOAD_COMPLETE = 2155347969, NS_ERROR_DOWNLOAD_NOT_PARTIAL = 2155347970, NS_ERROR_UNORM_MOREOUTPUT = 2155348001, @@ -3796,12 +3860,6 @@ pub mod root { 8usize); } } - #[repr(C)] - #[derive(Debug, Copy, Clone)] - pub struct HeapBase<T> { - pub _address: u8, - pub _phantom_0: ::std::marker::PhantomData<T>, - } /** * The Heap<T> class is a heap-stored reference to a JS GC thing. All members of * heap classes that refer to GC things should use Heap<T> (or possibly @@ -3826,6 +3884,7 @@ pub mod root { pub struct Heap<T> { pub ptr: T, } + pub type Heap_ElementType<T> = T; /** * The TenuredHeap<T> class is similar to the Heap<T> class above in that it * encapsulates the GC concerns of an on-heap reference to a JS object. However, @@ -3861,15 +3920,16 @@ pub mod root { pub bits: usize, pub _phantom_0: ::std::marker::PhantomData<T>, } + pub type TenuredHeap_ElementType<T> = T; pub const TenuredHeap_maskBits: root::JS::TenuredHeap__bindgen_ty_1 = TenuredHeap__bindgen_ty_1::maskBits; - pub const flagsMask: root::JS::TenuredHeap__bindgen_ty_1 = + pub const TenuredHeap_flagsMask: root::JS::TenuredHeap__bindgen_ty_1 = TenuredHeap__bindgen_ty_1::maskBits; #[repr(i32)] #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] pub enum TenuredHeap__bindgen_ty_1 { maskBits = 0, } #[test] - fn __bindgen_test_layout_template_5() { + fn __bindgen_test_layout_template_4() { assert_eq!(::std::mem::size_of::<root::mozilla::UniquePtr<*mut ::std::os::raw::c_char, root::JS::FreePolicy>>() , 8usize); @@ -3894,6 +3954,12 @@ pub mod root { use self::super::super::super::root; } #[repr(C)] + #[derive(Debug, Copy, Clone)] + pub struct HeapBase<T> { + pub _address: u8, + pub _phantom_0: ::std::marker::PhantomData<T>, + } + #[repr(C)] pub struct SourceHook__bindgen_vtable { } /** @@ -4244,13 +4310,13 @@ pub mod root { pub _phantom_0: ::std::marker::PhantomData<CharT>, } #[test] - fn __bindgen_test_layout_template_6() { + fn __bindgen_test_layout_template_5() { assert_eq!(::std::mem::size_of::<root::nsCharTraits<u16>>() , 1usize); assert_eq!(::std::mem::align_of::<root::nsCharTraits<u16>>() , 1usize); } #[test] - fn __bindgen_test_layout_template_7() { + fn __bindgen_test_layout_template_6() { assert_eq!(::std::mem::size_of::<root::nsCharTraits<::std::os::raw::c_char>>() , 1usize); assert_eq!(::std::mem::align_of::<root::nsCharTraits<::std::os::raw::c_char>>() @@ -4384,10 +4450,7 @@ pub mod root { pub struct nsAutoRefCnt { pub mValue: root::nsrefcnt, } - extern "C" { - #[link_name = "_ZN12nsAutoRefCnt12isThreadSafeE"] - pub static nsAutoRefCnt_isThreadSafe: bool; - } + pub const nsAutoRefCnt_isThreadSafe: bool = false; #[test] fn bindgen_test_layout_nsAutoRefCnt() { assert_eq!(::std::mem::size_of::<nsAutoRefCnt>() , 8usize); @@ -4445,6 +4508,13 @@ pub mod root { ((val as u32 as u32) << 31u32) & (2147483648usize as u32); } } + #[repr(C)] + #[derive(Debug)] + pub struct nsCOMPtr<T> { + pub _base: root::nsCOMPtr_base, + pub _phantom_0: ::std::marker::PhantomData<T>, + } + pub type nsCOMPtr_element_type<T> = T; /** * Factors implementation for all template versions of nsCOMPtr. * @@ -4459,15 +4529,8 @@ pub mod root { pub struct nsCOMPtr_base { pub mRawPtr: *mut root::nsISupports, } - #[repr(C)] - #[derive(Debug)] - pub struct nsCOMPtr<T> { - pub _base: root::nsCOMPtr_base, - pub _phantom_0: ::std::marker::PhantomData<T>, - } - pub type nsCOMPtr_element_type<T> = T; #[test] - fn __bindgen_test_layout_template_8() { + fn __bindgen_test_layout_template_7() { assert_eq!(::std::mem::size_of::<root::nsCOMPtr<root::nsISupports>>() , 8usize); assert_eq!(::std::mem::align_of::<root::nsCOMPtr<root::nsISupports>>() @@ -4575,26 +4638,6 @@ pub mod root { } #[repr(C)] #[derive(Debug, Copy)] - pub struct nsISerializable { - pub _base: root::nsISupports, - } - #[repr(C)] - #[derive(Debug, Copy, Clone)] - pub struct nsISerializable_COMTypeInfo<T, U> { - pub _address: u8, - pub _phantom_0: ::std::marker::PhantomData<T>, - pub _phantom_1: ::std::marker::PhantomData<U>, - } - #[test] - fn bindgen_test_layout_nsISerializable() { - assert_eq!(::std::mem::size_of::<nsISerializable>() , 8usize); - assert_eq!(::std::mem::align_of::<nsISerializable>() , 8usize); - } - impl Clone for nsISerializable { - fn clone(&self) -> Self { *self } - } - #[repr(C)] - #[derive(Debug, Copy)] pub struct nsIPrincipal { pub _base: root::nsISerializable, } @@ -4803,364 +4846,61 @@ pub mod root { } #[repr(C)] #[derive(Debug, Copy)] - pub struct nsIURI { + pub struct nsISerializable { pub _base: root::nsISupports, } #[repr(C)] #[derive(Debug, Copy, Clone)] - pub struct nsIURI_COMTypeInfo<T, U> { + pub struct nsISerializable_COMTypeInfo<T, U> { pub _address: u8, pub _phantom_0: ::std::marker::PhantomData<T>, pub _phantom_1: ::std::marker::PhantomData<U>, } #[test] - fn bindgen_test_layout_nsIURI() { - assert_eq!(::std::mem::size_of::<nsIURI>() , 8usize); - assert_eq!(::std::mem::align_of::<nsIURI>() , 8usize); + fn bindgen_test_layout_nsISerializable() { + assert_eq!(::std::mem::size_of::<nsISerializable>() , 8usize); + assert_eq!(::std::mem::align_of::<nsISerializable>() , 8usize); } - impl Clone for nsIURI { + impl Clone for nsISerializable { fn clone(&self) -> Self { *self } } - #[test] - fn __bindgen_test_layout_template_9() { - assert_eq!(::std::mem::size_of::<[u64; 28usize]>() , 224usize); - assert_eq!(::std::mem::align_of::<[u64; 28usize]>() , 8usize); - } - #[repr(C)] - #[derive(Debug)] - pub struct nsPIDOMWindowInner { - pub _base: [u64; 28usize], - } - #[repr(C)] - #[derive(Debug, Copy, Clone)] - pub struct nsPIDOMWindowInner_COMTypeInfo<T, U> { - pub _address: u8, - pub _phantom_0: ::std::marker::PhantomData<T>, - pub _phantom_1: ::std::marker::PhantomData<U>, - } - #[test] - fn bindgen_test_layout_nsPIDOMWindowInner() { - assert_eq!(::std::mem::size_of::<nsPIDOMWindowInner>() , 224usize); - assert_eq!(::std::mem::align_of::<nsPIDOMWindowInner>() , 8usize); - } #[repr(C)] #[derive(Debug, Copy)] - pub struct nsIDOMEventTarget { + pub struct nsIURI { pub _base: root::nsISupports, } #[repr(C)] #[derive(Debug, Copy, Clone)] - pub struct nsIDOMEventTarget_COMTypeInfo<T, U> { + pub struct nsIURI_COMTypeInfo<T, U> { pub _address: u8, pub _phantom_0: ::std::marker::PhantomData<T>, pub _phantom_1: ::std::marker::PhantomData<U>, } #[test] - fn bindgen_test_layout_nsIDOMEventTarget() { - assert_eq!(::std::mem::size_of::<nsIDOMEventTarget>() , 8usize); - assert_eq!(::std::mem::align_of::<nsIDOMEventTarget>() , 8usize); + fn bindgen_test_layout_nsIURI() { + assert_eq!(::std::mem::size_of::<nsIURI>() , 8usize); + assert_eq!(::std::mem::align_of::<nsIURI>() , 8usize); } - impl Clone for nsIDOMEventTarget { + impl Clone for nsIURI { fn clone(&self) -> Self { *self } } #[repr(C)] #[derive(Debug)] - pub struct EventTarget { - pub _base: root::nsIDOMEventTarget, - pub _base_1: root::nsWrapperCache, - } - #[repr(C)] - #[derive(Debug, Copy, Clone)] - pub struct EventTarget_COMTypeInfo<T, U> { - pub _address: u8, - pub _phantom_0: ::std::marker::PhantomData<T>, - pub _phantom_1: ::std::marker::PhantomData<U>, - } - #[test] - fn bindgen_test_layout_EventTarget() { - assert_eq!(::std::mem::size_of::<EventTarget>() , 32usize); - assert_eq!(::std::mem::align_of::<EventTarget>() , 8usize); + pub struct nsPIDOMWindowInner { + pub _base: [u64; 28usize], } - /** - * An internal interface that abstracts some DOMNode-related parts that both - * nsIContent and nsIDocument share. An instance of this interface has a list - * of nsIContent children and provides access to them. - */ - #[repr(C)] - #[derive(Debug)] - pub struct nsINode { - pub _base: root::EventTarget, - pub mNodeInfo: root::RefPtr<root::mozilla::dom::NodeInfo>, - pub mParent: *mut root::nsINode, - pub mBoolFlags: u32, - pub mNextSibling: *mut root::nsIContent, - pub mPreviousSibling: *mut root::nsIContent, - pub mFirstChild: *mut root::nsIContent, - pub __bindgen_anon_1: root::nsINode__bindgen_ty_1, - pub mSlots: *mut root::nsINode_nsSlots, - } - pub type nsINode_BoxQuadOptions = root::mozilla::dom::BoxQuadOptions; - pub type nsINode_ConvertCoordinateOptions = - root::mozilla::dom::ConvertCoordinateOptions; - pub type nsINode_DOMPoint = root::mozilla::dom::DOMPoint; - pub type nsINode_DOMPointInit = root::mozilla::dom::DOMPointInit; - pub type nsINode_DOMQuad = root::mozilla::dom::DOMQuad; - pub type nsINode_DOMRectReadOnly = root::mozilla::dom::DOMRectReadOnly; - pub type nsINode_OwningNodeOrString = - root::mozilla::dom::OwningNodeOrString; - pub type nsINode_TextOrElementOrDocument = - root::mozilla::dom::TextOrElementOrDocument; - pub type nsINode_ErrorResult = [u64; 2usize]; #[repr(C)] #[derive(Debug, Copy, Clone)] - pub struct nsINode_COMTypeInfo<T, U> { + pub struct nsPIDOMWindowInner_COMTypeInfo<T, U> { pub _address: u8, pub _phantom_0: ::std::marker::PhantomData<T>, pub _phantom_1: ::std::marker::PhantomData<U>, } - pub const nsINode_eCONTENT: root::nsINode__bindgen_ty_2 = - nsINode__bindgen_ty_2::eCONTENT; - pub const nsINode_eDOCUMENT: root::nsINode__bindgen_ty_2 = - nsINode__bindgen_ty_2::eDOCUMENT; - pub const nsINode_eATTRIBUTE: root::nsINode__bindgen_ty_2 = - nsINode__bindgen_ty_2::eATTRIBUTE; - pub const nsINode_eTEXT: root::nsINode__bindgen_ty_2 = - nsINode__bindgen_ty_2::eTEXT; - pub const nsINode_ePROCESSING_INSTRUCTION: root::nsINode__bindgen_ty_2 = - nsINode__bindgen_ty_2::ePROCESSING_INSTRUCTION; - pub const nsINode_eCOMMENT: root::nsINode__bindgen_ty_2 = - nsINode__bindgen_ty_2::eCOMMENT; - pub const nsINode_eHTML_FORM_CONTROL: root::nsINode__bindgen_ty_2 = - nsINode__bindgen_ty_2::eHTML_FORM_CONTROL; - pub const nsINode_eDOCUMENT_FRAGMENT: root::nsINode__bindgen_ty_2 = - nsINode__bindgen_ty_2::eDOCUMENT_FRAGMENT; - pub const nsINode_eDATA_NODE: root::nsINode__bindgen_ty_2 = - nsINode__bindgen_ty_2::eDATA_NODE; - pub const nsINode_eMEDIA: root::nsINode__bindgen_ty_2 = - nsINode__bindgen_ty_2::eMEDIA; - pub const nsINode_eANIMATION: root::nsINode__bindgen_ty_2 = - nsINode__bindgen_ty_2::eANIMATION; - pub const nsINode_eFILTER: root::nsINode__bindgen_ty_2 = - nsINode__bindgen_ty_2::eFILTER; - #[repr(u32)] - /** - * Bit-flags to pass (or'ed together) to IsNodeOfType() - */ - #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] - pub enum nsINode__bindgen_ty_2 { - eCONTENT = 1, - eDOCUMENT = 2, - eATTRIBUTE = 4, - eTEXT = 8, - ePROCESSING_INSTRUCTION = 16, - eCOMMENT = 32, - eHTML_FORM_CONTROL = 64, - eDOCUMENT_FRAGMENT = 128, - eDATA_NODE = 256, - eMEDIA = 512, - eANIMATION = 1024, - eFILTER = 2048, - } - #[repr(C)] - pub struct nsINode_nsSlots__bindgen_vtable { - } - #[repr(C)] - #[derive(Debug)] - pub struct nsINode_nsSlots { - pub vtable_: *const nsINode_nsSlots__bindgen_vtable, - /** - * A list of mutation observers - */ - pub mMutationObservers: [u64; 2usize], - /** - * An object implementing nsIDOMNodeList for this content (childNodes) - * @see nsIDOMNodeList - * @see nsGenericHTMLElement::GetChildNodes - */ - pub mChildNodes: root::RefPtr<root::nsChildContentList>, - /** - * Weak reference to this node. This is cleared by the destructor of - * nsNodeWeakReference. - */ - pub mWeakReference: *mut root::nsNodeWeakReference, - /** - * Number of descendant nodes in the uncomposed document that have been - * explicitly set as editable. - */ - pub mEditableDescendantCount: u32, - } - #[test] - fn bindgen_test_layout_nsINode_nsSlots() { - assert_eq!(::std::mem::size_of::<nsINode_nsSlots>() , 48usize); - assert_eq!(::std::mem::align_of::<nsINode_nsSlots>() , 8usize); - } - #[repr(u32)] - /** - * Boolean flags - */ - #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] - pub enum nsINode_BooleanFlag { - NodeHasRenderingObservers = 0, - IsInDocument = 1, - ParentIsContent = 2, - NodeIsElement = 3, - ElementHasID = 4, - ElementMayHaveStyle = 5, - ElementHasName = 6, - ElementMayHaveContentEditableAttr = 7, - NodeIsCommonAncestorForRangeInSelection = 8, - NodeIsDescendantOfCommonAncestorForRangeInSelection = 9, - NodeIsCCMarkedRoot = 10, - NodeIsCCBlackTree = 11, - NodeIsPurpleRoot = 12, - NodeHasExplicitBaseURI = 13, - ElementHasLockedStyleStates = 14, - ElementHasPointerLock = 15, - NodeMayHaveDOMMutationObserver = 16, - NodeIsContent = 17, - ElementHasAnimations = 18, - NodeHasValidDirAttribute = 19, - NodeHasFixedDir = 20, - NodeHasDirAutoSet = 21, - NodeHasTextNodeDirectionalityMap = 22, - NodeHasDirAuto = 23, - NodeAncestorHasDirAuto = 24, - ElementIsInStyleScope = 25, - ElementIsScopedStyleRoot = 26, - NodeHandlingClick = 27, - NodeHasRelevantHoverRules = 28, - ElementHasWeirdParserInsertionMode = 29, - ParserHasNotified = 30, - MayBeApzAware = 31, - BooleanFlagCount = 32, - } - #[repr(C)] - #[derive(Debug, Copy)] - pub struct nsINode__bindgen_ty_1 { - pub mPrimaryFrame: root::__BindgenUnionField<*mut root::nsIFrame>, - pub mSubtreeRoot: root::__BindgenUnionField<*mut root::nsINode>, - pub bindgen_union_field: u64, - } - #[test] - fn bindgen_test_layout_nsINode__bindgen_ty_1() { - assert_eq!(::std::mem::size_of::<nsINode__bindgen_ty_1>() , 8usize); - assert_eq!(::std::mem::align_of::<nsINode__bindgen_ty_1>() , 8usize); - } - impl Clone for nsINode__bindgen_ty_1 { - fn clone(&self) -> Self { *self } - } - #[test] - fn bindgen_test_layout_nsINode() { - assert_eq!(::std::mem::size_of::<nsINode>() , 96usize); - assert_eq!(::std::mem::align_of::<nsINode>() , 8usize); - } - #[repr(u8)] - /** - * Enumeration that represents one of the two supported style system backends. - */ - #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] - pub enum StyleBackendType { Gecko = 1, Servo = 2, } - #[repr(i32)] - #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] - pub enum ConsumeStyleBehavior { Consume = 0, DontConsume = 1, } - #[repr(i32)] - #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] - pub enum LazyComputeBehavior { Allow = 0, Assert = 1, } - #[repr(u8)] - #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] - pub enum SheetType { - Agent = 0, - User = 1, - PresHint = 2, - SVGAttrAnimation = 3, - Doc = 4, - ScopedDoc = 5, - StyleAttr = 6, - Override = 7, - Animation = 8, - Transition = 9, - Count = 10, - Unknown = 255, - } - /** - * EventStates is the class used to represent the event states of nsIContent - * instances. These states are calculated by IntrinsicState() and - * ContentStatesChanged() has to be called when one of them changes thus - * informing the layout/style engine of the change. - * Event states are associated with pseudo-classes. - */ - #[repr(C)] - #[derive(Debug, Copy)] - pub struct EventStates { - pub mStates: root::EventStates_InternalType, - } - pub type EventStates_InternalType = u64; - pub type EventStates_ServoType = u8; #[test] - fn bindgen_test_layout_EventStates() { - assert_eq!(::std::mem::size_of::<EventStates>() , 8usize); - assert_eq!(::std::mem::align_of::<EventStates>() , 8usize); - } - impl Clone for EventStates { - fn clone(&self) -> Self { *self } - } - pub const nsRestyleHint_eRestyle_Self: root::nsRestyleHint = - nsRestyleHint(1); - pub const nsRestyleHint_eRestyle_SomeDescendants: root::nsRestyleHint = - nsRestyleHint(2); - pub const nsRestyleHint_eRestyle_Subtree: root::nsRestyleHint = - nsRestyleHint(4); - pub const nsRestyleHint_eRestyle_LaterSiblings: root::nsRestyleHint = - nsRestyleHint(8); - pub const nsRestyleHint_eRestyle_CSSTransitions: root::nsRestyleHint = - nsRestyleHint(16); - pub const nsRestyleHint_eRestyle_CSSAnimations: root::nsRestyleHint = - nsRestyleHint(32); - pub const nsRestyleHint_eRestyle_SVGAttrAnimations: root::nsRestyleHint = - nsRestyleHint(64); - pub const nsRestyleHint_eRestyle_StyleAttribute: root::nsRestyleHint = - nsRestyleHint(128); - pub const nsRestyleHint_eRestyle_StyleAttribute_Animations: - root::nsRestyleHint = - nsRestyleHint(256); - pub const nsRestyleHint_eRestyle_Force: root::nsRestyleHint = - nsRestyleHint(512); - pub const nsRestyleHint_eRestyle_ForceDescendants: root::nsRestyleHint = - nsRestyleHint(1024); - pub const nsRestyleHint_eRestyle_AllHintsWithAnimations: - root::nsRestyleHint = - nsRestyleHint(368); - impl ::std::ops::BitOr<root::nsRestyleHint> for root::nsRestyleHint { - type - Output - = - Self; - #[inline] - fn bitor(self, other: Self) -> Self { - nsRestyleHint(self.0 | other.0) - } + fn bindgen_test_layout_nsPIDOMWindowInner() { + assert_eq!(::std::mem::size_of::<nsPIDOMWindowInner>() , 224usize); + assert_eq!(::std::mem::align_of::<nsPIDOMWindowInner>() , 8usize); } - #[repr(C)] - /** - * |nsRestyleHint| is a bitfield for the result of - * |HasStateDependentStyle| and |HasAttributeDependentStyle|. When no - * restyling is necessary, use |nsRestyleHint(0)|. - * - * Without eRestyle_Force or eRestyle_ForceDescendants, the restyling process - * can stop processing at a frame when it detects no style changes and it is - * known that the styles of the subtree beneath it will not change, leaving - * the old style context on the frame. eRestyle_Force can be used to skip this - * optimization on a frame, and to force its new style context to be used. - * - * Similarly, eRestyle_ForceDescendants will cause the frame and all of its - * descendants to be traversed and for the new style contexts that are created - * to be set on the frames. - * - * NOTE: When adding new restyle hints, please also add them to - * RestyleManager::RestyleHintToString. - */ - #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] - pub struct nsRestyleHint(pub u32); /** * Smart pointer class that can hold a pointer to either an nsStyleSet * or a ServoStyleSet. @@ -5192,96 +4932,27 @@ pub mod root { fn clone(&self) -> Self { *self } } /** - * Instances of this class represent moments in time, or a special - * "null" moment. We do not use the non-monotonic system clock or - * local time, since they can be reset, causing apparent backward - * travel in time, which can confuse algorithms. Instead we measure - * elapsed time according to the system. This time can never go - * backwards (i.e. it never wraps around, at least not in less than - * five million years of system elapsed time). It might not advance - * while the system is sleeping. If TimeStamp::SetNow() is not called - * at all for hours or days, we might not notice the passage of some - * of that time. - * - * We deliberately do not expose a way to convert TimeStamps to some - * particular unit. All you can do is compute a difference between two - * TimeStamps to get a TimeDuration. You can also add a TimeDuration - * to a TimeStamp to get a new TimeStamp. You can't do something - * meaningless like add two TimeStamps. - * - * Internally this is implemented as either a wrapper around - * - high-resolution, monotonic, system clocks if they exist on this - * platform - * - PRIntervalTime otherwise. We detect wraparounds of - * PRIntervalTime and work around them. - * - * This class is similar to C++11's time_point, however it is - * explicitly nullable and provides an IsNull() method. time_point - * is initialized to the clock's epoch and provides a - * time_since_epoch() method that functions similiarly. i.e. - * t.IsNull() is equivalent to t.time_since_epoch() == decltype(t)::duration::zero(); + * EventStates is the class used to represent the event states of nsIContent + * instances. These states are calculated by IntrinsicState() and + * ContentStatesChanged() has to be called when one of them changes thus + * informing the layout/style engine of the change. + * Event states are associated with pseudo-classes. */ #[repr(C)] #[derive(Debug, Copy)] - pub struct TimeStamp { - /** - * When built with PRIntervalTime, a value of 0 means this instance - * is "null". Otherwise, the low 32 bits represent a PRIntervalTime, - * and the high 32 bits represent a counter of the number of - * rollovers of PRIntervalTime that we've seen. This counter starts - * at 1 to avoid a real time colliding with the "null" value. - * - * PR_INTERVAL_MAX is set at 100,000 ticks per second. So the minimum - * time to wrap around is about 2^64/100000 seconds, i.e. about - * 5,849,424 years. - * - * When using a system clock, a value is system dependent. - */ - pub mValue: root::mozilla::TimeStampValue, - } - #[test] - fn bindgen_test_layout_TimeStamp() { - assert_eq!(::std::mem::size_of::<TimeStamp>() , 8usize); - assert_eq!(::std::mem::align_of::<TimeStamp>() , 8usize); - } - impl Clone for TimeStamp { - fn clone(&self) -> Self { *self } - } - #[repr(C)] - #[derive(Debug, Copy)] - pub struct nsIObserver { - pub _base: root::nsISupports, - } - #[repr(C)] - #[derive(Debug, Copy, Clone)] - pub struct nsIObserver_COMTypeInfo<T, U> { - pub _address: u8, - pub _phantom_0: ::std::marker::PhantomData<T>, - pub _phantom_1: ::std::marker::PhantomData<U>, + pub struct EventStates { + pub mStates: root::EventStates_InternalType, } + pub type EventStates_InternalType = u64; + pub type EventStates_ServoType = u8; #[test] - fn bindgen_test_layout_nsIObserver() { - assert_eq!(::std::mem::size_of::<nsIObserver>() , 8usize); - assert_eq!(::std::mem::align_of::<nsIObserver>() , 8usize); + fn bindgen_test_layout_EventStates() { + assert_eq!(::std::mem::size_of::<EventStates>() , 8usize); + assert_eq!(::std::mem::align_of::<EventStates>() , 8usize); } - impl Clone for nsIObserver { + impl Clone for EventStates { fn clone(&self) -> Self { *self } } - #[repr(u32)] - #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] - pub enum nsCompatibility { - eCompatibility_FullStandards = 1, - eCompatibility_AlmostStandards = 2, - eCompatibility_NavQuirks = 3, - } - #[repr(u32)] - #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] - pub enum VisibilityState { - Hidden = 0, - Visible = 1, - Prerender = 2, - EndGuard_ = 3, - } #[repr(C)] #[derive(Debug)] pub struct nsIDocument { @@ -5327,7 +4998,7 @@ pub mod root { pub mCompatMode: root::nsCompatibility, pub mReadyState: root::nsIDocument_ReadyState, pub mStyleBackendType: root::StyleBackendType, - pub mVisibilityState: root::VisibilityState, + pub mVisibilityState: root::mozilla::dom::VisibilityState, pub _bitfield_1: u64, pub mType: root::nsIDocument_Type, pub mDefaultElementType: u8, @@ -5378,7 +5049,7 @@ pub mod root { pub mChildDocumentUseCounters: [u64; 2usize], pub mNotifiedPageForUseCounter: [u64; 2usize], pub mUserHasInteracted: bool, - pub mPageUnloadingEventTimeStamp: root::TimeStamp, + pub mPageUnloadingEventTimeStamp: root::mozilla::TimeStamp, pub mDocGroup: root::RefPtr<root::mozilla::dom::DocGroup>, pub mTrackingScripts: [u64; 5usize], } @@ -6244,6 +5915,26 @@ pub mod root { } #[repr(C)] #[derive(Debug, Copy)] + pub struct nsIObserver { + pub _base: root::nsISupports, + } + #[repr(C)] + #[derive(Debug, Copy, Clone)] + pub struct nsIObserver_COMTypeInfo<T, U> { + pub _address: u8, + pub _phantom_0: ::std::marker::PhantomData<T>, + pub _phantom_1: ::std::marker::PhantomData<U>, + } + #[test] + fn bindgen_test_layout_nsIObserver() { + assert_eq!(::std::mem::size_of::<nsIObserver>() , 8usize); + assert_eq!(::std::mem::align_of::<nsIObserver>() , 8usize); + } + impl Clone for nsIObserver { + fn clone(&self) -> Self { *self } + } + #[repr(C)] + #[derive(Debug, Copy)] pub struct nsIVariant { pub _base: root::nsISupports, } @@ -6285,6 +5976,26 @@ pub mod root { pub type DOMHighResTimeStamp = f64; #[repr(C)] #[derive(Debug, Copy)] + pub struct nsIDOMAttr { + pub _base: root::nsIDOMNode, + } + #[repr(C)] + #[derive(Debug, Copy, Clone)] + pub struct nsIDOMAttr_COMTypeInfo<T, U> { + pub _address: u8, + pub _phantom_0: ::std::marker::PhantomData<T>, + pub _phantom_1: ::std::marker::PhantomData<U>, + } + #[test] + fn bindgen_test_layout_nsIDOMAttr() { + assert_eq!(::std::mem::size_of::<nsIDOMAttr>() , 8usize); + assert_eq!(::std::mem::align_of::<nsIDOMAttr>() , 8usize); + } + impl Clone for nsIDOMAttr { + fn clone(&self) -> Self { *self } + } + #[repr(C)] + #[derive(Debug, Copy)] pub struct nsIDOMNode { pub _base: root::nsISupports, } @@ -6376,62 +6087,62 @@ pub mod root { } #[repr(C)] #[derive(Debug, Copy)] - pub struct nsIDOMAttr { - pub _base: root::nsIDOMNode, + pub struct nsIDOMClientRect { + pub _base: root::nsISupports, } #[repr(C)] #[derive(Debug, Copy, Clone)] - pub struct nsIDOMAttr_COMTypeInfo<T, U> { + pub struct nsIDOMClientRect_COMTypeInfo<T, U> { pub _address: u8, pub _phantom_0: ::std::marker::PhantomData<T>, pub _phantom_1: ::std::marker::PhantomData<U>, } #[test] - fn bindgen_test_layout_nsIDOMAttr() { - assert_eq!(::std::mem::size_of::<nsIDOMAttr>() , 8usize); - assert_eq!(::std::mem::align_of::<nsIDOMAttr>() , 8usize); + fn bindgen_test_layout_nsIDOMClientRect() { + assert_eq!(::std::mem::size_of::<nsIDOMClientRect>() , 8usize); + assert_eq!(::std::mem::align_of::<nsIDOMClientRect>() , 8usize); } - impl Clone for nsIDOMAttr { + impl Clone for nsIDOMClientRect { fn clone(&self) -> Self { *self } } #[repr(C)] #[derive(Debug, Copy)] - pub struct nsIDOMClientRect { + pub struct nsIDOMStyleSheet { pub _base: root::nsISupports, } #[repr(C)] #[derive(Debug, Copy, Clone)] - pub struct nsIDOMClientRect_COMTypeInfo<T, U> { + pub struct nsIDOMStyleSheet_COMTypeInfo<T, U> { pub _address: u8, pub _phantom_0: ::std::marker::PhantomData<T>, pub _phantom_1: ::std::marker::PhantomData<U>, } #[test] - fn bindgen_test_layout_nsIDOMClientRect() { - assert_eq!(::std::mem::size_of::<nsIDOMClientRect>() , 8usize); - assert_eq!(::std::mem::align_of::<nsIDOMClientRect>() , 8usize); + fn bindgen_test_layout_nsIDOMStyleSheet() { + assert_eq!(::std::mem::size_of::<nsIDOMStyleSheet>() , 8usize); + assert_eq!(::std::mem::align_of::<nsIDOMStyleSheet>() , 8usize); } - impl Clone for nsIDOMClientRect { + impl Clone for nsIDOMStyleSheet { fn clone(&self) -> Self { *self } } #[repr(C)] #[derive(Debug, Copy)] - pub struct nsIDOMStyleSheet { + pub struct nsIDOMEventTarget { pub _base: root::nsISupports, } #[repr(C)] #[derive(Debug, Copy, Clone)] - pub struct nsIDOMStyleSheet_COMTypeInfo<T, U> { + pub struct nsIDOMEventTarget_COMTypeInfo<T, U> { pub _address: u8, pub _phantom_0: ::std::marker::PhantomData<T>, pub _phantom_1: ::std::marker::PhantomData<U>, } #[test] - fn bindgen_test_layout_nsIDOMStyleSheet() { - assert_eq!(::std::mem::size_of::<nsIDOMStyleSheet>() , 8usize); - assert_eq!(::std::mem::align_of::<nsIDOMStyleSheet>() , 8usize); + fn bindgen_test_layout_nsIDOMEventTarget() { + assert_eq!(::std::mem::size_of::<nsIDOMEventTarget>() , 8usize); + assert_eq!(::std::mem::align_of::<nsIDOMEventTarget>() , 8usize); } - impl Clone for nsIDOMStyleSheet { + impl Clone for nsIDOMEventTarget { fn clone(&self) -> Self { *self } } #[repr(C)] @@ -6482,11 +6193,12 @@ pub mod root { impl Clone for nsIControllers { fn clone(&self) -> Self { *self } } - #[test] - fn __bindgen_test_layout_template_10() { - assert_eq!(::std::mem::size_of::<u64>() , 8usize); - assert_eq!(::std::mem::align_of::<u64>() , 8usize); - } + #[repr(u8)] + /** + * Enumeration that represents one of the two supported style system backends. + */ + #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] + pub enum StyleBackendType { Gecko = 1, Servo = 2, } pub const nsChangeHint_nsChangeHint_Empty: root::nsChangeHint = nsChangeHint(0); pub const nsChangeHint_nsChangeHint_RepaintFrame: root::nsChangeHint = @@ -6575,49 +6287,71 @@ pub mod root { #[repr(C)] #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] pub struct nsChangeHint(pub u32); - /** - * Smart pointer class that can hold a pointer to either a RestyleManager - * or a ServoRestyleManager. - */ - #[repr(C)] - #[derive(Debug, Copy)] - pub struct RestyleManagerHandle { - pub mPtr: root::RestyleManagerHandle_Ptr, + pub const nsRestyleHint_eRestyle_Self: root::nsRestyleHint = + nsRestyleHint(1); + pub const nsRestyleHint_eRestyle_SomeDescendants: root::nsRestyleHint = + nsRestyleHint(2); + pub const nsRestyleHint_eRestyle_Subtree: root::nsRestyleHint = + nsRestyleHint(4); + pub const nsRestyleHint_eRestyle_LaterSiblings: root::nsRestyleHint = + nsRestyleHint(8); + pub const nsRestyleHint_eRestyle_CSSTransitions: root::nsRestyleHint = + nsRestyleHint(16); + pub const nsRestyleHint_eRestyle_CSSAnimations: root::nsRestyleHint = + nsRestyleHint(32); + pub const nsRestyleHint_eRestyle_SVGAttrAnimations: root::nsRestyleHint = + nsRestyleHint(64); + pub const nsRestyleHint_eRestyle_StyleAttribute: root::nsRestyleHint = + nsRestyleHint(128); + pub const nsRestyleHint_eRestyle_StyleAttribute_Animations: + root::nsRestyleHint = + nsRestyleHint(256); + pub const nsRestyleHint_eRestyle_Force: root::nsRestyleHint = + nsRestyleHint(512); + pub const nsRestyleHint_eRestyle_ForceDescendants: root::nsRestyleHint = + nsRestyleHint(1024); + pub const nsRestyleHint_eRestyle_AllHintsWithAnimations: + root::nsRestyleHint = + nsRestyleHint(368); + impl ::std::ops::BitOr<root::nsRestyleHint> for root::nsRestyleHint { + type + Output + = + Self; + #[inline] + fn bitor(self, other: Self) -> Self { + nsRestyleHint(self.0 | other.0) + } } - pub type RestyleManagerHandle_RefPtr = - root::mozilla::HandleRefPtr<root::RestyleManagerHandle>; #[repr(C)] - #[derive(Debug, Copy)] - pub struct RestyleManagerHandle_Ptr { - pub mValue: usize, - } - #[test] - fn bindgen_test_layout_RestyleManagerHandle_Ptr() { - assert_eq!(::std::mem::size_of::<RestyleManagerHandle_Ptr>() , - 8usize); - assert_eq!(::std::mem::align_of::<RestyleManagerHandle_Ptr>() , - 8usize); - } - impl Clone for RestyleManagerHandle_Ptr { - fn clone(&self) -> Self { *self } - } - #[test] - fn bindgen_test_layout_RestyleManagerHandle() { - assert_eq!(::std::mem::size_of::<RestyleManagerHandle>() , 8usize); - assert_eq!(::std::mem::align_of::<RestyleManagerHandle>() , 8usize); - } - impl Clone for RestyleManagerHandle { - fn clone(&self) -> Self { *self } - } - pub type nscolor = u32; + /** + * |nsRestyleHint| is a bitfield for the result of + * |HasStateDependentStyle| and |HasAttributeDependentStyle|. When no + * restyling is necessary, use |nsRestyleHint(0)|. + * + * Without eRestyle_Force or eRestyle_ForceDescendants, the restyling process + * can stop processing at a frame when it detects no style changes and it is + * known that the styles of the subtree beneath it will not change, leaving + * the old style context on the frame. eRestyle_Force can be used to skip this + * optimization on a frame, and to force its new style context to be used. + * + * Similarly, eRestyle_ForceDescendants will cause the frame and all of its + * descendants to be traversed and for the new style contexts that are created + * to be set on the frames. + * + * NOTE: When adding new restyle hints, please also add them to + * RestyleManager::RestyleHintToString. + */ + #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] + pub struct nsRestyleHint(pub u32); #[repr(u32)] #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] - pub enum Side { - eSideTop = 0, - eSideRight = 1, - eSideBottom = 2, - eSideLeft = 3, + pub enum nsCompatibility { + eCompatibility_FullStandards = 1, + eCompatibility_AlmostStandards = 2, + eCompatibility_NavQuirks = 3, } + pub type nscolor = u32; #[repr(C)] #[derive(Debug)] pub struct nsPresContext { @@ -6633,7 +6367,7 @@ pub mod root { pub mEffectCompositor: root::RefPtr<root::mozilla::EffectCompositor>, pub mTransitionManager: root::RefPtr<root::nsTransitionManager>, pub mAnimationManager: root::RefPtr<root::nsAnimationManager>, - pub mRestyleManager: root::RestyleManagerHandle_RefPtr, + pub mRestyleManager: root::mozilla::RestyleManagerHandle_RefPtr, pub mCounterStyleManager: root::RefPtr<root::mozilla::CounterStyleManager>, pub mMedium: *mut root::nsIAtom, pub mMediaEmulated: root::nsCOMPtr<root::nsIAtom>, @@ -6680,8 +6414,8 @@ pub mod root { pub mElementsRestyled: u64, pub mFramesConstructed: u64, pub mFramesReflowed: u64, - pub mReflowStartTime: root::TimeStamp, - pub mLastStyleUpdateForAllAnimations: root::TimeStamp, + pub mReflowStartTime: root::mozilla::TimeStamp, + pub mLastStyleUpdateForAllAnimations: root::mozilla::TimeStamp, pub _bitfield_1: u64, } pub type nsPresContext_FramePropertyTable = @@ -7452,15 +7186,9 @@ pub mod root { #[repr(u32)] #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] pub enum PLDHashTable_SearchReason { ForSearchOrRemove = 0, ForAdd = 1, } - extern "C" { - #[link_name = "_ZN12PLDHashTable12kMaxCapacityE"] - pub static PLDHashTable_kMaxCapacity: u32; - } + pub const PLDHashTable_kMaxCapacity: u32 = 67108864; pub const PLDHashTable_kMinCapacity: u32 = 8; - extern "C" { - #[link_name = "_ZN12PLDHashTable17kMaxInitialLengthE"] - pub static PLDHashTable_kMaxInitialLength: u32; - } + pub const PLDHashTable_kMaxInitialLength: u32 = 33554432; pub const PLDHashTable_kDefaultInitialLength: u32 = 4; pub const PLDHashTable_kHashBits: u32 = 32; pub const PLDHashTable_kGoldenRatio: u32 = 2654435769; @@ -7686,73 +7414,6 @@ pub mod root { fn clone(&self) -> Self { *self } } pub type nsWeakPtr = root::nsCOMPtr<root::nsIWeakReference>; - pub type nsLoadFlags = u32; - #[repr(C)] - #[derive(Debug, Copy)] - pub struct nsIRequest { - pub _base: root::nsISupports, - } - #[repr(C)] - #[derive(Debug, Copy, Clone)] - pub struct nsIRequest_COMTypeInfo<T, U> { - pub _address: u8, - pub _phantom_0: ::std::marker::PhantomData<T>, - pub _phantom_1: ::std::marker::PhantomData<U>, - } - pub const nsIRequest_LOAD_REQUESTMASK: root::nsIRequest__bindgen_ty_1 = - nsIRequest__bindgen_ty_1::LOAD_REQUESTMASK; - pub const nsIRequest_LOAD_NORMAL: root::nsIRequest__bindgen_ty_1 = - nsIRequest__bindgen_ty_1::LOAD_NORMAL; - pub const nsIRequest_LOAD_BACKGROUND: root::nsIRequest__bindgen_ty_1 = - nsIRequest__bindgen_ty_1::LOAD_BACKGROUND; - pub const nsIRequest_INHIBIT_PIPELINE: root::nsIRequest__bindgen_ty_1 = - nsIRequest__bindgen_ty_1::INHIBIT_PIPELINE; - pub const nsIRequest_INHIBIT_CACHING: root::nsIRequest__bindgen_ty_1 = - nsIRequest__bindgen_ty_1::INHIBIT_CACHING; - pub const nsIRequest_INHIBIT_PERSISTENT_CACHING: - root::nsIRequest__bindgen_ty_1 = - nsIRequest__bindgen_ty_1::INHIBIT_PERSISTENT_CACHING; - pub const nsIRequest_LOAD_BYPASS_CACHE: root::nsIRequest__bindgen_ty_1 = - nsIRequest__bindgen_ty_1::LOAD_BYPASS_CACHE; - pub const nsIRequest_LOAD_FROM_CACHE: root::nsIRequest__bindgen_ty_1 = - nsIRequest__bindgen_ty_1::LOAD_FROM_CACHE; - pub const nsIRequest_VALIDATE_ALWAYS: root::nsIRequest__bindgen_ty_1 = - nsIRequest__bindgen_ty_1::VALIDATE_ALWAYS; - pub const nsIRequest_VALIDATE_NEVER: root::nsIRequest__bindgen_ty_1 = - nsIRequest__bindgen_ty_1::VALIDATE_NEVER; - pub const nsIRequest_VALIDATE_ONCE_PER_SESSION: - root::nsIRequest__bindgen_ty_1 = - nsIRequest__bindgen_ty_1::VALIDATE_ONCE_PER_SESSION; - pub const nsIRequest_LOAD_ANONYMOUS: root::nsIRequest__bindgen_ty_1 = - nsIRequest__bindgen_ty_1::LOAD_ANONYMOUS; - pub const nsIRequest_LOAD_FRESH_CONNECTION: root::nsIRequest__bindgen_ty_1 - = - nsIRequest__bindgen_ty_1::LOAD_FRESH_CONNECTION; - #[repr(u32)] - #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] - pub enum nsIRequest__bindgen_ty_1 { - LOAD_REQUESTMASK = 65535, - LOAD_NORMAL = 0, - LOAD_BACKGROUND = 1, - INHIBIT_PIPELINE = 64, - INHIBIT_CACHING = 128, - INHIBIT_PERSISTENT_CACHING = 256, - LOAD_BYPASS_CACHE = 512, - LOAD_FROM_CACHE = 1024, - VALIDATE_ALWAYS = 2048, - VALIDATE_NEVER = 4096, - VALIDATE_ONCE_PER_SESSION = 8192, - LOAD_ANONYMOUS = 16384, - LOAD_FRESH_CONNECTION = 32768, - } - #[test] - fn bindgen_test_layout_nsIRequest() { - assert_eq!(::std::mem::size_of::<nsIRequest>() , 8usize); - assert_eq!(::std::mem::align_of::<nsIRequest>() , 8usize); - } - impl Clone for nsIRequest { - fn clone(&self) -> Self { *self } - } #[repr(C)] #[derive(Debug, Copy)] pub struct nsIChannel { @@ -7824,6 +7485,7 @@ pub mod root { impl Clone for nsIChannel { fn clone(&self) -> Self { *self } } + pub type nsLoadFlags = u32; #[repr(C)] #[derive(Debug, Copy)] pub struct nsILoadGroup { @@ -7845,6 +7507,245 @@ pub mod root { fn clone(&self) -> Self { *self } } #[repr(C)] + #[derive(Debug, Copy)] + pub struct nsIRequest { + pub _base: root::nsISupports, + } + #[repr(C)] + #[derive(Debug, Copy, Clone)] + pub struct nsIRequest_COMTypeInfo<T, U> { + pub _address: u8, + pub _phantom_0: ::std::marker::PhantomData<T>, + pub _phantom_1: ::std::marker::PhantomData<U>, + } + pub const nsIRequest_LOAD_REQUESTMASK: root::nsIRequest__bindgen_ty_1 = + nsIRequest__bindgen_ty_1::LOAD_REQUESTMASK; + pub const nsIRequest_LOAD_NORMAL: root::nsIRequest__bindgen_ty_1 = + nsIRequest__bindgen_ty_1::LOAD_NORMAL; + pub const nsIRequest_LOAD_BACKGROUND: root::nsIRequest__bindgen_ty_1 = + nsIRequest__bindgen_ty_1::LOAD_BACKGROUND; + pub const nsIRequest_INHIBIT_PIPELINE: root::nsIRequest__bindgen_ty_1 = + nsIRequest__bindgen_ty_1::INHIBIT_PIPELINE; + pub const nsIRequest_INHIBIT_CACHING: root::nsIRequest__bindgen_ty_1 = + nsIRequest__bindgen_ty_1::INHIBIT_CACHING; + pub const nsIRequest_INHIBIT_PERSISTENT_CACHING: + root::nsIRequest__bindgen_ty_1 = + nsIRequest__bindgen_ty_1::INHIBIT_PERSISTENT_CACHING; + pub const nsIRequest_LOAD_BYPASS_CACHE: root::nsIRequest__bindgen_ty_1 = + nsIRequest__bindgen_ty_1::LOAD_BYPASS_CACHE; + pub const nsIRequest_LOAD_FROM_CACHE: root::nsIRequest__bindgen_ty_1 = + nsIRequest__bindgen_ty_1::LOAD_FROM_CACHE; + pub const nsIRequest_VALIDATE_ALWAYS: root::nsIRequest__bindgen_ty_1 = + nsIRequest__bindgen_ty_1::VALIDATE_ALWAYS; + pub const nsIRequest_VALIDATE_NEVER: root::nsIRequest__bindgen_ty_1 = + nsIRequest__bindgen_ty_1::VALIDATE_NEVER; + pub const nsIRequest_VALIDATE_ONCE_PER_SESSION: + root::nsIRequest__bindgen_ty_1 = + nsIRequest__bindgen_ty_1::VALIDATE_ONCE_PER_SESSION; + pub const nsIRequest_LOAD_ANONYMOUS: root::nsIRequest__bindgen_ty_1 = + nsIRequest__bindgen_ty_1::LOAD_ANONYMOUS; + pub const nsIRequest_LOAD_FRESH_CONNECTION: root::nsIRequest__bindgen_ty_1 + = + nsIRequest__bindgen_ty_1::LOAD_FRESH_CONNECTION; + #[repr(u32)] + #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] + pub enum nsIRequest__bindgen_ty_1 { + LOAD_REQUESTMASK = 65535, + LOAD_NORMAL = 0, + LOAD_BACKGROUND = 1, + INHIBIT_PIPELINE = 64, + INHIBIT_CACHING = 128, + INHIBIT_PERSISTENT_CACHING = 256, + LOAD_BYPASS_CACHE = 512, + LOAD_FROM_CACHE = 1024, + VALIDATE_ALWAYS = 2048, + VALIDATE_NEVER = 4096, + VALIDATE_ONCE_PER_SESSION = 8192, + LOAD_ANONYMOUS = 16384, + LOAD_FRESH_CONNECTION = 32768, + } + #[test] + fn bindgen_test_layout_nsIRequest() { + assert_eq!(::std::mem::size_of::<nsIRequest>() , 8usize); + assert_eq!(::std::mem::align_of::<nsIRequest>() , 8usize); + } + impl Clone for nsIRequest { + fn clone(&self) -> Self { *self } + } + /** + * An internal interface that abstracts some DOMNode-related parts that both + * nsIContent and nsIDocument share. An instance of this interface has a list + * of nsIContent children and provides access to them. + */ + #[repr(C)] + #[derive(Debug)] + pub struct nsINode { + pub _base: root::mozilla::dom::EventTarget, + pub mNodeInfo: root::RefPtr<root::mozilla::dom::NodeInfo>, + pub mParent: *mut root::nsINode, + pub mBoolFlags: u32, + pub mNextSibling: *mut root::nsIContent, + pub mPreviousSibling: *mut root::nsIContent, + pub mFirstChild: *mut root::nsIContent, + pub __bindgen_anon_1: root::nsINode__bindgen_ty_1, + pub mSlots: *mut root::nsINode_nsSlots, + } + pub type nsINode_BoxQuadOptions = root::mozilla::dom::BoxQuadOptions; + pub type nsINode_ConvertCoordinateOptions = + root::mozilla::dom::ConvertCoordinateOptions; + pub type nsINode_DOMPoint = root::mozilla::dom::DOMPoint; + pub type nsINode_DOMPointInit = root::mozilla::dom::DOMPointInit; + pub type nsINode_DOMQuad = root::mozilla::dom::DOMQuad; + pub type nsINode_DOMRectReadOnly = root::mozilla::dom::DOMRectReadOnly; + pub type nsINode_OwningNodeOrString = + root::mozilla::dom::OwningNodeOrString; + pub type nsINode_TextOrElementOrDocument = + root::mozilla::dom::TextOrElementOrDocument; + pub type nsINode_ErrorResult = [u64; 2usize]; + #[repr(C)] + #[derive(Debug, Copy, Clone)] + pub struct nsINode_COMTypeInfo<T, U> { + pub _address: u8, + pub _phantom_0: ::std::marker::PhantomData<T>, + pub _phantom_1: ::std::marker::PhantomData<U>, + } + pub const nsINode_eCONTENT: root::nsINode__bindgen_ty_2 = + nsINode__bindgen_ty_2::eCONTENT; + pub const nsINode_eDOCUMENT: root::nsINode__bindgen_ty_2 = + nsINode__bindgen_ty_2::eDOCUMENT; + pub const nsINode_eATTRIBUTE: root::nsINode__bindgen_ty_2 = + nsINode__bindgen_ty_2::eATTRIBUTE; + pub const nsINode_eTEXT: root::nsINode__bindgen_ty_2 = + nsINode__bindgen_ty_2::eTEXT; + pub const nsINode_ePROCESSING_INSTRUCTION: root::nsINode__bindgen_ty_2 = + nsINode__bindgen_ty_2::ePROCESSING_INSTRUCTION; + pub const nsINode_eCOMMENT: root::nsINode__bindgen_ty_2 = + nsINode__bindgen_ty_2::eCOMMENT; + pub const nsINode_eHTML_FORM_CONTROL: root::nsINode__bindgen_ty_2 = + nsINode__bindgen_ty_2::eHTML_FORM_CONTROL; + pub const nsINode_eDOCUMENT_FRAGMENT: root::nsINode__bindgen_ty_2 = + nsINode__bindgen_ty_2::eDOCUMENT_FRAGMENT; + pub const nsINode_eDATA_NODE: root::nsINode__bindgen_ty_2 = + nsINode__bindgen_ty_2::eDATA_NODE; + pub const nsINode_eMEDIA: root::nsINode__bindgen_ty_2 = + nsINode__bindgen_ty_2::eMEDIA; + pub const nsINode_eANIMATION: root::nsINode__bindgen_ty_2 = + nsINode__bindgen_ty_2::eANIMATION; + pub const nsINode_eFILTER: root::nsINode__bindgen_ty_2 = + nsINode__bindgen_ty_2::eFILTER; + #[repr(u32)] + /** + * Bit-flags to pass (or'ed together) to IsNodeOfType() + */ + #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] + pub enum nsINode__bindgen_ty_2 { + eCONTENT = 1, + eDOCUMENT = 2, + eATTRIBUTE = 4, + eTEXT = 8, + ePROCESSING_INSTRUCTION = 16, + eCOMMENT = 32, + eHTML_FORM_CONTROL = 64, + eDOCUMENT_FRAGMENT = 128, + eDATA_NODE = 256, + eMEDIA = 512, + eANIMATION = 1024, + eFILTER = 2048, + } + #[repr(C)] + pub struct nsINode_nsSlots__bindgen_vtable { + } + #[repr(C)] + #[derive(Debug)] + pub struct nsINode_nsSlots { + pub vtable_: *const nsINode_nsSlots__bindgen_vtable, + /** + * A list of mutation observers + */ + pub mMutationObservers: [u64; 2usize], + /** + * An object implementing nsIDOMNodeList for this content (childNodes) + * @see nsIDOMNodeList + * @see nsGenericHTMLElement::GetChildNodes + */ + pub mChildNodes: root::RefPtr<root::nsChildContentList>, + /** + * Weak reference to this node. This is cleared by the destructor of + * nsNodeWeakReference. + */ + pub mWeakReference: *mut root::nsNodeWeakReference, + /** + * Number of descendant nodes in the uncomposed document that have been + * explicitly set as editable. + */ + pub mEditableDescendantCount: u32, + } + #[test] + fn bindgen_test_layout_nsINode_nsSlots() { + assert_eq!(::std::mem::size_of::<nsINode_nsSlots>() , 48usize); + assert_eq!(::std::mem::align_of::<nsINode_nsSlots>() , 8usize); + } + #[repr(u32)] + /** + * Boolean flags + */ + #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] + pub enum nsINode_BooleanFlag { + NodeHasRenderingObservers = 0, + IsInDocument = 1, + ParentIsContent = 2, + NodeIsElement = 3, + ElementHasID = 4, + ElementMayHaveStyle = 5, + ElementHasName = 6, + ElementMayHaveContentEditableAttr = 7, + NodeIsCommonAncestorForRangeInSelection = 8, + NodeIsDescendantOfCommonAncestorForRangeInSelection = 9, + NodeIsCCMarkedRoot = 10, + NodeIsCCBlackTree = 11, + NodeIsPurpleRoot = 12, + NodeHasExplicitBaseURI = 13, + ElementHasLockedStyleStates = 14, + ElementHasPointerLock = 15, + NodeMayHaveDOMMutationObserver = 16, + NodeIsContent = 17, + ElementHasAnimations = 18, + NodeHasValidDirAttribute = 19, + NodeHasFixedDir = 20, + NodeHasDirAutoSet = 21, + NodeHasTextNodeDirectionalityMap = 22, + NodeHasDirAuto = 23, + NodeAncestorHasDirAuto = 24, + ElementIsInStyleScope = 25, + ElementIsScopedStyleRoot = 26, + NodeHandlingClick = 27, + NodeHasRelevantHoverRules = 28, + ElementHasWeirdParserInsertionMode = 29, + ParserHasNotified = 30, + MayBeApzAware = 31, + BooleanFlagCount = 32, + } + #[repr(C)] + #[derive(Debug, Copy)] + pub struct nsINode__bindgen_ty_1 { + pub mPrimaryFrame: root::__BindgenUnionField<*mut root::nsIFrame>, + pub mSubtreeRoot: root::__BindgenUnionField<*mut root::nsINode>, + pub bindgen_union_field: u64, + } + #[test] + fn bindgen_test_layout_nsINode__bindgen_ty_1() { + assert_eq!(::std::mem::size_of::<nsINode__bindgen_ty_1>() , 8usize); + assert_eq!(::std::mem::align_of::<nsINode__bindgen_ty_1>() , 8usize); + } + impl Clone for nsINode__bindgen_ty_1 { + fn clone(&self) -> Self { *self } + } + #[test] + fn bindgen_test_layout_nsINode() { + assert_eq!(::std::mem::size_of::<nsINode>() , 96usize); + assert_eq!(::std::mem::align_of::<nsINode>() , 8usize); + } + #[repr(C)] #[derive(Debug)] pub struct nsCOMArray_base { pub mArray: root::nsTArray<*mut root::nsISupports>, @@ -8111,26 +8012,6 @@ pub mod root { fn clone(&self) -> Self { *self } } #[repr(C)] - #[derive(Debug, Copy)] - pub struct nsIDOMMozNamedAttrMap { - pub _base: root::nsISupports, - } - #[repr(C)] - #[derive(Debug, Copy, Clone)] - pub struct nsIDOMMozNamedAttrMap_COMTypeInfo<T, U> { - pub _address: u8, - pub _phantom_0: ::std::marker::PhantomData<T>, - pub _phantom_1: ::std::marker::PhantomData<U>, - } - #[test] - fn bindgen_test_layout_nsIDOMMozNamedAttrMap() { - assert_eq!(::std::mem::size_of::<nsIDOMMozNamedAttrMap>() , 8usize); - assert_eq!(::std::mem::align_of::<nsIDOMMozNamedAttrMap>() , 8usize); - } - impl Clone for nsIDOMMozNamedAttrMap { - fn clone(&self) -> Self { *self } - } - #[repr(C)] #[derive(Debug)] pub struct nsDOMAttributeMap { pub _base: root::nsIDOMMozNamedAttrMap, @@ -8271,9 +8152,9 @@ pub mod root { nsIPresShell__bindgen_ty_1::SCROLL_TOP; pub const nsIPresShell_SCROLL_BOTTOM: root::nsIPresShell__bindgen_ty_1 = nsIPresShell__bindgen_ty_1::SCROLL_BOTTOM; - pub const SCROLL_LEFT: root::nsIPresShell__bindgen_ty_1 = + pub const nsIPresShell_SCROLL_LEFT: root::nsIPresShell__bindgen_ty_1 = nsIPresShell__bindgen_ty_1::SCROLL_TOP; - pub const SCROLL_RIGHT: root::nsIPresShell__bindgen_ty_1 = + pub const nsIPresShell_SCROLL_RIGHT: root::nsIPresShell__bindgen_ty_1 = nsIPresShell__bindgen_ty_1::SCROLL_BOTTOM; pub const nsIPresShell_SCROLL_CENTER: root::nsIPresShell__bindgen_ty_1 = nsIPresShell__bindgen_ty_1::SCROLL_CENTER; @@ -8684,63 +8565,63 @@ pub mod root { impl Clone for nsDOMMutationObserver { fn clone(&self) -> Self { *self } } - pub const NODE_HAS_LISTENERMANAGER: root::_bindgen_ty_62 = - _bindgen_ty_62::NODE_HAS_LISTENERMANAGER; - pub const NODE_HAS_PROPERTIES: root::_bindgen_ty_62 = - _bindgen_ty_62::NODE_HAS_PROPERTIES; - pub const NODE_IS_ANONYMOUS_ROOT: root::_bindgen_ty_62 = - _bindgen_ty_62::NODE_IS_ANONYMOUS_ROOT; - pub const NODE_IS_IN_NATIVE_ANONYMOUS_SUBTREE: root::_bindgen_ty_62 = - _bindgen_ty_62::NODE_IS_IN_NATIVE_ANONYMOUS_SUBTREE; - pub const NODE_IS_NATIVE_ANONYMOUS_ROOT: root::_bindgen_ty_62 = - _bindgen_ty_62::NODE_IS_NATIVE_ANONYMOUS_ROOT; - pub const NODE_FORCE_XBL_BINDINGS: root::_bindgen_ty_62 = - _bindgen_ty_62::NODE_FORCE_XBL_BINDINGS; - pub const NODE_MAY_BE_IN_BINDING_MNGR: root::_bindgen_ty_62 = - _bindgen_ty_62::NODE_MAY_BE_IN_BINDING_MNGR; - pub const NODE_IS_EDITABLE: root::_bindgen_ty_62 = - _bindgen_ty_62::NODE_IS_EDITABLE; - pub const NODE_MAY_HAVE_CLASS: root::_bindgen_ty_62 = - _bindgen_ty_62::NODE_MAY_HAVE_CLASS; - pub const NODE_IS_IN_SHADOW_TREE: root::_bindgen_ty_62 = - _bindgen_ty_62::NODE_IS_IN_SHADOW_TREE; - pub const NODE_HAS_EMPTY_SELECTOR: root::_bindgen_ty_62 = - _bindgen_ty_62::NODE_HAS_EMPTY_SELECTOR; - pub const NODE_HAS_SLOW_SELECTOR: root::_bindgen_ty_62 = - _bindgen_ty_62::NODE_HAS_SLOW_SELECTOR; - pub const NODE_HAS_EDGE_CHILD_SELECTOR: root::_bindgen_ty_62 = - _bindgen_ty_62::NODE_HAS_EDGE_CHILD_SELECTOR; - pub const NODE_HAS_SLOW_SELECTOR_LATER_SIBLINGS: root::_bindgen_ty_62 = - _bindgen_ty_62::NODE_HAS_SLOW_SELECTOR_LATER_SIBLINGS; - pub const NODE_ALL_SELECTOR_FLAGS: root::_bindgen_ty_62 = - _bindgen_ty_62::NODE_ALL_SELECTOR_FLAGS; - pub const NODE_NEEDS_FRAME: root::_bindgen_ty_62 = - _bindgen_ty_62::NODE_NEEDS_FRAME; - pub const NODE_DESCENDANTS_NEED_FRAMES: root::_bindgen_ty_62 = - _bindgen_ty_62::NODE_DESCENDANTS_NEED_FRAMES; - pub const NODE_HAS_ACCESSKEY: root::_bindgen_ty_62 = - _bindgen_ty_62::NODE_HAS_ACCESSKEY; - pub const NODE_HAS_DIRECTION_RTL: root::_bindgen_ty_62 = - _bindgen_ty_62::NODE_HAS_DIRECTION_RTL; - pub const NODE_HAS_DIRECTION_LTR: root::_bindgen_ty_62 = - _bindgen_ty_62::NODE_HAS_DIRECTION_LTR; - pub const NODE_ALL_DIRECTION_FLAGS: root::_bindgen_ty_62 = - _bindgen_ty_62::NODE_ALL_DIRECTION_FLAGS; - pub const NODE_CHROME_ONLY_ACCESS: root::_bindgen_ty_62 = - _bindgen_ty_62::NODE_CHROME_ONLY_ACCESS; - pub const NODE_IS_ROOT_OF_CHROME_ONLY_ACCESS: root::_bindgen_ty_62 = - _bindgen_ty_62::NODE_IS_ROOT_OF_CHROME_ONLY_ACCESS; - pub const NODE_SHARED_RESTYLE_BIT_1: root::_bindgen_ty_62 = - _bindgen_ty_62::NODE_SHARED_RESTYLE_BIT_1; - pub const NODE_SHARED_RESTYLE_BIT_2: root::_bindgen_ty_62 = - _bindgen_ty_62::NODE_SHARED_RESTYLE_BIT_2; - pub const NODE_HAS_DIRTY_DESCENDANTS_FOR_SERVO: root::_bindgen_ty_62 = - _bindgen_ty_62::NODE_SHARED_RESTYLE_BIT_1; - pub const NODE_TYPE_SPECIFIC_BITS_OFFSET: root::_bindgen_ty_62 = - _bindgen_ty_62::NODE_TYPE_SPECIFIC_BITS_OFFSET; + pub const NODE_HAS_LISTENERMANAGER: root::_bindgen_ty_118 = + _bindgen_ty_118::NODE_HAS_LISTENERMANAGER; + pub const NODE_HAS_PROPERTIES: root::_bindgen_ty_118 = + _bindgen_ty_118::NODE_HAS_PROPERTIES; + pub const NODE_IS_ANONYMOUS_ROOT: root::_bindgen_ty_118 = + _bindgen_ty_118::NODE_IS_ANONYMOUS_ROOT; + pub const NODE_IS_IN_NATIVE_ANONYMOUS_SUBTREE: root::_bindgen_ty_118 = + _bindgen_ty_118::NODE_IS_IN_NATIVE_ANONYMOUS_SUBTREE; + pub const NODE_IS_NATIVE_ANONYMOUS_ROOT: root::_bindgen_ty_118 = + _bindgen_ty_118::NODE_IS_NATIVE_ANONYMOUS_ROOT; + pub const NODE_FORCE_XBL_BINDINGS: root::_bindgen_ty_118 = + _bindgen_ty_118::NODE_FORCE_XBL_BINDINGS; + pub const NODE_MAY_BE_IN_BINDING_MNGR: root::_bindgen_ty_118 = + _bindgen_ty_118::NODE_MAY_BE_IN_BINDING_MNGR; + pub const NODE_IS_EDITABLE: root::_bindgen_ty_118 = + _bindgen_ty_118::NODE_IS_EDITABLE; + pub const NODE_MAY_HAVE_CLASS: root::_bindgen_ty_118 = + _bindgen_ty_118::NODE_MAY_HAVE_CLASS; + pub const NODE_IS_IN_SHADOW_TREE: root::_bindgen_ty_118 = + _bindgen_ty_118::NODE_IS_IN_SHADOW_TREE; + pub const NODE_HAS_EMPTY_SELECTOR: root::_bindgen_ty_118 = + _bindgen_ty_118::NODE_HAS_EMPTY_SELECTOR; + pub const NODE_HAS_SLOW_SELECTOR: root::_bindgen_ty_118 = + _bindgen_ty_118::NODE_HAS_SLOW_SELECTOR; + pub const NODE_HAS_EDGE_CHILD_SELECTOR: root::_bindgen_ty_118 = + _bindgen_ty_118::NODE_HAS_EDGE_CHILD_SELECTOR; + pub const NODE_HAS_SLOW_SELECTOR_LATER_SIBLINGS: root::_bindgen_ty_118 = + _bindgen_ty_118::NODE_HAS_SLOW_SELECTOR_LATER_SIBLINGS; + pub const NODE_ALL_SELECTOR_FLAGS: root::_bindgen_ty_118 = + _bindgen_ty_118::NODE_ALL_SELECTOR_FLAGS; + pub const NODE_NEEDS_FRAME: root::_bindgen_ty_118 = + _bindgen_ty_118::NODE_NEEDS_FRAME; + pub const NODE_DESCENDANTS_NEED_FRAMES: root::_bindgen_ty_118 = + _bindgen_ty_118::NODE_DESCENDANTS_NEED_FRAMES; + pub const NODE_HAS_ACCESSKEY: root::_bindgen_ty_118 = + _bindgen_ty_118::NODE_HAS_ACCESSKEY; + pub const NODE_HAS_DIRECTION_RTL: root::_bindgen_ty_118 = + _bindgen_ty_118::NODE_HAS_DIRECTION_RTL; + pub const NODE_HAS_DIRECTION_LTR: root::_bindgen_ty_118 = + _bindgen_ty_118::NODE_HAS_DIRECTION_LTR; + pub const NODE_ALL_DIRECTION_FLAGS: root::_bindgen_ty_118 = + _bindgen_ty_118::NODE_ALL_DIRECTION_FLAGS; + pub const NODE_CHROME_ONLY_ACCESS: root::_bindgen_ty_118 = + _bindgen_ty_118::NODE_CHROME_ONLY_ACCESS; + pub const NODE_IS_ROOT_OF_CHROME_ONLY_ACCESS: root::_bindgen_ty_118 = + _bindgen_ty_118::NODE_IS_ROOT_OF_CHROME_ONLY_ACCESS; + pub const NODE_SHARED_RESTYLE_BIT_1: root::_bindgen_ty_118 = + _bindgen_ty_118::NODE_SHARED_RESTYLE_BIT_1; + pub const NODE_SHARED_RESTYLE_BIT_2: root::_bindgen_ty_118 = + _bindgen_ty_118::NODE_SHARED_RESTYLE_BIT_2; + pub const NODE_HAS_DIRTY_DESCENDANTS_FOR_SERVO: root::_bindgen_ty_118 = + _bindgen_ty_118::NODE_SHARED_RESTYLE_BIT_1; + pub const NODE_TYPE_SPECIFIC_BITS_OFFSET: root::_bindgen_ty_118 = + _bindgen_ty_118::NODE_TYPE_SPECIFIC_BITS_OFFSET; #[repr(u32)] #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] - pub enum _bindgen_ty_62 { + pub enum _bindgen_ty_118 { NODE_HAS_LISTENERMANAGER = 4, NODE_HAS_PROPERTIES = 8, NODE_IS_ANONYMOUS_ROOT = 16, @@ -9100,6 +8981,26 @@ pub mod root { impl Clone for nsDOMStringMap { fn clone(&self) -> Self { *self } } + #[repr(C)] + #[derive(Debug, Copy)] + pub struct nsIDOMMozNamedAttrMap { + pub _base: root::nsISupports, + } + #[repr(C)] + #[derive(Debug, Copy, Clone)] + pub struct nsIDOMMozNamedAttrMap_COMTypeInfo<T, U> { + pub _address: u8, + pub _phantom_0: ::std::marker::PhantomData<T>, + pub _phantom_1: ::std::marker::PhantomData<U>, + } + #[test] + fn bindgen_test_layout_nsIDOMMozNamedAttrMap() { + assert_eq!(::std::mem::size_of::<nsIDOMMozNamedAttrMap>() , 8usize); + assert_eq!(::std::mem::align_of::<nsIDOMMozNamedAttrMap>() , 8usize); + } + impl Clone for nsIDOMMozNamedAttrMap { + fn clone(&self) -> Self { *self } + } /** * Interface used for handling clicks on links */ @@ -9124,6 +9025,24 @@ pub mod root { fn clone(&self) -> Self { *self } } #[repr(C)] + #[derive(Debug)] + pub struct nsIAttribute { + pub _base: root::nsINode, + pub mAttrMap: root::RefPtr<root::nsDOMAttributeMap>, + } + #[repr(C)] + #[derive(Debug, Copy, Clone)] + pub struct nsIAttribute_COMTypeInfo<T, U> { + pub _address: u8, + pub _phantom_0: ::std::marker::PhantomData<T>, + pub _phantom_1: ::std::marker::PhantomData<U>, + } + #[test] + fn bindgen_test_layout_nsIAttribute() { + assert_eq!(::std::mem::size_of::<nsIAttribute>() , 104usize); + assert_eq!(::std::mem::align_of::<nsIAttribute>() , 8usize); + } + #[repr(C)] #[derive(Debug, Copy)] pub struct nsStyleContext { pub _address: u8, @@ -9524,21 +9443,21 @@ pub mod root { } #[repr(C)] #[derive(Debug, Copy)] - pub struct _bindgen_ty_26 { + pub struct _bindgen_ty_25 { pub mInt: root::__BindgenUnionField<i32>, pub mFloat: root::__BindgenUnionField<f32>, pub mPointer: root::__BindgenUnionField<*mut ::std::os::raw::c_void>, pub bindgen_union_field: u64, } #[test] - fn bindgen_test_layout__bindgen_ty_26() { - assert_eq!(::std::mem::size_of::<_bindgen_ty_26>() , 8usize); - assert_eq!(::std::mem::align_of::<_bindgen_ty_26>() , 8usize); + fn bindgen_test_layout__bindgen_ty_25() { + assert_eq!(::std::mem::size_of::<_bindgen_ty_25>() , 8usize); + assert_eq!(::std::mem::align_of::<_bindgen_ty_25>() , 8usize); } - impl Clone for _bindgen_ty_26 { + impl Clone for _bindgen_ty_25 { fn clone(&self) -> Self { *self } } - pub type nsStyleUnion = root::_bindgen_ty_26; + pub type nsStyleUnion = root::_bindgen_ty_25; /** * Class that hold a single size specification used by the style * system. The size specification consists of two parts -- a number @@ -10637,7 +10556,7 @@ pub mod root { eCSSProperty_animation_name = 8, eCSSProperty_animation_play_state = 9, eCSSProperty_animation_timing_function = 10, - eCSSProperty_appearance = 11, + eCSSProperty__moz_appearance = 11, eCSSProperty_backface_visibility = 12, eCSSProperty_background_attachment = 13, eCSSProperty_background_blend_mode = 14, @@ -10649,7 +10568,7 @@ pub mod root { eCSSProperty_background_position_y = 20, eCSSProperty_background_repeat = 21, eCSSProperty_background_size = 22, - eCSSProperty_binding = 23, + eCSSProperty__moz_binding = 23, eCSSProperty_block_size = 24, eCSSProperty_border_block_end_color = 25, eCSSProperty_border_block_end_style = 26, @@ -10658,7 +10577,7 @@ pub mod root { eCSSProperty_border_block_start_style = 29, eCSSProperty_border_block_start_width = 30, eCSSProperty_border_bottom_color = 31, - eCSSProperty_border_bottom_colors = 32, + eCSSProperty__moz_border_bottom_colors = 32, eCSSProperty_border_bottom_left_radius = 33, eCSSProperty_border_bottom_right_radius = 34, eCSSProperty_border_bottom_style = 35, @@ -10676,28 +10595,28 @@ pub mod root { eCSSProperty_border_inline_start_style = 47, eCSSProperty_border_inline_start_width = 48, eCSSProperty_border_left_color = 49, - eCSSProperty_border_left_colors = 50, + eCSSProperty__moz_border_left_colors = 50, eCSSProperty_border_left_style = 51, eCSSProperty_border_left_width = 52, eCSSProperty_border_right_color = 53, - eCSSProperty_border_right_colors = 54, + eCSSProperty__moz_border_right_colors = 54, eCSSProperty_border_right_style = 55, eCSSProperty_border_right_width = 56, eCSSProperty_border_spacing = 57, eCSSProperty_border_top_color = 58, - eCSSProperty_border_top_colors = 59, + eCSSProperty__moz_border_top_colors = 59, eCSSProperty_border_top_left_radius = 60, eCSSProperty_border_top_right_radius = 61, eCSSProperty_border_top_style = 62, eCSSProperty_border_top_width = 63, eCSSProperty_bottom = 64, - eCSSProperty_box_align = 65, + eCSSProperty__moz_box_align = 65, eCSSProperty_box_decoration_break = 66, - eCSSProperty_box_direction = 67, - eCSSProperty_box_flex = 68, - eCSSProperty_box_ordinal_group = 69, - eCSSProperty_box_orient = 70, - eCSSProperty_box_pack = 71, + eCSSProperty__moz_box_direction = 67, + eCSSProperty__moz_box_flex = 68, + eCSSProperty__moz_box_ordinal_group = 69, + eCSSProperty__moz_box_orient = 70, + eCSSProperty__moz_box_pack = 71, eCSSProperty_box_shadow = 72, eCSSProperty_box_sizing = 73, eCSSProperty_caption_side = 74, @@ -10736,7 +10655,7 @@ pub mod root { eCSSProperty_flex_shrink = 107, eCSSProperty_flex_wrap = 108, eCSSProperty_float_ = 109, - eCSSProperty_float_edge = 110, + eCSSProperty__moz_float_edge = 110, eCSSProperty_flood_color = 111, eCSSProperty_flood_opacity = 112, eCSSProperty_font_family = 113, @@ -10756,7 +10675,7 @@ pub mod root { eCSSProperty_font_variant_position = 127, eCSSProperty_font_variation_settings = 128, eCSSProperty_font_weight = 129, - eCSSProperty_force_broken_image_icon = 130, + eCSSProperty__moz_force_broken_image_icon = 130, eCSSProperty_grid_auto_columns = 131, eCSSProperty_grid_auto_flow = 132, eCSSProperty_grid_auto_rows = 133, @@ -10773,7 +10692,7 @@ pub mod root { eCSSProperty_hyphens = 144, eCSSProperty_initial_letter = 145, eCSSProperty_image_orientation = 146, - eCSSProperty_image_region = 147, + eCSSProperty__moz_image_region = 147, eCSSProperty_image_rendering = 148, eCSSProperty_ime_mode = 149, eCSSProperty_inline_size = 150, @@ -10810,8 +10729,8 @@ pub mod root { eCSSProperty_mask_repeat = 181, eCSSProperty_mask_size = 182, eCSSProperty_mask_type = 183, - eCSSProperty_math_display = 184, - eCSSProperty_math_variant = 185, + eCSSProperty__moz_math_display = 184, + eCSSProperty__moz_math_variant = 185, eCSSProperty_max_block_size = 186, eCSSProperty_max_height = 187, eCSSProperty_max_inline_size = 188, @@ -10830,14 +10749,14 @@ pub mod root { eCSSProperty_offset_inline_start = 201, eCSSProperty_opacity = 202, eCSSProperty_order = 203, - eCSSProperty_orient = 204, - eCSSProperty_osx_font_smoothing = 205, + eCSSProperty__moz_orient = 204, + eCSSProperty__moz_osx_font_smoothing = 205, eCSSProperty_outline_color = 206, eCSSProperty_outline_offset = 207, - eCSSProperty__moz_outline_radius_bottomLeft = 208, - eCSSProperty__moz_outline_radius_bottomRight = 209, - eCSSProperty__moz_outline_radius_topLeft = 210, - eCSSProperty__moz_outline_radius_topRight = 211, + eCSSProperty__moz_outline_radius_bottomleft = 208, + eCSSProperty__moz_outline_radius_bottomright = 209, + eCSSProperty__moz_outline_radius_topleft = 210, + eCSSProperty__moz_outline_radius_topright = 211, eCSSProperty_outline_style = 212, eCSSProperty_outline_width = 213, eCSSProperty_overflow_clip_box = 214, @@ -10864,9 +10783,9 @@ pub mod root { eCSSProperty_right = 235, eCSSProperty_ruby_align = 236, eCSSProperty_ruby_position = 237, - eCSSProperty_script_level = 238, - eCSSProperty_script_min_size = 239, - eCSSProperty_script_size_multiplier = 240, + eCSSProperty__moz_script_level = 238, + eCSSProperty__moz_script_min_size = 239, + eCSSProperty__moz_script_size_multiplier = 240, eCSSProperty_scroll_behavior = 241, eCSSProperty_scroll_snap_coordinate = 242, eCSSProperty_scroll_snap_destination = 243, @@ -10877,7 +10796,7 @@ pub mod root { eCSSProperty_shape_outside = 248, eCSSProperty_shape_rendering = 249, eCSSProperty__x_span = 250, - eCSSProperty_stack_sizing = 251, + eCSSProperty__moz_stack_sizing = 251, eCSSProperty_stop_color = 252, eCSSProperty_stop_opacity = 253, eCSSProperty_stroke = 254, @@ -10907,7 +10826,7 @@ pub mod root { eCSSProperty_text_overflow = 278, eCSSProperty_text_rendering = 279, eCSSProperty_text_shadow = 280, - eCSSProperty_text_size_adjust = 281, + eCSSProperty__moz_text_size_adjust = 281, eCSSProperty__webkit_text_stroke_color = 282, eCSSProperty__webkit_text_stroke_width = 283, eCSSProperty_text_transform = 284, @@ -10924,10 +10843,10 @@ pub mod root { eCSSProperty_transition_property = 295, eCSSProperty_transition_timing_function = 296, eCSSProperty_unicode_bidi = 297, - eCSSProperty_user_focus = 298, - eCSSProperty_user_input = 299, - eCSSProperty_user_modify = 300, - eCSSProperty_user_select = 301, + eCSSProperty__moz_user_focus = 298, + eCSSProperty__moz_user_input = 299, + eCSSProperty__moz_user_modify = 300, + eCSSProperty__moz_user_select = 301, eCSSProperty_vector_effect = 302, eCSSProperty_vertical_align = 303, eCSSProperty_visibility = 304, @@ -11156,127 +11075,11 @@ pub mod root { pub struct nsMainThreadPtrHandle<T> { pub mPtr: root::RefPtr<T>, } - #[test] - fn __bindgen_test_layout_template_11() { - assert_eq!(::std::mem::size_of::<u64>() , 8usize); - assert_eq!(::std::mem::align_of::<u64>() , 8usize); - } - #[repr(C)] - pub struct IProgressObserver__bindgen_vtable { - } - /** - * An interface for observing changes to image state, as reported by - * ProgressTracker. - * - * This is the ImageLib-internal version of imgINotificationObserver, - * essentially, with implementation details that code outside of ImageLib - * shouldn't see. - * - * XXX(seth): It's preferable to avoid adding anything to this interface if - * possible. In the long term, it would be ideal to get to a place where we can - * just use the imgINotificationObserver interface internally as well. - */ - #[repr(C)] - #[derive(Debug)] - pub struct IProgressObserver { - pub vtable_: *const IProgressObserver__bindgen_vtable, - pub _base: u64, - } - #[test] - fn bindgen_test_layout_IProgressObserver() { - assert_eq!(::std::mem::size_of::<IProgressObserver>() , 16usize); - assert_eq!(::std::mem::align_of::<IProgressObserver>() , 8usize); - } - #[repr(C)] - #[derive(Debug, Copy)] - pub struct nsISupportsPriority { - pub _base: root::nsISupports, - } - #[repr(C)] - #[derive(Debug, Copy, Clone)] - pub struct nsISupportsPriority_COMTypeInfo<T, U> { - pub _address: u8, - pub _phantom_0: ::std::marker::PhantomData<T>, - pub _phantom_1: ::std::marker::PhantomData<U>, - } - pub const nsISupportsPriority_PRIORITY_HIGHEST: - root::nsISupportsPriority__bindgen_ty_1 = - nsISupportsPriority__bindgen_ty_1::PRIORITY_HIGHEST; - pub const nsISupportsPriority_PRIORITY_HIGH: - root::nsISupportsPriority__bindgen_ty_1 = - nsISupportsPriority__bindgen_ty_1::PRIORITY_HIGH; - pub const nsISupportsPriority_PRIORITY_NORMAL: - root::nsISupportsPriority__bindgen_ty_1 = - nsISupportsPriority__bindgen_ty_1::PRIORITY_NORMAL; - pub const nsISupportsPriority_PRIORITY_LOW: - root::nsISupportsPriority__bindgen_ty_1 = - nsISupportsPriority__bindgen_ty_1::PRIORITY_LOW; - pub const nsISupportsPriority_PRIORITY_LOWEST: - root::nsISupportsPriority__bindgen_ty_1 = - nsISupportsPriority__bindgen_ty_1::PRIORITY_LOWEST; - #[repr(i32)] - #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] - pub enum nsISupportsPriority__bindgen_ty_1 { - PRIORITY_HIGHEST = -20, - PRIORITY_HIGH = -10, - PRIORITY_NORMAL = 0, - PRIORITY_LOW = 10, - PRIORITY_LOWEST = 20, - } - #[test] - fn bindgen_test_layout_nsISupportsPriority() { - assert_eq!(::std::mem::size_of::<nsISupportsPriority>() , 8usize); - assert_eq!(::std::mem::align_of::<nsISupportsPriority>() , 8usize); - } - impl Clone for nsISupportsPriority { - fn clone(&self) -> Self { *self } - } - #[repr(C)] - #[derive(Debug, Copy)] - pub struct nsISecurityInfoProvider { - pub _base: root::nsISupports, - } - #[repr(C)] - #[derive(Debug, Copy, Clone)] - pub struct nsISecurityInfoProvider_COMTypeInfo<T, U> { - pub _address: u8, - pub _phantom_0: ::std::marker::PhantomData<T>, - pub _phantom_1: ::std::marker::PhantomData<U>, - } - #[test] - fn bindgen_test_layout_nsISecurityInfoProvider() { - assert_eq!(::std::mem::size_of::<nsISecurityInfoProvider>() , 8usize); - assert_eq!(::std::mem::align_of::<nsISecurityInfoProvider>() , - 8usize); - } - impl Clone for nsISecurityInfoProvider { - fn clone(&self) -> Self { *self } - } - #[repr(C)] - #[derive(Debug, Copy)] - pub struct nsITimedChannel { - pub _base: root::nsISupports, - } - #[repr(C)] - #[derive(Debug, Copy, Clone)] - pub struct nsITimedChannel_COMTypeInfo<T, U> { - pub _address: u8, - pub _phantom_0: ::std::marker::PhantomData<T>, - pub _phantom_1: ::std::marker::PhantomData<U>, - } - #[test] - fn bindgen_test_layout_nsITimedChannel() { - assert_eq!(::std::mem::size_of::<nsITimedChannel>() , 8usize); - assert_eq!(::std::mem::align_of::<nsITimedChannel>() , 8usize); - } - impl Clone for nsITimedChannel { - fn clone(&self) -> Self { *self } - } #[repr(C)] #[derive(Debug)] pub struct imgRequestProxy { pub _base: root::imgIRequest, - pub _base_1: root::IProgressObserver, + pub _base_1: root::mozilla::image::IProgressObserver, pub _base_2: root::nsISupportsPriority, pub _base_3: root::nsISecurityInfoProvider, pub _base_4: root::nsITimedChannel, @@ -11467,7 +11270,7 @@ pub mod root { pub mSheetPrincipal: root::nsCOMPtr<root::nsIPrincipal>, pub mLineNumber: u32, pub mLineOffset: u32, - pub mLevel: root::SheetType, + pub mLevel: root::mozilla::SheetType, } pub type nsCSSValueTokenStream_HasThreadSafeRefCnt = root::mozilla::FalseType; @@ -11752,6 +11555,91 @@ pub mod root { } #[repr(C)] #[derive(Debug, Copy)] + pub struct nsISecurityInfoProvider { + pub _base: root::nsISupports, + } + #[repr(C)] + #[derive(Debug, Copy, Clone)] + pub struct nsISecurityInfoProvider_COMTypeInfo<T, U> { + pub _address: u8, + pub _phantom_0: ::std::marker::PhantomData<T>, + pub _phantom_1: ::std::marker::PhantomData<U>, + } + #[test] + fn bindgen_test_layout_nsISecurityInfoProvider() { + assert_eq!(::std::mem::size_of::<nsISecurityInfoProvider>() , 8usize); + assert_eq!(::std::mem::align_of::<nsISecurityInfoProvider>() , + 8usize); + } + impl Clone for nsISecurityInfoProvider { + fn clone(&self) -> Self { *self } + } + #[repr(C)] + #[derive(Debug, Copy)] + pub struct nsISupportsPriority { + pub _base: root::nsISupports, + } + #[repr(C)] + #[derive(Debug, Copy, Clone)] + pub struct nsISupportsPriority_COMTypeInfo<T, U> { + pub _address: u8, + pub _phantom_0: ::std::marker::PhantomData<T>, + pub _phantom_1: ::std::marker::PhantomData<U>, + } + pub const nsISupportsPriority_PRIORITY_HIGHEST: + root::nsISupportsPriority__bindgen_ty_1 = + nsISupportsPriority__bindgen_ty_1::PRIORITY_HIGHEST; + pub const nsISupportsPriority_PRIORITY_HIGH: + root::nsISupportsPriority__bindgen_ty_1 = + nsISupportsPriority__bindgen_ty_1::PRIORITY_HIGH; + pub const nsISupportsPriority_PRIORITY_NORMAL: + root::nsISupportsPriority__bindgen_ty_1 = + nsISupportsPriority__bindgen_ty_1::PRIORITY_NORMAL; + pub const nsISupportsPriority_PRIORITY_LOW: + root::nsISupportsPriority__bindgen_ty_1 = + nsISupportsPriority__bindgen_ty_1::PRIORITY_LOW; + pub const nsISupportsPriority_PRIORITY_LOWEST: + root::nsISupportsPriority__bindgen_ty_1 = + nsISupportsPriority__bindgen_ty_1::PRIORITY_LOWEST; + #[repr(i32)] + #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] + pub enum nsISupportsPriority__bindgen_ty_1 { + PRIORITY_HIGHEST = -20, + PRIORITY_HIGH = -10, + PRIORITY_NORMAL = 0, + PRIORITY_LOW = 10, + PRIORITY_LOWEST = 20, + } + #[test] + fn bindgen_test_layout_nsISupportsPriority() { + assert_eq!(::std::mem::size_of::<nsISupportsPriority>() , 8usize); + assert_eq!(::std::mem::align_of::<nsISupportsPriority>() , 8usize); + } + impl Clone for nsISupportsPriority { + fn clone(&self) -> Self { *self } + } + #[repr(C)] + #[derive(Debug, Copy)] + pub struct nsITimedChannel { + pub _base: root::nsISupports, + } + #[repr(C)] + #[derive(Debug, Copy, Clone)] + pub struct nsITimedChannel_COMTypeInfo<T, U> { + pub _address: u8, + pub _phantom_0: ::std::marker::PhantomData<T>, + pub _phantom_1: ::std::marker::PhantomData<U>, + } + #[test] + fn bindgen_test_layout_nsITimedChannel() { + assert_eq!(::std::mem::size_of::<nsITimedChannel>() , 8usize); + assert_eq!(::std::mem::align_of::<nsITimedChannel>() , 8usize); + } + impl Clone for nsITimedChannel { + fn clone(&self) -> Self { *self } + } + #[repr(C)] + #[derive(Debug, Copy)] pub struct ProxyBehaviour { pub _address: u8, } @@ -11898,7 +11786,7 @@ pub mod root { assert_eq!(::std::mem::align_of::<CachedBorderImageData>() , 8usize); } #[test] - fn __bindgen_test_layout_template_12() { + fn __bindgen_test_layout_template_8() { assert_eq!(::std::mem::size_of::<root::mozilla::UniquePtr<root::nsStyleSides, root::mozilla::DefaultDelete<root::nsStyleSides>>>() , 8usize); @@ -13074,190 +12962,176 @@ pub mod root { root::nsMainThreadPtrHolder<root::nsIPrincipal>; pub type ThreadSafeURIHolder = root::nsMainThreadPtrHolder<root::nsIURI>; #[test] - fn __bindgen_test_layout_template_13() { + fn __bindgen_test_layout_template_9() { assert_eq!(::std::mem::size_of::<root::JS::TenuredHeap<*mut root::JSObject>>() , 8usize); assert_eq!(::std::mem::align_of::<root::JS::TenuredHeap<*mut root::JSObject>>() , 8usize); } #[test] - fn __bindgen_test_layout_template_14() { + fn __bindgen_test_layout_template_10() { assert_eq!(::std::mem::size_of::<root::JS::Heap<*mut root::JSObject>>() , 8usize); assert_eq!(::std::mem::align_of::<root::JS::Heap<*mut root::JSObject>>() , 8usize); } #[test] - fn __bindgen_test_layout_template_15() { + fn __bindgen_test_layout_template_11() { assert_eq!(::std::mem::size_of::<root::nsTArray<root::nsCString>>() , 8usize); assert_eq!(::std::mem::align_of::<root::nsTArray<root::nsCString>>() , 8usize); } #[test] - fn __bindgen_test_layout_template_16() { - assert_eq!(::std::mem::size_of::<root::nsTArray<::nsstring::nsStringRepr>>() , - 8usize); - assert_eq!(::std::mem::align_of::<root::nsTArray<::nsstring::nsStringRepr>>() , - 8usize); - } - #[test] - fn __bindgen_test_layout_template_17() { + fn __bindgen_test_layout_template_12() { assert_eq!(::std::mem::size_of::<root::nsCOMPtr<root::nsIPrincipal>>() , 8usize); assert_eq!(::std::mem::align_of::<root::nsCOMPtr<root::nsIPrincipal>>() , 8usize); } #[test] - fn __bindgen_test_layout_template_18() { - assert_eq!(::std::mem::size_of::<root::nsTArray<root::RefPtr<root::mozilla::dom::AnonymousContent>>>() - , 8usize); - assert_eq!(::std::mem::align_of::<root::nsTArray<root::RefPtr<root::mozilla::dom::AnonymousContent>>>() - , 8usize); - } - #[test] - fn __bindgen_test_layout_template_19() { + fn __bindgen_test_layout_template_13() { assert_eq!(::std::mem::size_of::<root::RefPtr<root::mozilla::dom::Element>>() , 8usize); assert_eq!(::std::mem::align_of::<root::RefPtr<root::mozilla::dom::Element>>() , 8usize); } #[test] - fn __bindgen_test_layout_template_20() { + fn __bindgen_test_layout_template_14() { assert_eq!(::std::mem::size_of::<root::nsTArray<root::RefPtr<root::mozilla::dom::Element>>>() , 8usize); assert_eq!(::std::mem::align_of::<root::nsTArray<root::RefPtr<root::mozilla::dom::Element>>>() , 8usize); } #[test] - fn __bindgen_test_layout_template_21() { + fn __bindgen_test_layout_template_15() { assert_eq!(::std::mem::size_of::<root::nsCOMPtr<root::nsIObserver>>() , 8usize); assert_eq!(::std::mem::align_of::<root::nsCOMPtr<root::nsIObserver>>() , 8usize); } #[test] - fn __bindgen_test_layout_template_22() { - assert_eq!(::std::mem::size_of::<root::nsTArray<root::nsCOMPtr<root::nsIObserver>>>() - , 8usize); - assert_eq!(::std::mem::align_of::<root::nsTArray<root::nsCOMPtr<root::nsIObserver>>>() - , 8usize); - } - #[test] - fn __bindgen_test_layout_template_23() { + fn __bindgen_test_layout_template_16() { assert_eq!(::std::mem::size_of::<root::nsCOMPtr<root::nsIWeakReference>>() , 8usize); assert_eq!(::std::mem::align_of::<root::nsCOMPtr<root::nsIWeakReference>>() , 8usize); } #[test] - fn __bindgen_test_layout_template_24() { + fn __bindgen_test_layout_template_17() { assert_eq!(::std::mem::size_of::<root::nsTArray<*mut root::nsIContent>>() , 8usize); assert_eq!(::std::mem::align_of::<root::nsTArray<*mut root::nsIContent>>() , 8usize); } #[test] - fn __bindgen_test_layout_template_25() { + fn __bindgen_test_layout_template_18() { + assert_eq!(::std::mem::size_of::<root::nsTArray<::nsstring::nsStringRepr>>() , + 8usize); + assert_eq!(::std::mem::align_of::<root::nsTArray<::nsstring::nsStringRepr>>() , + 8usize); + } + #[test] + fn __bindgen_test_layout_template_19() { + assert_eq!(::std::mem::size_of::<root::mozilla::DefaultDelete<root::mozilla::dom::TimeoutManager>>() + , 1usize); + assert_eq!(::std::mem::align_of::<root::mozilla::DefaultDelete<root::mozilla::dom::TimeoutManager>>() + , 1usize); + } + #[test] + fn __bindgen_test_layout_template_20() { assert_eq!(::std::mem::size_of::<root::nsCOMPtr<root::nsIRunnable>>() , 8usize); assert_eq!(::std::mem::align_of::<root::nsCOMPtr<root::nsIRunnable>>() , 8usize); } #[test] - fn __bindgen_test_layout_template_26() { + fn __bindgen_test_layout_template_21() { assert_eq!(::std::mem::size_of::<root::mozilla::OwningNonNull<root::nsINode>>() , 8usize); assert_eq!(::std::mem::align_of::<root::mozilla::OwningNonNull<root::nsINode>>() , 8usize); } #[test] - fn __bindgen_test_layout_template_27() { + fn __bindgen_test_layout_template_22() { assert_eq!(::std::mem::size_of::<root::nsTArray<f64>>() , 8usize); assert_eq!(::std::mem::align_of::<root::nsTArray<f64>>() , 8usize); } #[test] - fn __bindgen_test_layout_template_28() { + fn __bindgen_test_layout_template_23() { assert_eq!(::std::mem::size_of::<root::RefPtr<root::mozilla::dom::DOMIntersectionObserverEntry>>() , 8usize); assert_eq!(::std::mem::align_of::<root::RefPtr<root::mozilla::dom::DOMIntersectionObserverEntry>>() , 8usize); } #[test] - fn __bindgen_test_layout_template_29() { + fn __bindgen_test_layout_template_24() { assert_eq!(::std::mem::size_of::<root::nsTArray<root::RefPtr<root::mozilla::dom::DOMIntersectionObserverEntry>>>() , 8usize); assert_eq!(::std::mem::align_of::<root::nsTArray<root::RefPtr<root::mozilla::dom::DOMIntersectionObserverEntry>>>() , 8usize); } #[test] - fn __bindgen_test_layout_template_30() { - assert_eq!(::std::mem::size_of::<root::nsTArray<root::mozilla::FontFamilyName>>() - , 8usize); - assert_eq!(::std::mem::align_of::<root::nsTArray<root::mozilla::FontFamilyName>>() + fn __bindgen_test_layout_template_25() { + assert_eq!(::std::mem::size_of::<root::nsMainThreadPtrHolder<root::nsIURI>>() + , 24usize); + assert_eq!(::std::mem::align_of::<root::nsMainThreadPtrHolder<root::nsIURI>>() , 8usize); } #[test] - fn __bindgen_test_layout_template_31() { - assert_eq!(::std::mem::size_of::<root::nsTArray<root::mozilla::FramePropertyTable_PropertyValue>>() + fn __bindgen_test_layout_template_26() { + assert_eq!(::std::mem::size_of::<root::nsMainThreadPtrHolder<root::nsIPrincipal>>() + , 24usize); + assert_eq!(::std::mem::align_of::<root::nsMainThreadPtrHolder<root::nsIPrincipal>>() , 8usize); - assert_eq!(::std::mem::align_of::<root::nsTArray<root::mozilla::FramePropertyTable_PropertyValue>>() + } + #[test] + fn __bindgen_test_layout_template_27() { + assert_eq!(::std::mem::size_of::<root::nsPtrHashKey<root::nsIFrame>>() + , 16usize); + assert_eq!(::std::mem::align_of::<root::nsPtrHashKey<root::nsIFrame>>() , 8usize); } #[test] - fn __bindgen_test_layout_template_32() { + fn __bindgen_test_layout_template_28() { assert_eq!(::std::mem::size_of::<root::nsTArray<root::mozilla::DisplayItemClip_RoundedRect>>() , 8usize); assert_eq!(::std::mem::align_of::<root::nsTArray<root::mozilla::DisplayItemClip_RoundedRect>>() , 8usize); } #[test] - fn __bindgen_test_layout_template_33() { + fn __bindgen_test_layout_template_29() { assert_eq!(::std::mem::size_of::<root::RefPtr<root::mozilla::dom::DOMRect>>() , 8usize); assert_eq!(::std::mem::align_of::<root::RefPtr<root::mozilla::dom::DOMRect>>() , 8usize); } #[test] - fn __bindgen_test_layout_template_34() { + fn __bindgen_test_layout_template_30() { assert_eq!(::std::mem::size_of::<root::mozilla::DefaultDelete<root::ProxyBehaviour>>() , 1usize); assert_eq!(::std::mem::align_of::<root::mozilla::DefaultDelete<root::ProxyBehaviour>>() , 1usize); } #[test] - fn __bindgen_test_layout_template_35() { + fn __bindgen_test_layout_template_31() { assert_eq!(::std::mem::size_of::<root::mozilla::DefaultDelete<root::nsStyleSides>>() , 1usize); assert_eq!(::std::mem::align_of::<root::mozilla::DefaultDelete<root::nsStyleSides>>() , 1usize); } #[test] - fn __bindgen_test_layout_template_36() { + fn __bindgen_test_layout_template_32() { assert_eq!(::std::mem::size_of::<root::mozilla::DefaultDelete<root::CachedBorderImageData>>() , 1usize); assert_eq!(::std::mem::align_of::<root::mozilla::DefaultDelete<root::CachedBorderImageData>>() , 1usize); } #[test] - fn __bindgen_test_layout_template_37() { + fn __bindgen_test_layout_template_33() { assert_eq!(::std::mem::size_of::<root::std::pair<::nsstring::nsStringRepr, ::nsstring::nsStringRepr>>() , 32usize); assert_eq!(::std::mem::align_of::<root::std::pair<::nsstring::nsStringRepr, ::nsstring::nsStringRepr>>() , 8usize); } - #[test] - fn __bindgen_test_layout_template_38() { - assert_eq!(::std::mem::size_of::<root::nsMainThreadPtrHolder<root::nsIPrincipal>>() - , 24usize); - assert_eq!(::std::mem::align_of::<root::nsMainThreadPtrHolder<root::nsIPrincipal>>() - , 8usize); - } - #[test] - fn __bindgen_test_layout_template_39() { - assert_eq!(::std::mem::size_of::<root::nsMainThreadPtrHolder<root::nsIURI>>() - , 24usize); - assert_eq!(::std::mem::align_of::<root::nsMainThreadPtrHolder<root::nsIURI>>() - , 8usize); - } } diff --git a/components/style/gecko_string_cache/atom_macro.rs b/components/style/gecko_string_cache/atom_macro.rs index 66e0925a1d3..fb8abab1acb 100644 --- a/components/style/gecko_string_cache/atom_macro.rs +++ b/components/style/gecko_string_cache/atom_macro.rs @@ -11,8 +11,6 @@ pub enum nsICSSPseudoElement {} pub enum nsICSSAnonBoxPseudo {} -pub enum nsICSSProperty {} - #[inline(always)] pub unsafe fn atom_from_static(ptr: *mut nsIAtom) -> Atom { Atom::from_static(ptr) @@ -1366,6 +1364,8 @@ cfg_if! { pub static nsGkAtoms_onattributewritereq: *mut nsIAtom; #[link_name = "_ZN9nsGkAtoms14onaudioprocessE"] pub static nsGkAtoms_onaudioprocess: *mut nsIAtom; + #[link_name = "_ZN9nsGkAtoms10onauxclickE"] + pub static nsGkAtoms_onauxclick: *mut nsIAtom; #[link_name = "_ZN9nsGkAtoms12onbeforecopyE"] pub static nsGkAtoms_onbeforecopy: *mut nsIAtom; #[link_name = "_ZN9nsGkAtoms11onbeforecutE"] @@ -1638,14 +1638,6 @@ cfg_if! { pub static nsGkAtoms_onmouseup: *mut nsIAtom; #[link_name = "_ZN9nsGkAtoms15onMozAfterPaintE"] pub static nsGkAtoms_onMozAfterPaint: *mut nsIAtom; - #[link_name = "_ZN9nsGkAtoms24onmozbrowserafterkeydownE"] - pub static nsGkAtoms_onmozbrowserafterkeydown: *mut nsIAtom; - #[link_name = "_ZN9nsGkAtoms22onmozbrowserafterkeyupE"] - pub static nsGkAtoms_onmozbrowserafterkeyup: *mut nsIAtom; - #[link_name = "_ZN9nsGkAtoms25onmozbrowserbeforekeydownE"] - pub static nsGkAtoms_onmozbrowserbeforekeydown: *mut nsIAtom; - #[link_name = "_ZN9nsGkAtoms23onmozbrowserbeforekeyupE"] - pub static nsGkAtoms_onmozbrowserbeforekeyup: *mut nsIAtom; #[link_name = "_ZN9nsGkAtoms21onmozfullscreenchangeE"] pub static nsGkAtoms_onmozfullscreenchange: *mut nsIAtom; #[link_name = "_ZN9nsGkAtoms20onmozfullscreenerrorE"] @@ -1840,6 +1832,8 @@ cfg_if! { pub static nsGkAtoms_ontouchmove: *mut nsIAtom; #[link_name = "_ZN9nsGkAtoms13ontouchcancelE"] pub static nsGkAtoms_ontouchcancel: *mut nsIAtom; + #[link_name = "_ZN9nsGkAtoms18ontransitioncancelE"] + pub static nsGkAtoms_ontransitioncancel: *mut nsIAtom; #[link_name = "_ZN9nsGkAtoms15ontransitionendE"] pub static nsGkAtoms_ontransitionend: *mut nsIAtom; #[link_name = "_ZN9nsGkAtoms15ontransitionrunE"] @@ -2302,8 +2296,6 @@ cfg_if! { pub static nsGkAtoms_spinner: *mut nsIAtom; #[link_name = "_ZN9nsGkAtoms5splitE"] pub static nsGkAtoms_split: *mut nsIAtom; - #[link_name = "_ZN9nsGkAtoms9splitmenuE"] - pub static nsGkAtoms_splitmenu: *mut nsIAtom; #[link_name = "_ZN9nsGkAtoms8splitterE"] pub static nsGkAtoms_splitter: *mut nsIAtom; #[link_name = "_ZN9nsGkAtoms6springE"] @@ -4008,6 +4000,8 @@ cfg_if! { pub static nsGkAtoms_svgForeignObjectFrame: *mut nsIAtom; #[link_name = "_ZN9nsGkAtoms24svgGenericContainerFrameE"] pub static nsGkAtoms_svgGenericContainerFrame: *mut nsIAtom; + #[link_name = "_ZN9nsGkAtoms16svgGeometryFrameE"] + pub static nsGkAtoms_svgGeometryFrame: *mut nsIAtom; #[link_name = "_ZN9nsGkAtoms9svgGFrameE"] pub static nsGkAtoms_svgGFrame: *mut nsIAtom; #[link_name = "_ZN9nsGkAtoms16svgGradientFrameE"] @@ -4028,8 +4022,6 @@ cfg_if! { pub static nsGkAtoms_svgOuterSVGFrame: *mut nsIAtom; #[link_name = "_ZN9nsGkAtoms25svgOuterSVGAnonChildFrameE"] pub static nsGkAtoms_svgOuterSVGAnonChildFrame: *mut nsIAtom; - #[link_name = "_ZN9nsGkAtoms20svgPathGeometryFrameE"] - pub static nsGkAtoms_svgPathGeometryFrame: *mut nsIAtom; #[link_name = "_ZN9nsGkAtoms15svgPatternFrameE"] pub static nsGkAtoms_svgPatternFrame: *mut nsIAtom; #[link_name = "_ZN9nsGkAtoms22svgRadialGradientFrameE"] @@ -4938,732 +4930,6 @@ cfg_if! { pub static nsCSSAnonBoxes_mozSVGForeignContent: *mut nsICSSAnonBoxPseudo; #[link_name = "_ZN14nsCSSAnonBoxes10mozSVGTextE"] pub static nsCSSAnonBoxes_mozSVGText: *mut nsICSSAnonBoxPseudo; - #[link_name = "_ZN10nsCSSProps13align_contentE"] - pub static nsCSSProps_align_content: *mut nsICSSProperty; - #[link_name = "_ZN10nsCSSProps11align_itemsE"] - pub static nsCSSProps_align_items: *mut nsICSSProperty; - #[link_name = "_ZN10nsCSSProps10align_selfE"] - pub static nsCSSProps_align_self: *mut nsICSSProperty; - #[link_name = "_ZN10nsCSSProps3allE"] - pub static nsCSSProps_all: *mut nsICSSProperty; - #[link_name = "_ZN10nsCSSProps9animationE"] - pub static nsCSSProps_animation: *mut nsICSSProperty; - #[link_name = "_ZN10nsCSSProps15animation_delayE"] - pub static nsCSSProps_animation_delay: *mut nsICSSProperty; - #[link_name = "_ZN10nsCSSProps19animation_directionE"] - pub static nsCSSProps_animation_direction: *mut nsICSSProperty; - #[link_name = "_ZN10nsCSSProps18animation_durationE"] - pub static nsCSSProps_animation_duration: *mut nsICSSProperty; - #[link_name = "_ZN10nsCSSProps19animation_fill_modeE"] - pub static nsCSSProps_animation_fill_mode: *mut nsICSSProperty; - #[link_name = "_ZN10nsCSSProps25animation_iteration_countE"] - pub static nsCSSProps_animation_iteration_count: *mut nsICSSProperty; - #[link_name = "_ZN10nsCSSProps14animation_nameE"] - pub static nsCSSProps_animation_name: *mut nsICSSProperty; - #[link_name = "_ZN10nsCSSProps20animation_play_stateE"] - pub static nsCSSProps_animation_play_state: *mut nsICSSProperty; - #[link_name = "_ZN10nsCSSProps25animation_timing_functionE"] - pub static nsCSSProps_animation_timing_function: *mut nsICSSProperty; - #[link_name = "_ZN10nsCSSProps10appearanceE"] - pub static nsCSSProps_appearance: *mut nsICSSProperty; - #[link_name = "_ZN10nsCSSProps19backface_visibilityE"] - pub static nsCSSProps_backface_visibility: *mut nsICSSProperty; - #[link_name = "_ZN10nsCSSProps10backgroundE"] - pub static nsCSSProps_background: *mut nsICSSProperty; - #[link_name = "_ZN10nsCSSProps21background_attachmentE"] - pub static nsCSSProps_background_attachment: *mut nsICSSProperty; - #[link_name = "_ZN10nsCSSProps21background_blend_modeE"] - pub static nsCSSProps_background_blend_mode: *mut nsICSSProperty; - #[link_name = "_ZN10nsCSSProps15background_clipE"] - pub static nsCSSProps_background_clip: *mut nsICSSProperty; - #[link_name = "_ZN10nsCSSProps16background_colorE"] - pub static nsCSSProps_background_color: *mut nsICSSProperty; - #[link_name = "_ZN10nsCSSProps16background_imageE"] - pub static nsCSSProps_background_image: *mut nsICSSProperty; - #[link_name = "_ZN10nsCSSProps17background_originE"] - pub static nsCSSProps_background_origin: *mut nsICSSProperty; - #[link_name = "_ZN10nsCSSProps19background_positionE"] - pub static nsCSSProps_background_position: *mut nsICSSProperty; - #[link_name = "_ZN10nsCSSProps21background_position_xE"] - pub static nsCSSProps_background_position_x: *mut nsICSSProperty; - #[link_name = "_ZN10nsCSSProps21background_position_yE"] - pub static nsCSSProps_background_position_y: *mut nsICSSProperty; - #[link_name = "_ZN10nsCSSProps17background_repeatE"] - pub static nsCSSProps_background_repeat: *mut nsICSSProperty; - #[link_name = "_ZN10nsCSSProps15background_sizeE"] - pub static nsCSSProps_background_size: *mut nsICSSProperty; - #[link_name = "_ZN10nsCSSProps7bindingE"] - pub static nsCSSProps_binding: *mut nsICSSProperty; - #[link_name = "_ZN10nsCSSProps10block_sizeE"] - pub static nsCSSProps_block_size: *mut nsICSSProperty; - #[link_name = "_ZN10nsCSSProps6borderE"] - pub static nsCSSProps_border: *mut nsICSSProperty; - #[link_name = "_ZN10nsCSSProps16border_block_endE"] - pub static nsCSSProps_border_block_end: *mut nsICSSProperty; - #[link_name = "_ZN10nsCSSProps22border_block_end_colorE"] - pub static nsCSSProps_border_block_end_color: *mut nsICSSProperty; - #[link_name = "_ZN10nsCSSProps22border_block_end_styleE"] - pub static nsCSSProps_border_block_end_style: *mut nsICSSProperty; - #[link_name = "_ZN10nsCSSProps22border_block_end_widthE"] - pub static nsCSSProps_border_block_end_width: *mut nsICSSProperty; - #[link_name = "_ZN10nsCSSProps18border_block_startE"] - pub static nsCSSProps_border_block_start: *mut nsICSSProperty; - #[link_name = "_ZN10nsCSSProps24border_block_start_colorE"] - pub static nsCSSProps_border_block_start_color: *mut nsICSSProperty; - #[link_name = "_ZN10nsCSSProps24border_block_start_styleE"] - pub static nsCSSProps_border_block_start_style: *mut nsICSSProperty; - #[link_name = "_ZN10nsCSSProps24border_block_start_widthE"] - pub static nsCSSProps_border_block_start_width: *mut nsICSSProperty; - #[link_name = "_ZN10nsCSSProps13border_bottomE"] - pub static nsCSSProps_border_bottom: *mut nsICSSProperty; - #[link_name = "_ZN10nsCSSProps19border_bottom_colorE"] - pub static nsCSSProps_border_bottom_color: *mut nsICSSProperty; - #[link_name = "_ZN10nsCSSProps20border_bottom_colorsE"] - pub static nsCSSProps_border_bottom_colors: *mut nsICSSProperty; - #[link_name = "_ZN10nsCSSProps25border_bottom_left_radiusE"] - pub static nsCSSProps_border_bottom_left_radius: *mut nsICSSProperty; - #[link_name = "_ZN10nsCSSProps26border_bottom_right_radiusE"] - pub static nsCSSProps_border_bottom_right_radius: *mut nsICSSProperty; - #[link_name = "_ZN10nsCSSProps19border_bottom_styleE"] - pub static nsCSSProps_border_bottom_style: *mut nsICSSProperty; - #[link_name = "_ZN10nsCSSProps19border_bottom_widthE"] - pub static nsCSSProps_border_bottom_width: *mut nsICSSProperty; - #[link_name = "_ZN10nsCSSProps15border_collapseE"] - pub static nsCSSProps_border_collapse: *mut nsICSSProperty; - #[link_name = "_ZN10nsCSSProps12border_colorE"] - pub static nsCSSProps_border_color: *mut nsICSSProperty; - #[link_name = "_ZN10nsCSSProps12border_imageE"] - pub static nsCSSProps_border_image: *mut nsICSSProperty; - #[link_name = "_ZN10nsCSSProps19border_image_outsetE"] - pub static nsCSSProps_border_image_outset: *mut nsICSSProperty; - #[link_name = "_ZN10nsCSSProps19border_image_repeatE"] - pub static nsCSSProps_border_image_repeat: *mut nsICSSProperty; - #[link_name = "_ZN10nsCSSProps18border_image_sliceE"] - pub static nsCSSProps_border_image_slice: *mut nsICSSProperty; - #[link_name = "_ZN10nsCSSProps19border_image_sourceE"] - pub static nsCSSProps_border_image_source: *mut nsICSSProperty; - #[link_name = "_ZN10nsCSSProps18border_image_widthE"] - pub static nsCSSProps_border_image_width: *mut nsICSSProperty; - #[link_name = "_ZN10nsCSSProps17border_inline_endE"] - pub static nsCSSProps_border_inline_end: *mut nsICSSProperty; - #[link_name = "_ZN10nsCSSProps23border_inline_end_colorE"] - pub static nsCSSProps_border_inline_end_color: *mut nsICSSProperty; - #[link_name = "_ZN10nsCSSProps23border_inline_end_styleE"] - pub static nsCSSProps_border_inline_end_style: *mut nsICSSProperty; - #[link_name = "_ZN10nsCSSProps23border_inline_end_widthE"] - pub static nsCSSProps_border_inline_end_width: *mut nsICSSProperty; - #[link_name = "_ZN10nsCSSProps19border_inline_startE"] - pub static nsCSSProps_border_inline_start: *mut nsICSSProperty; - #[link_name = "_ZN10nsCSSProps25border_inline_start_colorE"] - pub static nsCSSProps_border_inline_start_color: *mut nsICSSProperty; - #[link_name = "_ZN10nsCSSProps25border_inline_start_styleE"] - pub static nsCSSProps_border_inline_start_style: *mut nsICSSProperty; - #[link_name = "_ZN10nsCSSProps25border_inline_start_widthE"] - pub static nsCSSProps_border_inline_start_width: *mut nsICSSProperty; - #[link_name = "_ZN10nsCSSProps11border_leftE"] - pub static nsCSSProps_border_left: *mut nsICSSProperty; - #[link_name = "_ZN10nsCSSProps17border_left_colorE"] - pub static nsCSSProps_border_left_color: *mut nsICSSProperty; - #[link_name = "_ZN10nsCSSProps18border_left_colorsE"] - pub static nsCSSProps_border_left_colors: *mut nsICSSProperty; - #[link_name = "_ZN10nsCSSProps17border_left_styleE"] - pub static nsCSSProps_border_left_style: *mut nsICSSProperty; - #[link_name = "_ZN10nsCSSProps17border_left_widthE"] - pub static nsCSSProps_border_left_width: *mut nsICSSProperty; - #[link_name = "_ZN10nsCSSProps13border_radiusE"] - pub static nsCSSProps_border_radius: *mut nsICSSProperty; - #[link_name = "_ZN10nsCSSProps12border_rightE"] - pub static nsCSSProps_border_right: *mut nsICSSProperty; - #[link_name = "_ZN10nsCSSProps18border_right_colorE"] - pub static nsCSSProps_border_right_color: *mut nsICSSProperty; - #[link_name = "_ZN10nsCSSProps19border_right_colorsE"] - pub static nsCSSProps_border_right_colors: *mut nsICSSProperty; - #[link_name = "_ZN10nsCSSProps18border_right_styleE"] - pub static nsCSSProps_border_right_style: *mut nsICSSProperty; - #[link_name = "_ZN10nsCSSProps18border_right_widthE"] - pub static nsCSSProps_border_right_width: *mut nsICSSProperty; - #[link_name = "_ZN10nsCSSProps14border_spacingE"] - pub static nsCSSProps_border_spacing: *mut nsICSSProperty; - #[link_name = "_ZN10nsCSSProps12border_styleE"] - pub static nsCSSProps_border_style: *mut nsICSSProperty; - #[link_name = "_ZN10nsCSSProps10border_topE"] - pub static nsCSSProps_border_top: *mut nsICSSProperty; - #[link_name = "_ZN10nsCSSProps16border_top_colorE"] - pub static nsCSSProps_border_top_color: *mut nsICSSProperty; - #[link_name = "_ZN10nsCSSProps17border_top_colorsE"] - pub static nsCSSProps_border_top_colors: *mut nsICSSProperty; - #[link_name = "_ZN10nsCSSProps22border_top_left_radiusE"] - pub static nsCSSProps_border_top_left_radius: *mut nsICSSProperty; - #[link_name = "_ZN10nsCSSProps23border_top_right_radiusE"] - pub static nsCSSProps_border_top_right_radius: *mut nsICSSProperty; - #[link_name = "_ZN10nsCSSProps16border_top_styleE"] - pub static nsCSSProps_border_top_style: *mut nsICSSProperty; - #[link_name = "_ZN10nsCSSProps16border_top_widthE"] - pub static nsCSSProps_border_top_width: *mut nsICSSProperty; - #[link_name = "_ZN10nsCSSProps12border_widthE"] - pub static nsCSSProps_border_width: *mut nsICSSProperty; - #[link_name = "_ZN10nsCSSProps6bottomE"] - pub static nsCSSProps_bottom: *mut nsICSSProperty; - #[link_name = "_ZN10nsCSSProps9box_alignE"] - pub static nsCSSProps_box_align: *mut nsICSSProperty; - #[link_name = "_ZN10nsCSSProps20box_decoration_breakE"] - pub static nsCSSProps_box_decoration_break: *mut nsICSSProperty; - #[link_name = "_ZN10nsCSSProps13box_directionE"] - pub static nsCSSProps_box_direction: *mut nsICSSProperty; - #[link_name = "_ZN10nsCSSProps8box_flexE"] - pub static nsCSSProps_box_flex: *mut nsICSSProperty; - #[link_name = "_ZN10nsCSSProps17box_ordinal_groupE"] - pub static nsCSSProps_box_ordinal_group: *mut nsICSSProperty; - #[link_name = "_ZN10nsCSSProps10box_orientE"] - pub static nsCSSProps_box_orient: *mut nsICSSProperty; - #[link_name = "_ZN10nsCSSProps8box_packE"] - pub static nsCSSProps_box_pack: *mut nsICSSProperty; - #[link_name = "_ZN10nsCSSProps10box_shadowE"] - pub static nsCSSProps_box_shadow: *mut nsICSSProperty; - #[link_name = "_ZN10nsCSSProps10box_sizingE"] - pub static nsCSSProps_box_sizing: *mut nsICSSProperty; - #[link_name = "_ZN10nsCSSProps12caption_sideE"] - pub static nsCSSProps_caption_side: *mut nsICSSProperty; - #[link_name = "_ZN10nsCSSProps5clearE"] - pub static nsCSSProps_clear: *mut nsICSSProperty; - #[link_name = "_ZN10nsCSSProps4clipE"] - pub static nsCSSProps_clip: *mut nsICSSProperty; - #[link_name = "_ZN10nsCSSProps9clip_pathE"] - pub static nsCSSProps_clip_path: *mut nsICSSProperty; - #[link_name = "_ZN10nsCSSProps9clip_ruleE"] - pub static nsCSSProps_clip_rule: *mut nsICSSProperty; - #[link_name = "_ZN10nsCSSProps5colorE"] - pub static nsCSSProps_color: *mut nsICSSProperty; - #[link_name = "_ZN10nsCSSProps12color_adjustE"] - pub static nsCSSProps_color_adjust: *mut nsICSSProperty; - #[link_name = "_ZN10nsCSSProps19color_interpolationE"] - pub static nsCSSProps_color_interpolation: *mut nsICSSProperty; - #[link_name = "_ZN10nsCSSProps27color_interpolation_filtersE"] - pub static nsCSSProps_color_interpolation_filters: *mut nsICSSProperty; - #[link_name = "_ZN10nsCSSProps12column_countE"] - pub static nsCSSProps_column_count: *mut nsICSSProperty; - #[link_name = "_ZN10nsCSSProps11column_fillE"] - pub static nsCSSProps_column_fill: *mut nsICSSProperty; - #[link_name = "_ZN10nsCSSProps10column_gapE"] - pub static nsCSSProps_column_gap: *mut nsICSSProperty; - #[link_name = "_ZN10nsCSSProps11column_ruleE"] - pub static nsCSSProps_column_rule: *mut nsICSSProperty; - #[link_name = "_ZN10nsCSSProps17column_rule_colorE"] - pub static nsCSSProps_column_rule_color: *mut nsICSSProperty; - #[link_name = "_ZN10nsCSSProps17column_rule_styleE"] - pub static nsCSSProps_column_rule_style: *mut nsICSSProperty; - #[link_name = "_ZN10nsCSSProps17column_rule_widthE"] - pub static nsCSSProps_column_rule_width: *mut nsICSSProperty; - #[link_name = "_ZN10nsCSSProps12column_widthE"] - pub static nsCSSProps_column_width: *mut nsICSSProperty; - #[link_name = "_ZN10nsCSSProps7columnsE"] - pub static nsCSSProps_columns: *mut nsICSSProperty; - #[link_name = "_ZN10nsCSSProps7containE"] - pub static nsCSSProps_contain: *mut nsICSSProperty; - #[link_name = "_ZN10nsCSSProps7contentE"] - pub static nsCSSProps_content: *mut nsICSSProperty; - #[link_name = "_ZN10nsCSSProps33_moz_control_character_visibilityE"] - pub static nsCSSProps__moz_control_character_visibility: *mut nsICSSProperty; - #[link_name = "_ZN10nsCSSProps17counter_incrementE"] - pub static nsCSSProps_counter_increment: *mut nsICSSProperty; - #[link_name = "_ZN10nsCSSProps13counter_resetE"] - pub static nsCSSProps_counter_reset: *mut nsICSSProperty; - #[link_name = "_ZN10nsCSSProps6cursorE"] - pub static nsCSSProps_cursor: *mut nsICSSProperty; - #[link_name = "_ZN10nsCSSProps9directionE"] - pub static nsCSSProps_direction: *mut nsICSSProperty; - #[link_name = "_ZN10nsCSSProps7displayE"] - pub static nsCSSProps_display: *mut nsICSSProperty; - #[link_name = "_ZN10nsCSSProps17dominant_baselineE"] - pub static nsCSSProps_dominant_baseline: *mut nsICSSProperty; - #[link_name = "_ZN10nsCSSProps11empty_cellsE"] - pub static nsCSSProps_empty_cells: *mut nsICSSProperty; - #[link_name = "_ZN10nsCSSProps4fillE"] - pub static nsCSSProps_fill: *mut nsICSSProperty; - #[link_name = "_ZN10nsCSSProps12fill_opacityE"] - pub static nsCSSProps_fill_opacity: *mut nsICSSProperty; - #[link_name = "_ZN10nsCSSProps9fill_ruleE"] - pub static nsCSSProps_fill_rule: *mut nsICSSProperty; - #[link_name = "_ZN10nsCSSProps6filterE"] - pub static nsCSSProps_filter: *mut nsICSSProperty; - #[link_name = "_ZN10nsCSSProps4flexE"] - pub static nsCSSProps_flex: *mut nsICSSProperty; - #[link_name = "_ZN10nsCSSProps10flex_basisE"] - pub static nsCSSProps_flex_basis: *mut nsICSSProperty; - #[link_name = "_ZN10nsCSSProps14flex_directionE"] - pub static nsCSSProps_flex_direction: *mut nsICSSProperty; - #[link_name = "_ZN10nsCSSProps9flex_flowE"] - pub static nsCSSProps_flex_flow: *mut nsICSSProperty; - #[link_name = "_ZN10nsCSSProps9flex_growE"] - pub static nsCSSProps_flex_grow: *mut nsICSSProperty; - #[link_name = "_ZN10nsCSSProps11flex_shrinkE"] - pub static nsCSSProps_flex_shrink: *mut nsICSSProperty; - #[link_name = "_ZN10nsCSSProps9flex_wrapE"] - pub static nsCSSProps_flex_wrap: *mut nsICSSProperty; - #[link_name = "_ZN10nsCSSProps6float_E"] - pub static nsCSSProps_float_: *mut nsICSSProperty; - #[link_name = "_ZN10nsCSSProps10float_edgeE"] - pub static nsCSSProps_float_edge: *mut nsICSSProperty; - #[link_name = "_ZN10nsCSSProps11flood_colorE"] - pub static nsCSSProps_flood_color: *mut nsICSSProperty; - #[link_name = "_ZN10nsCSSProps13flood_opacityE"] - pub static nsCSSProps_flood_opacity: *mut nsICSSProperty; - #[link_name = "_ZN10nsCSSProps4fontE"] - pub static nsCSSProps_font: *mut nsICSSProperty; - #[link_name = "_ZN10nsCSSProps11font_familyE"] - pub static nsCSSProps_font_family: *mut nsICSSProperty; - #[link_name = "_ZN10nsCSSProps21font_feature_settingsE"] - pub static nsCSSProps_font_feature_settings: *mut nsICSSProperty; - #[link_name = "_ZN10nsCSSProps12font_kerningE"] - pub static nsCSSProps_font_kerning: *mut nsICSSProperty; - #[link_name = "_ZN10nsCSSProps22font_language_overrideE"] - pub static nsCSSProps_font_language_override: *mut nsICSSProperty; - #[link_name = "_ZN10nsCSSProps9font_sizeE"] - pub static nsCSSProps_font_size: *mut nsICSSProperty; - #[link_name = "_ZN10nsCSSProps16font_size_adjustE"] - pub static nsCSSProps_font_size_adjust: *mut nsICSSProperty; - #[link_name = "_ZN10nsCSSProps12font_stretchE"] - pub static nsCSSProps_font_stretch: *mut nsICSSProperty; - #[link_name = "_ZN10nsCSSProps10font_styleE"] - pub static nsCSSProps_font_style: *mut nsICSSProperty; - #[link_name = "_ZN10nsCSSProps14font_synthesisE"] - pub static nsCSSProps_font_synthesis: *mut nsICSSProperty; - #[link_name = "_ZN10nsCSSProps12font_variantE"] - pub static nsCSSProps_font_variant: *mut nsICSSProperty; - #[link_name = "_ZN10nsCSSProps23font_variant_alternatesE"] - pub static nsCSSProps_font_variant_alternates: *mut nsICSSProperty; - #[link_name = "_ZN10nsCSSProps17font_variant_capsE"] - pub static nsCSSProps_font_variant_caps: *mut nsICSSProperty; - #[link_name = "_ZN10nsCSSProps23font_variant_east_asianE"] - pub static nsCSSProps_font_variant_east_asian: *mut nsICSSProperty; - #[link_name = "_ZN10nsCSSProps22font_variant_ligaturesE"] - pub static nsCSSProps_font_variant_ligatures: *mut nsICSSProperty; - #[link_name = "_ZN10nsCSSProps20font_variant_numericE"] - pub static nsCSSProps_font_variant_numeric: *mut nsICSSProperty; - #[link_name = "_ZN10nsCSSProps21font_variant_positionE"] - pub static nsCSSProps_font_variant_position: *mut nsICSSProperty; - #[link_name = "_ZN10nsCSSProps23font_variation_settingsE"] - pub static nsCSSProps_font_variation_settings: *mut nsICSSProperty; - #[link_name = "_ZN10nsCSSProps11font_weightE"] - pub static nsCSSProps_font_weight: *mut nsICSSProperty; - #[link_name = "_ZN10nsCSSProps23force_broken_image_iconE"] - pub static nsCSSProps_force_broken_image_icon: *mut nsICSSProperty; - #[link_name = "_ZN10nsCSSProps4gridE"] - pub static nsCSSProps_grid: *mut nsICSSProperty; - #[link_name = "_ZN10nsCSSProps9grid_areaE"] - pub static nsCSSProps_grid_area: *mut nsICSSProperty; - #[link_name = "_ZN10nsCSSProps17grid_auto_columnsE"] - pub static nsCSSProps_grid_auto_columns: *mut nsICSSProperty; - #[link_name = "_ZN10nsCSSProps14grid_auto_flowE"] - pub static nsCSSProps_grid_auto_flow: *mut nsICSSProperty; - #[link_name = "_ZN10nsCSSProps14grid_auto_rowsE"] - pub static nsCSSProps_grid_auto_rows: *mut nsICSSProperty; - #[link_name = "_ZN10nsCSSProps11grid_columnE"] - pub static nsCSSProps_grid_column: *mut nsICSSProperty; - #[link_name = "_ZN10nsCSSProps15grid_column_endE"] - pub static nsCSSProps_grid_column_end: *mut nsICSSProperty; - #[link_name = "_ZN10nsCSSProps15grid_column_gapE"] - pub static nsCSSProps_grid_column_gap: *mut nsICSSProperty; - #[link_name = "_ZN10nsCSSProps17grid_column_startE"] - pub static nsCSSProps_grid_column_start: *mut nsICSSProperty; - #[link_name = "_ZN10nsCSSProps8grid_gapE"] - pub static nsCSSProps_grid_gap: *mut nsICSSProperty; - #[link_name = "_ZN10nsCSSProps8grid_rowE"] - pub static nsCSSProps_grid_row: *mut nsICSSProperty; - #[link_name = "_ZN10nsCSSProps12grid_row_endE"] - pub static nsCSSProps_grid_row_end: *mut nsICSSProperty; - #[link_name = "_ZN10nsCSSProps12grid_row_gapE"] - pub static nsCSSProps_grid_row_gap: *mut nsICSSProperty; - #[link_name = "_ZN10nsCSSProps14grid_row_startE"] - pub static nsCSSProps_grid_row_start: *mut nsICSSProperty; - #[link_name = "_ZN10nsCSSProps13grid_templateE"] - pub static nsCSSProps_grid_template: *mut nsICSSProperty; - #[link_name = "_ZN10nsCSSProps19grid_template_areasE"] - pub static nsCSSProps_grid_template_areas: *mut nsICSSProperty; - #[link_name = "_ZN10nsCSSProps21grid_template_columnsE"] - pub static nsCSSProps_grid_template_columns: *mut nsICSSProperty; - #[link_name = "_ZN10nsCSSProps18grid_template_rowsE"] - pub static nsCSSProps_grid_template_rows: *mut nsICSSProperty; - #[link_name = "_ZN10nsCSSProps6heightE"] - pub static nsCSSProps_height: *mut nsICSSProperty; - #[link_name = "_ZN10nsCSSProps7hyphensE"] - pub static nsCSSProps_hyphens: *mut nsICSSProperty; - #[link_name = "_ZN10nsCSSProps14initial_letterE"] - pub static nsCSSProps_initial_letter: *mut nsICSSProperty; - #[link_name = "_ZN10nsCSSProps17image_orientationE"] - pub static nsCSSProps_image_orientation: *mut nsICSSProperty; - #[link_name = "_ZN10nsCSSProps12image_regionE"] - pub static nsCSSProps_image_region: *mut nsICSSProperty; - #[link_name = "_ZN10nsCSSProps15image_renderingE"] - pub static nsCSSProps_image_rendering: *mut nsICSSProperty; - #[link_name = "_ZN10nsCSSProps8ime_modeE"] - pub static nsCSSProps_ime_mode: *mut nsICSSProperty; - #[link_name = "_ZN10nsCSSProps11inline_sizeE"] - pub static nsCSSProps_inline_size: *mut nsICSSProperty; - #[link_name = "_ZN10nsCSSProps9isolationE"] - pub static nsCSSProps_isolation: *mut nsICSSProperty; - #[link_name = "_ZN10nsCSSProps15justify_contentE"] - pub static nsCSSProps_justify_content: *mut nsICSSProperty; - #[link_name = "_ZN10nsCSSProps13justify_itemsE"] - pub static nsCSSProps_justify_items: *mut nsICSSProperty; - #[link_name = "_ZN10nsCSSProps12justify_selfE"] - pub static nsCSSProps_justify_self: *mut nsICSSProperty; - #[link_name = "_ZN10nsCSSProps7_x_langE"] - pub static nsCSSProps__x_lang: *mut nsICSSProperty; - #[link_name = "_ZN10nsCSSProps4leftE"] - pub static nsCSSProps_left: *mut nsICSSProperty; - #[link_name = "_ZN10nsCSSProps14letter_spacingE"] - pub static nsCSSProps_letter_spacing: *mut nsICSSProperty; - #[link_name = "_ZN10nsCSSProps14lighting_colorE"] - pub static nsCSSProps_lighting_color: *mut nsICSSProperty; - #[link_name = "_ZN10nsCSSProps11line_heightE"] - pub static nsCSSProps_line_height: *mut nsICSSProperty; - #[link_name = "_ZN10nsCSSProps10list_styleE"] - pub static nsCSSProps_list_style: *mut nsICSSProperty; - #[link_name = "_ZN10nsCSSProps16list_style_imageE"] - pub static nsCSSProps_list_style_image: *mut nsICSSProperty; - #[link_name = "_ZN10nsCSSProps19list_style_positionE"] - pub static nsCSSProps_list_style_position: *mut nsICSSProperty; - #[link_name = "_ZN10nsCSSProps15list_style_typeE"] - pub static nsCSSProps_list_style_type: *mut nsICSSProperty; - #[link_name = "_ZN10nsCSSProps6marginE"] - pub static nsCSSProps_margin: *mut nsICSSProperty; - #[link_name = "_ZN10nsCSSProps16margin_block_endE"] - pub static nsCSSProps_margin_block_end: *mut nsICSSProperty; - #[link_name = "_ZN10nsCSSProps18margin_block_startE"] - pub static nsCSSProps_margin_block_start: *mut nsICSSProperty; - #[link_name = "_ZN10nsCSSProps13margin_bottomE"] - pub static nsCSSProps_margin_bottom: *mut nsICSSProperty; - #[link_name = "_ZN10nsCSSProps17margin_inline_endE"] - pub static nsCSSProps_margin_inline_end: *mut nsICSSProperty; - #[link_name = "_ZN10nsCSSProps19margin_inline_startE"] - pub static nsCSSProps_margin_inline_start: *mut nsICSSProperty; - #[link_name = "_ZN10nsCSSProps11margin_leftE"] - pub static nsCSSProps_margin_left: *mut nsICSSProperty; - #[link_name = "_ZN10nsCSSProps12margin_rightE"] - pub static nsCSSProps_margin_right: *mut nsICSSProperty; - #[link_name = "_ZN10nsCSSProps10margin_topE"] - pub static nsCSSProps_margin_top: *mut nsICSSProperty; - #[link_name = "_ZN10nsCSSProps6markerE"] - pub static nsCSSProps_marker: *mut nsICSSProperty; - #[link_name = "_ZN10nsCSSProps10marker_endE"] - pub static nsCSSProps_marker_end: *mut nsICSSProperty; - #[link_name = "_ZN10nsCSSProps10marker_midE"] - pub static nsCSSProps_marker_mid: *mut nsICSSProperty; - #[link_name = "_ZN10nsCSSProps12marker_startE"] - pub static nsCSSProps_marker_start: *mut nsICSSProperty; - #[link_name = "_ZN10nsCSSProps4maskE"] - pub static nsCSSProps_mask: *mut nsICSSProperty; - #[link_name = "_ZN10nsCSSProps9mask_clipE"] - pub static nsCSSProps_mask_clip: *mut nsICSSProperty; - #[link_name = "_ZN10nsCSSProps14mask_compositeE"] - pub static nsCSSProps_mask_composite: *mut nsICSSProperty; - #[link_name = "_ZN10nsCSSProps10mask_imageE"] - pub static nsCSSProps_mask_image: *mut nsICSSProperty; - #[link_name = "_ZN10nsCSSProps9mask_modeE"] - pub static nsCSSProps_mask_mode: *mut nsICSSProperty; - #[link_name = "_ZN10nsCSSProps11mask_originE"] - pub static nsCSSProps_mask_origin: *mut nsICSSProperty; - #[link_name = "_ZN10nsCSSProps13mask_positionE"] - pub static nsCSSProps_mask_position: *mut nsICSSProperty; - #[link_name = "_ZN10nsCSSProps15mask_position_xE"] - pub static nsCSSProps_mask_position_x: *mut nsICSSProperty; - #[link_name = "_ZN10nsCSSProps15mask_position_yE"] - pub static nsCSSProps_mask_position_y: *mut nsICSSProperty; - #[link_name = "_ZN10nsCSSProps11mask_repeatE"] - pub static nsCSSProps_mask_repeat: *mut nsICSSProperty; - #[link_name = "_ZN10nsCSSProps9mask_sizeE"] - pub static nsCSSProps_mask_size: *mut nsICSSProperty; - #[link_name = "_ZN10nsCSSProps9mask_typeE"] - pub static nsCSSProps_mask_type: *mut nsICSSProperty; - #[link_name = "_ZN10nsCSSProps12math_displayE"] - pub static nsCSSProps_math_display: *mut nsICSSProperty; - #[link_name = "_ZN10nsCSSProps12math_variantE"] - pub static nsCSSProps_math_variant: *mut nsICSSProperty; - #[link_name = "_ZN10nsCSSProps14max_block_sizeE"] - pub static nsCSSProps_max_block_size: *mut nsICSSProperty; - #[link_name = "_ZN10nsCSSProps10max_heightE"] - pub static nsCSSProps_max_height: *mut nsICSSProperty; - #[link_name = "_ZN10nsCSSProps15max_inline_sizeE"] - pub static nsCSSProps_max_inline_size: *mut nsICSSProperty; - #[link_name = "_ZN10nsCSSProps9max_widthE"] - pub static nsCSSProps_max_width: *mut nsICSSProperty; - #[link_name = "_ZN10nsCSSProps14min_block_sizeE"] - pub static nsCSSProps_min_block_size: *mut nsICSSProperty; - #[link_name = "_ZN10nsCSSProps24_moz_min_font_size_ratioE"] - pub static nsCSSProps__moz_min_font_size_ratio: *mut nsICSSProperty; - #[link_name = "_ZN10nsCSSProps10min_heightE"] - pub static nsCSSProps_min_height: *mut nsICSSProperty; - #[link_name = "_ZN10nsCSSProps15min_inline_sizeE"] - pub static nsCSSProps_min_inline_size: *mut nsICSSProperty; - #[link_name = "_ZN10nsCSSProps9min_widthE"] - pub static nsCSSProps_min_width: *mut nsICSSProperty; - #[link_name = "_ZN10nsCSSProps14mix_blend_modeE"] - pub static nsCSSProps_mix_blend_mode: *mut nsICSSProperty; - #[link_name = "_ZN10nsCSSProps10object_fitE"] - pub static nsCSSProps_object_fit: *mut nsICSSProperty; - #[link_name = "_ZN10nsCSSProps15object_positionE"] - pub static nsCSSProps_object_position: *mut nsICSSProperty; - #[link_name = "_ZN10nsCSSProps16offset_block_endE"] - pub static nsCSSProps_offset_block_end: *mut nsICSSProperty; - #[link_name = "_ZN10nsCSSProps18offset_block_startE"] - pub static nsCSSProps_offset_block_start: *mut nsICSSProperty; - #[link_name = "_ZN10nsCSSProps17offset_inline_endE"] - pub static nsCSSProps_offset_inline_end: *mut nsICSSProperty; - #[link_name = "_ZN10nsCSSProps19offset_inline_startE"] - pub static nsCSSProps_offset_inline_start: *mut nsICSSProperty; - #[link_name = "_ZN10nsCSSProps7opacityE"] - pub static nsCSSProps_opacity: *mut nsICSSProperty; - #[link_name = "_ZN10nsCSSProps5orderE"] - pub static nsCSSProps_order: *mut nsICSSProperty; - #[link_name = "_ZN10nsCSSProps6orientE"] - pub static nsCSSProps_orient: *mut nsICSSProperty; - #[link_name = "_ZN10nsCSSProps18osx_font_smoothingE"] - pub static nsCSSProps_osx_font_smoothing: *mut nsICSSProperty; - #[link_name = "_ZN10nsCSSProps7outlineE"] - pub static nsCSSProps_outline: *mut nsICSSProperty; - #[link_name = "_ZN10nsCSSProps13outline_colorE"] - pub static nsCSSProps_outline_color: *mut nsICSSProperty; - #[link_name = "_ZN10nsCSSProps14outline_offsetE"] - pub static nsCSSProps_outline_offset: *mut nsICSSProperty; - #[link_name = "_ZN10nsCSSProps19_moz_outline_radiusE"] - pub static nsCSSProps__moz_outline_radius: *mut nsICSSProperty; - #[link_name = "_ZN10nsCSSProps30_moz_outline_radius_bottomLeftE"] - pub static nsCSSProps__moz_outline_radius_bottomLeft: *mut nsICSSProperty; - #[link_name = "_ZN10nsCSSProps31_moz_outline_radius_bottomRightE"] - pub static nsCSSProps__moz_outline_radius_bottomRight: *mut nsICSSProperty; - #[link_name = "_ZN10nsCSSProps27_moz_outline_radius_topLeftE"] - pub static nsCSSProps__moz_outline_radius_topLeft: *mut nsICSSProperty; - #[link_name = "_ZN10nsCSSProps28_moz_outline_radius_topRightE"] - pub static nsCSSProps__moz_outline_radius_topRight: *mut nsICSSProperty; - #[link_name = "_ZN10nsCSSProps13outline_styleE"] - pub static nsCSSProps_outline_style: *mut nsICSSProperty; - #[link_name = "_ZN10nsCSSProps13outline_widthE"] - pub static nsCSSProps_outline_width: *mut nsICSSProperty; - #[link_name = "_ZN10nsCSSProps8overflowE"] - pub static nsCSSProps_overflow: *mut nsICSSProperty; - #[link_name = "_ZN10nsCSSProps17overflow_clip_boxE"] - pub static nsCSSProps_overflow_clip_box: *mut nsICSSProperty; - #[link_name = "_ZN10nsCSSProps10overflow_xE"] - pub static nsCSSProps_overflow_x: *mut nsICSSProperty; - #[link_name = "_ZN10nsCSSProps10overflow_yE"] - pub static nsCSSProps_overflow_y: *mut nsICSSProperty; - #[link_name = "_ZN10nsCSSProps7paddingE"] - pub static nsCSSProps_padding: *mut nsICSSProperty; - #[link_name = "_ZN10nsCSSProps17padding_block_endE"] - pub static nsCSSProps_padding_block_end: *mut nsICSSProperty; - #[link_name = "_ZN10nsCSSProps19padding_block_startE"] - pub static nsCSSProps_padding_block_start: *mut nsICSSProperty; - #[link_name = "_ZN10nsCSSProps14padding_bottomE"] - pub static nsCSSProps_padding_bottom: *mut nsICSSProperty; - #[link_name = "_ZN10nsCSSProps18padding_inline_endE"] - pub static nsCSSProps_padding_inline_end: *mut nsICSSProperty; - #[link_name = "_ZN10nsCSSProps20padding_inline_startE"] - pub static nsCSSProps_padding_inline_start: *mut nsICSSProperty; - #[link_name = "_ZN10nsCSSProps12padding_leftE"] - pub static nsCSSProps_padding_left: *mut nsICSSProperty; - #[link_name = "_ZN10nsCSSProps13padding_rightE"] - pub static nsCSSProps_padding_right: *mut nsICSSProperty; - #[link_name = "_ZN10nsCSSProps11padding_topE"] - pub static nsCSSProps_padding_top: *mut nsICSSProperty; - #[link_name = "_ZN10nsCSSProps16page_break_afterE"] - pub static nsCSSProps_page_break_after: *mut nsICSSProperty; - #[link_name = "_ZN10nsCSSProps17page_break_beforeE"] - pub static nsCSSProps_page_break_before: *mut nsICSSProperty; - #[link_name = "_ZN10nsCSSProps17page_break_insideE"] - pub static nsCSSProps_page_break_inside: *mut nsICSSProperty; - #[link_name = "_ZN10nsCSSProps11paint_orderE"] - pub static nsCSSProps_paint_order: *mut nsICSSProperty; - #[link_name = "_ZN10nsCSSProps11perspectiveE"] - pub static nsCSSProps_perspective: *mut nsICSSProperty; - #[link_name = "_ZN10nsCSSProps18perspective_originE"] - pub static nsCSSProps_perspective_origin: *mut nsICSSProperty; - #[link_name = "_ZN10nsCSSProps13place_contentE"] - pub static nsCSSProps_place_content: *mut nsICSSProperty; - #[link_name = "_ZN10nsCSSProps11place_itemsE"] - pub static nsCSSProps_place_items: *mut nsICSSProperty; - #[link_name = "_ZN10nsCSSProps10place_selfE"] - pub static nsCSSProps_place_self: *mut nsICSSProperty; - #[link_name = "_ZN10nsCSSProps14pointer_eventsE"] - pub static nsCSSProps_pointer_events: *mut nsICSSProperty; - #[link_name = "_ZN10nsCSSProps8positionE"] - pub static nsCSSProps_position: *mut nsICSSProperty; - #[link_name = "_ZN10nsCSSProps6quotesE"] - pub static nsCSSProps_quotes: *mut nsICSSProperty; - #[link_name = "_ZN10nsCSSProps6resizeE"] - pub static nsCSSProps_resize: *mut nsICSSProperty; - #[link_name = "_ZN10nsCSSProps5rightE"] - pub static nsCSSProps_right: *mut nsICSSProperty; - #[link_name = "_ZN10nsCSSProps10ruby_alignE"] - pub static nsCSSProps_ruby_align: *mut nsICSSProperty; - #[link_name = "_ZN10nsCSSProps13ruby_positionE"] - pub static nsCSSProps_ruby_position: *mut nsICSSProperty; - #[link_name = "_ZN10nsCSSProps12script_levelE"] - pub static nsCSSProps_script_level: *mut nsICSSProperty; - #[link_name = "_ZN10nsCSSProps15script_min_sizeE"] - pub static nsCSSProps_script_min_size: *mut nsICSSProperty; - #[link_name = "_ZN10nsCSSProps22script_size_multiplierE"] - pub static nsCSSProps_script_size_multiplier: *mut nsICSSProperty; - #[link_name = "_ZN10nsCSSProps15scroll_behaviorE"] - pub static nsCSSProps_scroll_behavior: *mut nsICSSProperty; - #[link_name = "_ZN10nsCSSProps22scroll_snap_coordinateE"] - pub static nsCSSProps_scroll_snap_coordinate: *mut nsICSSProperty; - #[link_name = "_ZN10nsCSSProps23scroll_snap_destinationE"] - pub static nsCSSProps_scroll_snap_destination: *mut nsICSSProperty; - #[link_name = "_ZN10nsCSSProps20scroll_snap_points_xE"] - pub static nsCSSProps_scroll_snap_points_x: *mut nsICSSProperty; - #[link_name = "_ZN10nsCSSProps20scroll_snap_points_yE"] - pub static nsCSSProps_scroll_snap_points_y: *mut nsICSSProperty; - #[link_name = "_ZN10nsCSSProps16scroll_snap_typeE"] - pub static nsCSSProps_scroll_snap_type: *mut nsICSSProperty; - #[link_name = "_ZN10nsCSSProps18scroll_snap_type_xE"] - pub static nsCSSProps_scroll_snap_type_x: *mut nsICSSProperty; - #[link_name = "_ZN10nsCSSProps18scroll_snap_type_yE"] - pub static nsCSSProps_scroll_snap_type_y: *mut nsICSSProperty; - #[link_name = "_ZN10nsCSSProps13shape_outsideE"] - pub static nsCSSProps_shape_outside: *mut nsICSSProperty; - #[link_name = "_ZN10nsCSSProps15shape_renderingE"] - pub static nsCSSProps_shape_rendering: *mut nsICSSProperty; - #[link_name = "_ZN10nsCSSProps7_x_spanE"] - pub static nsCSSProps__x_span: *mut nsICSSProperty; - #[link_name = "_ZN10nsCSSProps12stack_sizingE"] - pub static nsCSSProps_stack_sizing: *mut nsICSSProperty; - #[link_name = "_ZN10nsCSSProps10stop_colorE"] - pub static nsCSSProps_stop_color: *mut nsICSSProperty; - #[link_name = "_ZN10nsCSSProps12stop_opacityE"] - pub static nsCSSProps_stop_opacity: *mut nsICSSProperty; - #[link_name = "_ZN10nsCSSProps6strokeE"] - pub static nsCSSProps_stroke: *mut nsICSSProperty; - #[link_name = "_ZN10nsCSSProps16stroke_dasharrayE"] - pub static nsCSSProps_stroke_dasharray: *mut nsICSSProperty; - #[link_name = "_ZN10nsCSSProps17stroke_dashoffsetE"] - pub static nsCSSProps_stroke_dashoffset: *mut nsICSSProperty; - #[link_name = "_ZN10nsCSSProps14stroke_linecapE"] - pub static nsCSSProps_stroke_linecap: *mut nsICSSProperty; - #[link_name = "_ZN10nsCSSProps15stroke_linejoinE"] - pub static nsCSSProps_stroke_linejoin: *mut nsICSSProperty; - #[link_name = "_ZN10nsCSSProps17stroke_miterlimitE"] - pub static nsCSSProps_stroke_miterlimit: *mut nsICSSProperty; - #[link_name = "_ZN10nsCSSProps14stroke_opacityE"] - pub static nsCSSProps_stroke_opacity: *mut nsICSSProperty; - #[link_name = "_ZN10nsCSSProps12stroke_widthE"] - pub static nsCSSProps_stroke_width: *mut nsICSSProperty; - #[link_name = "_ZN10nsCSSProps14_x_system_fontE"] - pub static nsCSSProps__x_system_font: *mut nsICSSProperty; - #[link_name = "_ZN10nsCSSProps13_moz_tab_sizeE"] - pub static nsCSSProps__moz_tab_size: *mut nsICSSProperty; - #[link_name = "_ZN10nsCSSProps12table_layoutE"] - pub static nsCSSProps_table_layout: *mut nsICSSProperty; - #[link_name = "_ZN10nsCSSProps10text_alignE"] - pub static nsCSSProps_text_align: *mut nsICSSProperty; - #[link_name = "_ZN10nsCSSProps15text_align_lastE"] - pub static nsCSSProps_text_align_last: *mut nsICSSProperty; - #[link_name = "_ZN10nsCSSProps11text_anchorE"] - pub static nsCSSProps_text_anchor: *mut nsICSSProperty; - #[link_name = "_ZN10nsCSSProps20text_combine_uprightE"] - pub static nsCSSProps_text_combine_upright: *mut nsICSSProperty; - #[link_name = "_ZN10nsCSSProps15text_decorationE"] - pub static nsCSSProps_text_decoration: *mut nsICSSProperty; - #[link_name = "_ZN10nsCSSProps21text_decoration_colorE"] - pub static nsCSSProps_text_decoration_color: *mut nsICSSProperty; - #[link_name = "_ZN10nsCSSProps20text_decoration_lineE"] - pub static nsCSSProps_text_decoration_line: *mut nsICSSProperty; - #[link_name = "_ZN10nsCSSProps21text_decoration_styleE"] - pub static nsCSSProps_text_decoration_style: *mut nsICSSProperty; - #[link_name = "_ZN10nsCSSProps13text_emphasisE"] - pub static nsCSSProps_text_emphasis: *mut nsICSSProperty; - #[link_name = "_ZN10nsCSSProps19text_emphasis_colorE"] - pub static nsCSSProps_text_emphasis_color: *mut nsICSSProperty; - #[link_name = "_ZN10nsCSSProps22text_emphasis_positionE"] - pub static nsCSSProps_text_emphasis_position: *mut nsICSSProperty; - #[link_name = "_ZN10nsCSSProps19text_emphasis_styleE"] - pub static nsCSSProps_text_emphasis_style: *mut nsICSSProperty; - #[link_name = "_ZN10nsCSSProps23_webkit_text_fill_colorE"] - pub static nsCSSProps__webkit_text_fill_color: *mut nsICSSProperty; - #[link_name = "_ZN10nsCSSProps11text_indentE"] - pub static nsCSSProps_text_indent: *mut nsICSSProperty; - #[link_name = "_ZN10nsCSSProps16text_orientationE"] - pub static nsCSSProps_text_orientation: *mut nsICSSProperty; - #[link_name = "_ZN10nsCSSProps13text_overflowE"] - pub static nsCSSProps_text_overflow: *mut nsICSSProperty; - #[link_name = "_ZN10nsCSSProps14text_renderingE"] - pub static nsCSSProps_text_rendering: *mut nsICSSProperty; - #[link_name = "_ZN10nsCSSProps11text_shadowE"] - pub static nsCSSProps_text_shadow: *mut nsICSSProperty; - #[link_name = "_ZN10nsCSSProps16text_size_adjustE"] - pub static nsCSSProps_text_size_adjust: *mut nsICSSProperty; - #[link_name = "_ZN10nsCSSProps19_webkit_text_strokeE"] - pub static nsCSSProps__webkit_text_stroke: *mut nsICSSProperty; - #[link_name = "_ZN10nsCSSProps25_webkit_text_stroke_colorE"] - pub static nsCSSProps__webkit_text_stroke_color: *mut nsICSSProperty; - #[link_name = "_ZN10nsCSSProps25_webkit_text_stroke_widthE"] - pub static nsCSSProps__webkit_text_stroke_width: *mut nsICSSProperty; - #[link_name = "_ZN10nsCSSProps14text_transformE"] - pub static nsCSSProps_text_transform: *mut nsICSSProperty; - #[link_name = "_ZN10nsCSSProps12_x_text_zoomE"] - pub static nsCSSProps__x_text_zoom: *mut nsICSSProperty; - #[link_name = "_ZN10nsCSSProps3topE"] - pub static nsCSSProps_top: *mut nsICSSProperty; - #[link_name = "_ZN10nsCSSProps14_moz_top_layerE"] - pub static nsCSSProps__moz_top_layer: *mut nsICSSProperty; - #[link_name = "_ZN10nsCSSProps12touch_actionE"] - pub static nsCSSProps_touch_action: *mut nsICSSProperty; - #[link_name = "_ZN10nsCSSProps9transformE"] - pub static nsCSSProps_transform: *mut nsICSSProperty; - #[link_name = "_ZN10nsCSSProps14_moz_transformE"] - pub static nsCSSProps__moz_transform: *mut nsICSSProperty; - #[link_name = "_ZN10nsCSSProps13transform_boxE"] - pub static nsCSSProps_transform_box: *mut nsICSSProperty; - #[link_name = "_ZN10nsCSSProps16transform_originE"] - pub static nsCSSProps_transform_origin: *mut nsICSSProperty; - #[link_name = "_ZN10nsCSSProps15transform_styleE"] - pub static nsCSSProps_transform_style: *mut nsICSSProperty; - #[link_name = "_ZN10nsCSSProps10transitionE"] - pub static nsCSSProps_transition: *mut nsICSSProperty; - #[link_name = "_ZN10nsCSSProps16transition_delayE"] - pub static nsCSSProps_transition_delay: *mut nsICSSProperty; - #[link_name = "_ZN10nsCSSProps19transition_durationE"] - pub static nsCSSProps_transition_duration: *mut nsICSSProperty; - #[link_name = "_ZN10nsCSSProps19transition_propertyE"] - pub static nsCSSProps_transition_property: *mut nsICSSProperty; - #[link_name = "_ZN10nsCSSProps26transition_timing_functionE"] - pub static nsCSSProps_transition_timing_function: *mut nsICSSProperty; - #[link_name = "_ZN10nsCSSProps12unicode_bidiE"] - pub static nsCSSProps_unicode_bidi: *mut nsICSSProperty; - #[link_name = "_ZN10nsCSSProps10user_focusE"] - pub static nsCSSProps_user_focus: *mut nsICSSProperty; - #[link_name = "_ZN10nsCSSProps10user_inputE"] - pub static nsCSSProps_user_input: *mut nsICSSProperty; - #[link_name = "_ZN10nsCSSProps11user_modifyE"] - pub static nsCSSProps_user_modify: *mut nsICSSProperty; - #[link_name = "_ZN10nsCSSProps11user_selectE"] - pub static nsCSSProps_user_select: *mut nsICSSProperty; - #[link_name = "_ZN10nsCSSProps13vector_effectE"] - pub static nsCSSProps_vector_effect: *mut nsICSSProperty; - #[link_name = "_ZN10nsCSSProps14vertical_alignE"] - pub static nsCSSProps_vertical_align: *mut nsICSSProperty; - #[link_name = "_ZN10nsCSSProps10visibilityE"] - pub static nsCSSProps_visibility: *mut nsICSSProperty; - #[link_name = "_ZN10nsCSSProps11white_spaceE"] - pub static nsCSSProps_white_space: *mut nsICSSProperty; - #[link_name = "_ZN10nsCSSProps5widthE"] - pub static nsCSSProps_width: *mut nsICSSProperty; - #[link_name = "_ZN10nsCSSProps11will_changeE"] - pub static nsCSSProps_will_change: *mut nsICSSProperty; - #[link_name = "_ZN10nsCSSProps20_moz_window_draggingE"] - pub static nsCSSProps__moz_window_dragging: *mut nsICSSProperty; - #[link_name = "_ZN10nsCSSProps18_moz_window_shadowE"] - pub static nsCSSProps__moz_window_shadow: *mut nsICSSProperty; - #[link_name = "_ZN10nsCSSProps10word_breakE"] - pub static nsCSSProps_word_break: *mut nsICSSProperty; - #[link_name = "_ZN10nsCSSProps12word_spacingE"] - pub static nsCSSProps_word_spacing: *mut nsICSSProperty; - #[link_name = "_ZN10nsCSSProps13overflow_wrapE"] - pub static nsCSSProps_overflow_wrap: *mut nsICSSProperty; - #[link_name = "_ZN10nsCSSProps12writing_modeE"] - pub static nsCSSProps_writing_mode: *mut nsICSSProperty; - #[link_name = "_ZN10nsCSSProps7z_indexE"] - pub static nsCSSProps_z_index: *mut nsICSSProperty; } } else if #[cfg(target_pointer_width = "64")] { extern { @@ -7011,6 +6277,8 @@ cfg_if! { pub static nsGkAtoms_onattributewritereq: *mut nsIAtom; #[link_name = "?onaudioprocess@nsGkAtoms@@2PEAVnsIAtom@@EA"] pub static nsGkAtoms_onaudioprocess: *mut nsIAtom; + #[link_name = "?onauxclick@nsGkAtoms@@2PEAVnsIAtom@@EA"] + pub static nsGkAtoms_onauxclick: *mut nsIAtom; #[link_name = "?onbeforecopy@nsGkAtoms@@2PEAVnsIAtom@@EA"] pub static nsGkAtoms_onbeforecopy: *mut nsIAtom; #[link_name = "?onbeforecut@nsGkAtoms@@2PEAVnsIAtom@@EA"] @@ -7283,14 +6551,6 @@ cfg_if! { pub static nsGkAtoms_onmouseup: *mut nsIAtom; #[link_name = "?onMozAfterPaint@nsGkAtoms@@2PEAVnsIAtom@@EA"] pub static nsGkAtoms_onMozAfterPaint: *mut nsIAtom; - #[link_name = "?onmozbrowserafterkeydown@nsGkAtoms@@2PEAVnsIAtom@@EA"] - pub static nsGkAtoms_onmozbrowserafterkeydown: *mut nsIAtom; - #[link_name = "?onmozbrowserafterkeyup@nsGkAtoms@@2PEAVnsIAtom@@EA"] - pub static nsGkAtoms_onmozbrowserafterkeyup: *mut nsIAtom; - #[link_name = "?onmozbrowserbeforekeydown@nsGkAtoms@@2PEAVnsIAtom@@EA"] - pub static nsGkAtoms_onmozbrowserbeforekeydown: *mut nsIAtom; - #[link_name = "?onmozbrowserbeforekeyup@nsGkAtoms@@2PEAVnsIAtom@@EA"] - pub static nsGkAtoms_onmozbrowserbeforekeyup: *mut nsIAtom; #[link_name = "?onmozfullscreenchange@nsGkAtoms@@2PEAVnsIAtom@@EA"] pub static nsGkAtoms_onmozfullscreenchange: *mut nsIAtom; #[link_name = "?onmozfullscreenerror@nsGkAtoms@@2PEAVnsIAtom@@EA"] @@ -7485,6 +6745,8 @@ cfg_if! { pub static nsGkAtoms_ontouchmove: *mut nsIAtom; #[link_name = "?ontouchcancel@nsGkAtoms@@2PEAVnsIAtom@@EA"] pub static nsGkAtoms_ontouchcancel: *mut nsIAtom; + #[link_name = "?ontransitioncancel@nsGkAtoms@@2PEAVnsIAtom@@EA"] + pub static nsGkAtoms_ontransitioncancel: *mut nsIAtom; #[link_name = "?ontransitionend@nsGkAtoms@@2PEAVnsIAtom@@EA"] pub static nsGkAtoms_ontransitionend: *mut nsIAtom; #[link_name = "?ontransitionrun@nsGkAtoms@@2PEAVnsIAtom@@EA"] @@ -7947,8 +7209,6 @@ cfg_if! { pub static nsGkAtoms_spinner: *mut nsIAtom; #[link_name = "?split@nsGkAtoms@@2PEAVnsIAtom@@EA"] pub static nsGkAtoms_split: *mut nsIAtom; - #[link_name = "?splitmenu@nsGkAtoms@@2PEAVnsIAtom@@EA"] - pub static nsGkAtoms_splitmenu: *mut nsIAtom; #[link_name = "?splitter@nsGkAtoms@@2PEAVnsIAtom@@EA"] pub static nsGkAtoms_splitter: *mut nsIAtom; #[link_name = "?spring@nsGkAtoms@@2PEAVnsIAtom@@EA"] @@ -9653,6 +8913,8 @@ cfg_if! { pub static nsGkAtoms_svgForeignObjectFrame: *mut nsIAtom; #[link_name = "?svgGenericContainerFrame@nsGkAtoms@@2PEAVnsIAtom@@EA"] pub static nsGkAtoms_svgGenericContainerFrame: *mut nsIAtom; + #[link_name = "?svgGeometryFrame@nsGkAtoms@@2PEAVnsIAtom@@EA"] + pub static nsGkAtoms_svgGeometryFrame: *mut nsIAtom; #[link_name = "?svgGFrame@nsGkAtoms@@2PEAVnsIAtom@@EA"] pub static nsGkAtoms_svgGFrame: *mut nsIAtom; #[link_name = "?svgGradientFrame@nsGkAtoms@@2PEAVnsIAtom@@EA"] @@ -9673,8 +8935,6 @@ cfg_if! { pub static nsGkAtoms_svgOuterSVGFrame: *mut nsIAtom; #[link_name = "?svgOuterSVGAnonChildFrame@nsGkAtoms@@2PEAVnsIAtom@@EA"] pub static nsGkAtoms_svgOuterSVGAnonChildFrame: *mut nsIAtom; - #[link_name = "?svgPathGeometryFrame@nsGkAtoms@@2PEAVnsIAtom@@EA"] - pub static nsGkAtoms_svgPathGeometryFrame: *mut nsIAtom; #[link_name = "?svgPatternFrame@nsGkAtoms@@2PEAVnsIAtom@@EA"] pub static nsGkAtoms_svgPatternFrame: *mut nsIAtom; #[link_name = "?svgRadialGradientFrame@nsGkAtoms@@2PEAVnsIAtom@@EA"] @@ -10583,732 +9843,6 @@ cfg_if! { pub static nsCSSAnonBoxes_mozSVGForeignContent: *mut nsICSSAnonBoxPseudo; #[link_name = "?mozSVGText@nsCSSAnonBoxes@@2PEAVnsICSSAnonBoxPseudo@@EA"] pub static nsCSSAnonBoxes_mozSVGText: *mut nsICSSAnonBoxPseudo; - #[link_name = "?align_content@nsCSSProps@@2PEAVnsICSSProperty@@EA"] - pub static nsCSSProps_align_content: *mut nsICSSProperty; - #[link_name = "?align_items@nsCSSProps@@2PEAVnsICSSProperty@@EA"] - pub static nsCSSProps_align_items: *mut nsICSSProperty; - #[link_name = "?align_self@nsCSSProps@@2PEAVnsICSSProperty@@EA"] - pub static nsCSSProps_align_self: *mut nsICSSProperty; - #[link_name = "?all@nsCSSProps@@2PEAVnsICSSProperty@@EA"] - pub static nsCSSProps_all: *mut nsICSSProperty; - #[link_name = "?animation@nsCSSProps@@2PEAVnsICSSProperty@@EA"] - pub static nsCSSProps_animation: *mut nsICSSProperty; - #[link_name = "?animation_delay@nsCSSProps@@2PEAVnsICSSProperty@@EA"] - pub static nsCSSProps_animation_delay: *mut nsICSSProperty; - #[link_name = "?animation_direction@nsCSSProps@@2PEAVnsICSSProperty@@EA"] - pub static nsCSSProps_animation_direction: *mut nsICSSProperty; - #[link_name = "?animation_duration@nsCSSProps@@2PEAVnsICSSProperty@@EA"] - pub static nsCSSProps_animation_duration: *mut nsICSSProperty; - #[link_name = "?animation_fill_mode@nsCSSProps@@2PEAVnsICSSProperty@@EA"] - pub static nsCSSProps_animation_fill_mode: *mut nsICSSProperty; - #[link_name = "?animation_iteration_count@nsCSSProps@@2PEAVnsICSSProperty@@EA"] - pub static nsCSSProps_animation_iteration_count: *mut nsICSSProperty; - #[link_name = "?animation_name@nsCSSProps@@2PEAVnsICSSProperty@@EA"] - pub static nsCSSProps_animation_name: *mut nsICSSProperty; - #[link_name = "?animation_play_state@nsCSSProps@@2PEAVnsICSSProperty@@EA"] - pub static nsCSSProps_animation_play_state: *mut nsICSSProperty; - #[link_name = "?animation_timing_function@nsCSSProps@@2PEAVnsICSSProperty@@EA"] - pub static nsCSSProps_animation_timing_function: *mut nsICSSProperty; - #[link_name = "?appearance@nsCSSProps@@2PEAVnsICSSProperty@@EA"] - pub static nsCSSProps_appearance: *mut nsICSSProperty; - #[link_name = "?backface_visibility@nsCSSProps@@2PEAVnsICSSProperty@@EA"] - pub static nsCSSProps_backface_visibility: *mut nsICSSProperty; - #[link_name = "?background@nsCSSProps@@2PEAVnsICSSProperty@@EA"] - pub static nsCSSProps_background: *mut nsICSSProperty; - #[link_name = "?background_attachment@nsCSSProps@@2PEAVnsICSSProperty@@EA"] - pub static nsCSSProps_background_attachment: *mut nsICSSProperty; - #[link_name = "?background_blend_mode@nsCSSProps@@2PEAVnsICSSProperty@@EA"] - pub static nsCSSProps_background_blend_mode: *mut nsICSSProperty; - #[link_name = "?background_clip@nsCSSProps@@2PEAVnsICSSProperty@@EA"] - pub static nsCSSProps_background_clip: *mut nsICSSProperty; - #[link_name = "?background_color@nsCSSProps@@2PEAVnsICSSProperty@@EA"] - pub static nsCSSProps_background_color: *mut nsICSSProperty; - #[link_name = "?background_image@nsCSSProps@@2PEAVnsICSSProperty@@EA"] - pub static nsCSSProps_background_image: *mut nsICSSProperty; - #[link_name = "?background_origin@nsCSSProps@@2PEAVnsICSSProperty@@EA"] - pub static nsCSSProps_background_origin: *mut nsICSSProperty; - #[link_name = "?background_position@nsCSSProps@@2PEAVnsICSSProperty@@EA"] - pub static nsCSSProps_background_position: *mut nsICSSProperty; - #[link_name = "?background_position_x@nsCSSProps@@2PEAVnsICSSProperty@@EA"] - pub static nsCSSProps_background_position_x: *mut nsICSSProperty; - #[link_name = "?background_position_y@nsCSSProps@@2PEAVnsICSSProperty@@EA"] - pub static nsCSSProps_background_position_y: *mut nsICSSProperty; - #[link_name = "?background_repeat@nsCSSProps@@2PEAVnsICSSProperty@@EA"] - pub static nsCSSProps_background_repeat: *mut nsICSSProperty; - #[link_name = "?background_size@nsCSSProps@@2PEAVnsICSSProperty@@EA"] - pub static nsCSSProps_background_size: *mut nsICSSProperty; - #[link_name = "?binding@nsCSSProps@@2PEAVnsICSSProperty@@EA"] - pub static nsCSSProps_binding: *mut nsICSSProperty; - #[link_name = "?block_size@nsCSSProps@@2PEAVnsICSSProperty@@EA"] - pub static nsCSSProps_block_size: *mut nsICSSProperty; - #[link_name = "?border@nsCSSProps@@2PEAVnsICSSProperty@@EA"] - pub static nsCSSProps_border: *mut nsICSSProperty; - #[link_name = "?border_block_end@nsCSSProps@@2PEAVnsICSSProperty@@EA"] - pub static nsCSSProps_border_block_end: *mut nsICSSProperty; - #[link_name = "?border_block_end_color@nsCSSProps@@2PEAVnsICSSProperty@@EA"] - pub static nsCSSProps_border_block_end_color: *mut nsICSSProperty; - #[link_name = "?border_block_end_style@nsCSSProps@@2PEAVnsICSSProperty@@EA"] - pub static nsCSSProps_border_block_end_style: *mut nsICSSProperty; - #[link_name = "?border_block_end_width@nsCSSProps@@2PEAVnsICSSProperty@@EA"] - pub static nsCSSProps_border_block_end_width: *mut nsICSSProperty; - #[link_name = "?border_block_start@nsCSSProps@@2PEAVnsICSSProperty@@EA"] - pub static nsCSSProps_border_block_start: *mut nsICSSProperty; - #[link_name = "?border_block_start_color@nsCSSProps@@2PEAVnsICSSProperty@@EA"] - pub static nsCSSProps_border_block_start_color: *mut nsICSSProperty; - #[link_name = "?border_block_start_style@nsCSSProps@@2PEAVnsICSSProperty@@EA"] - pub static nsCSSProps_border_block_start_style: *mut nsICSSProperty; - #[link_name = "?border_block_start_width@nsCSSProps@@2PEAVnsICSSProperty@@EA"] - pub static nsCSSProps_border_block_start_width: *mut nsICSSProperty; - #[link_name = "?border_bottom@nsCSSProps@@2PEAVnsICSSProperty@@EA"] - pub static nsCSSProps_border_bottom: *mut nsICSSProperty; - #[link_name = "?border_bottom_color@nsCSSProps@@2PEAVnsICSSProperty@@EA"] - pub static nsCSSProps_border_bottom_color: *mut nsICSSProperty; - #[link_name = "?border_bottom_colors@nsCSSProps@@2PEAVnsICSSProperty@@EA"] - pub static nsCSSProps_border_bottom_colors: *mut nsICSSProperty; - #[link_name = "?border_bottom_left_radius@nsCSSProps@@2PEAVnsICSSProperty@@EA"] - pub static nsCSSProps_border_bottom_left_radius: *mut nsICSSProperty; - #[link_name = "?border_bottom_right_radius@nsCSSProps@@2PEAVnsICSSProperty@@EA"] - pub static nsCSSProps_border_bottom_right_radius: *mut nsICSSProperty; - #[link_name = "?border_bottom_style@nsCSSProps@@2PEAVnsICSSProperty@@EA"] - pub static nsCSSProps_border_bottom_style: *mut nsICSSProperty; - #[link_name = "?border_bottom_width@nsCSSProps@@2PEAVnsICSSProperty@@EA"] - pub static nsCSSProps_border_bottom_width: *mut nsICSSProperty; - #[link_name = "?border_collapse@nsCSSProps@@2PEAVnsICSSProperty@@EA"] - pub static nsCSSProps_border_collapse: *mut nsICSSProperty; - #[link_name = "?border_color@nsCSSProps@@2PEAVnsICSSProperty@@EA"] - pub static nsCSSProps_border_color: *mut nsICSSProperty; - #[link_name = "?border_image@nsCSSProps@@2PEAVnsICSSProperty@@EA"] - pub static nsCSSProps_border_image: *mut nsICSSProperty; - #[link_name = "?border_image_outset@nsCSSProps@@2PEAVnsICSSProperty@@EA"] - pub static nsCSSProps_border_image_outset: *mut nsICSSProperty; - #[link_name = "?border_image_repeat@nsCSSProps@@2PEAVnsICSSProperty@@EA"] - pub static nsCSSProps_border_image_repeat: *mut nsICSSProperty; - #[link_name = "?border_image_slice@nsCSSProps@@2PEAVnsICSSProperty@@EA"] - pub static nsCSSProps_border_image_slice: *mut nsICSSProperty; - #[link_name = "?border_image_source@nsCSSProps@@2PEAVnsICSSProperty@@EA"] - pub static nsCSSProps_border_image_source: *mut nsICSSProperty; - #[link_name = "?border_image_width@nsCSSProps@@2PEAVnsICSSProperty@@EA"] - pub static nsCSSProps_border_image_width: *mut nsICSSProperty; - #[link_name = "?border_inline_end@nsCSSProps@@2PEAVnsICSSProperty@@EA"] - pub static nsCSSProps_border_inline_end: *mut nsICSSProperty; - #[link_name = "?border_inline_end_color@nsCSSProps@@2PEAVnsICSSProperty@@EA"] - pub static nsCSSProps_border_inline_end_color: *mut nsICSSProperty; - #[link_name = "?border_inline_end_style@nsCSSProps@@2PEAVnsICSSProperty@@EA"] - pub static nsCSSProps_border_inline_end_style: *mut nsICSSProperty; - #[link_name = "?border_inline_end_width@nsCSSProps@@2PEAVnsICSSProperty@@EA"] - pub static nsCSSProps_border_inline_end_width: *mut nsICSSProperty; - #[link_name = "?border_inline_start@nsCSSProps@@2PEAVnsICSSProperty@@EA"] - pub static nsCSSProps_border_inline_start: *mut nsICSSProperty; - #[link_name = "?border_inline_start_color@nsCSSProps@@2PEAVnsICSSProperty@@EA"] - pub static nsCSSProps_border_inline_start_color: *mut nsICSSProperty; - #[link_name = "?border_inline_start_style@nsCSSProps@@2PEAVnsICSSProperty@@EA"] - pub static nsCSSProps_border_inline_start_style: *mut nsICSSProperty; - #[link_name = "?border_inline_start_width@nsCSSProps@@2PEAVnsICSSProperty@@EA"] - pub static nsCSSProps_border_inline_start_width: *mut nsICSSProperty; - #[link_name = "?border_left@nsCSSProps@@2PEAVnsICSSProperty@@EA"] - pub static nsCSSProps_border_left: *mut nsICSSProperty; - #[link_name = "?border_left_color@nsCSSProps@@2PEAVnsICSSProperty@@EA"] - pub static nsCSSProps_border_left_color: *mut nsICSSProperty; - #[link_name = "?border_left_colors@nsCSSProps@@2PEAVnsICSSProperty@@EA"] - pub static nsCSSProps_border_left_colors: *mut nsICSSProperty; - #[link_name = "?border_left_style@nsCSSProps@@2PEAVnsICSSProperty@@EA"] - pub static nsCSSProps_border_left_style: *mut nsICSSProperty; - #[link_name = "?border_left_width@nsCSSProps@@2PEAVnsICSSProperty@@EA"] - pub static nsCSSProps_border_left_width: *mut nsICSSProperty; - #[link_name = "?border_radius@nsCSSProps@@2PEAVnsICSSProperty@@EA"] - pub static nsCSSProps_border_radius: *mut nsICSSProperty; - #[link_name = "?border_right@nsCSSProps@@2PEAVnsICSSProperty@@EA"] - pub static nsCSSProps_border_right: *mut nsICSSProperty; - #[link_name = "?border_right_color@nsCSSProps@@2PEAVnsICSSProperty@@EA"] - pub static nsCSSProps_border_right_color: *mut nsICSSProperty; - #[link_name = "?border_right_colors@nsCSSProps@@2PEAVnsICSSProperty@@EA"] - pub static nsCSSProps_border_right_colors: *mut nsICSSProperty; - #[link_name = "?border_right_style@nsCSSProps@@2PEAVnsICSSProperty@@EA"] - pub static nsCSSProps_border_right_style: *mut nsICSSProperty; - #[link_name = "?border_right_width@nsCSSProps@@2PEAVnsICSSProperty@@EA"] - pub static nsCSSProps_border_right_width: *mut nsICSSProperty; - #[link_name = "?border_spacing@nsCSSProps@@2PEAVnsICSSProperty@@EA"] - pub static nsCSSProps_border_spacing: *mut nsICSSProperty; - #[link_name = "?border_style@nsCSSProps@@2PEAVnsICSSProperty@@EA"] - pub static nsCSSProps_border_style: *mut nsICSSProperty; - #[link_name = "?border_top@nsCSSProps@@2PEAVnsICSSProperty@@EA"] - pub static nsCSSProps_border_top: *mut nsICSSProperty; - #[link_name = "?border_top_color@nsCSSProps@@2PEAVnsICSSProperty@@EA"] - pub static nsCSSProps_border_top_color: *mut nsICSSProperty; - #[link_name = "?border_top_colors@nsCSSProps@@2PEAVnsICSSProperty@@EA"] - pub static nsCSSProps_border_top_colors: *mut nsICSSProperty; - #[link_name = "?border_top_left_radius@nsCSSProps@@2PEAVnsICSSProperty@@EA"] - pub static nsCSSProps_border_top_left_radius: *mut nsICSSProperty; - #[link_name = "?border_top_right_radius@nsCSSProps@@2PEAVnsICSSProperty@@EA"] - pub static nsCSSProps_border_top_right_radius: *mut nsICSSProperty; - #[link_name = "?border_top_style@nsCSSProps@@2PEAVnsICSSProperty@@EA"] - pub static nsCSSProps_border_top_style: *mut nsICSSProperty; - #[link_name = "?border_top_width@nsCSSProps@@2PEAVnsICSSProperty@@EA"] - pub static nsCSSProps_border_top_width: *mut nsICSSProperty; - #[link_name = "?border_width@nsCSSProps@@2PEAVnsICSSProperty@@EA"] - pub static nsCSSProps_border_width: *mut nsICSSProperty; - #[link_name = "?bottom@nsCSSProps@@2PEAVnsICSSProperty@@EA"] - pub static nsCSSProps_bottom: *mut nsICSSProperty; - #[link_name = "?box_align@nsCSSProps@@2PEAVnsICSSProperty@@EA"] - pub static nsCSSProps_box_align: *mut nsICSSProperty; - #[link_name = "?box_decoration_break@nsCSSProps@@2PEAVnsICSSProperty@@EA"] - pub static nsCSSProps_box_decoration_break: *mut nsICSSProperty; - #[link_name = "?box_direction@nsCSSProps@@2PEAVnsICSSProperty@@EA"] - pub static nsCSSProps_box_direction: *mut nsICSSProperty; - #[link_name = "?box_flex@nsCSSProps@@2PEAVnsICSSProperty@@EA"] - pub static nsCSSProps_box_flex: *mut nsICSSProperty; - #[link_name = "?box_ordinal_group@nsCSSProps@@2PEAVnsICSSProperty@@EA"] - pub static nsCSSProps_box_ordinal_group: *mut nsICSSProperty; - #[link_name = "?box_orient@nsCSSProps@@2PEAVnsICSSProperty@@EA"] - pub static nsCSSProps_box_orient: *mut nsICSSProperty; - #[link_name = "?box_pack@nsCSSProps@@2PEAVnsICSSProperty@@EA"] - pub static nsCSSProps_box_pack: *mut nsICSSProperty; - #[link_name = "?box_shadow@nsCSSProps@@2PEAVnsICSSProperty@@EA"] - pub static nsCSSProps_box_shadow: *mut nsICSSProperty; - #[link_name = "?box_sizing@nsCSSProps@@2PEAVnsICSSProperty@@EA"] - pub static nsCSSProps_box_sizing: *mut nsICSSProperty; - #[link_name = "?caption_side@nsCSSProps@@2PEAVnsICSSProperty@@EA"] - pub static nsCSSProps_caption_side: *mut nsICSSProperty; - #[link_name = "?clear@nsCSSProps@@2PEAVnsICSSProperty@@EA"] - pub static nsCSSProps_clear: *mut nsICSSProperty; - #[link_name = "?clip@nsCSSProps@@2PEAVnsICSSProperty@@EA"] - pub static nsCSSProps_clip: *mut nsICSSProperty; - #[link_name = "?clip_path@nsCSSProps@@2PEAVnsICSSProperty@@EA"] - pub static nsCSSProps_clip_path: *mut nsICSSProperty; - #[link_name = "?clip_rule@nsCSSProps@@2PEAVnsICSSProperty@@EA"] - pub static nsCSSProps_clip_rule: *mut nsICSSProperty; - #[link_name = "?color@nsCSSProps@@2PEAVnsICSSProperty@@EA"] - pub static nsCSSProps_color: *mut nsICSSProperty; - #[link_name = "?color_adjust@nsCSSProps@@2PEAVnsICSSProperty@@EA"] - pub static nsCSSProps_color_adjust: *mut nsICSSProperty; - #[link_name = "?color_interpolation@nsCSSProps@@2PEAVnsICSSProperty@@EA"] - pub static nsCSSProps_color_interpolation: *mut nsICSSProperty; - #[link_name = "?color_interpolation_filters@nsCSSProps@@2PEAVnsICSSProperty@@EA"] - pub static nsCSSProps_color_interpolation_filters: *mut nsICSSProperty; - #[link_name = "?column_count@nsCSSProps@@2PEAVnsICSSProperty@@EA"] - pub static nsCSSProps_column_count: *mut nsICSSProperty; - #[link_name = "?column_fill@nsCSSProps@@2PEAVnsICSSProperty@@EA"] - pub static nsCSSProps_column_fill: *mut nsICSSProperty; - #[link_name = "?column_gap@nsCSSProps@@2PEAVnsICSSProperty@@EA"] - pub static nsCSSProps_column_gap: *mut nsICSSProperty; - #[link_name = "?column_rule@nsCSSProps@@2PEAVnsICSSProperty@@EA"] - pub static nsCSSProps_column_rule: *mut nsICSSProperty; - #[link_name = "?column_rule_color@nsCSSProps@@2PEAVnsICSSProperty@@EA"] - pub static nsCSSProps_column_rule_color: *mut nsICSSProperty; - #[link_name = "?column_rule_style@nsCSSProps@@2PEAVnsICSSProperty@@EA"] - pub static nsCSSProps_column_rule_style: *mut nsICSSProperty; - #[link_name = "?column_rule_width@nsCSSProps@@2PEAVnsICSSProperty@@EA"] - pub static nsCSSProps_column_rule_width: *mut nsICSSProperty; - #[link_name = "?column_width@nsCSSProps@@2PEAVnsICSSProperty@@EA"] - pub static nsCSSProps_column_width: *mut nsICSSProperty; - #[link_name = "?columns@nsCSSProps@@2PEAVnsICSSProperty@@EA"] - pub static nsCSSProps_columns: *mut nsICSSProperty; - #[link_name = "?contain@nsCSSProps@@2PEAVnsICSSProperty@@EA"] - pub static nsCSSProps_contain: *mut nsICSSProperty; - #[link_name = "?content@nsCSSProps@@2PEAVnsICSSProperty@@EA"] - pub static nsCSSProps_content: *mut nsICSSProperty; - #[link_name = "?_moz_control_character_visibility@nsCSSProps@@2PEAVnsICSSProperty@@EA"] - pub static nsCSSProps__moz_control_character_visibility: *mut nsICSSProperty; - #[link_name = "?counter_increment@nsCSSProps@@2PEAVnsICSSProperty@@EA"] - pub static nsCSSProps_counter_increment: *mut nsICSSProperty; - #[link_name = "?counter_reset@nsCSSProps@@2PEAVnsICSSProperty@@EA"] - pub static nsCSSProps_counter_reset: *mut nsICSSProperty; - #[link_name = "?cursor@nsCSSProps@@2PEAVnsICSSProperty@@EA"] - pub static nsCSSProps_cursor: *mut nsICSSProperty; - #[link_name = "?direction@nsCSSProps@@2PEAVnsICSSProperty@@EA"] - pub static nsCSSProps_direction: *mut nsICSSProperty; - #[link_name = "?display@nsCSSProps@@2PEAVnsICSSProperty@@EA"] - pub static nsCSSProps_display: *mut nsICSSProperty; - #[link_name = "?dominant_baseline@nsCSSProps@@2PEAVnsICSSProperty@@EA"] - pub static nsCSSProps_dominant_baseline: *mut nsICSSProperty; - #[link_name = "?empty_cells@nsCSSProps@@2PEAVnsICSSProperty@@EA"] - pub static nsCSSProps_empty_cells: *mut nsICSSProperty; - #[link_name = "?fill@nsCSSProps@@2PEAVnsICSSProperty@@EA"] - pub static nsCSSProps_fill: *mut nsICSSProperty; - #[link_name = "?fill_opacity@nsCSSProps@@2PEAVnsICSSProperty@@EA"] - pub static nsCSSProps_fill_opacity: *mut nsICSSProperty; - #[link_name = "?fill_rule@nsCSSProps@@2PEAVnsICSSProperty@@EA"] - pub static nsCSSProps_fill_rule: *mut nsICSSProperty; - #[link_name = "?filter@nsCSSProps@@2PEAVnsICSSProperty@@EA"] - pub static nsCSSProps_filter: *mut nsICSSProperty; - #[link_name = "?flex@nsCSSProps@@2PEAVnsICSSProperty@@EA"] - pub static nsCSSProps_flex: *mut nsICSSProperty; - #[link_name = "?flex_basis@nsCSSProps@@2PEAVnsICSSProperty@@EA"] - pub static nsCSSProps_flex_basis: *mut nsICSSProperty; - #[link_name = "?flex_direction@nsCSSProps@@2PEAVnsICSSProperty@@EA"] - pub static nsCSSProps_flex_direction: *mut nsICSSProperty; - #[link_name = "?flex_flow@nsCSSProps@@2PEAVnsICSSProperty@@EA"] - pub static nsCSSProps_flex_flow: *mut nsICSSProperty; - #[link_name = "?flex_grow@nsCSSProps@@2PEAVnsICSSProperty@@EA"] - pub static nsCSSProps_flex_grow: *mut nsICSSProperty; - #[link_name = "?flex_shrink@nsCSSProps@@2PEAVnsICSSProperty@@EA"] - pub static nsCSSProps_flex_shrink: *mut nsICSSProperty; - #[link_name = "?flex_wrap@nsCSSProps@@2PEAVnsICSSProperty@@EA"] - pub static nsCSSProps_flex_wrap: *mut nsICSSProperty; - #[link_name = "?float_@nsCSSProps@@2PEAVnsICSSProperty@@EA"] - pub static nsCSSProps_float_: *mut nsICSSProperty; - #[link_name = "?float_edge@nsCSSProps@@2PEAVnsICSSProperty@@EA"] - pub static nsCSSProps_float_edge: *mut nsICSSProperty; - #[link_name = "?flood_color@nsCSSProps@@2PEAVnsICSSProperty@@EA"] - pub static nsCSSProps_flood_color: *mut nsICSSProperty; - #[link_name = "?flood_opacity@nsCSSProps@@2PEAVnsICSSProperty@@EA"] - pub static nsCSSProps_flood_opacity: *mut nsICSSProperty; - #[link_name = "?font@nsCSSProps@@2PEAVnsICSSProperty@@EA"] - pub static nsCSSProps_font: *mut nsICSSProperty; - #[link_name = "?font_family@nsCSSProps@@2PEAVnsICSSProperty@@EA"] - pub static nsCSSProps_font_family: *mut nsICSSProperty; - #[link_name = "?font_feature_settings@nsCSSProps@@2PEAVnsICSSProperty@@EA"] - pub static nsCSSProps_font_feature_settings: *mut nsICSSProperty; - #[link_name = "?font_kerning@nsCSSProps@@2PEAVnsICSSProperty@@EA"] - pub static nsCSSProps_font_kerning: *mut nsICSSProperty; - #[link_name = "?font_language_override@nsCSSProps@@2PEAVnsICSSProperty@@EA"] - pub static nsCSSProps_font_language_override: *mut nsICSSProperty; - #[link_name = "?font_size@nsCSSProps@@2PEAVnsICSSProperty@@EA"] - pub static nsCSSProps_font_size: *mut nsICSSProperty; - #[link_name = "?font_size_adjust@nsCSSProps@@2PEAVnsICSSProperty@@EA"] - pub static nsCSSProps_font_size_adjust: *mut nsICSSProperty; - #[link_name = "?font_stretch@nsCSSProps@@2PEAVnsICSSProperty@@EA"] - pub static nsCSSProps_font_stretch: *mut nsICSSProperty; - #[link_name = "?font_style@nsCSSProps@@2PEAVnsICSSProperty@@EA"] - pub static nsCSSProps_font_style: *mut nsICSSProperty; - #[link_name = "?font_synthesis@nsCSSProps@@2PEAVnsICSSProperty@@EA"] - pub static nsCSSProps_font_synthesis: *mut nsICSSProperty; - #[link_name = "?font_variant@nsCSSProps@@2PEAVnsICSSProperty@@EA"] - pub static nsCSSProps_font_variant: *mut nsICSSProperty; - #[link_name = "?font_variant_alternates@nsCSSProps@@2PEAVnsICSSProperty@@EA"] - pub static nsCSSProps_font_variant_alternates: *mut nsICSSProperty; - #[link_name = "?font_variant_caps@nsCSSProps@@2PEAVnsICSSProperty@@EA"] - pub static nsCSSProps_font_variant_caps: *mut nsICSSProperty; - #[link_name = "?font_variant_east_asian@nsCSSProps@@2PEAVnsICSSProperty@@EA"] - pub static nsCSSProps_font_variant_east_asian: *mut nsICSSProperty; - #[link_name = "?font_variant_ligatures@nsCSSProps@@2PEAVnsICSSProperty@@EA"] - pub static nsCSSProps_font_variant_ligatures: *mut nsICSSProperty; - #[link_name = "?font_variant_numeric@nsCSSProps@@2PEAVnsICSSProperty@@EA"] - pub static nsCSSProps_font_variant_numeric: *mut nsICSSProperty; - #[link_name = "?font_variant_position@nsCSSProps@@2PEAVnsICSSProperty@@EA"] - pub static nsCSSProps_font_variant_position: *mut nsICSSProperty; - #[link_name = "?font_variation_settings@nsCSSProps@@2PEAVnsICSSProperty@@EA"] - pub static nsCSSProps_font_variation_settings: *mut nsICSSProperty; - #[link_name = "?font_weight@nsCSSProps@@2PEAVnsICSSProperty@@EA"] - pub static nsCSSProps_font_weight: *mut nsICSSProperty; - #[link_name = "?force_broken_image_icon@nsCSSProps@@2PEAVnsICSSProperty@@EA"] - pub static nsCSSProps_force_broken_image_icon: *mut nsICSSProperty; - #[link_name = "?grid@nsCSSProps@@2PEAVnsICSSProperty@@EA"] - pub static nsCSSProps_grid: *mut nsICSSProperty; - #[link_name = "?grid_area@nsCSSProps@@2PEAVnsICSSProperty@@EA"] - pub static nsCSSProps_grid_area: *mut nsICSSProperty; - #[link_name = "?grid_auto_columns@nsCSSProps@@2PEAVnsICSSProperty@@EA"] - pub static nsCSSProps_grid_auto_columns: *mut nsICSSProperty; - #[link_name = "?grid_auto_flow@nsCSSProps@@2PEAVnsICSSProperty@@EA"] - pub static nsCSSProps_grid_auto_flow: *mut nsICSSProperty; - #[link_name = "?grid_auto_rows@nsCSSProps@@2PEAVnsICSSProperty@@EA"] - pub static nsCSSProps_grid_auto_rows: *mut nsICSSProperty; - #[link_name = "?grid_column@nsCSSProps@@2PEAVnsICSSProperty@@EA"] - pub static nsCSSProps_grid_column: *mut nsICSSProperty; - #[link_name = "?grid_column_end@nsCSSProps@@2PEAVnsICSSProperty@@EA"] - pub static nsCSSProps_grid_column_end: *mut nsICSSProperty; - #[link_name = "?grid_column_gap@nsCSSProps@@2PEAVnsICSSProperty@@EA"] - pub static nsCSSProps_grid_column_gap: *mut nsICSSProperty; - #[link_name = "?grid_column_start@nsCSSProps@@2PEAVnsICSSProperty@@EA"] - pub static nsCSSProps_grid_column_start: *mut nsICSSProperty; - #[link_name = "?grid_gap@nsCSSProps@@2PEAVnsICSSProperty@@EA"] - pub static nsCSSProps_grid_gap: *mut nsICSSProperty; - #[link_name = "?grid_row@nsCSSProps@@2PEAVnsICSSProperty@@EA"] - pub static nsCSSProps_grid_row: *mut nsICSSProperty; - #[link_name = "?grid_row_end@nsCSSProps@@2PEAVnsICSSProperty@@EA"] - pub static nsCSSProps_grid_row_end: *mut nsICSSProperty; - #[link_name = "?grid_row_gap@nsCSSProps@@2PEAVnsICSSProperty@@EA"] - pub static nsCSSProps_grid_row_gap: *mut nsICSSProperty; - #[link_name = "?grid_row_start@nsCSSProps@@2PEAVnsICSSProperty@@EA"] - pub static nsCSSProps_grid_row_start: *mut nsICSSProperty; - #[link_name = "?grid_template@nsCSSProps@@2PEAVnsICSSProperty@@EA"] - pub static nsCSSProps_grid_template: *mut nsICSSProperty; - #[link_name = "?grid_template_areas@nsCSSProps@@2PEAVnsICSSProperty@@EA"] - pub static nsCSSProps_grid_template_areas: *mut nsICSSProperty; - #[link_name = "?grid_template_columns@nsCSSProps@@2PEAVnsICSSProperty@@EA"] - pub static nsCSSProps_grid_template_columns: *mut nsICSSProperty; - #[link_name = "?grid_template_rows@nsCSSProps@@2PEAVnsICSSProperty@@EA"] - pub static nsCSSProps_grid_template_rows: *mut nsICSSProperty; - #[link_name = "?height@nsCSSProps@@2PEAVnsICSSProperty@@EA"] - pub static nsCSSProps_height: *mut nsICSSProperty; - #[link_name = "?hyphens@nsCSSProps@@2PEAVnsICSSProperty@@EA"] - pub static nsCSSProps_hyphens: *mut nsICSSProperty; - #[link_name = "?initial_letter@nsCSSProps@@2PEAVnsICSSProperty@@EA"] - pub static nsCSSProps_initial_letter: *mut nsICSSProperty; - #[link_name = "?image_orientation@nsCSSProps@@2PEAVnsICSSProperty@@EA"] - pub static nsCSSProps_image_orientation: *mut nsICSSProperty; - #[link_name = "?image_region@nsCSSProps@@2PEAVnsICSSProperty@@EA"] - pub static nsCSSProps_image_region: *mut nsICSSProperty; - #[link_name = "?image_rendering@nsCSSProps@@2PEAVnsICSSProperty@@EA"] - pub static nsCSSProps_image_rendering: *mut nsICSSProperty; - #[link_name = "?ime_mode@nsCSSProps@@2PEAVnsICSSProperty@@EA"] - pub static nsCSSProps_ime_mode: *mut nsICSSProperty; - #[link_name = "?inline_size@nsCSSProps@@2PEAVnsICSSProperty@@EA"] - pub static nsCSSProps_inline_size: *mut nsICSSProperty; - #[link_name = "?isolation@nsCSSProps@@2PEAVnsICSSProperty@@EA"] - pub static nsCSSProps_isolation: *mut nsICSSProperty; - #[link_name = "?justify_content@nsCSSProps@@2PEAVnsICSSProperty@@EA"] - pub static nsCSSProps_justify_content: *mut nsICSSProperty; - #[link_name = "?justify_items@nsCSSProps@@2PEAVnsICSSProperty@@EA"] - pub static nsCSSProps_justify_items: *mut nsICSSProperty; - #[link_name = "?justify_self@nsCSSProps@@2PEAVnsICSSProperty@@EA"] - pub static nsCSSProps_justify_self: *mut nsICSSProperty; - #[link_name = "?_x_lang@nsCSSProps@@2PEAVnsICSSProperty@@EA"] - pub static nsCSSProps__x_lang: *mut nsICSSProperty; - #[link_name = "?left@nsCSSProps@@2PEAVnsICSSProperty@@EA"] - pub static nsCSSProps_left: *mut nsICSSProperty; - #[link_name = "?letter_spacing@nsCSSProps@@2PEAVnsICSSProperty@@EA"] - pub static nsCSSProps_letter_spacing: *mut nsICSSProperty; - #[link_name = "?lighting_color@nsCSSProps@@2PEAVnsICSSProperty@@EA"] - pub static nsCSSProps_lighting_color: *mut nsICSSProperty; - #[link_name = "?line_height@nsCSSProps@@2PEAVnsICSSProperty@@EA"] - pub static nsCSSProps_line_height: *mut nsICSSProperty; - #[link_name = "?list_style@nsCSSProps@@2PEAVnsICSSProperty@@EA"] - pub static nsCSSProps_list_style: *mut nsICSSProperty; - #[link_name = "?list_style_image@nsCSSProps@@2PEAVnsICSSProperty@@EA"] - pub static nsCSSProps_list_style_image: *mut nsICSSProperty; - #[link_name = "?list_style_position@nsCSSProps@@2PEAVnsICSSProperty@@EA"] - pub static nsCSSProps_list_style_position: *mut nsICSSProperty; - #[link_name = "?list_style_type@nsCSSProps@@2PEAVnsICSSProperty@@EA"] - pub static nsCSSProps_list_style_type: *mut nsICSSProperty; - #[link_name = "?margin@nsCSSProps@@2PEAVnsICSSProperty@@EA"] - pub static nsCSSProps_margin: *mut nsICSSProperty; - #[link_name = "?margin_block_end@nsCSSProps@@2PEAVnsICSSProperty@@EA"] - pub static nsCSSProps_margin_block_end: *mut nsICSSProperty; - #[link_name = "?margin_block_start@nsCSSProps@@2PEAVnsICSSProperty@@EA"] - pub static nsCSSProps_margin_block_start: *mut nsICSSProperty; - #[link_name = "?margin_bottom@nsCSSProps@@2PEAVnsICSSProperty@@EA"] - pub static nsCSSProps_margin_bottom: *mut nsICSSProperty; - #[link_name = "?margin_inline_end@nsCSSProps@@2PEAVnsICSSProperty@@EA"] - pub static nsCSSProps_margin_inline_end: *mut nsICSSProperty; - #[link_name = "?margin_inline_start@nsCSSProps@@2PEAVnsICSSProperty@@EA"] - pub static nsCSSProps_margin_inline_start: *mut nsICSSProperty; - #[link_name = "?margin_left@nsCSSProps@@2PEAVnsICSSProperty@@EA"] - pub static nsCSSProps_margin_left: *mut nsICSSProperty; - #[link_name = "?margin_right@nsCSSProps@@2PEAVnsICSSProperty@@EA"] - pub static nsCSSProps_margin_right: *mut nsICSSProperty; - #[link_name = "?margin_top@nsCSSProps@@2PEAVnsICSSProperty@@EA"] - pub static nsCSSProps_margin_top: *mut nsICSSProperty; - #[link_name = "?marker@nsCSSProps@@2PEAVnsICSSProperty@@EA"] - pub static nsCSSProps_marker: *mut nsICSSProperty; - #[link_name = "?marker_end@nsCSSProps@@2PEAVnsICSSProperty@@EA"] - pub static nsCSSProps_marker_end: *mut nsICSSProperty; - #[link_name = "?marker_mid@nsCSSProps@@2PEAVnsICSSProperty@@EA"] - pub static nsCSSProps_marker_mid: *mut nsICSSProperty; - #[link_name = "?marker_start@nsCSSProps@@2PEAVnsICSSProperty@@EA"] - pub static nsCSSProps_marker_start: *mut nsICSSProperty; - #[link_name = "?mask@nsCSSProps@@2PEAVnsICSSProperty@@EA"] - pub static nsCSSProps_mask: *mut nsICSSProperty; - #[link_name = "?mask_clip@nsCSSProps@@2PEAVnsICSSProperty@@EA"] - pub static nsCSSProps_mask_clip: *mut nsICSSProperty; - #[link_name = "?mask_composite@nsCSSProps@@2PEAVnsICSSProperty@@EA"] - pub static nsCSSProps_mask_composite: *mut nsICSSProperty; - #[link_name = "?mask_image@nsCSSProps@@2PEAVnsICSSProperty@@EA"] - pub static nsCSSProps_mask_image: *mut nsICSSProperty; - #[link_name = "?mask_mode@nsCSSProps@@2PEAVnsICSSProperty@@EA"] - pub static nsCSSProps_mask_mode: *mut nsICSSProperty; - #[link_name = "?mask_origin@nsCSSProps@@2PEAVnsICSSProperty@@EA"] - pub static nsCSSProps_mask_origin: *mut nsICSSProperty; - #[link_name = "?mask_position@nsCSSProps@@2PEAVnsICSSProperty@@EA"] - pub static nsCSSProps_mask_position: *mut nsICSSProperty; - #[link_name = "?mask_position_x@nsCSSProps@@2PEAVnsICSSProperty@@EA"] - pub static nsCSSProps_mask_position_x: *mut nsICSSProperty; - #[link_name = "?mask_position_y@nsCSSProps@@2PEAVnsICSSProperty@@EA"] - pub static nsCSSProps_mask_position_y: *mut nsICSSProperty; - #[link_name = "?mask_repeat@nsCSSProps@@2PEAVnsICSSProperty@@EA"] - pub static nsCSSProps_mask_repeat: *mut nsICSSProperty; - #[link_name = "?mask_size@nsCSSProps@@2PEAVnsICSSProperty@@EA"] - pub static nsCSSProps_mask_size: *mut nsICSSProperty; - #[link_name = "?mask_type@nsCSSProps@@2PEAVnsICSSProperty@@EA"] - pub static nsCSSProps_mask_type: *mut nsICSSProperty; - #[link_name = "?math_display@nsCSSProps@@2PEAVnsICSSProperty@@EA"] - pub static nsCSSProps_math_display: *mut nsICSSProperty; - #[link_name = "?math_variant@nsCSSProps@@2PEAVnsICSSProperty@@EA"] - pub static nsCSSProps_math_variant: *mut nsICSSProperty; - #[link_name = "?max_block_size@nsCSSProps@@2PEAVnsICSSProperty@@EA"] - pub static nsCSSProps_max_block_size: *mut nsICSSProperty; - #[link_name = "?max_height@nsCSSProps@@2PEAVnsICSSProperty@@EA"] - pub static nsCSSProps_max_height: *mut nsICSSProperty; - #[link_name = "?max_inline_size@nsCSSProps@@2PEAVnsICSSProperty@@EA"] - pub static nsCSSProps_max_inline_size: *mut nsICSSProperty; - #[link_name = "?max_width@nsCSSProps@@2PEAVnsICSSProperty@@EA"] - pub static nsCSSProps_max_width: *mut nsICSSProperty; - #[link_name = "?min_block_size@nsCSSProps@@2PEAVnsICSSProperty@@EA"] - pub static nsCSSProps_min_block_size: *mut nsICSSProperty; - #[link_name = "?_moz_min_font_size_ratio@nsCSSProps@@2PEAVnsICSSProperty@@EA"] - pub static nsCSSProps__moz_min_font_size_ratio: *mut nsICSSProperty; - #[link_name = "?min_height@nsCSSProps@@2PEAVnsICSSProperty@@EA"] - pub static nsCSSProps_min_height: *mut nsICSSProperty; - #[link_name = "?min_inline_size@nsCSSProps@@2PEAVnsICSSProperty@@EA"] - pub static nsCSSProps_min_inline_size: *mut nsICSSProperty; - #[link_name = "?min_width@nsCSSProps@@2PEAVnsICSSProperty@@EA"] - pub static nsCSSProps_min_width: *mut nsICSSProperty; - #[link_name = "?mix_blend_mode@nsCSSProps@@2PEAVnsICSSProperty@@EA"] - pub static nsCSSProps_mix_blend_mode: *mut nsICSSProperty; - #[link_name = "?object_fit@nsCSSProps@@2PEAVnsICSSProperty@@EA"] - pub static nsCSSProps_object_fit: *mut nsICSSProperty; - #[link_name = "?object_position@nsCSSProps@@2PEAVnsICSSProperty@@EA"] - pub static nsCSSProps_object_position: *mut nsICSSProperty; - #[link_name = "?offset_block_end@nsCSSProps@@2PEAVnsICSSProperty@@EA"] - pub static nsCSSProps_offset_block_end: *mut nsICSSProperty; - #[link_name = "?offset_block_start@nsCSSProps@@2PEAVnsICSSProperty@@EA"] - pub static nsCSSProps_offset_block_start: *mut nsICSSProperty; - #[link_name = "?offset_inline_end@nsCSSProps@@2PEAVnsICSSProperty@@EA"] - pub static nsCSSProps_offset_inline_end: *mut nsICSSProperty; - #[link_name = "?offset_inline_start@nsCSSProps@@2PEAVnsICSSProperty@@EA"] - pub static nsCSSProps_offset_inline_start: *mut nsICSSProperty; - #[link_name = "?opacity@nsCSSProps@@2PEAVnsICSSProperty@@EA"] - pub static nsCSSProps_opacity: *mut nsICSSProperty; - #[link_name = "?order@nsCSSProps@@2PEAVnsICSSProperty@@EA"] - pub static nsCSSProps_order: *mut nsICSSProperty; - #[link_name = "?orient@nsCSSProps@@2PEAVnsICSSProperty@@EA"] - pub static nsCSSProps_orient: *mut nsICSSProperty; - #[link_name = "?osx_font_smoothing@nsCSSProps@@2PEAVnsICSSProperty@@EA"] - pub static nsCSSProps_osx_font_smoothing: *mut nsICSSProperty; - #[link_name = "?outline@nsCSSProps@@2PEAVnsICSSProperty@@EA"] - pub static nsCSSProps_outline: *mut nsICSSProperty; - #[link_name = "?outline_color@nsCSSProps@@2PEAVnsICSSProperty@@EA"] - pub static nsCSSProps_outline_color: *mut nsICSSProperty; - #[link_name = "?outline_offset@nsCSSProps@@2PEAVnsICSSProperty@@EA"] - pub static nsCSSProps_outline_offset: *mut nsICSSProperty; - #[link_name = "?_moz_outline_radius@nsCSSProps@@2PEAVnsICSSProperty@@EA"] - pub static nsCSSProps__moz_outline_radius: *mut nsICSSProperty; - #[link_name = "?_moz_outline_radius_bottomLeft@nsCSSProps@@2PEAVnsICSSProperty@@EA"] - pub static nsCSSProps__moz_outline_radius_bottomLeft: *mut nsICSSProperty; - #[link_name = "?_moz_outline_radius_bottomRight@nsCSSProps@@2PEAVnsICSSProperty@@EA"] - pub static nsCSSProps__moz_outline_radius_bottomRight: *mut nsICSSProperty; - #[link_name = "?_moz_outline_radius_topLeft@nsCSSProps@@2PEAVnsICSSProperty@@EA"] - pub static nsCSSProps__moz_outline_radius_topLeft: *mut nsICSSProperty; - #[link_name = "?_moz_outline_radius_topRight@nsCSSProps@@2PEAVnsICSSProperty@@EA"] - pub static nsCSSProps__moz_outline_radius_topRight: *mut nsICSSProperty; - #[link_name = "?outline_style@nsCSSProps@@2PEAVnsICSSProperty@@EA"] - pub static nsCSSProps_outline_style: *mut nsICSSProperty; - #[link_name = "?outline_width@nsCSSProps@@2PEAVnsICSSProperty@@EA"] - pub static nsCSSProps_outline_width: *mut nsICSSProperty; - #[link_name = "?overflow@nsCSSProps@@2PEAVnsICSSProperty@@EA"] - pub static nsCSSProps_overflow: *mut nsICSSProperty; - #[link_name = "?overflow_clip_box@nsCSSProps@@2PEAVnsICSSProperty@@EA"] - pub static nsCSSProps_overflow_clip_box: *mut nsICSSProperty; - #[link_name = "?overflow_x@nsCSSProps@@2PEAVnsICSSProperty@@EA"] - pub static nsCSSProps_overflow_x: *mut nsICSSProperty; - #[link_name = "?overflow_y@nsCSSProps@@2PEAVnsICSSProperty@@EA"] - pub static nsCSSProps_overflow_y: *mut nsICSSProperty; - #[link_name = "?padding@nsCSSProps@@2PEAVnsICSSProperty@@EA"] - pub static nsCSSProps_padding: *mut nsICSSProperty; - #[link_name = "?padding_block_end@nsCSSProps@@2PEAVnsICSSProperty@@EA"] - pub static nsCSSProps_padding_block_end: *mut nsICSSProperty; - #[link_name = "?padding_block_start@nsCSSProps@@2PEAVnsICSSProperty@@EA"] - pub static nsCSSProps_padding_block_start: *mut nsICSSProperty; - #[link_name = "?padding_bottom@nsCSSProps@@2PEAVnsICSSProperty@@EA"] - pub static nsCSSProps_padding_bottom: *mut nsICSSProperty; - #[link_name = "?padding_inline_end@nsCSSProps@@2PEAVnsICSSProperty@@EA"] - pub static nsCSSProps_padding_inline_end: *mut nsICSSProperty; - #[link_name = "?padding_inline_start@nsCSSProps@@2PEAVnsICSSProperty@@EA"] - pub static nsCSSProps_padding_inline_start: *mut nsICSSProperty; - #[link_name = "?padding_left@nsCSSProps@@2PEAVnsICSSProperty@@EA"] - pub static nsCSSProps_padding_left: *mut nsICSSProperty; - #[link_name = "?padding_right@nsCSSProps@@2PEAVnsICSSProperty@@EA"] - pub static nsCSSProps_padding_right: *mut nsICSSProperty; - #[link_name = "?padding_top@nsCSSProps@@2PEAVnsICSSProperty@@EA"] - pub static nsCSSProps_padding_top: *mut nsICSSProperty; - #[link_name = "?page_break_after@nsCSSProps@@2PEAVnsICSSProperty@@EA"] - pub static nsCSSProps_page_break_after: *mut nsICSSProperty; - #[link_name = "?page_break_before@nsCSSProps@@2PEAVnsICSSProperty@@EA"] - pub static nsCSSProps_page_break_before: *mut nsICSSProperty; - #[link_name = "?page_break_inside@nsCSSProps@@2PEAVnsICSSProperty@@EA"] - pub static nsCSSProps_page_break_inside: *mut nsICSSProperty; - #[link_name = "?paint_order@nsCSSProps@@2PEAVnsICSSProperty@@EA"] - pub static nsCSSProps_paint_order: *mut nsICSSProperty; - #[link_name = "?perspective@nsCSSProps@@2PEAVnsICSSProperty@@EA"] - pub static nsCSSProps_perspective: *mut nsICSSProperty; - #[link_name = "?perspective_origin@nsCSSProps@@2PEAVnsICSSProperty@@EA"] - pub static nsCSSProps_perspective_origin: *mut nsICSSProperty; - #[link_name = "?place_content@nsCSSProps@@2PEAVnsICSSProperty@@EA"] - pub static nsCSSProps_place_content: *mut nsICSSProperty; - #[link_name = "?place_items@nsCSSProps@@2PEAVnsICSSProperty@@EA"] - pub static nsCSSProps_place_items: *mut nsICSSProperty; - #[link_name = "?place_self@nsCSSProps@@2PEAVnsICSSProperty@@EA"] - pub static nsCSSProps_place_self: *mut nsICSSProperty; - #[link_name = "?pointer_events@nsCSSProps@@2PEAVnsICSSProperty@@EA"] - pub static nsCSSProps_pointer_events: *mut nsICSSProperty; - #[link_name = "?position@nsCSSProps@@2PEAVnsICSSProperty@@EA"] - pub static nsCSSProps_position: *mut nsICSSProperty; - #[link_name = "?quotes@nsCSSProps@@2PEAVnsICSSProperty@@EA"] - pub static nsCSSProps_quotes: *mut nsICSSProperty; - #[link_name = "?resize@nsCSSProps@@2PEAVnsICSSProperty@@EA"] - pub static nsCSSProps_resize: *mut nsICSSProperty; - #[link_name = "?right@nsCSSProps@@2PEAVnsICSSProperty@@EA"] - pub static nsCSSProps_right: *mut nsICSSProperty; - #[link_name = "?ruby_align@nsCSSProps@@2PEAVnsICSSProperty@@EA"] - pub static nsCSSProps_ruby_align: *mut nsICSSProperty; - #[link_name = "?ruby_position@nsCSSProps@@2PEAVnsICSSProperty@@EA"] - pub static nsCSSProps_ruby_position: *mut nsICSSProperty; - #[link_name = "?script_level@nsCSSProps@@2PEAVnsICSSProperty@@EA"] - pub static nsCSSProps_script_level: *mut nsICSSProperty; - #[link_name = "?script_min_size@nsCSSProps@@2PEAVnsICSSProperty@@EA"] - pub static nsCSSProps_script_min_size: *mut nsICSSProperty; - #[link_name = "?script_size_multiplier@nsCSSProps@@2PEAVnsICSSProperty@@EA"] - pub static nsCSSProps_script_size_multiplier: *mut nsICSSProperty; - #[link_name = "?scroll_behavior@nsCSSProps@@2PEAVnsICSSProperty@@EA"] - pub static nsCSSProps_scroll_behavior: *mut nsICSSProperty; - #[link_name = "?scroll_snap_coordinate@nsCSSProps@@2PEAVnsICSSProperty@@EA"] - pub static nsCSSProps_scroll_snap_coordinate: *mut nsICSSProperty; - #[link_name = "?scroll_snap_destination@nsCSSProps@@2PEAVnsICSSProperty@@EA"] - pub static nsCSSProps_scroll_snap_destination: *mut nsICSSProperty; - #[link_name = "?scroll_snap_points_x@nsCSSProps@@2PEAVnsICSSProperty@@EA"] - pub static nsCSSProps_scroll_snap_points_x: *mut nsICSSProperty; - #[link_name = "?scroll_snap_points_y@nsCSSProps@@2PEAVnsICSSProperty@@EA"] - pub static nsCSSProps_scroll_snap_points_y: *mut nsICSSProperty; - #[link_name = "?scroll_snap_type@nsCSSProps@@2PEAVnsICSSProperty@@EA"] - pub static nsCSSProps_scroll_snap_type: *mut nsICSSProperty; - #[link_name = "?scroll_snap_type_x@nsCSSProps@@2PEAVnsICSSProperty@@EA"] - pub static nsCSSProps_scroll_snap_type_x: *mut nsICSSProperty; - #[link_name = "?scroll_snap_type_y@nsCSSProps@@2PEAVnsICSSProperty@@EA"] - pub static nsCSSProps_scroll_snap_type_y: *mut nsICSSProperty; - #[link_name = "?shape_outside@nsCSSProps@@2PEAVnsICSSProperty@@EA"] - pub static nsCSSProps_shape_outside: *mut nsICSSProperty; - #[link_name = "?shape_rendering@nsCSSProps@@2PEAVnsICSSProperty@@EA"] - pub static nsCSSProps_shape_rendering: *mut nsICSSProperty; - #[link_name = "?_x_span@nsCSSProps@@2PEAVnsICSSProperty@@EA"] - pub static nsCSSProps__x_span: *mut nsICSSProperty; - #[link_name = "?stack_sizing@nsCSSProps@@2PEAVnsICSSProperty@@EA"] - pub static nsCSSProps_stack_sizing: *mut nsICSSProperty; - #[link_name = "?stop_color@nsCSSProps@@2PEAVnsICSSProperty@@EA"] - pub static nsCSSProps_stop_color: *mut nsICSSProperty; - #[link_name = "?stop_opacity@nsCSSProps@@2PEAVnsICSSProperty@@EA"] - pub static nsCSSProps_stop_opacity: *mut nsICSSProperty; - #[link_name = "?stroke@nsCSSProps@@2PEAVnsICSSProperty@@EA"] - pub static nsCSSProps_stroke: *mut nsICSSProperty; - #[link_name = "?stroke_dasharray@nsCSSProps@@2PEAVnsICSSProperty@@EA"] - pub static nsCSSProps_stroke_dasharray: *mut nsICSSProperty; - #[link_name = "?stroke_dashoffset@nsCSSProps@@2PEAVnsICSSProperty@@EA"] - pub static nsCSSProps_stroke_dashoffset: *mut nsICSSProperty; - #[link_name = "?stroke_linecap@nsCSSProps@@2PEAVnsICSSProperty@@EA"] - pub static nsCSSProps_stroke_linecap: *mut nsICSSProperty; - #[link_name = "?stroke_linejoin@nsCSSProps@@2PEAVnsICSSProperty@@EA"] - pub static nsCSSProps_stroke_linejoin: *mut nsICSSProperty; - #[link_name = "?stroke_miterlimit@nsCSSProps@@2PEAVnsICSSProperty@@EA"] - pub static nsCSSProps_stroke_miterlimit: *mut nsICSSProperty; - #[link_name = "?stroke_opacity@nsCSSProps@@2PEAVnsICSSProperty@@EA"] - pub static nsCSSProps_stroke_opacity: *mut nsICSSProperty; - #[link_name = "?stroke_width@nsCSSProps@@2PEAVnsICSSProperty@@EA"] - pub static nsCSSProps_stroke_width: *mut nsICSSProperty; - #[link_name = "?_x_system_font@nsCSSProps@@2PEAVnsICSSProperty@@EA"] - pub static nsCSSProps__x_system_font: *mut nsICSSProperty; - #[link_name = "?_moz_tab_size@nsCSSProps@@2PEAVnsICSSProperty@@EA"] - pub static nsCSSProps__moz_tab_size: *mut nsICSSProperty; - #[link_name = "?table_layout@nsCSSProps@@2PEAVnsICSSProperty@@EA"] - pub static nsCSSProps_table_layout: *mut nsICSSProperty; - #[link_name = "?text_align@nsCSSProps@@2PEAVnsICSSProperty@@EA"] - pub static nsCSSProps_text_align: *mut nsICSSProperty; - #[link_name = "?text_align_last@nsCSSProps@@2PEAVnsICSSProperty@@EA"] - pub static nsCSSProps_text_align_last: *mut nsICSSProperty; - #[link_name = "?text_anchor@nsCSSProps@@2PEAVnsICSSProperty@@EA"] - pub static nsCSSProps_text_anchor: *mut nsICSSProperty; - #[link_name = "?text_combine_upright@nsCSSProps@@2PEAVnsICSSProperty@@EA"] - pub static nsCSSProps_text_combine_upright: *mut nsICSSProperty; - #[link_name = "?text_decoration@nsCSSProps@@2PEAVnsICSSProperty@@EA"] - pub static nsCSSProps_text_decoration: *mut nsICSSProperty; - #[link_name = "?text_decoration_color@nsCSSProps@@2PEAVnsICSSProperty@@EA"] - pub static nsCSSProps_text_decoration_color: *mut nsICSSProperty; - #[link_name = "?text_decoration_line@nsCSSProps@@2PEAVnsICSSProperty@@EA"] - pub static nsCSSProps_text_decoration_line: *mut nsICSSProperty; - #[link_name = "?text_decoration_style@nsCSSProps@@2PEAVnsICSSProperty@@EA"] - pub static nsCSSProps_text_decoration_style: *mut nsICSSProperty; - #[link_name = "?text_emphasis@nsCSSProps@@2PEAVnsICSSProperty@@EA"] - pub static nsCSSProps_text_emphasis: *mut nsICSSProperty; - #[link_name = "?text_emphasis_color@nsCSSProps@@2PEAVnsICSSProperty@@EA"] - pub static nsCSSProps_text_emphasis_color: *mut nsICSSProperty; - #[link_name = "?text_emphasis_position@nsCSSProps@@2PEAVnsICSSProperty@@EA"] - pub static nsCSSProps_text_emphasis_position: *mut nsICSSProperty; - #[link_name = "?text_emphasis_style@nsCSSProps@@2PEAVnsICSSProperty@@EA"] - pub static nsCSSProps_text_emphasis_style: *mut nsICSSProperty; - #[link_name = "?_webkit_text_fill_color@nsCSSProps@@2PEAVnsICSSProperty@@EA"] - pub static nsCSSProps__webkit_text_fill_color: *mut nsICSSProperty; - #[link_name = "?text_indent@nsCSSProps@@2PEAVnsICSSProperty@@EA"] - pub static nsCSSProps_text_indent: *mut nsICSSProperty; - #[link_name = "?text_orientation@nsCSSProps@@2PEAVnsICSSProperty@@EA"] - pub static nsCSSProps_text_orientation: *mut nsICSSProperty; - #[link_name = "?text_overflow@nsCSSProps@@2PEAVnsICSSProperty@@EA"] - pub static nsCSSProps_text_overflow: *mut nsICSSProperty; - #[link_name = "?text_rendering@nsCSSProps@@2PEAVnsICSSProperty@@EA"] - pub static nsCSSProps_text_rendering: *mut nsICSSProperty; - #[link_name = "?text_shadow@nsCSSProps@@2PEAVnsICSSProperty@@EA"] - pub static nsCSSProps_text_shadow: *mut nsICSSProperty; - #[link_name = "?text_size_adjust@nsCSSProps@@2PEAVnsICSSProperty@@EA"] - pub static nsCSSProps_text_size_adjust: *mut nsICSSProperty; - #[link_name = "?_webkit_text_stroke@nsCSSProps@@2PEAVnsICSSProperty@@EA"] - pub static nsCSSProps__webkit_text_stroke: *mut nsICSSProperty; - #[link_name = "?_webkit_text_stroke_color@nsCSSProps@@2PEAVnsICSSProperty@@EA"] - pub static nsCSSProps__webkit_text_stroke_color: *mut nsICSSProperty; - #[link_name = "?_webkit_text_stroke_width@nsCSSProps@@2PEAVnsICSSProperty@@EA"] - pub static nsCSSProps__webkit_text_stroke_width: *mut nsICSSProperty; - #[link_name = "?text_transform@nsCSSProps@@2PEAVnsICSSProperty@@EA"] - pub static nsCSSProps_text_transform: *mut nsICSSProperty; - #[link_name = "?_x_text_zoom@nsCSSProps@@2PEAVnsICSSProperty@@EA"] - pub static nsCSSProps__x_text_zoom: *mut nsICSSProperty; - #[link_name = "?top@nsCSSProps@@2PEAVnsICSSProperty@@EA"] - pub static nsCSSProps_top: *mut nsICSSProperty; - #[link_name = "?_moz_top_layer@nsCSSProps@@2PEAVnsICSSProperty@@EA"] - pub static nsCSSProps__moz_top_layer: *mut nsICSSProperty; - #[link_name = "?touch_action@nsCSSProps@@2PEAVnsICSSProperty@@EA"] - pub static nsCSSProps_touch_action: *mut nsICSSProperty; - #[link_name = "?transform@nsCSSProps@@2PEAVnsICSSProperty@@EA"] - pub static nsCSSProps_transform: *mut nsICSSProperty; - #[link_name = "?_moz_transform@nsCSSProps@@2PEAVnsICSSProperty@@EA"] - pub static nsCSSProps__moz_transform: *mut nsICSSProperty; - #[link_name = "?transform_box@nsCSSProps@@2PEAVnsICSSProperty@@EA"] - pub static nsCSSProps_transform_box: *mut nsICSSProperty; - #[link_name = "?transform_origin@nsCSSProps@@2PEAVnsICSSProperty@@EA"] - pub static nsCSSProps_transform_origin: *mut nsICSSProperty; - #[link_name = "?transform_style@nsCSSProps@@2PEAVnsICSSProperty@@EA"] - pub static nsCSSProps_transform_style: *mut nsICSSProperty; - #[link_name = "?transition@nsCSSProps@@2PEAVnsICSSProperty@@EA"] - pub static nsCSSProps_transition: *mut nsICSSProperty; - #[link_name = "?transition_delay@nsCSSProps@@2PEAVnsICSSProperty@@EA"] - pub static nsCSSProps_transition_delay: *mut nsICSSProperty; - #[link_name = "?transition_duration@nsCSSProps@@2PEAVnsICSSProperty@@EA"] - pub static nsCSSProps_transition_duration: *mut nsICSSProperty; - #[link_name = "?transition_property@nsCSSProps@@2PEAVnsICSSProperty@@EA"] - pub static nsCSSProps_transition_property: *mut nsICSSProperty; - #[link_name = "?transition_timing_function@nsCSSProps@@2PEAVnsICSSProperty@@EA"] - pub static nsCSSProps_transition_timing_function: *mut nsICSSProperty; - #[link_name = "?unicode_bidi@nsCSSProps@@2PEAVnsICSSProperty@@EA"] - pub static nsCSSProps_unicode_bidi: *mut nsICSSProperty; - #[link_name = "?user_focus@nsCSSProps@@2PEAVnsICSSProperty@@EA"] - pub static nsCSSProps_user_focus: *mut nsICSSProperty; - #[link_name = "?user_input@nsCSSProps@@2PEAVnsICSSProperty@@EA"] - pub static nsCSSProps_user_input: *mut nsICSSProperty; - #[link_name = "?user_modify@nsCSSProps@@2PEAVnsICSSProperty@@EA"] - pub static nsCSSProps_user_modify: *mut nsICSSProperty; - #[link_name = "?user_select@nsCSSProps@@2PEAVnsICSSProperty@@EA"] - pub static nsCSSProps_user_select: *mut nsICSSProperty; - #[link_name = "?vector_effect@nsCSSProps@@2PEAVnsICSSProperty@@EA"] - pub static nsCSSProps_vector_effect: *mut nsICSSProperty; - #[link_name = "?vertical_align@nsCSSProps@@2PEAVnsICSSProperty@@EA"] - pub static nsCSSProps_vertical_align: *mut nsICSSProperty; - #[link_name = "?visibility@nsCSSProps@@2PEAVnsICSSProperty@@EA"] - pub static nsCSSProps_visibility: *mut nsICSSProperty; - #[link_name = "?white_space@nsCSSProps@@2PEAVnsICSSProperty@@EA"] - pub static nsCSSProps_white_space: *mut nsICSSProperty; - #[link_name = "?width@nsCSSProps@@2PEAVnsICSSProperty@@EA"] - pub static nsCSSProps_width: *mut nsICSSProperty; - #[link_name = "?will_change@nsCSSProps@@2PEAVnsICSSProperty@@EA"] - pub static nsCSSProps_will_change: *mut nsICSSProperty; - #[link_name = "?_moz_window_dragging@nsCSSProps@@2PEAVnsICSSProperty@@EA"] - pub static nsCSSProps__moz_window_dragging: *mut nsICSSProperty; - #[link_name = "?_moz_window_shadow@nsCSSProps@@2PEAVnsICSSProperty@@EA"] - pub static nsCSSProps__moz_window_shadow: *mut nsICSSProperty; - #[link_name = "?word_break@nsCSSProps@@2PEAVnsICSSProperty@@EA"] - pub static nsCSSProps_word_break: *mut nsICSSProperty; - #[link_name = "?word_spacing@nsCSSProps@@2PEAVnsICSSProperty@@EA"] - pub static nsCSSProps_word_spacing: *mut nsICSSProperty; - #[link_name = "?overflow_wrap@nsCSSProps@@2PEAVnsICSSProperty@@EA"] - pub static nsCSSProps_overflow_wrap: *mut nsICSSProperty; - #[link_name = "?writing_mode@nsCSSProps@@2PEAVnsICSSProperty@@EA"] - pub static nsCSSProps_writing_mode: *mut nsICSSProperty; - #[link_name = "?z_index@nsCSSProps@@2PEAVnsICSSProperty@@EA"] - pub static nsCSSProps_z_index: *mut nsICSSProperty; } } else { extern { @@ -12656,6 +11190,8 @@ cfg_if! { pub static nsGkAtoms_onattributewritereq: *mut nsIAtom; #[link_name = "\x01?onaudioprocess@nsGkAtoms@@2PAVnsIAtom@@A"] pub static nsGkAtoms_onaudioprocess: *mut nsIAtom; + #[link_name = "\x01?onauxclick@nsGkAtoms@@2PAVnsIAtom@@A"] + pub static nsGkAtoms_onauxclick: *mut nsIAtom; #[link_name = "\x01?onbeforecopy@nsGkAtoms@@2PAVnsIAtom@@A"] pub static nsGkAtoms_onbeforecopy: *mut nsIAtom; #[link_name = "\x01?onbeforecut@nsGkAtoms@@2PAVnsIAtom@@A"] @@ -12928,14 +11464,6 @@ cfg_if! { pub static nsGkAtoms_onmouseup: *mut nsIAtom; #[link_name = "\x01?onMozAfterPaint@nsGkAtoms@@2PAVnsIAtom@@A"] pub static nsGkAtoms_onMozAfterPaint: *mut nsIAtom; - #[link_name = "\x01?onmozbrowserafterkeydown@nsGkAtoms@@2PAVnsIAtom@@A"] - pub static nsGkAtoms_onmozbrowserafterkeydown: *mut nsIAtom; - #[link_name = "\x01?onmozbrowserafterkeyup@nsGkAtoms@@2PAVnsIAtom@@A"] - pub static nsGkAtoms_onmozbrowserafterkeyup: *mut nsIAtom; - #[link_name = "\x01?onmozbrowserbeforekeydown@nsGkAtoms@@2PAVnsIAtom@@A"] - pub static nsGkAtoms_onmozbrowserbeforekeydown: *mut nsIAtom; - #[link_name = "\x01?onmozbrowserbeforekeyup@nsGkAtoms@@2PAVnsIAtom@@A"] - pub static nsGkAtoms_onmozbrowserbeforekeyup: *mut nsIAtom; #[link_name = "\x01?onmozfullscreenchange@nsGkAtoms@@2PAVnsIAtom@@A"] pub static nsGkAtoms_onmozfullscreenchange: *mut nsIAtom; #[link_name = "\x01?onmozfullscreenerror@nsGkAtoms@@2PAVnsIAtom@@A"] @@ -13130,6 +11658,8 @@ cfg_if! { pub static nsGkAtoms_ontouchmove: *mut nsIAtom; #[link_name = "\x01?ontouchcancel@nsGkAtoms@@2PAVnsIAtom@@A"] pub static nsGkAtoms_ontouchcancel: *mut nsIAtom; + #[link_name = "\x01?ontransitioncancel@nsGkAtoms@@2PAVnsIAtom@@A"] + pub static nsGkAtoms_ontransitioncancel: *mut nsIAtom; #[link_name = "\x01?ontransitionend@nsGkAtoms@@2PAVnsIAtom@@A"] pub static nsGkAtoms_ontransitionend: *mut nsIAtom; #[link_name = "\x01?ontransitionrun@nsGkAtoms@@2PAVnsIAtom@@A"] @@ -13592,8 +12122,6 @@ cfg_if! { pub static nsGkAtoms_spinner: *mut nsIAtom; #[link_name = "\x01?split@nsGkAtoms@@2PAVnsIAtom@@A"] pub static nsGkAtoms_split: *mut nsIAtom; - #[link_name = "\x01?splitmenu@nsGkAtoms@@2PAVnsIAtom@@A"] - pub static nsGkAtoms_splitmenu: *mut nsIAtom; #[link_name = "\x01?splitter@nsGkAtoms@@2PAVnsIAtom@@A"] pub static nsGkAtoms_splitter: *mut nsIAtom; #[link_name = "\x01?spring@nsGkAtoms@@2PAVnsIAtom@@A"] @@ -15298,6 +13826,8 @@ cfg_if! { pub static nsGkAtoms_svgForeignObjectFrame: *mut nsIAtom; #[link_name = "\x01?svgGenericContainerFrame@nsGkAtoms@@2PAVnsIAtom@@A"] pub static nsGkAtoms_svgGenericContainerFrame: *mut nsIAtom; + #[link_name = "\x01?svgGeometryFrame@nsGkAtoms@@2PAVnsIAtom@@A"] + pub static nsGkAtoms_svgGeometryFrame: *mut nsIAtom; #[link_name = "\x01?svgGFrame@nsGkAtoms@@2PAVnsIAtom@@A"] pub static nsGkAtoms_svgGFrame: *mut nsIAtom; #[link_name = "\x01?svgGradientFrame@nsGkAtoms@@2PAVnsIAtom@@A"] @@ -15318,8 +13848,6 @@ cfg_if! { pub static nsGkAtoms_svgOuterSVGFrame: *mut nsIAtom; #[link_name = "\x01?svgOuterSVGAnonChildFrame@nsGkAtoms@@2PAVnsIAtom@@A"] pub static nsGkAtoms_svgOuterSVGAnonChildFrame: *mut nsIAtom; - #[link_name = "\x01?svgPathGeometryFrame@nsGkAtoms@@2PAVnsIAtom@@A"] - pub static nsGkAtoms_svgPathGeometryFrame: *mut nsIAtom; #[link_name = "\x01?svgPatternFrame@nsGkAtoms@@2PAVnsIAtom@@A"] pub static nsGkAtoms_svgPatternFrame: *mut nsIAtom; #[link_name = "\x01?svgRadialGradientFrame@nsGkAtoms@@2PAVnsIAtom@@A"] @@ -16228,732 +14756,6 @@ cfg_if! { pub static nsCSSAnonBoxes_mozSVGForeignContent: *mut nsICSSAnonBoxPseudo; #[link_name = "\x01?mozSVGText@nsCSSAnonBoxes@@2PAVnsICSSAnonBoxPseudo@@A"] pub static nsCSSAnonBoxes_mozSVGText: *mut nsICSSAnonBoxPseudo; - #[link_name = "\x01?align_content@nsCSSProps@@2PAVnsICSSProperty@@A"] - pub static nsCSSProps_align_content: *mut nsICSSProperty; - #[link_name = "\x01?align_items@nsCSSProps@@2PAVnsICSSProperty@@A"] - pub static nsCSSProps_align_items: *mut nsICSSProperty; - #[link_name = "\x01?align_self@nsCSSProps@@2PAVnsICSSProperty@@A"] - pub static nsCSSProps_align_self: *mut nsICSSProperty; - #[link_name = "\x01?all@nsCSSProps@@2PAVnsICSSProperty@@A"] - pub static nsCSSProps_all: *mut nsICSSProperty; - #[link_name = "\x01?animation@nsCSSProps@@2PAVnsICSSProperty@@A"] - pub static nsCSSProps_animation: *mut nsICSSProperty; - #[link_name = "\x01?animation_delay@nsCSSProps@@2PAVnsICSSProperty@@A"] - pub static nsCSSProps_animation_delay: *mut nsICSSProperty; - #[link_name = "\x01?animation_direction@nsCSSProps@@2PAVnsICSSProperty@@A"] - pub static nsCSSProps_animation_direction: *mut nsICSSProperty; - #[link_name = "\x01?animation_duration@nsCSSProps@@2PAVnsICSSProperty@@A"] - pub static nsCSSProps_animation_duration: *mut nsICSSProperty; - #[link_name = "\x01?animation_fill_mode@nsCSSProps@@2PAVnsICSSProperty@@A"] - pub static nsCSSProps_animation_fill_mode: *mut nsICSSProperty; - #[link_name = "\x01?animation_iteration_count@nsCSSProps@@2PAVnsICSSProperty@@A"] - pub static nsCSSProps_animation_iteration_count: *mut nsICSSProperty; - #[link_name = "\x01?animation_name@nsCSSProps@@2PAVnsICSSProperty@@A"] - pub static nsCSSProps_animation_name: *mut nsICSSProperty; - #[link_name = "\x01?animation_play_state@nsCSSProps@@2PAVnsICSSProperty@@A"] - pub static nsCSSProps_animation_play_state: *mut nsICSSProperty; - #[link_name = "\x01?animation_timing_function@nsCSSProps@@2PAVnsICSSProperty@@A"] - pub static nsCSSProps_animation_timing_function: *mut nsICSSProperty; - #[link_name = "\x01?appearance@nsCSSProps@@2PAVnsICSSProperty@@A"] - pub static nsCSSProps_appearance: *mut nsICSSProperty; - #[link_name = "\x01?backface_visibility@nsCSSProps@@2PAVnsICSSProperty@@A"] - pub static nsCSSProps_backface_visibility: *mut nsICSSProperty; - #[link_name = "\x01?background@nsCSSProps@@2PAVnsICSSProperty@@A"] - pub static nsCSSProps_background: *mut nsICSSProperty; - #[link_name = "\x01?background_attachment@nsCSSProps@@2PAVnsICSSProperty@@A"] - pub static nsCSSProps_background_attachment: *mut nsICSSProperty; - #[link_name = "\x01?background_blend_mode@nsCSSProps@@2PAVnsICSSProperty@@A"] - pub static nsCSSProps_background_blend_mode: *mut nsICSSProperty; - #[link_name = "\x01?background_clip@nsCSSProps@@2PAVnsICSSProperty@@A"] - pub static nsCSSProps_background_clip: *mut nsICSSProperty; - #[link_name = "\x01?background_color@nsCSSProps@@2PAVnsICSSProperty@@A"] - pub static nsCSSProps_background_color: *mut nsICSSProperty; - #[link_name = "\x01?background_image@nsCSSProps@@2PAVnsICSSProperty@@A"] - pub static nsCSSProps_background_image: *mut nsICSSProperty; - #[link_name = "\x01?background_origin@nsCSSProps@@2PAVnsICSSProperty@@A"] - pub static nsCSSProps_background_origin: *mut nsICSSProperty; - #[link_name = "\x01?background_position@nsCSSProps@@2PAVnsICSSProperty@@A"] - pub static nsCSSProps_background_position: *mut nsICSSProperty; - #[link_name = "\x01?background_position_x@nsCSSProps@@2PAVnsICSSProperty@@A"] - pub static nsCSSProps_background_position_x: *mut nsICSSProperty; - #[link_name = "\x01?background_position_y@nsCSSProps@@2PAVnsICSSProperty@@A"] - pub static nsCSSProps_background_position_y: *mut nsICSSProperty; - #[link_name = "\x01?background_repeat@nsCSSProps@@2PAVnsICSSProperty@@A"] - pub static nsCSSProps_background_repeat: *mut nsICSSProperty; - #[link_name = "\x01?background_size@nsCSSProps@@2PAVnsICSSProperty@@A"] - pub static nsCSSProps_background_size: *mut nsICSSProperty; - #[link_name = "\x01?binding@nsCSSProps@@2PAVnsICSSProperty@@A"] - pub static nsCSSProps_binding: *mut nsICSSProperty; - #[link_name = "\x01?block_size@nsCSSProps@@2PAVnsICSSProperty@@A"] - pub static nsCSSProps_block_size: *mut nsICSSProperty; - #[link_name = "\x01?border@nsCSSProps@@2PAVnsICSSProperty@@A"] - pub static nsCSSProps_border: *mut nsICSSProperty; - #[link_name = "\x01?border_block_end@nsCSSProps@@2PAVnsICSSProperty@@A"] - pub static nsCSSProps_border_block_end: *mut nsICSSProperty; - #[link_name = "\x01?border_block_end_color@nsCSSProps@@2PAVnsICSSProperty@@A"] - pub static nsCSSProps_border_block_end_color: *mut nsICSSProperty; - #[link_name = "\x01?border_block_end_style@nsCSSProps@@2PAVnsICSSProperty@@A"] - pub static nsCSSProps_border_block_end_style: *mut nsICSSProperty; - #[link_name = "\x01?border_block_end_width@nsCSSProps@@2PAVnsICSSProperty@@A"] - pub static nsCSSProps_border_block_end_width: *mut nsICSSProperty; - #[link_name = "\x01?border_block_start@nsCSSProps@@2PAVnsICSSProperty@@A"] - pub static nsCSSProps_border_block_start: *mut nsICSSProperty; - #[link_name = "\x01?border_block_start_color@nsCSSProps@@2PAVnsICSSProperty@@A"] - pub static nsCSSProps_border_block_start_color: *mut nsICSSProperty; - #[link_name = "\x01?border_block_start_style@nsCSSProps@@2PAVnsICSSProperty@@A"] - pub static nsCSSProps_border_block_start_style: *mut nsICSSProperty; - #[link_name = "\x01?border_block_start_width@nsCSSProps@@2PAVnsICSSProperty@@A"] - pub static nsCSSProps_border_block_start_width: *mut nsICSSProperty; - #[link_name = "\x01?border_bottom@nsCSSProps@@2PAVnsICSSProperty@@A"] - pub static nsCSSProps_border_bottom: *mut nsICSSProperty; - #[link_name = "\x01?border_bottom_color@nsCSSProps@@2PAVnsICSSProperty@@A"] - pub static nsCSSProps_border_bottom_color: *mut nsICSSProperty; - #[link_name = "\x01?border_bottom_colors@nsCSSProps@@2PAVnsICSSProperty@@A"] - pub static nsCSSProps_border_bottom_colors: *mut nsICSSProperty; - #[link_name = "\x01?border_bottom_left_radius@nsCSSProps@@2PAVnsICSSProperty@@A"] - pub static nsCSSProps_border_bottom_left_radius: *mut nsICSSProperty; - #[link_name = "\x01?border_bottom_right_radius@nsCSSProps@@2PAVnsICSSProperty@@A"] - pub static nsCSSProps_border_bottom_right_radius: *mut nsICSSProperty; - #[link_name = "\x01?border_bottom_style@nsCSSProps@@2PAVnsICSSProperty@@A"] - pub static nsCSSProps_border_bottom_style: *mut nsICSSProperty; - #[link_name = "\x01?border_bottom_width@nsCSSProps@@2PAVnsICSSProperty@@A"] - pub static nsCSSProps_border_bottom_width: *mut nsICSSProperty; - #[link_name = "\x01?border_collapse@nsCSSProps@@2PAVnsICSSProperty@@A"] - pub static nsCSSProps_border_collapse: *mut nsICSSProperty; - #[link_name = "\x01?border_color@nsCSSProps@@2PAVnsICSSProperty@@A"] - pub static nsCSSProps_border_color: *mut nsICSSProperty; - #[link_name = "\x01?border_image@nsCSSProps@@2PAVnsICSSProperty@@A"] - pub static nsCSSProps_border_image: *mut nsICSSProperty; - #[link_name = "\x01?border_image_outset@nsCSSProps@@2PAVnsICSSProperty@@A"] - pub static nsCSSProps_border_image_outset: *mut nsICSSProperty; - #[link_name = "\x01?border_image_repeat@nsCSSProps@@2PAVnsICSSProperty@@A"] - pub static nsCSSProps_border_image_repeat: *mut nsICSSProperty; - #[link_name = "\x01?border_image_slice@nsCSSProps@@2PAVnsICSSProperty@@A"] - pub static nsCSSProps_border_image_slice: *mut nsICSSProperty; - #[link_name = "\x01?border_image_source@nsCSSProps@@2PAVnsICSSProperty@@A"] - pub static nsCSSProps_border_image_source: *mut nsICSSProperty; - #[link_name = "\x01?border_image_width@nsCSSProps@@2PAVnsICSSProperty@@A"] - pub static nsCSSProps_border_image_width: *mut nsICSSProperty; - #[link_name = "\x01?border_inline_end@nsCSSProps@@2PAVnsICSSProperty@@A"] - pub static nsCSSProps_border_inline_end: *mut nsICSSProperty; - #[link_name = "\x01?border_inline_end_color@nsCSSProps@@2PAVnsICSSProperty@@A"] - pub static nsCSSProps_border_inline_end_color: *mut nsICSSProperty; - #[link_name = "\x01?border_inline_end_style@nsCSSProps@@2PAVnsICSSProperty@@A"] - pub static nsCSSProps_border_inline_end_style: *mut nsICSSProperty; - #[link_name = "\x01?border_inline_end_width@nsCSSProps@@2PAVnsICSSProperty@@A"] - pub static nsCSSProps_border_inline_end_width: *mut nsICSSProperty; - #[link_name = "\x01?border_inline_start@nsCSSProps@@2PAVnsICSSProperty@@A"] - pub static nsCSSProps_border_inline_start: *mut nsICSSProperty; - #[link_name = "\x01?border_inline_start_color@nsCSSProps@@2PAVnsICSSProperty@@A"] - pub static nsCSSProps_border_inline_start_color: *mut nsICSSProperty; - #[link_name = "\x01?border_inline_start_style@nsCSSProps@@2PAVnsICSSProperty@@A"] - pub static nsCSSProps_border_inline_start_style: *mut nsICSSProperty; - #[link_name = "\x01?border_inline_start_width@nsCSSProps@@2PAVnsICSSProperty@@A"] - pub static nsCSSProps_border_inline_start_width: *mut nsICSSProperty; - #[link_name = "\x01?border_left@nsCSSProps@@2PAVnsICSSProperty@@A"] - pub static nsCSSProps_border_left: *mut nsICSSProperty; - #[link_name = "\x01?border_left_color@nsCSSProps@@2PAVnsICSSProperty@@A"] - pub static nsCSSProps_border_left_color: *mut nsICSSProperty; - #[link_name = "\x01?border_left_colors@nsCSSProps@@2PAVnsICSSProperty@@A"] - pub static nsCSSProps_border_left_colors: *mut nsICSSProperty; - #[link_name = "\x01?border_left_style@nsCSSProps@@2PAVnsICSSProperty@@A"] - pub static nsCSSProps_border_left_style: *mut nsICSSProperty; - #[link_name = "\x01?border_left_width@nsCSSProps@@2PAVnsICSSProperty@@A"] - pub static nsCSSProps_border_left_width: *mut nsICSSProperty; - #[link_name = "\x01?border_radius@nsCSSProps@@2PAVnsICSSProperty@@A"] - pub static nsCSSProps_border_radius: *mut nsICSSProperty; - #[link_name = "\x01?border_right@nsCSSProps@@2PAVnsICSSProperty@@A"] - pub static nsCSSProps_border_right: *mut nsICSSProperty; - #[link_name = "\x01?border_right_color@nsCSSProps@@2PAVnsICSSProperty@@A"] - pub static nsCSSProps_border_right_color: *mut nsICSSProperty; - #[link_name = "\x01?border_right_colors@nsCSSProps@@2PAVnsICSSProperty@@A"] - pub static nsCSSProps_border_right_colors: *mut nsICSSProperty; - #[link_name = "\x01?border_right_style@nsCSSProps@@2PAVnsICSSProperty@@A"] - pub static nsCSSProps_border_right_style: *mut nsICSSProperty; - #[link_name = "\x01?border_right_width@nsCSSProps@@2PAVnsICSSProperty@@A"] - pub static nsCSSProps_border_right_width: *mut nsICSSProperty; - #[link_name = "\x01?border_spacing@nsCSSProps@@2PAVnsICSSProperty@@A"] - pub static nsCSSProps_border_spacing: *mut nsICSSProperty; - #[link_name = "\x01?border_style@nsCSSProps@@2PAVnsICSSProperty@@A"] - pub static nsCSSProps_border_style: *mut nsICSSProperty; - #[link_name = "\x01?border_top@nsCSSProps@@2PAVnsICSSProperty@@A"] - pub static nsCSSProps_border_top: *mut nsICSSProperty; - #[link_name = "\x01?border_top_color@nsCSSProps@@2PAVnsICSSProperty@@A"] - pub static nsCSSProps_border_top_color: *mut nsICSSProperty; - #[link_name = "\x01?border_top_colors@nsCSSProps@@2PAVnsICSSProperty@@A"] - pub static nsCSSProps_border_top_colors: *mut nsICSSProperty; - #[link_name = "\x01?border_top_left_radius@nsCSSProps@@2PAVnsICSSProperty@@A"] - pub static nsCSSProps_border_top_left_radius: *mut nsICSSProperty; - #[link_name = "\x01?border_top_right_radius@nsCSSProps@@2PAVnsICSSProperty@@A"] - pub static nsCSSProps_border_top_right_radius: *mut nsICSSProperty; - #[link_name = "\x01?border_top_style@nsCSSProps@@2PAVnsICSSProperty@@A"] - pub static nsCSSProps_border_top_style: *mut nsICSSProperty; - #[link_name = "\x01?border_top_width@nsCSSProps@@2PAVnsICSSProperty@@A"] - pub static nsCSSProps_border_top_width: *mut nsICSSProperty; - #[link_name = "\x01?border_width@nsCSSProps@@2PAVnsICSSProperty@@A"] - pub static nsCSSProps_border_width: *mut nsICSSProperty; - #[link_name = "\x01?bottom@nsCSSProps@@2PAVnsICSSProperty@@A"] - pub static nsCSSProps_bottom: *mut nsICSSProperty; - #[link_name = "\x01?box_align@nsCSSProps@@2PAVnsICSSProperty@@A"] - pub static nsCSSProps_box_align: *mut nsICSSProperty; - #[link_name = "\x01?box_decoration_break@nsCSSProps@@2PAVnsICSSProperty@@A"] - pub static nsCSSProps_box_decoration_break: *mut nsICSSProperty; - #[link_name = "\x01?box_direction@nsCSSProps@@2PAVnsICSSProperty@@A"] - pub static nsCSSProps_box_direction: *mut nsICSSProperty; - #[link_name = "\x01?box_flex@nsCSSProps@@2PAVnsICSSProperty@@A"] - pub static nsCSSProps_box_flex: *mut nsICSSProperty; - #[link_name = "\x01?box_ordinal_group@nsCSSProps@@2PAVnsICSSProperty@@A"] - pub static nsCSSProps_box_ordinal_group: *mut nsICSSProperty; - #[link_name = "\x01?box_orient@nsCSSProps@@2PAVnsICSSProperty@@A"] - pub static nsCSSProps_box_orient: *mut nsICSSProperty; - #[link_name = "\x01?box_pack@nsCSSProps@@2PAVnsICSSProperty@@A"] - pub static nsCSSProps_box_pack: *mut nsICSSProperty; - #[link_name = "\x01?box_shadow@nsCSSProps@@2PAVnsICSSProperty@@A"] - pub static nsCSSProps_box_shadow: *mut nsICSSProperty; - #[link_name = "\x01?box_sizing@nsCSSProps@@2PAVnsICSSProperty@@A"] - pub static nsCSSProps_box_sizing: *mut nsICSSProperty; - #[link_name = "\x01?caption_side@nsCSSProps@@2PAVnsICSSProperty@@A"] - pub static nsCSSProps_caption_side: *mut nsICSSProperty; - #[link_name = "\x01?clear@nsCSSProps@@2PAVnsICSSProperty@@A"] - pub static nsCSSProps_clear: *mut nsICSSProperty; - #[link_name = "\x01?clip@nsCSSProps@@2PAVnsICSSProperty@@A"] - pub static nsCSSProps_clip: *mut nsICSSProperty; - #[link_name = "\x01?clip_path@nsCSSProps@@2PAVnsICSSProperty@@A"] - pub static nsCSSProps_clip_path: *mut nsICSSProperty; - #[link_name = "\x01?clip_rule@nsCSSProps@@2PAVnsICSSProperty@@A"] - pub static nsCSSProps_clip_rule: *mut nsICSSProperty; - #[link_name = "\x01?color@nsCSSProps@@2PAVnsICSSProperty@@A"] - pub static nsCSSProps_color: *mut nsICSSProperty; - #[link_name = "\x01?color_adjust@nsCSSProps@@2PAVnsICSSProperty@@A"] - pub static nsCSSProps_color_adjust: *mut nsICSSProperty; - #[link_name = "\x01?color_interpolation@nsCSSProps@@2PAVnsICSSProperty@@A"] - pub static nsCSSProps_color_interpolation: *mut nsICSSProperty; - #[link_name = "\x01?color_interpolation_filters@nsCSSProps@@2PAVnsICSSProperty@@A"] - pub static nsCSSProps_color_interpolation_filters: *mut nsICSSProperty; - #[link_name = "\x01?column_count@nsCSSProps@@2PAVnsICSSProperty@@A"] - pub static nsCSSProps_column_count: *mut nsICSSProperty; - #[link_name = "\x01?column_fill@nsCSSProps@@2PAVnsICSSProperty@@A"] - pub static nsCSSProps_column_fill: *mut nsICSSProperty; - #[link_name = "\x01?column_gap@nsCSSProps@@2PAVnsICSSProperty@@A"] - pub static nsCSSProps_column_gap: *mut nsICSSProperty; - #[link_name = "\x01?column_rule@nsCSSProps@@2PAVnsICSSProperty@@A"] - pub static nsCSSProps_column_rule: *mut nsICSSProperty; - #[link_name = "\x01?column_rule_color@nsCSSProps@@2PAVnsICSSProperty@@A"] - pub static nsCSSProps_column_rule_color: *mut nsICSSProperty; - #[link_name = "\x01?column_rule_style@nsCSSProps@@2PAVnsICSSProperty@@A"] - pub static nsCSSProps_column_rule_style: *mut nsICSSProperty; - #[link_name = "\x01?column_rule_width@nsCSSProps@@2PAVnsICSSProperty@@A"] - pub static nsCSSProps_column_rule_width: *mut nsICSSProperty; - #[link_name = "\x01?column_width@nsCSSProps@@2PAVnsICSSProperty@@A"] - pub static nsCSSProps_column_width: *mut nsICSSProperty; - #[link_name = "\x01?columns@nsCSSProps@@2PAVnsICSSProperty@@A"] - pub static nsCSSProps_columns: *mut nsICSSProperty; - #[link_name = "\x01?contain@nsCSSProps@@2PAVnsICSSProperty@@A"] - pub static nsCSSProps_contain: *mut nsICSSProperty; - #[link_name = "\x01?content@nsCSSProps@@2PAVnsICSSProperty@@A"] - pub static nsCSSProps_content: *mut nsICSSProperty; - #[link_name = "\x01?_moz_control_character_visibility@nsCSSProps@@2PAVnsICSSProperty@@A"] - pub static nsCSSProps__moz_control_character_visibility: *mut nsICSSProperty; - #[link_name = "\x01?counter_increment@nsCSSProps@@2PAVnsICSSProperty@@A"] - pub static nsCSSProps_counter_increment: *mut nsICSSProperty; - #[link_name = "\x01?counter_reset@nsCSSProps@@2PAVnsICSSProperty@@A"] - pub static nsCSSProps_counter_reset: *mut nsICSSProperty; - #[link_name = "\x01?cursor@nsCSSProps@@2PAVnsICSSProperty@@A"] - pub static nsCSSProps_cursor: *mut nsICSSProperty; - #[link_name = "\x01?direction@nsCSSProps@@2PAVnsICSSProperty@@A"] - pub static nsCSSProps_direction: *mut nsICSSProperty; - #[link_name = "\x01?display@nsCSSProps@@2PAVnsICSSProperty@@A"] - pub static nsCSSProps_display: *mut nsICSSProperty; - #[link_name = "\x01?dominant_baseline@nsCSSProps@@2PAVnsICSSProperty@@A"] - pub static nsCSSProps_dominant_baseline: *mut nsICSSProperty; - #[link_name = "\x01?empty_cells@nsCSSProps@@2PAVnsICSSProperty@@A"] - pub static nsCSSProps_empty_cells: *mut nsICSSProperty; - #[link_name = "\x01?fill@nsCSSProps@@2PAVnsICSSProperty@@A"] - pub static nsCSSProps_fill: *mut nsICSSProperty; - #[link_name = "\x01?fill_opacity@nsCSSProps@@2PAVnsICSSProperty@@A"] - pub static nsCSSProps_fill_opacity: *mut nsICSSProperty; - #[link_name = "\x01?fill_rule@nsCSSProps@@2PAVnsICSSProperty@@A"] - pub static nsCSSProps_fill_rule: *mut nsICSSProperty; - #[link_name = "\x01?filter@nsCSSProps@@2PAVnsICSSProperty@@A"] - pub static nsCSSProps_filter: *mut nsICSSProperty; - #[link_name = "\x01?flex@nsCSSProps@@2PAVnsICSSProperty@@A"] - pub static nsCSSProps_flex: *mut nsICSSProperty; - #[link_name = "\x01?flex_basis@nsCSSProps@@2PAVnsICSSProperty@@A"] - pub static nsCSSProps_flex_basis: *mut nsICSSProperty; - #[link_name = "\x01?flex_direction@nsCSSProps@@2PAVnsICSSProperty@@A"] - pub static nsCSSProps_flex_direction: *mut nsICSSProperty; - #[link_name = "\x01?flex_flow@nsCSSProps@@2PAVnsICSSProperty@@A"] - pub static nsCSSProps_flex_flow: *mut nsICSSProperty; - #[link_name = "\x01?flex_grow@nsCSSProps@@2PAVnsICSSProperty@@A"] - pub static nsCSSProps_flex_grow: *mut nsICSSProperty; - #[link_name = "\x01?flex_shrink@nsCSSProps@@2PAVnsICSSProperty@@A"] - pub static nsCSSProps_flex_shrink: *mut nsICSSProperty; - #[link_name = "\x01?flex_wrap@nsCSSProps@@2PAVnsICSSProperty@@A"] - pub static nsCSSProps_flex_wrap: *mut nsICSSProperty; - #[link_name = "\x01?float_@nsCSSProps@@2PAVnsICSSProperty@@A"] - pub static nsCSSProps_float_: *mut nsICSSProperty; - #[link_name = "\x01?float_edge@nsCSSProps@@2PAVnsICSSProperty@@A"] - pub static nsCSSProps_float_edge: *mut nsICSSProperty; - #[link_name = "\x01?flood_color@nsCSSProps@@2PAVnsICSSProperty@@A"] - pub static nsCSSProps_flood_color: *mut nsICSSProperty; - #[link_name = "\x01?flood_opacity@nsCSSProps@@2PAVnsICSSProperty@@A"] - pub static nsCSSProps_flood_opacity: *mut nsICSSProperty; - #[link_name = "\x01?font@nsCSSProps@@2PAVnsICSSProperty@@A"] - pub static nsCSSProps_font: *mut nsICSSProperty; - #[link_name = "\x01?font_family@nsCSSProps@@2PAVnsICSSProperty@@A"] - pub static nsCSSProps_font_family: *mut nsICSSProperty; - #[link_name = "\x01?font_feature_settings@nsCSSProps@@2PAVnsICSSProperty@@A"] - pub static nsCSSProps_font_feature_settings: *mut nsICSSProperty; - #[link_name = "\x01?font_kerning@nsCSSProps@@2PAVnsICSSProperty@@A"] - pub static nsCSSProps_font_kerning: *mut nsICSSProperty; - #[link_name = "\x01?font_language_override@nsCSSProps@@2PAVnsICSSProperty@@A"] - pub static nsCSSProps_font_language_override: *mut nsICSSProperty; - #[link_name = "\x01?font_size@nsCSSProps@@2PAVnsICSSProperty@@A"] - pub static nsCSSProps_font_size: *mut nsICSSProperty; - #[link_name = "\x01?font_size_adjust@nsCSSProps@@2PAVnsICSSProperty@@A"] - pub static nsCSSProps_font_size_adjust: *mut nsICSSProperty; - #[link_name = "\x01?font_stretch@nsCSSProps@@2PAVnsICSSProperty@@A"] - pub static nsCSSProps_font_stretch: *mut nsICSSProperty; - #[link_name = "\x01?font_style@nsCSSProps@@2PAVnsICSSProperty@@A"] - pub static nsCSSProps_font_style: *mut nsICSSProperty; - #[link_name = "\x01?font_synthesis@nsCSSProps@@2PAVnsICSSProperty@@A"] - pub static nsCSSProps_font_synthesis: *mut nsICSSProperty; - #[link_name = "\x01?font_variant@nsCSSProps@@2PAVnsICSSProperty@@A"] - pub static nsCSSProps_font_variant: *mut nsICSSProperty; - #[link_name = "\x01?font_variant_alternates@nsCSSProps@@2PAVnsICSSProperty@@A"] - pub static nsCSSProps_font_variant_alternates: *mut nsICSSProperty; - #[link_name = "\x01?font_variant_caps@nsCSSProps@@2PAVnsICSSProperty@@A"] - pub static nsCSSProps_font_variant_caps: *mut nsICSSProperty; - #[link_name = "\x01?font_variant_east_asian@nsCSSProps@@2PAVnsICSSProperty@@A"] - pub static nsCSSProps_font_variant_east_asian: *mut nsICSSProperty; - #[link_name = "\x01?font_variant_ligatures@nsCSSProps@@2PAVnsICSSProperty@@A"] - pub static nsCSSProps_font_variant_ligatures: *mut nsICSSProperty; - #[link_name = "\x01?font_variant_numeric@nsCSSProps@@2PAVnsICSSProperty@@A"] - pub static nsCSSProps_font_variant_numeric: *mut nsICSSProperty; - #[link_name = "\x01?font_variant_position@nsCSSProps@@2PAVnsICSSProperty@@A"] - pub static nsCSSProps_font_variant_position: *mut nsICSSProperty; - #[link_name = "\x01?font_variation_settings@nsCSSProps@@2PAVnsICSSProperty@@A"] - pub static nsCSSProps_font_variation_settings: *mut nsICSSProperty; - #[link_name = "\x01?font_weight@nsCSSProps@@2PAVnsICSSProperty@@A"] - pub static nsCSSProps_font_weight: *mut nsICSSProperty; - #[link_name = "\x01?force_broken_image_icon@nsCSSProps@@2PAVnsICSSProperty@@A"] - pub static nsCSSProps_force_broken_image_icon: *mut nsICSSProperty; - #[link_name = "\x01?grid@nsCSSProps@@2PAVnsICSSProperty@@A"] - pub static nsCSSProps_grid: *mut nsICSSProperty; - #[link_name = "\x01?grid_area@nsCSSProps@@2PAVnsICSSProperty@@A"] - pub static nsCSSProps_grid_area: *mut nsICSSProperty; - #[link_name = "\x01?grid_auto_columns@nsCSSProps@@2PAVnsICSSProperty@@A"] - pub static nsCSSProps_grid_auto_columns: *mut nsICSSProperty; - #[link_name = "\x01?grid_auto_flow@nsCSSProps@@2PAVnsICSSProperty@@A"] - pub static nsCSSProps_grid_auto_flow: *mut nsICSSProperty; - #[link_name = "\x01?grid_auto_rows@nsCSSProps@@2PAVnsICSSProperty@@A"] - pub static nsCSSProps_grid_auto_rows: *mut nsICSSProperty; - #[link_name = "\x01?grid_column@nsCSSProps@@2PAVnsICSSProperty@@A"] - pub static nsCSSProps_grid_column: *mut nsICSSProperty; - #[link_name = "\x01?grid_column_end@nsCSSProps@@2PAVnsICSSProperty@@A"] - pub static nsCSSProps_grid_column_end: *mut nsICSSProperty; - #[link_name = "\x01?grid_column_gap@nsCSSProps@@2PAVnsICSSProperty@@A"] - pub static nsCSSProps_grid_column_gap: *mut nsICSSProperty; - #[link_name = "\x01?grid_column_start@nsCSSProps@@2PAVnsICSSProperty@@A"] - pub static nsCSSProps_grid_column_start: *mut nsICSSProperty; - #[link_name = "\x01?grid_gap@nsCSSProps@@2PAVnsICSSProperty@@A"] - pub static nsCSSProps_grid_gap: *mut nsICSSProperty; - #[link_name = "\x01?grid_row@nsCSSProps@@2PAVnsICSSProperty@@A"] - pub static nsCSSProps_grid_row: *mut nsICSSProperty; - #[link_name = "\x01?grid_row_end@nsCSSProps@@2PAVnsICSSProperty@@A"] - pub static nsCSSProps_grid_row_end: *mut nsICSSProperty; - #[link_name = "\x01?grid_row_gap@nsCSSProps@@2PAVnsICSSProperty@@A"] - pub static nsCSSProps_grid_row_gap: *mut nsICSSProperty; - #[link_name = "\x01?grid_row_start@nsCSSProps@@2PAVnsICSSProperty@@A"] - pub static nsCSSProps_grid_row_start: *mut nsICSSProperty; - #[link_name = "\x01?grid_template@nsCSSProps@@2PAVnsICSSProperty@@A"] - pub static nsCSSProps_grid_template: *mut nsICSSProperty; - #[link_name = "\x01?grid_template_areas@nsCSSProps@@2PAVnsICSSProperty@@A"] - pub static nsCSSProps_grid_template_areas: *mut nsICSSProperty; - #[link_name = "\x01?grid_template_columns@nsCSSProps@@2PAVnsICSSProperty@@A"] - pub static nsCSSProps_grid_template_columns: *mut nsICSSProperty; - #[link_name = "\x01?grid_template_rows@nsCSSProps@@2PAVnsICSSProperty@@A"] - pub static nsCSSProps_grid_template_rows: *mut nsICSSProperty; - #[link_name = "\x01?height@nsCSSProps@@2PAVnsICSSProperty@@A"] - pub static nsCSSProps_height: *mut nsICSSProperty; - #[link_name = "\x01?hyphens@nsCSSProps@@2PAVnsICSSProperty@@A"] - pub static nsCSSProps_hyphens: *mut nsICSSProperty; - #[link_name = "\x01?initial_letter@nsCSSProps@@2PAVnsICSSProperty@@A"] - pub static nsCSSProps_initial_letter: *mut nsICSSProperty; - #[link_name = "\x01?image_orientation@nsCSSProps@@2PAVnsICSSProperty@@A"] - pub static nsCSSProps_image_orientation: *mut nsICSSProperty; - #[link_name = "\x01?image_region@nsCSSProps@@2PAVnsICSSProperty@@A"] - pub static nsCSSProps_image_region: *mut nsICSSProperty; - #[link_name = "\x01?image_rendering@nsCSSProps@@2PAVnsICSSProperty@@A"] - pub static nsCSSProps_image_rendering: *mut nsICSSProperty; - #[link_name = "\x01?ime_mode@nsCSSProps@@2PAVnsICSSProperty@@A"] - pub static nsCSSProps_ime_mode: *mut nsICSSProperty; - #[link_name = "\x01?inline_size@nsCSSProps@@2PAVnsICSSProperty@@A"] - pub static nsCSSProps_inline_size: *mut nsICSSProperty; - #[link_name = "\x01?isolation@nsCSSProps@@2PAVnsICSSProperty@@A"] - pub static nsCSSProps_isolation: *mut nsICSSProperty; - #[link_name = "\x01?justify_content@nsCSSProps@@2PAVnsICSSProperty@@A"] - pub static nsCSSProps_justify_content: *mut nsICSSProperty; - #[link_name = "\x01?justify_items@nsCSSProps@@2PAVnsICSSProperty@@A"] - pub static nsCSSProps_justify_items: *mut nsICSSProperty; - #[link_name = "\x01?justify_self@nsCSSProps@@2PAVnsICSSProperty@@A"] - pub static nsCSSProps_justify_self: *mut nsICSSProperty; - #[link_name = "\x01?_x_lang@nsCSSProps@@2PAVnsICSSProperty@@A"] - pub static nsCSSProps__x_lang: *mut nsICSSProperty; - #[link_name = "\x01?left@nsCSSProps@@2PAVnsICSSProperty@@A"] - pub static nsCSSProps_left: *mut nsICSSProperty; - #[link_name = "\x01?letter_spacing@nsCSSProps@@2PAVnsICSSProperty@@A"] - pub static nsCSSProps_letter_spacing: *mut nsICSSProperty; - #[link_name = "\x01?lighting_color@nsCSSProps@@2PAVnsICSSProperty@@A"] - pub static nsCSSProps_lighting_color: *mut nsICSSProperty; - #[link_name = "\x01?line_height@nsCSSProps@@2PAVnsICSSProperty@@A"] - pub static nsCSSProps_line_height: *mut nsICSSProperty; - #[link_name = "\x01?list_style@nsCSSProps@@2PAVnsICSSProperty@@A"] - pub static nsCSSProps_list_style: *mut nsICSSProperty; - #[link_name = "\x01?list_style_image@nsCSSProps@@2PAVnsICSSProperty@@A"] - pub static nsCSSProps_list_style_image: *mut nsICSSProperty; - #[link_name = "\x01?list_style_position@nsCSSProps@@2PAVnsICSSProperty@@A"] - pub static nsCSSProps_list_style_position: *mut nsICSSProperty; - #[link_name = "\x01?list_style_type@nsCSSProps@@2PAVnsICSSProperty@@A"] - pub static nsCSSProps_list_style_type: *mut nsICSSProperty; - #[link_name = "\x01?margin@nsCSSProps@@2PAVnsICSSProperty@@A"] - pub static nsCSSProps_margin: *mut nsICSSProperty; - #[link_name = "\x01?margin_block_end@nsCSSProps@@2PAVnsICSSProperty@@A"] - pub static nsCSSProps_margin_block_end: *mut nsICSSProperty; - #[link_name = "\x01?margin_block_start@nsCSSProps@@2PAVnsICSSProperty@@A"] - pub static nsCSSProps_margin_block_start: *mut nsICSSProperty; - #[link_name = "\x01?margin_bottom@nsCSSProps@@2PAVnsICSSProperty@@A"] - pub static nsCSSProps_margin_bottom: *mut nsICSSProperty; - #[link_name = "\x01?margin_inline_end@nsCSSProps@@2PAVnsICSSProperty@@A"] - pub static nsCSSProps_margin_inline_end: *mut nsICSSProperty; - #[link_name = "\x01?margin_inline_start@nsCSSProps@@2PAVnsICSSProperty@@A"] - pub static nsCSSProps_margin_inline_start: *mut nsICSSProperty; - #[link_name = "\x01?margin_left@nsCSSProps@@2PAVnsICSSProperty@@A"] - pub static nsCSSProps_margin_left: *mut nsICSSProperty; - #[link_name = "\x01?margin_right@nsCSSProps@@2PAVnsICSSProperty@@A"] - pub static nsCSSProps_margin_right: *mut nsICSSProperty; - #[link_name = "\x01?margin_top@nsCSSProps@@2PAVnsICSSProperty@@A"] - pub static nsCSSProps_margin_top: *mut nsICSSProperty; - #[link_name = "\x01?marker@nsCSSProps@@2PAVnsICSSProperty@@A"] - pub static nsCSSProps_marker: *mut nsICSSProperty; - #[link_name = "\x01?marker_end@nsCSSProps@@2PAVnsICSSProperty@@A"] - pub static nsCSSProps_marker_end: *mut nsICSSProperty; - #[link_name = "\x01?marker_mid@nsCSSProps@@2PAVnsICSSProperty@@A"] - pub static nsCSSProps_marker_mid: *mut nsICSSProperty; - #[link_name = "\x01?marker_start@nsCSSProps@@2PAVnsICSSProperty@@A"] - pub static nsCSSProps_marker_start: *mut nsICSSProperty; - #[link_name = "\x01?mask@nsCSSProps@@2PAVnsICSSProperty@@A"] - pub static nsCSSProps_mask: *mut nsICSSProperty; - #[link_name = "\x01?mask_clip@nsCSSProps@@2PAVnsICSSProperty@@A"] - pub static nsCSSProps_mask_clip: *mut nsICSSProperty; - #[link_name = "\x01?mask_composite@nsCSSProps@@2PAVnsICSSProperty@@A"] - pub static nsCSSProps_mask_composite: *mut nsICSSProperty; - #[link_name = "\x01?mask_image@nsCSSProps@@2PAVnsICSSProperty@@A"] - pub static nsCSSProps_mask_image: *mut nsICSSProperty; - #[link_name = "\x01?mask_mode@nsCSSProps@@2PAVnsICSSProperty@@A"] - pub static nsCSSProps_mask_mode: *mut nsICSSProperty; - #[link_name = "\x01?mask_origin@nsCSSProps@@2PAVnsICSSProperty@@A"] - pub static nsCSSProps_mask_origin: *mut nsICSSProperty; - #[link_name = "\x01?mask_position@nsCSSProps@@2PAVnsICSSProperty@@A"] - pub static nsCSSProps_mask_position: *mut nsICSSProperty; - #[link_name = "\x01?mask_position_x@nsCSSProps@@2PAVnsICSSProperty@@A"] - pub static nsCSSProps_mask_position_x: *mut nsICSSProperty; - #[link_name = "\x01?mask_position_y@nsCSSProps@@2PAVnsICSSProperty@@A"] - pub static nsCSSProps_mask_position_y: *mut nsICSSProperty; - #[link_name = "\x01?mask_repeat@nsCSSProps@@2PAVnsICSSProperty@@A"] - pub static nsCSSProps_mask_repeat: *mut nsICSSProperty; - #[link_name = "\x01?mask_size@nsCSSProps@@2PAVnsICSSProperty@@A"] - pub static nsCSSProps_mask_size: *mut nsICSSProperty; - #[link_name = "\x01?mask_type@nsCSSProps@@2PAVnsICSSProperty@@A"] - pub static nsCSSProps_mask_type: *mut nsICSSProperty; - #[link_name = "\x01?math_display@nsCSSProps@@2PAVnsICSSProperty@@A"] - pub static nsCSSProps_math_display: *mut nsICSSProperty; - #[link_name = "\x01?math_variant@nsCSSProps@@2PAVnsICSSProperty@@A"] - pub static nsCSSProps_math_variant: *mut nsICSSProperty; - #[link_name = "\x01?max_block_size@nsCSSProps@@2PAVnsICSSProperty@@A"] - pub static nsCSSProps_max_block_size: *mut nsICSSProperty; - #[link_name = "\x01?max_height@nsCSSProps@@2PAVnsICSSProperty@@A"] - pub static nsCSSProps_max_height: *mut nsICSSProperty; - #[link_name = "\x01?max_inline_size@nsCSSProps@@2PAVnsICSSProperty@@A"] - pub static nsCSSProps_max_inline_size: *mut nsICSSProperty; - #[link_name = "\x01?max_width@nsCSSProps@@2PAVnsICSSProperty@@A"] - pub static nsCSSProps_max_width: *mut nsICSSProperty; - #[link_name = "\x01?min_block_size@nsCSSProps@@2PAVnsICSSProperty@@A"] - pub static nsCSSProps_min_block_size: *mut nsICSSProperty; - #[link_name = "\x01?_moz_min_font_size_ratio@nsCSSProps@@2PAVnsICSSProperty@@A"] - pub static nsCSSProps__moz_min_font_size_ratio: *mut nsICSSProperty; - #[link_name = "\x01?min_height@nsCSSProps@@2PAVnsICSSProperty@@A"] - pub static nsCSSProps_min_height: *mut nsICSSProperty; - #[link_name = "\x01?min_inline_size@nsCSSProps@@2PAVnsICSSProperty@@A"] - pub static nsCSSProps_min_inline_size: *mut nsICSSProperty; - #[link_name = "\x01?min_width@nsCSSProps@@2PAVnsICSSProperty@@A"] - pub static nsCSSProps_min_width: *mut nsICSSProperty; - #[link_name = "\x01?mix_blend_mode@nsCSSProps@@2PAVnsICSSProperty@@A"] - pub static nsCSSProps_mix_blend_mode: *mut nsICSSProperty; - #[link_name = "\x01?object_fit@nsCSSProps@@2PAVnsICSSProperty@@A"] - pub static nsCSSProps_object_fit: *mut nsICSSProperty; - #[link_name = "\x01?object_position@nsCSSProps@@2PAVnsICSSProperty@@A"] - pub static nsCSSProps_object_position: *mut nsICSSProperty; - #[link_name = "\x01?offset_block_end@nsCSSProps@@2PAVnsICSSProperty@@A"] - pub static nsCSSProps_offset_block_end: *mut nsICSSProperty; - #[link_name = "\x01?offset_block_start@nsCSSProps@@2PAVnsICSSProperty@@A"] - pub static nsCSSProps_offset_block_start: *mut nsICSSProperty; - #[link_name = "\x01?offset_inline_end@nsCSSProps@@2PAVnsICSSProperty@@A"] - pub static nsCSSProps_offset_inline_end: *mut nsICSSProperty; - #[link_name = "\x01?offset_inline_start@nsCSSProps@@2PAVnsICSSProperty@@A"] - pub static nsCSSProps_offset_inline_start: *mut nsICSSProperty; - #[link_name = "\x01?opacity@nsCSSProps@@2PAVnsICSSProperty@@A"] - pub static nsCSSProps_opacity: *mut nsICSSProperty; - #[link_name = "\x01?order@nsCSSProps@@2PAVnsICSSProperty@@A"] - pub static nsCSSProps_order: *mut nsICSSProperty; - #[link_name = "\x01?orient@nsCSSProps@@2PAVnsICSSProperty@@A"] - pub static nsCSSProps_orient: *mut nsICSSProperty; - #[link_name = "\x01?osx_font_smoothing@nsCSSProps@@2PAVnsICSSProperty@@A"] - pub static nsCSSProps_osx_font_smoothing: *mut nsICSSProperty; - #[link_name = "\x01?outline@nsCSSProps@@2PAVnsICSSProperty@@A"] - pub static nsCSSProps_outline: *mut nsICSSProperty; - #[link_name = "\x01?outline_color@nsCSSProps@@2PAVnsICSSProperty@@A"] - pub static nsCSSProps_outline_color: *mut nsICSSProperty; - #[link_name = "\x01?outline_offset@nsCSSProps@@2PAVnsICSSProperty@@A"] - pub static nsCSSProps_outline_offset: *mut nsICSSProperty; - #[link_name = "\x01?_moz_outline_radius@nsCSSProps@@2PAVnsICSSProperty@@A"] - pub static nsCSSProps__moz_outline_radius: *mut nsICSSProperty; - #[link_name = "\x01?_moz_outline_radius_bottomLeft@nsCSSProps@@2PAVnsICSSProperty@@A"] - pub static nsCSSProps__moz_outline_radius_bottomLeft: *mut nsICSSProperty; - #[link_name = "\x01?_moz_outline_radius_bottomRight@nsCSSProps@@2PAVnsICSSProperty@@A"] - pub static nsCSSProps__moz_outline_radius_bottomRight: *mut nsICSSProperty; - #[link_name = "\x01?_moz_outline_radius_topLeft@nsCSSProps@@2PAVnsICSSProperty@@A"] - pub static nsCSSProps__moz_outline_radius_topLeft: *mut nsICSSProperty; - #[link_name = "\x01?_moz_outline_radius_topRight@nsCSSProps@@2PAVnsICSSProperty@@A"] - pub static nsCSSProps__moz_outline_radius_topRight: *mut nsICSSProperty; - #[link_name = "\x01?outline_style@nsCSSProps@@2PAVnsICSSProperty@@A"] - pub static nsCSSProps_outline_style: *mut nsICSSProperty; - #[link_name = "\x01?outline_width@nsCSSProps@@2PAVnsICSSProperty@@A"] - pub static nsCSSProps_outline_width: *mut nsICSSProperty; - #[link_name = "\x01?overflow@nsCSSProps@@2PAVnsICSSProperty@@A"] - pub static nsCSSProps_overflow: *mut nsICSSProperty; - #[link_name = "\x01?overflow_clip_box@nsCSSProps@@2PAVnsICSSProperty@@A"] - pub static nsCSSProps_overflow_clip_box: *mut nsICSSProperty; - #[link_name = "\x01?overflow_x@nsCSSProps@@2PAVnsICSSProperty@@A"] - pub static nsCSSProps_overflow_x: *mut nsICSSProperty; - #[link_name = "\x01?overflow_y@nsCSSProps@@2PAVnsICSSProperty@@A"] - pub static nsCSSProps_overflow_y: *mut nsICSSProperty; - #[link_name = "\x01?padding@nsCSSProps@@2PAVnsICSSProperty@@A"] - pub static nsCSSProps_padding: *mut nsICSSProperty; - #[link_name = "\x01?padding_block_end@nsCSSProps@@2PAVnsICSSProperty@@A"] - pub static nsCSSProps_padding_block_end: *mut nsICSSProperty; - #[link_name = "\x01?padding_block_start@nsCSSProps@@2PAVnsICSSProperty@@A"] - pub static nsCSSProps_padding_block_start: *mut nsICSSProperty; - #[link_name = "\x01?padding_bottom@nsCSSProps@@2PAVnsICSSProperty@@A"] - pub static nsCSSProps_padding_bottom: *mut nsICSSProperty; - #[link_name = "\x01?padding_inline_end@nsCSSProps@@2PAVnsICSSProperty@@A"] - pub static nsCSSProps_padding_inline_end: *mut nsICSSProperty; - #[link_name = "\x01?padding_inline_start@nsCSSProps@@2PAVnsICSSProperty@@A"] - pub static nsCSSProps_padding_inline_start: *mut nsICSSProperty; - #[link_name = "\x01?padding_left@nsCSSProps@@2PAVnsICSSProperty@@A"] - pub static nsCSSProps_padding_left: *mut nsICSSProperty; - #[link_name = "\x01?padding_right@nsCSSProps@@2PAVnsICSSProperty@@A"] - pub static nsCSSProps_padding_right: *mut nsICSSProperty; - #[link_name = "\x01?padding_top@nsCSSProps@@2PAVnsICSSProperty@@A"] - pub static nsCSSProps_padding_top: *mut nsICSSProperty; - #[link_name = "\x01?page_break_after@nsCSSProps@@2PAVnsICSSProperty@@A"] - pub static nsCSSProps_page_break_after: *mut nsICSSProperty; - #[link_name = "\x01?page_break_before@nsCSSProps@@2PAVnsICSSProperty@@A"] - pub static nsCSSProps_page_break_before: *mut nsICSSProperty; - #[link_name = "\x01?page_break_inside@nsCSSProps@@2PAVnsICSSProperty@@A"] - pub static nsCSSProps_page_break_inside: *mut nsICSSProperty; - #[link_name = "\x01?paint_order@nsCSSProps@@2PAVnsICSSProperty@@A"] - pub static nsCSSProps_paint_order: *mut nsICSSProperty; - #[link_name = "\x01?perspective@nsCSSProps@@2PAVnsICSSProperty@@A"] - pub static nsCSSProps_perspective: *mut nsICSSProperty; - #[link_name = "\x01?perspective_origin@nsCSSProps@@2PAVnsICSSProperty@@A"] - pub static nsCSSProps_perspective_origin: *mut nsICSSProperty; - #[link_name = "\x01?place_content@nsCSSProps@@2PAVnsICSSProperty@@A"] - pub static nsCSSProps_place_content: *mut nsICSSProperty; - #[link_name = "\x01?place_items@nsCSSProps@@2PAVnsICSSProperty@@A"] - pub static nsCSSProps_place_items: *mut nsICSSProperty; - #[link_name = "\x01?place_self@nsCSSProps@@2PAVnsICSSProperty@@A"] - pub static nsCSSProps_place_self: *mut nsICSSProperty; - #[link_name = "\x01?pointer_events@nsCSSProps@@2PAVnsICSSProperty@@A"] - pub static nsCSSProps_pointer_events: *mut nsICSSProperty; - #[link_name = "\x01?position@nsCSSProps@@2PAVnsICSSProperty@@A"] - pub static nsCSSProps_position: *mut nsICSSProperty; - #[link_name = "\x01?quotes@nsCSSProps@@2PAVnsICSSProperty@@A"] - pub static nsCSSProps_quotes: *mut nsICSSProperty; - #[link_name = "\x01?resize@nsCSSProps@@2PAVnsICSSProperty@@A"] - pub static nsCSSProps_resize: *mut nsICSSProperty; - #[link_name = "\x01?right@nsCSSProps@@2PAVnsICSSProperty@@A"] - pub static nsCSSProps_right: *mut nsICSSProperty; - #[link_name = "\x01?ruby_align@nsCSSProps@@2PAVnsICSSProperty@@A"] - pub static nsCSSProps_ruby_align: *mut nsICSSProperty; - #[link_name = "\x01?ruby_position@nsCSSProps@@2PAVnsICSSProperty@@A"] - pub static nsCSSProps_ruby_position: *mut nsICSSProperty; - #[link_name = "\x01?script_level@nsCSSProps@@2PAVnsICSSProperty@@A"] - pub static nsCSSProps_script_level: *mut nsICSSProperty; - #[link_name = "\x01?script_min_size@nsCSSProps@@2PAVnsICSSProperty@@A"] - pub static nsCSSProps_script_min_size: *mut nsICSSProperty; - #[link_name = "\x01?script_size_multiplier@nsCSSProps@@2PAVnsICSSProperty@@A"] - pub static nsCSSProps_script_size_multiplier: *mut nsICSSProperty; - #[link_name = "\x01?scroll_behavior@nsCSSProps@@2PAVnsICSSProperty@@A"] - pub static nsCSSProps_scroll_behavior: *mut nsICSSProperty; - #[link_name = "\x01?scroll_snap_coordinate@nsCSSProps@@2PAVnsICSSProperty@@A"] - pub static nsCSSProps_scroll_snap_coordinate: *mut nsICSSProperty; - #[link_name = "\x01?scroll_snap_destination@nsCSSProps@@2PAVnsICSSProperty@@A"] - pub static nsCSSProps_scroll_snap_destination: *mut nsICSSProperty; - #[link_name = "\x01?scroll_snap_points_x@nsCSSProps@@2PAVnsICSSProperty@@A"] - pub static nsCSSProps_scroll_snap_points_x: *mut nsICSSProperty; - #[link_name = "\x01?scroll_snap_points_y@nsCSSProps@@2PAVnsICSSProperty@@A"] - pub static nsCSSProps_scroll_snap_points_y: *mut nsICSSProperty; - #[link_name = "\x01?scroll_snap_type@nsCSSProps@@2PAVnsICSSProperty@@A"] - pub static nsCSSProps_scroll_snap_type: *mut nsICSSProperty; - #[link_name = "\x01?scroll_snap_type_x@nsCSSProps@@2PAVnsICSSProperty@@A"] - pub static nsCSSProps_scroll_snap_type_x: *mut nsICSSProperty; - #[link_name = "\x01?scroll_snap_type_y@nsCSSProps@@2PAVnsICSSProperty@@A"] - pub static nsCSSProps_scroll_snap_type_y: *mut nsICSSProperty; - #[link_name = "\x01?shape_outside@nsCSSProps@@2PAVnsICSSProperty@@A"] - pub static nsCSSProps_shape_outside: *mut nsICSSProperty; - #[link_name = "\x01?shape_rendering@nsCSSProps@@2PAVnsICSSProperty@@A"] - pub static nsCSSProps_shape_rendering: *mut nsICSSProperty; - #[link_name = "\x01?_x_span@nsCSSProps@@2PAVnsICSSProperty@@A"] - pub static nsCSSProps__x_span: *mut nsICSSProperty; - #[link_name = "\x01?stack_sizing@nsCSSProps@@2PAVnsICSSProperty@@A"] - pub static nsCSSProps_stack_sizing: *mut nsICSSProperty; - #[link_name = "\x01?stop_color@nsCSSProps@@2PAVnsICSSProperty@@A"] - pub static nsCSSProps_stop_color: *mut nsICSSProperty; - #[link_name = "\x01?stop_opacity@nsCSSProps@@2PAVnsICSSProperty@@A"] - pub static nsCSSProps_stop_opacity: *mut nsICSSProperty; - #[link_name = "\x01?stroke@nsCSSProps@@2PAVnsICSSProperty@@A"] - pub static nsCSSProps_stroke: *mut nsICSSProperty; - #[link_name = "\x01?stroke_dasharray@nsCSSProps@@2PAVnsICSSProperty@@A"] - pub static nsCSSProps_stroke_dasharray: *mut nsICSSProperty; - #[link_name = "\x01?stroke_dashoffset@nsCSSProps@@2PAVnsICSSProperty@@A"] - pub static nsCSSProps_stroke_dashoffset: *mut nsICSSProperty; - #[link_name = "\x01?stroke_linecap@nsCSSProps@@2PAVnsICSSProperty@@A"] - pub static nsCSSProps_stroke_linecap: *mut nsICSSProperty; - #[link_name = "\x01?stroke_linejoin@nsCSSProps@@2PAVnsICSSProperty@@A"] - pub static nsCSSProps_stroke_linejoin: *mut nsICSSProperty; - #[link_name = "\x01?stroke_miterlimit@nsCSSProps@@2PAVnsICSSProperty@@A"] - pub static nsCSSProps_stroke_miterlimit: *mut nsICSSProperty; - #[link_name = "\x01?stroke_opacity@nsCSSProps@@2PAVnsICSSProperty@@A"] - pub static nsCSSProps_stroke_opacity: *mut nsICSSProperty; - #[link_name = "\x01?stroke_width@nsCSSProps@@2PAVnsICSSProperty@@A"] - pub static nsCSSProps_stroke_width: *mut nsICSSProperty; - #[link_name = "\x01?_x_system_font@nsCSSProps@@2PAVnsICSSProperty@@A"] - pub static nsCSSProps__x_system_font: *mut nsICSSProperty; - #[link_name = "\x01?_moz_tab_size@nsCSSProps@@2PAVnsICSSProperty@@A"] - pub static nsCSSProps__moz_tab_size: *mut nsICSSProperty; - #[link_name = "\x01?table_layout@nsCSSProps@@2PAVnsICSSProperty@@A"] - pub static nsCSSProps_table_layout: *mut nsICSSProperty; - #[link_name = "\x01?text_align@nsCSSProps@@2PAVnsICSSProperty@@A"] - pub static nsCSSProps_text_align: *mut nsICSSProperty; - #[link_name = "\x01?text_align_last@nsCSSProps@@2PAVnsICSSProperty@@A"] - pub static nsCSSProps_text_align_last: *mut nsICSSProperty; - #[link_name = "\x01?text_anchor@nsCSSProps@@2PAVnsICSSProperty@@A"] - pub static nsCSSProps_text_anchor: *mut nsICSSProperty; - #[link_name = "\x01?text_combine_upright@nsCSSProps@@2PAVnsICSSProperty@@A"] - pub static nsCSSProps_text_combine_upright: *mut nsICSSProperty; - #[link_name = "\x01?text_decoration@nsCSSProps@@2PAVnsICSSProperty@@A"] - pub static nsCSSProps_text_decoration: *mut nsICSSProperty; - #[link_name = "\x01?text_decoration_color@nsCSSProps@@2PAVnsICSSProperty@@A"] - pub static nsCSSProps_text_decoration_color: *mut nsICSSProperty; - #[link_name = "\x01?text_decoration_line@nsCSSProps@@2PAVnsICSSProperty@@A"] - pub static nsCSSProps_text_decoration_line: *mut nsICSSProperty; - #[link_name = "\x01?text_decoration_style@nsCSSProps@@2PAVnsICSSProperty@@A"] - pub static nsCSSProps_text_decoration_style: *mut nsICSSProperty; - #[link_name = "\x01?text_emphasis@nsCSSProps@@2PAVnsICSSProperty@@A"] - pub static nsCSSProps_text_emphasis: *mut nsICSSProperty; - #[link_name = "\x01?text_emphasis_color@nsCSSProps@@2PAVnsICSSProperty@@A"] - pub static nsCSSProps_text_emphasis_color: *mut nsICSSProperty; - #[link_name = "\x01?text_emphasis_position@nsCSSProps@@2PAVnsICSSProperty@@A"] - pub static nsCSSProps_text_emphasis_position: *mut nsICSSProperty; - #[link_name = "\x01?text_emphasis_style@nsCSSProps@@2PAVnsICSSProperty@@A"] - pub static nsCSSProps_text_emphasis_style: *mut nsICSSProperty; - #[link_name = "\x01?_webkit_text_fill_color@nsCSSProps@@2PAVnsICSSProperty@@A"] - pub static nsCSSProps__webkit_text_fill_color: *mut nsICSSProperty; - #[link_name = "\x01?text_indent@nsCSSProps@@2PAVnsICSSProperty@@A"] - pub static nsCSSProps_text_indent: *mut nsICSSProperty; - #[link_name = "\x01?text_orientation@nsCSSProps@@2PAVnsICSSProperty@@A"] - pub static nsCSSProps_text_orientation: *mut nsICSSProperty; - #[link_name = "\x01?text_overflow@nsCSSProps@@2PAVnsICSSProperty@@A"] - pub static nsCSSProps_text_overflow: *mut nsICSSProperty; - #[link_name = "\x01?text_rendering@nsCSSProps@@2PAVnsICSSProperty@@A"] - pub static nsCSSProps_text_rendering: *mut nsICSSProperty; - #[link_name = "\x01?text_shadow@nsCSSProps@@2PAVnsICSSProperty@@A"] - pub static nsCSSProps_text_shadow: *mut nsICSSProperty; - #[link_name = "\x01?text_size_adjust@nsCSSProps@@2PAVnsICSSProperty@@A"] - pub static nsCSSProps_text_size_adjust: *mut nsICSSProperty; - #[link_name = "\x01?_webkit_text_stroke@nsCSSProps@@2PAVnsICSSProperty@@A"] - pub static nsCSSProps__webkit_text_stroke: *mut nsICSSProperty; - #[link_name = "\x01?_webkit_text_stroke_color@nsCSSProps@@2PAVnsICSSProperty@@A"] - pub static nsCSSProps__webkit_text_stroke_color: *mut nsICSSProperty; - #[link_name = "\x01?_webkit_text_stroke_width@nsCSSProps@@2PAVnsICSSProperty@@A"] - pub static nsCSSProps__webkit_text_stroke_width: *mut nsICSSProperty; - #[link_name = "\x01?text_transform@nsCSSProps@@2PAVnsICSSProperty@@A"] - pub static nsCSSProps_text_transform: *mut nsICSSProperty; - #[link_name = "\x01?_x_text_zoom@nsCSSProps@@2PAVnsICSSProperty@@A"] - pub static nsCSSProps__x_text_zoom: *mut nsICSSProperty; - #[link_name = "\x01?top@nsCSSProps@@2PAVnsICSSProperty@@A"] - pub static nsCSSProps_top: *mut nsICSSProperty; - #[link_name = "\x01?_moz_top_layer@nsCSSProps@@2PAVnsICSSProperty@@A"] - pub static nsCSSProps__moz_top_layer: *mut nsICSSProperty; - #[link_name = "\x01?touch_action@nsCSSProps@@2PAVnsICSSProperty@@A"] - pub static nsCSSProps_touch_action: *mut nsICSSProperty; - #[link_name = "\x01?transform@nsCSSProps@@2PAVnsICSSProperty@@A"] - pub static nsCSSProps_transform: *mut nsICSSProperty; - #[link_name = "\x01?_moz_transform@nsCSSProps@@2PAVnsICSSProperty@@A"] - pub static nsCSSProps__moz_transform: *mut nsICSSProperty; - #[link_name = "\x01?transform_box@nsCSSProps@@2PAVnsICSSProperty@@A"] - pub static nsCSSProps_transform_box: *mut nsICSSProperty; - #[link_name = "\x01?transform_origin@nsCSSProps@@2PAVnsICSSProperty@@A"] - pub static nsCSSProps_transform_origin: *mut nsICSSProperty; - #[link_name = "\x01?transform_style@nsCSSProps@@2PAVnsICSSProperty@@A"] - pub static nsCSSProps_transform_style: *mut nsICSSProperty; - #[link_name = "\x01?transition@nsCSSProps@@2PAVnsICSSProperty@@A"] - pub static nsCSSProps_transition: *mut nsICSSProperty; - #[link_name = "\x01?transition_delay@nsCSSProps@@2PAVnsICSSProperty@@A"] - pub static nsCSSProps_transition_delay: *mut nsICSSProperty; - #[link_name = "\x01?transition_duration@nsCSSProps@@2PAVnsICSSProperty@@A"] - pub static nsCSSProps_transition_duration: *mut nsICSSProperty; - #[link_name = "\x01?transition_property@nsCSSProps@@2PAVnsICSSProperty@@A"] - pub static nsCSSProps_transition_property: *mut nsICSSProperty; - #[link_name = "\x01?transition_timing_function@nsCSSProps@@2PAVnsICSSProperty@@A"] - pub static nsCSSProps_transition_timing_function: *mut nsICSSProperty; - #[link_name = "\x01?unicode_bidi@nsCSSProps@@2PAVnsICSSProperty@@A"] - pub static nsCSSProps_unicode_bidi: *mut nsICSSProperty; - #[link_name = "\x01?user_focus@nsCSSProps@@2PAVnsICSSProperty@@A"] - pub static nsCSSProps_user_focus: *mut nsICSSProperty; - #[link_name = "\x01?user_input@nsCSSProps@@2PAVnsICSSProperty@@A"] - pub static nsCSSProps_user_input: *mut nsICSSProperty; - #[link_name = "\x01?user_modify@nsCSSProps@@2PAVnsICSSProperty@@A"] - pub static nsCSSProps_user_modify: *mut nsICSSProperty; - #[link_name = "\x01?user_select@nsCSSProps@@2PAVnsICSSProperty@@A"] - pub static nsCSSProps_user_select: *mut nsICSSProperty; - #[link_name = "\x01?vector_effect@nsCSSProps@@2PAVnsICSSProperty@@A"] - pub static nsCSSProps_vector_effect: *mut nsICSSProperty; - #[link_name = "\x01?vertical_align@nsCSSProps@@2PAVnsICSSProperty@@A"] - pub static nsCSSProps_vertical_align: *mut nsICSSProperty; - #[link_name = "\x01?visibility@nsCSSProps@@2PAVnsICSSProperty@@A"] - pub static nsCSSProps_visibility: *mut nsICSSProperty; - #[link_name = "\x01?white_space@nsCSSProps@@2PAVnsICSSProperty@@A"] - pub static nsCSSProps_white_space: *mut nsICSSProperty; - #[link_name = "\x01?width@nsCSSProps@@2PAVnsICSSProperty@@A"] - pub static nsCSSProps_width: *mut nsICSSProperty; - #[link_name = "\x01?will_change@nsCSSProps@@2PAVnsICSSProperty@@A"] - pub static nsCSSProps_will_change: *mut nsICSSProperty; - #[link_name = "\x01?_moz_window_dragging@nsCSSProps@@2PAVnsICSSProperty@@A"] - pub static nsCSSProps__moz_window_dragging: *mut nsICSSProperty; - #[link_name = "\x01?_moz_window_shadow@nsCSSProps@@2PAVnsICSSProperty@@A"] - pub static nsCSSProps__moz_window_shadow: *mut nsICSSProperty; - #[link_name = "\x01?word_break@nsCSSProps@@2PAVnsICSSProperty@@A"] - pub static nsCSSProps_word_break: *mut nsICSSProperty; - #[link_name = "\x01?word_spacing@nsCSSProps@@2PAVnsICSSProperty@@A"] - pub static nsCSSProps_word_spacing: *mut nsICSSProperty; - #[link_name = "\x01?overflow_wrap@nsCSSProps@@2PAVnsICSSProperty@@A"] - pub static nsCSSProps_overflow_wrap: *mut nsICSSProperty; - #[link_name = "\x01?writing_mode@nsCSSProps@@2PAVnsICSSProperty@@A"] - pub static nsCSSProps_writing_mode: *mut nsICSSProperty; - #[link_name = "\x01?z_index@nsCSSProps@@2PAVnsICSSProperty@@A"] - pub static nsCSSProps_z_index: *mut nsICSSProperty; } } } @@ -18304,6 +16106,8 @@ macro_rules! atom { { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsGkAtoms_onattributewritereq as *mut _) } }; ("onaudioprocess") => { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsGkAtoms_onaudioprocess as *mut _) } }; +("onauxclick") => + { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsGkAtoms_onauxclick as *mut _) } }; ("onbeforecopy") => { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsGkAtoms_onbeforecopy as *mut _) } }; ("onbeforecut") => @@ -18576,14 +16380,6 @@ macro_rules! atom { { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsGkAtoms_onmouseup as *mut _) } }; ("onMozAfterPaint") => { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsGkAtoms_onMozAfterPaint as *mut _) } }; -("onmozbrowserafterkeydown") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsGkAtoms_onmozbrowserafterkeydown as *mut _) } }; -("onmozbrowserafterkeyup") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsGkAtoms_onmozbrowserafterkeyup as *mut _) } }; -("onmozbrowserbeforekeydown") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsGkAtoms_onmozbrowserbeforekeydown as *mut _) } }; -("onmozbrowserbeforekeyup") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsGkAtoms_onmozbrowserbeforekeyup as *mut _) } }; ("onmozfullscreenchange") => { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsGkAtoms_onmozfullscreenchange as *mut _) } }; ("onmozfullscreenerror") => @@ -18778,6 +16574,8 @@ macro_rules! atom { { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsGkAtoms_ontouchmove as *mut _) } }; ("ontouchcancel") => { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsGkAtoms_ontouchcancel as *mut _) } }; +("ontransitioncancel") => + { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsGkAtoms_ontransitioncancel as *mut _) } }; ("ontransitionend") => { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsGkAtoms_ontransitionend as *mut _) } }; ("ontransitionrun") => @@ -19240,8 +17038,6 @@ macro_rules! atom { { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsGkAtoms_spinner as *mut _) } }; ("split") => { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsGkAtoms_split as *mut _) } }; -("splitmenu") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsGkAtoms_splitmenu as *mut _) } }; ("splitter") => { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsGkAtoms_splitter as *mut _) } }; ("spring") => @@ -20946,6 +18742,8 @@ macro_rules! atom { { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsGkAtoms_svgForeignObjectFrame as *mut _) } }; ("SVGGenericContainerFrame") => { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsGkAtoms_svgGenericContainerFrame as *mut _) } }; +("SVGGeometryFrame") => + { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsGkAtoms_svgGeometryFrame as *mut _) } }; ("SVGGFrame") => { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsGkAtoms_svgGFrame as *mut _) } }; ("SVGGradientFrame") => @@ -20966,8 +18764,6 @@ macro_rules! atom { { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsGkAtoms_svgOuterSVGFrame as *mut _) } }; ("SVGOuterSVGAnonChildFrame") => { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsGkAtoms_svgOuterSVGAnonChildFrame as *mut _) } }; -("SVGPathGeometryFrame") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsGkAtoms_svgPathGeometryFrame as *mut _) } }; ("SVGPatternFrame") => { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsGkAtoms_svgPatternFrame as *mut _) } }; ("SVGRadialGradientFrame") => @@ -21876,730 +19672,4 @@ macro_rules! atom { { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSAnonBoxes_mozSVGForeignContent as *mut _) } }; (":-moz-svg-text") => { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSAnonBoxes_mozSVGText as *mut _) } }; -("align-content") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSProps_align_content as *mut _) } }; -("align-items") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSProps_align_items as *mut _) } }; -("align-self") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSProps_align_self as *mut _) } }; -("all") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSProps_all as *mut _) } }; -("animation") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSProps_animation as *mut _) } }; -("animation-delay") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSProps_animation_delay as *mut _) } }; -("animation-direction") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSProps_animation_direction as *mut _) } }; -("animation-duration") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSProps_animation_duration as *mut _) } }; -("animation-fill-mode") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSProps_animation_fill_mode as *mut _) } }; -("animation-iteration-count") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSProps_animation_iteration_count as *mut _) } }; -("animation-name") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSProps_animation_name as *mut _) } }; -("animation-play-state") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSProps_animation_play_state as *mut _) } }; -("animation-timing-function") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSProps_animation_timing_function as *mut _) } }; -("-moz-appearance") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSProps_appearance as *mut _) } }; -("backface-visibility") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSProps_backface_visibility as *mut _) } }; -("background") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSProps_background as *mut _) } }; -("background-attachment") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSProps_background_attachment as *mut _) } }; -("background-blend-mode") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSProps_background_blend_mode as *mut _) } }; -("background-clip") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSProps_background_clip as *mut _) } }; -("background-color") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSProps_background_color as *mut _) } }; -("background-image") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSProps_background_image as *mut _) } }; -("background-origin") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSProps_background_origin as *mut _) } }; -("background-position") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSProps_background_position as *mut _) } }; -("background-position-x") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSProps_background_position_x as *mut _) } }; -("background-position-y") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSProps_background_position_y as *mut _) } }; -("background-repeat") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSProps_background_repeat as *mut _) } }; -("background-size") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSProps_background_size as *mut _) } }; -("-moz-binding") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSProps_binding as *mut _) } }; -("block-size") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSProps_block_size as *mut _) } }; -("border") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSProps_border as *mut _) } }; -("border-block-end") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSProps_border_block_end as *mut _) } }; -("border-block-end-color") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSProps_border_block_end_color as *mut _) } }; -("border-block-end-style") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSProps_border_block_end_style as *mut _) } }; -("border-block-end-width") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSProps_border_block_end_width as *mut _) } }; -("border-block-start") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSProps_border_block_start as *mut _) } }; -("border-block-start-color") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSProps_border_block_start_color as *mut _) } }; -("border-block-start-style") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSProps_border_block_start_style as *mut _) } }; -("border-block-start-width") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSProps_border_block_start_width as *mut _) } }; -("border-bottom") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSProps_border_bottom as *mut _) } }; -("border-bottom-color") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSProps_border_bottom_color as *mut _) } }; -("-moz-border-bottom-colors") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSProps_border_bottom_colors as *mut _) } }; -("border-bottom-left-radius") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSProps_border_bottom_left_radius as *mut _) } }; -("border-bottom-right-radius") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSProps_border_bottom_right_radius as *mut _) } }; -("border-bottom-style") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSProps_border_bottom_style as *mut _) } }; -("border-bottom-width") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSProps_border_bottom_width as *mut _) } }; -("border-collapse") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSProps_border_collapse as *mut _) } }; -("border-color") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSProps_border_color as *mut _) } }; -("border-image") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSProps_border_image as *mut _) } }; -("border-image-outset") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSProps_border_image_outset as *mut _) } }; -("border-image-repeat") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSProps_border_image_repeat as *mut _) } }; -("border-image-slice") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSProps_border_image_slice as *mut _) } }; -("border-image-source") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSProps_border_image_source as *mut _) } }; -("border-image-width") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSProps_border_image_width as *mut _) } }; -("border-inline-end") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSProps_border_inline_end as *mut _) } }; -("border-inline-end-color") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSProps_border_inline_end_color as *mut _) } }; -("border-inline-end-style") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSProps_border_inline_end_style as *mut _) } }; -("border-inline-end-width") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSProps_border_inline_end_width as *mut _) } }; -("border-inline-start") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSProps_border_inline_start as *mut _) } }; -("border-inline-start-color") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSProps_border_inline_start_color as *mut _) } }; -("border-inline-start-style") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSProps_border_inline_start_style as *mut _) } }; -("border-inline-start-width") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSProps_border_inline_start_width as *mut _) } }; -("border-left") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSProps_border_left as *mut _) } }; -("border-left-color") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSProps_border_left_color as *mut _) } }; -("-moz-border-left-colors") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSProps_border_left_colors as *mut _) } }; -("border-left-style") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSProps_border_left_style as *mut _) } }; -("border-left-width") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSProps_border_left_width as *mut _) } }; -("border-radius") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSProps_border_radius as *mut _) } }; -("border-right") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSProps_border_right as *mut _) } }; -("border-right-color") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSProps_border_right_color as *mut _) } }; -("-moz-border-right-colors") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSProps_border_right_colors as *mut _) } }; -("border-right-style") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSProps_border_right_style as *mut _) } }; -("border-right-width") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSProps_border_right_width as *mut _) } }; -("border-spacing") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSProps_border_spacing as *mut _) } }; -("border-style") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSProps_border_style as *mut _) } }; -("border-top") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSProps_border_top as *mut _) } }; -("border-top-color") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSProps_border_top_color as *mut _) } }; -("-moz-border-top-colors") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSProps_border_top_colors as *mut _) } }; -("border-top-left-radius") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSProps_border_top_left_radius as *mut _) } }; -("border-top-right-radius") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSProps_border_top_right_radius as *mut _) } }; -("border-top-style") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSProps_border_top_style as *mut _) } }; -("border-top-width") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSProps_border_top_width as *mut _) } }; -("border-width") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSProps_border_width as *mut _) } }; -("bottom") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSProps_bottom as *mut _) } }; -("-moz-box-align") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSProps_box_align as *mut _) } }; -("box-decoration-break") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSProps_box_decoration_break as *mut _) } }; -("-moz-box-direction") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSProps_box_direction as *mut _) } }; -("-moz-box-flex") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSProps_box_flex as *mut _) } }; -("-moz-box-ordinal-group") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSProps_box_ordinal_group as *mut _) } }; -("-moz-box-orient") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSProps_box_orient as *mut _) } }; -("-moz-box-pack") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSProps_box_pack as *mut _) } }; -("box-shadow") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSProps_box_shadow as *mut _) } }; -("box-sizing") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSProps_box_sizing as *mut _) } }; -("caption-side") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSProps_caption_side as *mut _) } }; -("clear") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSProps_clear as *mut _) } }; -("clip") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSProps_clip as *mut _) } }; -("clip-path") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSProps_clip_path as *mut _) } }; -("clip-rule") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSProps_clip_rule as *mut _) } }; -("color") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSProps_color as *mut _) } }; -("color-adjust") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSProps_color_adjust as *mut _) } }; -("color-interpolation") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSProps_color_interpolation as *mut _) } }; -("color-interpolation-filters") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSProps_color_interpolation_filters as *mut _) } }; -("column-count") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSProps_column_count as *mut _) } }; -("column-fill") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSProps_column_fill as *mut _) } }; -("column-gap") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSProps_column_gap as *mut _) } }; -("column-rule") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSProps_column_rule as *mut _) } }; -("column-rule-color") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSProps_column_rule_color as *mut _) } }; -("column-rule-style") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSProps_column_rule_style as *mut _) } }; -("column-rule-width") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSProps_column_rule_width as *mut _) } }; -("column-width") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSProps_column_width as *mut _) } }; -("columns") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSProps_columns as *mut _) } }; -("contain") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSProps_contain as *mut _) } }; -("content") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSProps_content as *mut _) } }; -("-moz-control-character-visibility") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSProps__moz_control_character_visibility as *mut _) } }; -("counter-increment") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSProps_counter_increment as *mut _) } }; -("counter-reset") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSProps_counter_reset as *mut _) } }; -("cursor") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSProps_cursor as *mut _) } }; -("direction") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSProps_direction as *mut _) } }; -("display") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSProps_display as *mut _) } }; -("dominant-baseline") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSProps_dominant_baseline as *mut _) } }; -("empty-cells") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSProps_empty_cells as *mut _) } }; -("fill") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSProps_fill as *mut _) } }; -("fill-opacity") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSProps_fill_opacity as *mut _) } }; -("fill-rule") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSProps_fill_rule as *mut _) } }; -("filter") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSProps_filter as *mut _) } }; -("flex") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSProps_flex as *mut _) } }; -("flex-basis") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSProps_flex_basis as *mut _) } }; -("flex-direction") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSProps_flex_direction as *mut _) } }; -("flex-flow") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSProps_flex_flow as *mut _) } }; -("flex-grow") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSProps_flex_grow as *mut _) } }; -("flex-shrink") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSProps_flex_shrink as *mut _) } }; -("flex-wrap") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSProps_flex_wrap as *mut _) } }; -("float") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSProps_float_ as *mut _) } }; -("-moz-float-edge") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSProps_float_edge as *mut _) } }; -("flood-color") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSProps_flood_color as *mut _) } }; -("flood-opacity") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSProps_flood_opacity as *mut _) } }; -("font") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSProps_font as *mut _) } }; -("font-family") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSProps_font_family as *mut _) } }; -("font-feature-settings") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSProps_font_feature_settings as *mut _) } }; -("font-kerning") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSProps_font_kerning as *mut _) } }; -("font-language-override") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSProps_font_language_override as *mut _) } }; -("font-size") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSProps_font_size as *mut _) } }; -("font-size-adjust") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSProps_font_size_adjust as *mut _) } }; -("font-stretch") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSProps_font_stretch as *mut _) } }; -("font-style") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSProps_font_style as *mut _) } }; -("font-synthesis") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSProps_font_synthesis as *mut _) } }; -("font-variant") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSProps_font_variant as *mut _) } }; -("font-variant-alternates") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSProps_font_variant_alternates as *mut _) } }; -("font-variant-caps") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSProps_font_variant_caps as *mut _) } }; -("font-variant-east-asian") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSProps_font_variant_east_asian as *mut _) } }; -("font-variant-ligatures") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSProps_font_variant_ligatures as *mut _) } }; -("font-variant-numeric") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSProps_font_variant_numeric as *mut _) } }; -("font-variant-position") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSProps_font_variant_position as *mut _) } }; -("font-variation-settings") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSProps_font_variation_settings as *mut _) } }; -("font-weight") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSProps_font_weight as *mut _) } }; -("-moz-force-broken-image-icon") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSProps_force_broken_image_icon as *mut _) } }; -("grid") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSProps_grid as *mut _) } }; -("grid-area") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSProps_grid_area as *mut _) } }; -("grid-auto-columns") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSProps_grid_auto_columns as *mut _) } }; -("grid-auto-flow") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSProps_grid_auto_flow as *mut _) } }; -("grid-auto-rows") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSProps_grid_auto_rows as *mut _) } }; -("grid-column") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSProps_grid_column as *mut _) } }; -("grid-column-end") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSProps_grid_column_end as *mut _) } }; -("grid-column-gap") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSProps_grid_column_gap as *mut _) } }; -("grid-column-start") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSProps_grid_column_start as *mut _) } }; -("grid-gap") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSProps_grid_gap as *mut _) } }; -("grid-row") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSProps_grid_row as *mut _) } }; -("grid-row-end") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSProps_grid_row_end as *mut _) } }; -("grid-row-gap") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSProps_grid_row_gap as *mut _) } }; -("grid-row-start") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSProps_grid_row_start as *mut _) } }; -("grid-template") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSProps_grid_template as *mut _) } }; -("grid-template-areas") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSProps_grid_template_areas as *mut _) } }; -("grid-template-columns") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSProps_grid_template_columns as *mut _) } }; -("grid-template-rows") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSProps_grid_template_rows as *mut _) } }; -("height") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSProps_height as *mut _) } }; -("hyphens") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSProps_hyphens as *mut _) } }; -("initial-letter") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSProps_initial_letter as *mut _) } }; -("image-orientation") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSProps_image_orientation as *mut _) } }; -("-moz-image-region") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSProps_image_region as *mut _) } }; -("image-rendering") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSProps_image_rendering as *mut _) } }; -("ime-mode") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSProps_ime_mode as *mut _) } }; -("inline-size") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSProps_inline_size as *mut _) } }; -("isolation") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSProps_isolation as *mut _) } }; -("justify-content") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSProps_justify_content as *mut _) } }; -("justify-items") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSProps_justify_items as *mut _) } }; -("justify-self") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSProps_justify_self as *mut _) } }; -("-x-lang") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSProps__x_lang as *mut _) } }; -("left") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSProps_left as *mut _) } }; -("letter-spacing") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSProps_letter_spacing as *mut _) } }; -("lighting-color") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSProps_lighting_color as *mut _) } }; -("line-height") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSProps_line_height as *mut _) } }; -("list-style") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSProps_list_style as *mut _) } }; -("list-style-image") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSProps_list_style_image as *mut _) } }; -("list-style-position") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSProps_list_style_position as *mut _) } }; -("list-style-type") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSProps_list_style_type as *mut _) } }; -("margin") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSProps_margin as *mut _) } }; -("margin-block-end") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSProps_margin_block_end as *mut _) } }; -("margin-block-start") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSProps_margin_block_start as *mut _) } }; -("margin-bottom") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSProps_margin_bottom as *mut _) } }; -("margin-inline-end") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSProps_margin_inline_end as *mut _) } }; -("margin-inline-start") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSProps_margin_inline_start as *mut _) } }; -("margin-left") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSProps_margin_left as *mut _) } }; -("margin-right") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSProps_margin_right as *mut _) } }; -("margin-top") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSProps_margin_top as *mut _) } }; -("marker") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSProps_marker as *mut _) } }; -("marker-end") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSProps_marker_end as *mut _) } }; -("marker-mid") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSProps_marker_mid as *mut _) } }; -("marker-start") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSProps_marker_start as *mut _) } }; -("mask") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSProps_mask as *mut _) } }; -("mask-clip") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSProps_mask_clip as *mut _) } }; -("mask-composite") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSProps_mask_composite as *mut _) } }; -("mask-image") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSProps_mask_image as *mut _) } }; -("mask-mode") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSProps_mask_mode as *mut _) } }; -("mask-origin") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSProps_mask_origin as *mut _) } }; -("mask-position") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSProps_mask_position as *mut _) } }; -("mask-position-x") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSProps_mask_position_x as *mut _) } }; -("mask-position-y") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSProps_mask_position_y as *mut _) } }; -("mask-repeat") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSProps_mask_repeat as *mut _) } }; -("mask-size") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSProps_mask_size as *mut _) } }; -("mask-type") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSProps_mask_type as *mut _) } }; -("-moz-math-display") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSProps_math_display as *mut _) } }; -("-moz-math-variant") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSProps_math_variant as *mut _) } }; -("max-block-size") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSProps_max_block_size as *mut _) } }; -("max-height") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSProps_max_height as *mut _) } }; -("max-inline-size") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSProps_max_inline_size as *mut _) } }; -("max-width") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSProps_max_width as *mut _) } }; -("min-block-size") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSProps_min_block_size as *mut _) } }; -("-moz-min-font-size-ratio") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSProps__moz_min_font_size_ratio as *mut _) } }; -("min-height") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSProps_min_height as *mut _) } }; -("min-inline-size") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSProps_min_inline_size as *mut _) } }; -("min-width") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSProps_min_width as *mut _) } }; -("mix-blend-mode") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSProps_mix_blend_mode as *mut _) } }; -("object-fit") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSProps_object_fit as *mut _) } }; -("object-position") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSProps_object_position as *mut _) } }; -("offset-block-end") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSProps_offset_block_end as *mut _) } }; -("offset-block-start") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSProps_offset_block_start as *mut _) } }; -("offset-inline-end") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSProps_offset_inline_end as *mut _) } }; -("offset-inline-start") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSProps_offset_inline_start as *mut _) } }; -("opacity") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSProps_opacity as *mut _) } }; -("order") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSProps_order as *mut _) } }; -("-moz-orient") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSProps_orient as *mut _) } }; -("-moz-osx-font-smoothing") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSProps_osx_font_smoothing as *mut _) } }; -("outline") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSProps_outline as *mut _) } }; -("outline-color") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSProps_outline_color as *mut _) } }; -("outline-offset") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSProps_outline_offset as *mut _) } }; -("-moz-outline-radius") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSProps__moz_outline_radius as *mut _) } }; -("-moz-outline-radius-bottomleft") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSProps__moz_outline_radius_bottomLeft as *mut _) } }; -("-moz-outline-radius-bottomright") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSProps__moz_outline_radius_bottomRight as *mut _) } }; -("-moz-outline-radius-topleft") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSProps__moz_outline_radius_topLeft as *mut _) } }; -("-moz-outline-radius-topright") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSProps__moz_outline_radius_topRight as *mut _) } }; -("outline-style") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSProps_outline_style as *mut _) } }; -("outline-width") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSProps_outline_width as *mut _) } }; -("overflow") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSProps_overflow as *mut _) } }; -("overflow-clip-box") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSProps_overflow_clip_box as *mut _) } }; -("overflow-x") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSProps_overflow_x as *mut _) } }; -("overflow-y") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSProps_overflow_y as *mut _) } }; -("padding") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSProps_padding as *mut _) } }; -("padding-block-end") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSProps_padding_block_end as *mut _) } }; -("padding-block-start") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSProps_padding_block_start as *mut _) } }; -("padding-bottom") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSProps_padding_bottom as *mut _) } }; -("padding-inline-end") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSProps_padding_inline_end as *mut _) } }; -("padding-inline-start") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSProps_padding_inline_start as *mut _) } }; -("padding-left") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSProps_padding_left as *mut _) } }; -("padding-right") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSProps_padding_right as *mut _) } }; -("padding-top") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSProps_padding_top as *mut _) } }; -("page-break-after") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSProps_page_break_after as *mut _) } }; -("page-break-before") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSProps_page_break_before as *mut _) } }; -("page-break-inside") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSProps_page_break_inside as *mut _) } }; -("paint-order") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSProps_paint_order as *mut _) } }; -("perspective") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSProps_perspective as *mut _) } }; -("perspective-origin") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSProps_perspective_origin as *mut _) } }; -("place-content") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSProps_place_content as *mut _) } }; -("place-items") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSProps_place_items as *mut _) } }; -("place-self") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSProps_place_self as *mut _) } }; -("pointer-events") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSProps_pointer_events as *mut _) } }; -("position") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSProps_position as *mut _) } }; -("quotes") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSProps_quotes as *mut _) } }; -("resize") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSProps_resize as *mut _) } }; -("right") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSProps_right as *mut _) } }; -("ruby-align") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSProps_ruby_align as *mut _) } }; -("ruby-position") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSProps_ruby_position as *mut _) } }; -("-moz-script-level") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSProps_script_level as *mut _) } }; -("-moz-script-min-size") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSProps_script_min_size as *mut _) } }; -("-moz-script-size-multiplier") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSProps_script_size_multiplier as *mut _) } }; -("scroll-behavior") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSProps_scroll_behavior as *mut _) } }; -("scroll-snap-coordinate") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSProps_scroll_snap_coordinate as *mut _) } }; -("scroll-snap-destination") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSProps_scroll_snap_destination as *mut _) } }; -("scroll-snap-points-x") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSProps_scroll_snap_points_x as *mut _) } }; -("scroll-snap-points-y") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSProps_scroll_snap_points_y as *mut _) } }; -("scroll-snap-type") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSProps_scroll_snap_type as *mut _) } }; -("scroll-snap-type-x") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSProps_scroll_snap_type_x as *mut _) } }; -("scroll-snap-type-y") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSProps_scroll_snap_type_y as *mut _) } }; -("shape-outside") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSProps_shape_outside as *mut _) } }; -("shape-rendering") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSProps_shape_rendering as *mut _) } }; -("-x-span") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSProps__x_span as *mut _) } }; -("-moz-stack-sizing") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSProps_stack_sizing as *mut _) } }; -("stop-color") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSProps_stop_color as *mut _) } }; -("stop-opacity") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSProps_stop_opacity as *mut _) } }; -("stroke") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSProps_stroke as *mut _) } }; -("stroke-dasharray") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSProps_stroke_dasharray as *mut _) } }; -("stroke-dashoffset") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSProps_stroke_dashoffset as *mut _) } }; -("stroke-linecap") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSProps_stroke_linecap as *mut _) } }; -("stroke-linejoin") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSProps_stroke_linejoin as *mut _) } }; -("stroke-miterlimit") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSProps_stroke_miterlimit as *mut _) } }; -("stroke-opacity") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSProps_stroke_opacity as *mut _) } }; -("stroke-width") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSProps_stroke_width as *mut _) } }; -("-x-system-font") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSProps__x_system_font as *mut _) } }; -("-moz-tab-size") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSProps__moz_tab_size as *mut _) } }; -("table-layout") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSProps_table_layout as *mut _) } }; -("text-align") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSProps_text_align as *mut _) } }; -("text-align-last") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSProps_text_align_last as *mut _) } }; -("text-anchor") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSProps_text_anchor as *mut _) } }; -("text-combine-upright") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSProps_text_combine_upright as *mut _) } }; -("text-decoration") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSProps_text_decoration as *mut _) } }; -("text-decoration-color") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSProps_text_decoration_color as *mut _) } }; -("text-decoration-line") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSProps_text_decoration_line as *mut _) } }; -("text-decoration-style") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSProps_text_decoration_style as *mut _) } }; -("text-emphasis") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSProps_text_emphasis as *mut _) } }; -("text-emphasis-color") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSProps_text_emphasis_color as *mut _) } }; -("text-emphasis-position") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSProps_text_emphasis_position as *mut _) } }; -("text-emphasis-style") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSProps_text_emphasis_style as *mut _) } }; -("-webkit-text-fill-color") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSProps__webkit_text_fill_color as *mut _) } }; -("text-indent") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSProps_text_indent as *mut _) } }; -("text-orientation") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSProps_text_orientation as *mut _) } }; -("text-overflow") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSProps_text_overflow as *mut _) } }; -("text-rendering") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSProps_text_rendering as *mut _) } }; -("text-shadow") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSProps_text_shadow as *mut _) } }; -("-moz-text-size-adjust") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSProps_text_size_adjust as *mut _) } }; -("-webkit-text-stroke") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSProps__webkit_text_stroke as *mut _) } }; -("-webkit-text-stroke-color") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSProps__webkit_text_stroke_color as *mut _) } }; -("-webkit-text-stroke-width") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSProps__webkit_text_stroke_width as *mut _) } }; -("text-transform") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSProps_text_transform as *mut _) } }; -("-x-text-zoom") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSProps__x_text_zoom as *mut _) } }; -("top") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSProps_top as *mut _) } }; -("-moz-top-layer") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSProps__moz_top_layer as *mut _) } }; -("touch-action") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSProps_touch_action as *mut _) } }; -("transform") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSProps_transform as *mut _) } }; -("-moz-transform") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSProps__moz_transform as *mut _) } }; -("transform-box") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSProps_transform_box as *mut _) } }; -("transform-origin") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSProps_transform_origin as *mut _) } }; -("transform-style") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSProps_transform_style as *mut _) } }; -("transition") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSProps_transition as *mut _) } }; -("transition-delay") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSProps_transition_delay as *mut _) } }; -("transition-duration") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSProps_transition_duration as *mut _) } }; -("transition-property") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSProps_transition_property as *mut _) } }; -("transition-timing-function") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSProps_transition_timing_function as *mut _) } }; -("unicode-bidi") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSProps_unicode_bidi as *mut _) } }; -("-moz-user-focus") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSProps_user_focus as *mut _) } }; -("-moz-user-input") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSProps_user_input as *mut _) } }; -("-moz-user-modify") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSProps_user_modify as *mut _) } }; -("-moz-user-select") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSProps_user_select as *mut _) } }; -("vector-effect") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSProps_vector_effect as *mut _) } }; -("vertical-align") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSProps_vertical_align as *mut _) } }; -("visibility") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSProps_visibility as *mut _) } }; -("white-space") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSProps_white_space as *mut _) } }; -("width") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSProps_width as *mut _) } }; -("will-change") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSProps_will_change as *mut _) } }; -("-moz-window-dragging") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSProps__moz_window_dragging as *mut _) } }; -("-moz-window-shadow") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSProps__moz_window_shadow as *mut _) } }; -("word-break") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSProps_word_break as *mut _) } }; -("word-spacing") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSProps_word_spacing as *mut _) } }; -("overflow-wrap") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSProps_overflow_wrap as *mut _) } }; -("writing-mode") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSProps_writing_mode as *mut _) } }; -("z-index") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsCSSProps_z_index as *mut _) } }; } diff --git a/components/style/gecko_string_cache/mod.rs b/components/style/gecko_string_cache/mod.rs index a8798250699..5165b21f5d4 100644 --- a/components/style/gecko_string_cache/mod.rs +++ b/components/style/gecko_string_cache/mod.rs @@ -9,10 +9,9 @@ use gecko_bindings::bindings::Gecko_Atomize; use gecko_bindings::bindings::Gecko_ReleaseAtom; use gecko_bindings::structs::nsIAtom; use heapsize::HeapSizeOf; -use std::ascii::AsciiExt; use std::borrow::{Cow, Borrow}; use std::char::{self, DecodeUtf16}; -use std::fmt; +use std::fmt::{self, Write}; use std::hash::{Hash, Hasher}; use std::iter::Cloned; use std::mem; @@ -112,14 +111,6 @@ impl WeakAtom { } #[inline] - pub fn eq_str_ignore_ascii_case(&self, s: &str) -> bool { - self.chars().map(|r| match r { - Ok(c) => c.to_ascii_lowercase() as u32, - Err(e) => e.unpaired_surrogate() as u32, - }).eq(s.chars().map(|c| c.to_ascii_lowercase() as u32)) - } - - #[inline] pub fn to_string(&self) -> String { String::from_utf16(self.as_slice()).unwrap() } @@ -154,7 +145,7 @@ impl fmt::Debug for WeakAtom { impl fmt::Display for WeakAtom { fn fmt(&self, w: &mut fmt::Formatter) -> fmt::Result { for c in self.chars() { - try!(write!(w, "{}", c.unwrap_or(char::REPLACEMENT_CHARACTER))) + try!(w.write_char(c.unwrap_or(char::REPLACEMENT_CHARACTER))) } Ok(()) } diff --git a/components/style/keyframes.rs b/components/style/keyframes.rs index 474e4c8b539..c90e68a4630 100644 --- a/components/style/keyframes.rs +++ b/components/style/keyframes.rs @@ -6,7 +6,7 @@ use cssparser::{AtRuleParser, Parser, QualifiedRuleParser, RuleListParser}; use cssparser::{DeclarationListParser, DeclarationParser, parse_one_rule}; use parking_lot::RwLock; use parser::{ParserContext, ParserContextExtraData, log_css_error}; -use properties::{Importance, PropertyDeclaration, PropertyDeclarationBlock}; +use properties::{Importance, PropertyDeclaration, PropertyDeclarationBlock, PropertyId}; use properties::PropertyDeclarationParseResult; use properties::animated_properties::TransitionProperty; use std::fmt; @@ -50,10 +50,11 @@ impl KeyframePercentage { KeyframePercentage::new(1.) } else { let percentage = try!(input.expect_percentage()); - if percentage > 1. || percentage < 0. { + if percentage >= 0. && percentage <= 1. { + KeyframePercentage::new(percentage) + } else { return Err(()); } - KeyframePercentage::new(percentage) }; Ok(percentage) @@ -343,8 +344,9 @@ impl<'a, 'b> DeclarationParser for KeyframeDeclarationParser<'a, 'b> { type Declaration = Vec<PropertyDeclaration>; fn parse_value(&mut self, name: &str, input: &mut Parser) -> Result<Vec<PropertyDeclaration>, ()> { + let id = try!(PropertyId::parse(name.into())); let mut results = Vec::new(); - match PropertyDeclaration::parse(name, self.context, input, &mut results, true) { + match PropertyDeclaration::parse(id, self.context, input, &mut results, true) { PropertyDeclarationParseResult::ValidOrIgnoredDeclaration => {} _ => return Err(()) } diff --git a/components/style/lib.rs b/components/style/lib.rs index 0955a651105..2b31dc0f779 100644 --- a/components/style/lib.rs +++ b/components/style/lib.rs @@ -23,9 +23,7 @@ //! [cssparser]: ../cssparser/index.html //! [selectors]: ../selectors/index.html -#![cfg_attr(feature = "servo", feature(plugin))] #![cfg_attr(feature = "servo", feature(proc_macro))] -#![cfg_attr(feature = "servo", plugin(plugins))] #![deny(warnings)] @@ -38,7 +36,7 @@ //#![deny(unsafe_code)] #![allow(unused_unsafe)] -#![recursion_limit = "500"] // For match_ignore_ascii_case in PropertyDeclaration::parse +#![recursion_limit = "500"] // For define_css_keyword_enum! in -moz-appearance extern crate app_units; #[allow(unused_extern_crates)] @@ -71,6 +69,7 @@ extern crate num_traits; extern crate ordered_float; extern crate owning_ref; extern crate parking_lot; +extern crate phf; extern crate quickersort; extern crate rayon; extern crate rustc_serialize; @@ -79,6 +78,7 @@ extern crate selectors; extern crate serde; #[cfg(feature = "servo")] #[macro_use] extern crate serde_derive; #[cfg(feature = "servo")] #[macro_use] extern crate servo_atoms; +extern crate servo_config; extern crate servo_url; extern crate smallvec; #[macro_use] @@ -86,7 +86,6 @@ extern crate style_traits; extern crate time; #[allow(unused_extern_crates)] extern crate unicode_segmentation; -extern crate util; pub mod animation; pub mod atomic_refcell; @@ -112,9 +111,9 @@ pub mod media_queries; pub mod owning_handle; pub mod parallel; pub mod parser; -pub mod refcell; pub mod restyle_hints; pub mod rule_tree; +pub mod scoped_tls; pub mod selector_parser; pub mod stylist; #[cfg(feature = "servo")] #[allow(unsafe_code)] pub mod servo; @@ -123,7 +122,6 @@ pub mod sink; pub mod str; pub mod stylesheets; pub mod thread_state; -mod tid; pub mod timer; pub mod traversal; #[macro_use] diff --git a/components/style/matching.rs b/components/style/matching.rs index f88df07e980..8600d9bdc56 100644 --- a/components/style/matching.rs +++ b/components/style/matching.rs @@ -13,7 +13,7 @@ use cache::LRUCache; use cascade_info::CascadeInfo; use context::{SharedStyleContext, StyleContext}; use data::{ComputedStyle, ElementData, ElementStyles, PseudoStyles}; -use dom::{TElement, TNode, TRestyleDamage, UnsafeNode}; +use dom::{SendElement, TElement, TNode}; use properties::{CascadeFlags, ComputedValues, SHAREABLE, SKIP_ROOT_AND_ITEM_BASED_DISPLAY_FIXUP, cascade}; use properties::longhands::display::computed_value as display; use rule_tree::StrongRuleNode; @@ -21,13 +21,13 @@ use selector_parser::{PseudoElement, RestyleDamage, SelectorImpl}; use selectors::MatchAttr; use selectors::bloom::BloomFilter; use selectors::matching::{AFFECTED_BY_PSEUDO_ELEMENTS, MatchingReason, StyleRelations}; +use servo_config::opts; use sink::ForgetfulSink; use std::collections::HashMap; use std::hash::BuildHasherDefault; use std::slice::IterMut; use std::sync::Arc; use stylist::ApplicableDeclarationBlock; -use util::opts; fn create_common_style_affecting_attributes_from_element<E: TElement>(element: &E) -> CommonStyleAffectingAttributes { @@ -69,18 +69,19 @@ impl MatchResults { /// /// TODO: We can stick a lot more info here. #[derive(Debug)] -struct StyleSharingCandidate { - /// The node, guaranteed to be an element. - node: UnsafeNode, +struct StyleSharingCandidate<E: TElement> { + /// The element. We use SendElement here so that the cache may live in + /// ScopedTLS. + element: SendElement<E>, /// The cached common style affecting attribute info. common_style_affecting_attributes: Option<CommonStyleAffectingAttributes>, /// the cached class names. class_attributes: Option<Vec<Atom>>, } -impl PartialEq<StyleSharingCandidate> for StyleSharingCandidate { +impl<E: TElement> PartialEq<StyleSharingCandidate<E>> for StyleSharingCandidate<E> { fn eq(&self, other: &Self) -> bool { - self.node == other.node && + self.element == other.element && self.common_style_affecting_attributes == other.common_style_affecting_attributes } } @@ -90,13 +91,8 @@ impl PartialEq<StyleSharingCandidate> for StyleSharingCandidate { /// /// Note that this cache is flushed every time we steal work from the queue, so /// storing nodes here temporarily is safe. -/// -/// NB: We store UnsafeNode's, but this is not unsafe. It's a shame being -/// generic over elements is unfeasible (you can make compile style without much -/// difficulty, but good luck with layout and all the types with assoc. -/// lifetimes). -pub struct StyleSharingCandidateCache { - cache: LRUCache<StyleSharingCandidate, ()>, +pub struct StyleSharingCandidateCache<E: TElement> { + cache: LRUCache<StyleSharingCandidate<E>, ()>, } #[derive(Clone, Debug)] @@ -117,7 +113,7 @@ pub enum CacheMiss { } fn element_matches_candidate<E: TElement>(element: &E, - candidate: &mut StyleSharingCandidate, + candidate: &mut StyleSharingCandidate<E>, candidate_element: &E, shared_context: &SharedStyleContext) -> Result<ComputedStyle, CacheMiss> { @@ -186,13 +182,14 @@ fn element_matches_candidate<E: TElement>(element: &E, } let data = candidate_element.borrow_data().unwrap(); - let current_styles = data.current_styles(); + debug_assert!(data.has_current_styles()); + let current_styles = data.styles(); Ok(current_styles.primary.clone()) } fn have_same_common_style_affecting_attributes<E: TElement>(element: &E, - candidate: &mut StyleSharingCandidate, + candidate: &mut StyleSharingCandidate<E>, candidate_element: &E) -> bool { if candidate.common_style_affecting_attributes.is_none() { candidate.common_style_affecting_attributes = @@ -271,7 +268,7 @@ pub fn rare_style_affecting_attributes() -> [LocalName; 4] { } fn have_same_class<E: TElement>(element: &E, - candidate: &mut StyleSharingCandidate, + candidate: &mut StyleSharingCandidate<E>, candidate_element: &E) -> bool { // XXX Efficiency here, I'm only validating ideas. let mut element_class_attributes = vec![]; @@ -303,21 +300,21 @@ fn match_same_sibling_affecting_rules<E: TElement>(element: &E, static STYLE_SHARING_CANDIDATE_CACHE_SIZE: usize = 8; -impl StyleSharingCandidateCache { +impl<E: TElement> StyleSharingCandidateCache<E> { pub fn new() -> Self { StyleSharingCandidateCache { cache: LRUCache::new(STYLE_SHARING_CANDIDATE_CACHE_SIZE), } } - fn iter_mut(&mut self) -> IterMut<(StyleSharingCandidate, ())> { + fn iter_mut(&mut self) -> IterMut<(StyleSharingCandidate<E>, ())> { self.cache.iter_mut() } - pub fn insert_if_possible<E: TElement>(&mut self, - element: &E, - style: &Arc<ComputedValues>, - relations: StyleRelations) { + pub fn insert_if_possible(&mut self, + element: &E, + style: &Arc<ComputedValues>, + relations: StyleRelations) { use traversal::relations_are_shareable; let parent = match element.parent_element() { @@ -347,10 +344,10 @@ impl StyleSharingCandidateCache { } debug!("Inserting into cache: {:?} with parent {:?}", - element.as_node().to_unsafe(), parent.as_node().to_unsafe()); + element, parent); self.cache.insert(StyleSharingCandidate { - node: element.as_node().to_unsafe(), + element: unsafe { SendElement::new(*element) }, common_style_affecting_attributes: None, class_attributes: None, }, ()); @@ -390,16 +387,15 @@ trait PrivateMatchMethods: TElement { /// /// Note that animations only apply to nodes or ::before or ::after /// pseudo-elements. - fn cascade_node_pseudo_element<'a, Ctx>(&self, - context: &Ctx, - parent_style: Option<&Arc<ComputedValues>>, - old_style: Option<&Arc<ComputedValues>>, - rule_node: &StrongRuleNode, - possibly_expired_animations: &[PropertyAnimation], - booleans: CascadeBooleans) - -> Arc<ComputedValues> - where Ctx: StyleContext<'a> { - let shared_context = context.shared_context(); + fn cascade_node_pseudo_element<'a>(&self, + context: &StyleContext<Self>, + parent_style: Option<&Arc<ComputedValues>>, + old_style: Option<&Arc<ComputedValues>>, + rule_node: &StrongRuleNode, + possibly_expired_animations: &[PropertyAnimation], + booleans: CascadeBooleans) + -> Arc<ComputedValues> { + let shared_context = context.shared; let mut cascade_info = CascadeInfo::new(); let mut cascade_flags = CascadeFlags::empty(); if booleans.shareable { @@ -432,7 +428,7 @@ trait PrivateMatchMethods: TElement { let mut this_style = Arc::new(this_style); if booleans.animate { - let new_animations_sender = &context.local_context().new_animations_sender; + let new_animations_sender = &context.thread_local.new_animations_sender; let this_opaque = self.as_node().opaque(); // Trigger any present animations if necessary. animation::maybe_start_animations(&shared_context, @@ -497,37 +493,30 @@ trait PrivateMatchMethods: TElement { fn share_style_with_candidate_if_possible(&self, shared_context: &SharedStyleContext, - candidate: &mut StyleSharingCandidate) + candidate: &mut StyleSharingCandidate<Self>) -> Result<ComputedStyle, CacheMiss> { - let candidate_element = unsafe { - Self::ConcreteNode::from_unsafe(&candidate.node).as_element().unwrap() - }; - - element_matches_candidate(self, candidate, &candidate_element, - shared_context) + let candidate_element = *candidate.element; + element_matches_candidate(self, candidate, &candidate_element, shared_context) } } -fn compute_rule_node<'a, Ctx>(context: &Ctx, - applicable_declarations: &mut Vec<ApplicableDeclarationBlock>) - -> StrongRuleNode - where Ctx: StyleContext<'a> +fn compute_rule_node<E: TElement>(context: &StyleContext<E>, + applicable_declarations: &mut Vec<ApplicableDeclarationBlock>) + -> StrongRuleNode { - let shared_context = context.shared_context(); let rules = applicable_declarations.drain(..).map(|d| (d.source, d.importance)); - let rule_node = shared_context.stylist.rule_tree.insert_ordered_rules(rules); + let rule_node = context.shared.stylist.rule_tree.insert_ordered_rules(rules); rule_node } impl<E: TElement> PrivateMatchMethods for E {} pub trait MatchMethods : TElement { - fn match_element<'a, Ctx>(&self, context: &Ctx, parent_bf: Option<&BloomFilter>) - -> MatchResults - where Ctx: StyleContext<'a> + fn match_element(&self, context: &StyleContext<Self>, parent_bf: Option<&BloomFilter>) + -> MatchResults { let mut applicable_declarations: Vec<ApplicableDeclarationBlock> = Vec::with_capacity(16); - let stylist = &context.shared_context().stylist; + let stylist = &context.shared.stylist; let style_attribute = self.style_attribute(); // Compute the primary rule node. @@ -572,7 +561,7 @@ pub trait MatchMethods : TElement { /// guarantee that at the type system level yet. unsafe fn share_style_if_possible(&self, style_sharing_candidate_cache: - &mut StyleSharingCandidateCache, + &mut StyleSharingCandidateCache<Self>, shared_context: &SharedStyleContext, data: &mut AtomicRefMut<ElementData>) -> StyleSharingResult { @@ -600,7 +589,8 @@ pub trait MatchMethods : TElement { // can decide more easily if it knows that it's a child of // replaced content, or similar stuff! let damage = { - let previous_values = data.previous_styles().map(|x| &x.primary.values); + debug_assert!(!data.has_current_styles()); + let previous_values = data.get_styles().map(|x| &x.primary.values); match self.existing_style_for_restyle_damage(previous_values, None) { Some(ref source) => RestyleDamage::compute(source, &shared_style.values), None => RestyleDamage::rebuild_and_reflow(), @@ -719,29 +709,38 @@ pub trait MatchMethods : TElement { } } - unsafe fn cascade_node<'a, Ctx>(&self, - context: &Ctx, - mut data: &mut AtomicRefMut<ElementData>, - parent: Option<Self>, - primary_rule_node: StrongRuleNode, - pseudo_rule_nodes: PseudoRuleNodes, - primary_is_shareable: bool) - where Ctx: StyleContext<'a> + unsafe fn cascade_node(&self, + context: &StyleContext<Self>, + mut data: &mut AtomicRefMut<ElementData>, + parent: Option<Self>, + primary_rule_node: StrongRuleNode, + pseudo_rule_nodes: PseudoRuleNodes, + primary_is_shareable: bool) { // Get our parent's style. let parent_data = parent.as_ref().map(|x| x.borrow_data().unwrap()); - let parent_style = parent_data.as_ref().map(|x| &x.current_styles().primary.values); + let parent_style = parent_data.as_ref().map(|d| { + // Sometimes Gecko eagerly styles things without processing pending + // restyles first. In general we'd like to avoid this, but there can + // be good reasons (for example, needing to construct a frame for + // some small piece of newly-added content in order to do something + // specific with that frame, but not wanting to flush all of + // layout). + debug_assert!(cfg!(feature = "gecko") || d.has_current_styles()); + &d.styles().primary.values + }); let mut new_styles; let mut possibly_expired_animations = vec![]; let damage = { - let (old_primary, old_pseudos) = match data.previous_styles_mut() { + debug_assert!(!data.has_current_styles()); + let (old_primary, old_pseudos) = match data.get_styles_mut() { None => (None, None), Some(previous) => { // Update animations before the cascade. This may modify the // value of the old primary style. - self.update_animations_for_cascade(context.shared_context(), + self.update_animations_for_cascade(&context.shared, &mut previous.primary.values, &mut possibly_expired_animations); (Some(&previous.primary.values), Some(&mut previous.pseudos)) @@ -782,17 +781,16 @@ pub trait MatchMethods : TElement { data.finish_styling(new_styles, damage); } - fn compute_damage_and_cascade_pseudos<'a, Ctx>( + fn compute_damage_and_cascade_pseudos( &self, old_primary: Option<&Arc<ComputedValues>>, mut old_pseudos: Option<&mut PseudoStyles>, new_primary: &Arc<ComputedValues>, new_pseudos: &mut PseudoStyles, - context: &Ctx, + context: &StyleContext<Self>, mut pseudo_rule_nodes: PseudoRuleNodes, possibly_expired_animations: &mut Vec<PropertyAnimation>) -> RestyleDamage - where Ctx: StyleContext<'a> { // Here we optimise the case of the style changing but both the // previous and the new styles having display: none. In this @@ -847,7 +845,7 @@ pub trait MatchMethods : TElement { if let Some(ref mut old_pseudo_style) = maybe_old_pseudo_style { // Update animations before the cascade. This may modify // the value of old_pseudo_style. - self.update_animations_for_cascade(context.shared_context(), + self.update_animations_for_cascade(&context.shared, &mut old_pseudo_style.values, possibly_expired_animations); } diff --git a/components/style/media_queries.rs b/components/style/media_queries.rs index 5ac70856068..a450995c565 100644 --- a/components/style/media_queries.rs +++ b/components/style/media_queries.rs @@ -247,22 +247,24 @@ impl MediaQuery { pub fn parse_media_query_list(input: &mut Parser) -> MediaList { if input.is_exhausted() { - Default::default() - } else { - let mut media_queries = vec![]; - loop { - media_queries.push( - input.parse_until_before(Delimiter::Comma, MediaQuery::parse) - .unwrap_or(MediaQuery::new(Some(Qualifier::Not), - MediaQueryType::All, - vec!()))); - match input.next() { - Ok(Token::Comma) => continue, - Ok(_) => unreachable!(), - Err(()) => break, - } + return Default::default() + } + + let mut media_queries = vec![]; + loop { + media_queries.push( + input.parse_until_before(Delimiter::Comma, MediaQuery::parse) + .unwrap_or(MediaQuery::new(Some(Qualifier::Not), + MediaQueryType::All, + vec!()))); + match input.next() { + Ok(Token::Comma) => {}, + Ok(_) => unreachable!(), + Err(()) => break, } - MediaList { media_queries: media_queries } + } + MediaList { + media_queries: media_queries, } } @@ -295,4 +297,8 @@ impl MediaList { } }) } + + pub fn is_empty(&self) -> bool { + self.media_queries.is_empty() + } } diff --git a/components/style/parallel.rs b/components/style/parallel.rs index 1b9258e7aca..badd0b9f40a 100644 --- a/components/style/parallel.rs +++ b/components/style/parallel.rs @@ -4,38 +4,71 @@ //! Implements parallel traversal over the DOM tree. //! -//! This code is highly unsafe. Keep this file small and easy to audit. - -use dom::{OpaqueNode, TElement, TNode, UnsafeNode}; +//! This traversal is based on Rayon, and therefore its safety is largely +//! verified by the type system. +//! +//! The primary trickiness and fine print for the above relates to the +//! thread safety of the DOM nodes themselves. Accessing a DOM element +//! concurrently on multiple threads is actually mostly "safe", since all +//! the mutable state is protected by an AtomicRefCell, and so we'll +//! generally panic if something goes wrong. Still, we try to to enforce our +//! thread invariants at compile time whenever possible. As such, TNode and +//! TElement are not Send, so ordinary style system code cannot accidentally +//! share them with other threads. In the parallel traversal, we explicitly +//! invoke |unsafe { SendNode::new(n) }| to put nodes in containers that may +//! be sent to other threads. This occurs in only a handful of places and is +//! easy to grep for. At the time of this writing, there is no other unsafe +//! code in the parallel traversal. + +use dom::{OpaqueNode, SendNode, TElement, TNode}; use rayon; +use scoped_tls::ScopedTLS; +use servo_config::opts; use std::sync::atomic::Ordering; -use traversal::{DomTraversalContext, PerLevelTraversalData}; +use traversal::{DomTraversal, PerLevelTraversalData, PreTraverseToken}; use traversal::{STYLE_SHARING_CACHE_HITS, STYLE_SHARING_CACHE_MISSES}; -use util::opts; pub const CHUNK_SIZE: usize = 64; -pub fn traverse_dom<N, C>(root: N, +#[allow(unsafe_code)] +pub fn traverse_dom<N, D>(traversal: &D, + root: N::ConcreteElement, known_root_dom_depth: Option<usize>, - shared_context: &C::SharedContext, + token: PreTraverseToken, queue: &rayon::ThreadPool) where N: TNode, - C: DomTraversalContext<N> + D: DomTraversal<N> { if opts::get().style_sharing_stats { STYLE_SHARING_CACHE_HITS.store(0, Ordering::SeqCst); STYLE_SHARING_CACHE_MISSES.store(0, Ordering::SeqCst); } - let nodes = vec![root.to_unsafe()].into_boxed_slice(); - let data = PerLevelTraversalData { - current_dom_depth: known_root_dom_depth, + // Handle Gecko's eager initial styling. We don't currently support it + // in conjunction with bottom-up traversal. If we did, we'd need to put + // it on the context to make it available to the bottom-up phase. + let (nodes, depth) = if token.traverse_unstyled_children_only() { + debug_assert!(!D::needs_postorder_traversal()); + let mut children = vec![]; + for kid in root.as_node().children() { + if kid.as_element().map_or(false, |el| el.get_data().is_none()) { + children.push(unsafe { SendNode::new(kid) }); + } + } + (children, known_root_dom_depth.map(|x| x + 1)) + } else { + (vec![unsafe { SendNode::new(root.as_node()) }], known_root_dom_depth) + }; + + let traversal_data = PerLevelTraversalData { + current_dom_depth: depth, }; - let root = root.opaque(); + let tls = ScopedTLS::<D::ThreadLocalContext>::new(queue); + let root = root.as_node().opaque(); + queue.install(|| { rayon::scope(|scope| { - let nodes = nodes; - top_down_dom::<N, C>(&nodes, root, data, scope, shared_context); + traverse_nodes(nodes, root, traversal_data, scope, traversal, &tls); }); }); @@ -52,59 +85,82 @@ pub fn traverse_dom<N, C>(root: N, /// A parallel top-down DOM traversal. #[inline(always)] #[allow(unsafe_code)] -fn top_down_dom<'a, 'scope, N, C>(unsafe_nodes: &'a [UnsafeNode], +fn top_down_dom<'a, 'scope, N, D>(nodes: &'a [SendNode<N>], root: OpaqueNode, - mut data: PerLevelTraversalData, + mut traversal_data: PerLevelTraversalData, scope: &'a rayon::Scope<'scope>, - shared_context: &'scope C::SharedContext) - where N: TNode, - C: DomTraversalContext<N>, + traversal: &'scope D, + tls: &'scope ScopedTLS<'scope, D::ThreadLocalContext>) + where N: TNode + 'scope, + D: DomTraversal<N>, { - let context = C::new(shared_context, root); - let mut discovered_child_nodes = vec![]; - for unsafe_node in unsafe_nodes { - // Get a real layout node. - let node = unsafe { N::from_unsafe(&unsafe_node) }; - - // Perform the appropriate traversal. - let mut children_to_process = 0isize; - context.process_preorder(node, &mut data); - if let Some(el) = node.as_element() { - C::traverse_children(el, |kid| { - children_to_process += 1; - discovered_child_nodes.push(kid.to_unsafe()) - }); - } + { + // Scope the borrow of the TLS so that the borrow is dropped before + // potentially traversing a child on this thread. + let mut tlc = tls.ensure(|| traversal.create_thread_local_context()); + + for n in nodes { + // Perform the appropriate traversal. + let node = **n; + let mut children_to_process = 0isize; + traversal.process_preorder(&mut traversal_data, &mut *tlc, node); + if let Some(el) = node.as_element() { + D::traverse_children(el, |kid| { + children_to_process += 1; + discovered_child_nodes.push(unsafe { SendNode::new(kid) }) + }); + } - // Reset the count of children if we need to do a bottom-up traversal - // after the top up. - if context.needs_postorder_traversal() { - if children_to_process == 0 { - // If there were no more children, start walking back up. - bottom_up_dom::<N, C>(root, *unsafe_node, shared_context) - } else { - // Otherwise record the number of children to process when the - // time comes. - node.as_element().unwrap().store_children_to_process(children_to_process); + // Reset the count of children if we need to do a bottom-up traversal + // after the top up. + if D::needs_postorder_traversal() { + if children_to_process == 0 { + // If there were no more children, start walking back up. + bottom_up_dom(traversal, &mut *tlc, root, node) + } else { + // Otherwise record the number of children to process when the + // time comes. + node.as_element().unwrap().store_children_to_process(children_to_process); + } } } } - // NB: In parallel traversal mode we have to purge the LRU cache in order to - // be able to access it without races. - context.local_context().style_sharing_candidate_cache.borrow_mut().clear(); - - if let Some(ref mut depth) = data.current_dom_depth { + if let Some(ref mut depth) = traversal_data.current_dom_depth { *depth += 1; } - for chunk in discovered_child_nodes.chunks(CHUNK_SIZE) { + traverse_nodes(discovered_child_nodes, root, traversal_data, scope, traversal, tls); +} + +fn traverse_nodes<'a, 'scope, N, D>(nodes: Vec<SendNode<N>>, root: OpaqueNode, + traversal_data: PerLevelTraversalData, + scope: &'a rayon::Scope<'scope>, + traversal: &'scope D, + tls: &'scope ScopedTLS<'scope, D::ThreadLocalContext>) + where N: TNode + 'scope, + D: DomTraversal<N>, +{ + if nodes.is_empty() { + return; + } + + // Optimization: traverse directly and avoid a heap-allocating spawn() call if + // we're only pushing one work unit. + if nodes.len() <= CHUNK_SIZE { + let nodes = nodes.into_boxed_slice(); + top_down_dom(&nodes, root, traversal_data, scope, traversal, tls); + return; + } + + // General case. + for chunk in nodes.chunks(CHUNK_SIZE) { let nodes = chunk.iter().cloned().collect::<Vec<_>>().into_boxed_slice(); - let data = data.clone(); + let traversal_data = traversal_data.clone(); scope.spawn(move |scope| { let nodes = nodes; - top_down_dom::<N, C>(&nodes, root, data, scope, shared_context) + top_down_dom(&nodes, root, traversal_data, scope, traversal, tls) }) } } @@ -120,20 +176,16 @@ fn top_down_dom<'a, 'scope, N, C>(unsafe_nodes: &'a [UnsafeNode], /// /// The only communication between siblings is that they both /// fetch-and-subtract the parent's children count. -#[allow(unsafe_code)] -fn bottom_up_dom<N, C>(root: OpaqueNode, - unsafe_node: UnsafeNode, - shared_context: &C::SharedContext) +fn bottom_up_dom<N, D>(traversal: &D, + thread_local: &mut D::ThreadLocalContext, + root: OpaqueNode, + mut node: N) where N: TNode, - C: DomTraversalContext<N> + D: DomTraversal<N> { - let context = C::new(shared_context, root); - - // Get a real layout node. - let mut node = unsafe { N::from_unsafe(&unsafe_node) }; loop { // Perform the appropriate operation. - context.process_postorder(node); + traversal.process_postorder(thread_local, node); if node.opaque() == root { break; diff --git a/components/style/properties/build.py b/components/style/properties/build.py index 4e61f456541..c20cac95cb4 100644 --- a/components/style/properties/build.py +++ b/components/style/properties/build.py @@ -33,6 +33,7 @@ def main(): rust = render(template, product=product, data=properties, __file__=template) if output == "style-crate": write(os.environ["OUT_DIR"], "properties.rs", rust) + write(os.environ["OUT_DIR"], "static_ids.txt", static_ids(properties)) if product == "gecko": template = os.path.join(BASE, "gecko.mako.rs") rust = render(template, data=properties) @@ -69,6 +70,15 @@ def write(directory, filename, content): open(os.path.join(directory, filename), "wb").write(content) +def static_ids(properties): + return '\n'.join( + "%s\tStaticId::%s(%sId::%s)" % (p.name, kind, kind, p.camel_case) + for kind, props in [("Longhand", properties.longhands), + ("Shorthand", properties.shorthands)] + for p in props + ) + + def write_html(properties): properties = dict( (p.name, { diff --git a/components/style/properties/declaration_block.rs b/components/style/properties/declaration_block.rs index adabb526797..de2d274280b 100644 --- a/components/style/properties/declaration_block.rs +++ b/components/style/properties/declaration_block.rs @@ -7,7 +7,6 @@ use cssparser::{Parser, AtRuleParser, DeclarationParser, Delimiter}; use error_reporting::ParseErrorReporter; use parser::{ParserContext, ParserContextExtraData, log_css_error}; use servo_url::ServoUrl; -use std::ascii::AsciiExt; use std::boxed::Box as StdBox; use std::fmt; use style_traits::ToCss; @@ -65,90 +64,94 @@ impl PropertyDeclarationBlock { self.declarations.len() > self.important_count as usize } - pub fn get(&self, property_name: &str) -> Option< &(PropertyDeclaration, Importance)> { - self.declarations.iter().find(|&&(ref decl, _)| decl.matches(property_name)) + pub fn get(&self, property: PropertyDeclarationId) -> Option< &(PropertyDeclaration, Importance)> { + self.declarations.iter().find(|&&(ref decl, _)| decl.id() == property) } /// Find the value of the given property in this block and serialize it /// /// https://dev.w3.org/csswg/cssom/#dom-cssstyledeclaration-getpropertyvalue - pub fn property_value_to_css<W>(&self, property_name: &str, dest: &mut W) -> fmt::Result + pub fn property_value_to_css<W>(&self, property: &PropertyId, dest: &mut W) -> fmt::Result where W: fmt::Write { - // Step 1 - let property = property_name.to_ascii_lowercase(); + // Step 1: done when parsing a string to PropertyId // Step 2 - if let Some(shorthand) = Shorthand::from_name(&property) { - // Step 2.1 - let mut list = Vec::new(); - let mut important_count = 0; - - // Step 2.2 - for longhand in shorthand.longhands() { - // Step 2.2.1 - let declaration = self.get(longhand); - - // Step 2.2.2 & 2.2.3 - match declaration { - Some(&(ref declaration, importance)) => { - list.push(declaration); - if importance.important() { - important_count += 1; - } - }, - None => return Ok(()), + match property.as_shorthand() { + Ok(shorthand) => { + // Step 2.1 + let mut list = Vec::new(); + let mut important_count = 0; + + // Step 2.2 + for &longhand in shorthand.longhands() { + // Step 2.2.1 + let declaration = self.get(PropertyDeclarationId::Longhand(longhand)); + + // Step 2.2.2 & 2.2.3 + match declaration { + Some(&(ref declaration, importance)) => { + list.push(declaration); + if importance.important() { + important_count += 1; + } + }, + None => return Ok(()), + } } - } - // Step 3.3.2.4 - // If there is one or more longhand with important, and one or more - // without important, we don't serialize it as a shorthand. - if important_count > 0 && important_count != list.len() { - return Ok(()); - } - - // Step 2.3 - // We don't print !important when serializing individual properties, - // so we treat this as a normal-importance property - let importance = Importance::Normal; - let appendable_value = shorthand.get_shorthand_appendable_value(list).unwrap(); - return append_declaration_value(dest, appendable_value, importance) - } + // Step 3.3.2.4 + // If there is one or more longhand with important, and one or more + // without important, we don't serialize it as a shorthand. + if important_count > 0 && important_count != list.len() { + return Ok(()); + } - if let Some(&(ref value, _importance)) = self.get(property_name) { - // Step 3 - value.to_css(dest) - } else { - // Step 4 - Ok(()) + // Step 2.3 + // We don't print !important when serializing individual properties, + // so we treat this as a normal-importance property + let importance = Importance::Normal; + let appendable_value = shorthand.get_shorthand_appendable_value(list).unwrap(); + append_declaration_value(dest, appendable_value, importance) + } + Err(longhand_or_custom) => { + if let Some(&(ref value, _importance)) = self.get(longhand_or_custom) { + // Step 3 + value.to_css(dest) + } else { + // Step 4 + Ok(()) + } + } } } /// https://dev.w3.org/csswg/cssom/#dom-cssstyledeclaration-getpropertypriority - pub fn property_priority(&self, property_name: &str) -> Importance { - // Step 1 - let property = property_name.to_ascii_lowercase(); + pub fn property_priority(&self, property: &PropertyId) -> Importance { + // Step 1: done when parsing a string to PropertyId // Step 2 - if let Some(shorthand) = Shorthand::from_name(&property) { - // Step 2.1 & 2.2 & 2.3 - if shorthand.longhands().iter().all(|l| { - self.get(l).map_or(false, |&(_, importance)| importance.important()) - }) { - Importance::Important - } else { - Importance::Normal + match property.as_shorthand() { + Ok(shorthand) => { + // Step 2.1 & 2.2 & 2.3 + if shorthand.longhands().iter().all(|&l| { + self.get(PropertyDeclarationId::Longhand(l)) + .map_or(false, |&(_, importance)| importance.important()) + }) { + Importance::Important + } else { + Importance::Normal + } + } + Err(longhand_or_custom) => { + // Step 3 + self.get(longhand_or_custom).map_or(Importance::Normal, |&(_, importance)| importance) } - } else { - // Step 3 - self.get(&property).map_or(Importance::Normal, |&(_, importance)| importance) } } - pub fn set_parsed_declaration(&mut self, declaration: PropertyDeclaration, - importance: Importance) { + pub fn set_parsed_declaration(&mut self, declaration: PropertyDeclaration, importance: Importance) { for slot in &mut *self.declarations { - if slot.0.name() == declaration.name() { + if slot.0.id() == declaration.id() { match (slot.1, importance) { (Importance::Normal, Importance::Important) => { self.important_count += 1; @@ -169,9 +172,9 @@ impl PropertyDeclarationBlock { } } - pub fn set_importance(&mut self, property_names: &[&str], new_importance: Importance) { + pub fn set_importance(&mut self, property: &PropertyId, new_importance: Importance) { for &mut (ref declaration, ref mut importance) in &mut self.declarations { - if property_names.iter().any(|p| declaration.matches(p)) { + if declaration.id().is_or_is_longhand_of(property) { match (*importance, new_importance) { (Importance::Normal, Importance::Important) => { self.important_count += 1; @@ -187,44 +190,34 @@ impl PropertyDeclarationBlock { } /// https://dev.w3.org/csswg/cssom/#dom-cssstyledeclaration-removeproperty - pub fn remove_property(&mut self, property_name: &str) { - // Step 2 - let property = property_name.to_ascii_lowercase(); - - match Shorthand::from_name(&property) { - // Step 4 - Some(shorthand) => self.remove_longhands(shorthand.longhands()), - // Step 5 - None => self.remove_longhands(&[&*property]), - } - } - - fn remove_longhands(&mut self, names: &[&str]) { + pub fn remove_property(&mut self, property: &PropertyId) { let important_count = &mut self.important_count; self.declarations.retain(|&(ref declaration, importance)| { - let retain = !names.iter().any(|n| declaration.matches(n)); - if !retain && importance.important() { + let remove = declaration.id().is_or_is_longhand_of(property); + if remove && importance.important() { *important_count -= 1 } - retain + !remove }) } /// Take a declaration block known to contain a single property and serialize it. - pub fn single_value_to_css<W>(&self, property_name: &str, dest: &mut W) -> fmt::Result + pub fn single_value_to_css<W>(&self, property: &PropertyId, dest: &mut W) -> fmt::Result where W: fmt::Write { - match self.declarations.len() { - 0 => Err(fmt::Error), - 1 if self.declarations[0].0.name().eq_str_ignore_ascii_case(property_name) => { - self.declarations[0].0.to_css(dest) + match property.as_shorthand() { + Err(_longhand_or_custom) => { + if self.declarations.len() == 1 { + self.declarations[0].0.to_css(dest) + } else { + Err(fmt::Error) + } } - _ => { + Ok(shorthand) => { // we use this function because a closure won't be `Clone` fn get_declaration(dec: &(PropertyDeclaration, Importance)) -> &PropertyDeclaration { &dec.0 } - let shorthand = try!(Shorthand::from_name(property_name).ok_or(fmt::Error)); if !self.declarations.iter().all(|decl| decl.0.shorthands().contains(&shorthand)) { return Err(fmt::Error) } @@ -254,7 +247,7 @@ impl ToCss for PropertyDeclarationBlock { // Step 3 for &(ref declaration, importance) in &*self.declarations { // Step 3.1 - let property = declaration.name(); + let property = declaration.id(); // Step 3.2 if already_serialized.contains(&property) { @@ -266,11 +259,11 @@ impl ToCss for PropertyDeclarationBlock { if !shorthands.is_empty() { // Step 3.3.1 let mut longhands = self.declarations.iter() - .filter(|d| !already_serialized.contains(&d.0.name())) + .filter(|d| !already_serialized.contains(&d.0.id())) .collect::<Vec<_>>(); // Step 3.3.2 - for shorthand in shorthands { + for &shorthand in shorthands { let properties = shorthand.longhands(); // Substep 2 & 3 @@ -278,8 +271,7 @@ impl ToCss for PropertyDeclarationBlock { let mut important_count = 0; for &&(ref longhand, longhand_importance) in longhands.iter() { - let longhand_name = longhand.name(); - if properties.iter().any(|p| &longhand_name == *p) { + if longhand.id().is_longhand_of(shorthand) { current_longhands.push(longhand); if longhand_importance.important() { important_count += 1; @@ -325,7 +317,7 @@ impl ToCss for PropertyDeclarationBlock { for current_longhand in current_longhands { // Substep 9 - already_serialized.push(current_longhand.name()); + already_serialized.push(current_longhand.id()); let index_to_remove = longhands.iter().position(|l| l.0 == *current_longhand); if let Some(index) = index_to_remove { // Substep 10 @@ -348,9 +340,9 @@ impl ToCss for PropertyDeclarationBlock { // "error: unable to infer enough type information about `_`; // type annotations or generic parameter binding required [E0282]" // Use the same type as earlier call to reuse generated code. - try!(append_serialization::<W, Cloned<slice::Iter< &PropertyDeclaration>>>( + try!(append_serialization::<W, Cloned<slice::Iter< &PropertyDeclaration>>, _>( dest, - &property.to_string(), + &property, AppendableValue::Declaration(declaration), importance, &mut is_first_serialization)); @@ -367,7 +359,7 @@ impl ToCss for PropertyDeclarationBlock { pub enum AppendableValue<'a, I> where I: Iterator<Item=&'a PropertyDeclaration> { Declaration(&'a PropertyDeclaration), - DeclarationsForShorthand(Shorthand, I), + DeclarationsForShorthand(ShorthandId, I), Css(&'a str) } @@ -407,13 +399,15 @@ pub fn append_declaration_value<'a, W, I> Ok(()) } -pub fn append_serialization<'a, W, I>(dest: &mut W, - property_name: &str, +pub fn append_serialization<'a, W, I, N>(dest: &mut W, + property_name: &N, appendable_value: AppendableValue<'a, I>, importance: Importance, is_first_serialization: &mut bool) -> fmt::Result - where W: fmt::Write, I: Iterator<Item=&'a PropertyDeclaration> { + where W: fmt::Write, + I: Iterator<Item=&'a PropertyDeclaration>, + N: ToCss { try!(handle_first_serialization(dest, is_first_serialization)); // Overflow does not behave like a normal shorthand. When overflow-x and overflow-y are not of equal @@ -422,7 +416,8 @@ pub fn append_serialization<'a, W, I>(dest: &mut W, return append_declaration_value(dest, appendable_value, importance); } - try!(write!(dest, "{}:", property_name)); + try!(property_name.to_css(dest)); + try!(dest.write_char(':')); // for normal parsed values, add a space between key: and value match &appendable_value { @@ -451,7 +446,7 @@ pub fn parse_style_attribute(input: &str, parse_property_declaration_list(&context, &mut Parser::new(input)) } -pub fn parse_one_declaration(name: &str, +pub fn parse_one_declaration(id: PropertyId, input: &str, base_url: &ServoUrl, error_reporter: StdBox<ParseErrorReporter + Send>, @@ -459,7 +454,7 @@ pub fn parse_one_declaration(name: &str, -> Result<Vec<PropertyDeclaration>, ()> { let context = ParserContext::new_with_extra_data(Origin::Author, base_url, error_reporter, extra_data); let mut results = vec![]; - match PropertyDeclaration::parse(name, &context, &mut Parser::new(input), &mut results, false) { + match PropertyDeclaration::parse(id, &context, &mut Parser::new(input), &mut results, false) { PropertyDeclarationParseResult::ValidOrIgnoredDeclaration => Ok(results), _ => Err(()) } @@ -482,9 +477,10 @@ impl<'a, 'b> DeclarationParser for PropertyDeclarationParser<'a, 'b> { fn parse_value(&mut self, name: &str, input: &mut Parser) -> Result<(Vec<PropertyDeclaration>, Importance), ()> { + let id = try!(PropertyId::parse(name.into())); let mut results = vec![]; try!(input.parse_until_before(Delimiter::Bang, |input| { - match PropertyDeclaration::parse(name, self.context, input, &mut results, false) { + match PropertyDeclaration::parse(id, self.context, input, &mut results, false) { PropertyDeclarationParseResult::ValidOrIgnoredDeclaration => Ok(()), _ => Err(()) } diff --git a/components/style/properties/gecko.mako.rs b/components/style/properties/gecko.mako.rs index c424ca705a7..d85aa8b63ab 100644 --- a/components/style/properties/gecko.mako.rs +++ b/components/style/properties/gecko.mako.rs @@ -5,7 +5,7 @@ // `data` comes from components/style/properties.mako.rs; see build.rs for more details. <%! - from data import to_rust_ident + from data import to_rust_ident, to_camel_case from data import Keyword %> <%namespace name="helpers" file="/helpers.mako.rs" /> @@ -170,6 +170,11 @@ impl ComputedValues { self.custom_properties.as_ref().map(|x| x.clone()) } + #[allow(non_snake_case)] + pub fn has_moz_binding(&self) -> bool { + !self.get_box().gecko.mBinding.mRawPtr.is_null() + } + pub fn root_font_size(&self) -> Au { self.root_font_size } pub fn set_root_font_size(&mut self, s: Au) { self.root_font_size = s; } pub fn set_writing_mode(&mut self, mode: WritingMode) { self.writing_mode = mode; } @@ -626,8 +631,15 @@ class Corner(object): self.x_index = 2 * index self.y_index = 2 * index + 1 +class GridLine(object): + def __init__(self, name): + self.ident = "grid-" + name.lower() + self.name = self.ident.replace('-', '_') + self.gecko = "m" + to_camel_case(self.ident) + SIDES = [Side("Top", 0), Side("Right", 1), Side("Bottom", 2), Side("Left", 3)] CORNERS = [Corner("TOP_LEFT", 0), Corner("TOP_RIGHT", 1), Corner("BOTTOM_RIGHT", 2), Corner("BOTTOM_LEFT", 3)] +GRID_LINES = map(GridLine, ["row-start", "row-end", "column-start", "column-end"]) %> #[allow(dead_code)] @@ -817,7 +829,7 @@ fn static_assert() { % endfor </%self:impl_trait> -<% skip_position_longhands = " ".join(x.ident for x in SIDES) %> +<% skip_position_longhands = " ".join(x.ident for x in SIDES + GRID_LINES) %> <%self:impl_trait style_struct_name="Position" skip_longhands="${skip_position_longhands} z-index box-sizing order"> @@ -879,6 +891,27 @@ fn static_assert() { ${impl_simple_copy('order', 'mOrder')} + % for value in GRID_LINES: + pub fn set_${value.name}(&mut self, v: longhands::${value.name}::computed_value::T) { + use nsstring::nsCString; + use gecko_bindings::structs::{nsStyleGridLine_kMinLine, nsStyleGridLine_kMaxLine}; + + let ident = v.ident.unwrap_or(String::new()); + self.gecko.${value.gecko}.mLineName.assign_utf8(&nsCString::from(&*ident)); + self.gecko.${value.gecko}.mHasSpan = v.is_span; + self.gecko.${value.gecko}.mInteger = v.integer.map(|i| { + // clamping the integer between a range + cmp::max(nsStyleGridLine_kMinLine, cmp::min(i, nsStyleGridLine_kMaxLine)) + }).unwrap_or(0); + } + + pub fn copy_${value.name}_from(&mut self, other: &Self) { + self.gecko.${value.gecko}.mHasSpan = other.gecko.${value.gecko}.mHasSpan; + self.gecko.${value.gecko}.mInteger = other.gecko.${value.gecko}.mInteger; + self.gecko.${value.gecko}.mLineName.assign(&other.gecko.${value.gecko}.mLineName); + } + % endfor + </%self:impl_trait> <% skip_outline_longhands = " ".join("outline-style outline-width".split() + @@ -1119,7 +1152,10 @@ fn static_assert() { Either::Second(_none) => debug_assert!(self.gecko.mBinding.mRawPtr.is_null()), Either::First(ref url) => { let extra_data = url.extra_data(); - let (ptr, len) = url.as_slice_components(); + let (ptr, len) = match url.as_slice_components() { + Ok(value) => value, + Err(_) => (ptr::null(), 0), + }; unsafe { Gecko_SetMozBinding(&mut self.gecko, ptr, @@ -1384,6 +1420,7 @@ fn static_assert() { } </%self:simple_image_array_property> + % if shorthand != "background": pub fn copy_${shorthand}_position_from(&mut self, other: &Self) { use gecko_bindings::structs::nsStyleImageLayers_LayerType as LayerType; @@ -1419,7 +1456,7 @@ fn static_assert() { pub fn clone_${shorthand}_position(&self) -> longhands::${shorthand}_position::computed_value::T { use values::computed::position::Position; - longhands::background_position::computed_value::T( + longhands::${shorthand}_position::computed_value::T( self.gecko.${image_layers_field}.mLayers.iter() .take(self.gecko.${image_layers_field}.mPositionXCount as usize) .take(self.gecko.${image_layers_field}.mPositionYCount as usize) @@ -1448,6 +1485,7 @@ fn static_assert() { geckolayer.mPosition.mYPosition = servo.vertical.into(); } } + % endif <%self:simple_image_array_property name="size" shorthand="${shorthand}" field_name="mSize"> use gecko_bindings::structs::nsStyleImageLayers_Size_Dimension; @@ -1597,7 +1635,9 @@ fn static_assert() { background-image background-clip background-origin background-attachment background-size background-position - background-blend-mode""" %> + background-blend-mode + background-position-x + background-position-y""" %> <%self:impl_trait style_struct_name="Background" skip_longhands="${skip_background_longhands}" skip_additionals="*"> @@ -1635,6 +1675,56 @@ fn static_assert() { T::luminosity => structs::NS_STYLE_BLEND_LUMINOSITY as u8, } </%self:simple_image_array_property> + + % for orientation in [("x", "Horizontal"), ("y", "Vertical")]: + pub fn copy_background_position_${orientation[0]}_from(&mut self, other: &Self) { + use gecko_bindings::structs::nsStyleImageLayers_LayerType as LayerType; + + self.gecko.mImage.mPosition${orientation[0].upper()}Count + = cmp::min(1, other.gecko.mImage.mPosition${orientation[0].upper()}Count); + self.gecko.mImage.mLayers.mFirstElement.mPosition = + other.gecko.mImage.mLayers.mFirstElement.mPosition; + unsafe { + Gecko_EnsureImageLayersLength(&mut self.gecko.mImage, + other.gecko.mImage.mLayers.len(), + LayerType::Background); + } + for (layer, other) in self.gecko.mImage.mLayers.iter_mut() + .zip(other.gecko.mImage.mLayers.iter()) { + layer.mPosition.m${orientation[0].upper()}Position + = other.mPosition.m${orientation[0].upper()}Position; + } + self.gecko.mImage.mPosition${orientation[0].upper()}Count + = other.gecko.mImage.mPosition${orientation[0].upper()}Count; + } + + pub fn clone_background_position_${orientation[0]}(&self) + -> longhands::background_position_${orientation[0]}::computed_value::T { + use values::computed::position::${orientation[1]}Position; + longhands::background_position_${orientation[0]}::computed_value::T( + self.gecko.mImage.mLayers.iter() + .take(self.gecko.mImage.mPosition${orientation[0].upper()}Count as usize) + .map(|position| ${orientation[1]}Position(position.mPosition.m${orientation[0].upper()}Position.into())) + .collect() + ) + } + + pub fn set_background_position_${orientation[0]}(&mut self, + v: longhands::background_position_${orientation[0]}::computed_value::T) { + use gecko_bindings::structs::nsStyleImageLayers_LayerType as LayerType; + + unsafe { + Gecko_EnsureImageLayersLength(&mut self.gecko.mImage, v.0.len(), + LayerType::Background); + } + + self.gecko.mImage.mPosition${orientation[0].upper()}Count = v.0.len() as u32; + for (servo, geckolayer) in v.0.into_iter().zip(self.gecko.mImage + .mLayers.iter_mut()) { + geckolayer.mPosition.m${orientation[0].upper()}Position = servo.0.into(); + } + } + % endfor </%self:impl_trait> <%self:impl_trait style_struct_name="List" @@ -1650,7 +1740,9 @@ fn static_assert() { } } Either::First(ref url) => { - let (ptr, len) = url.as_slice_components(); + let (ptr, len) = match url.as_slice_components() { + Ok(value) | Err(value) => value + }; let extra_data = url.extra_data(); unsafe { Gecko_SetListStyleImage(&mut self.gecko, @@ -1809,7 +1901,7 @@ fn static_assert() { Sepia(factor) => fill_filter(NS_STYLE_FILTER_SEPIA, CoordDataValue::Factor(factor), gecko_filter), - DropShadow(offset_x, offset_y, blur_radius, ref color) => { + DropShadow(shadow) => { gecko_filter.mType = NS_STYLE_FILTER_DROP_SHADOW; fn init_shadow(filter: &mut nsStyleFilter) -> &mut nsCSSShadowArray { @@ -1823,13 +1915,13 @@ fn static_assert() { } let mut gecko_shadow = init_shadow(gecko_filter); - gecko_shadow.mArray[0].mXOffset = offset_x.0; - gecko_shadow.mArray[0].mYOffset = offset_y.0; - gecko_shadow.mArray[0].mRadius = blur_radius.0; + gecko_shadow.mArray[0].mXOffset = shadow.offset_x.0; + gecko_shadow.mArray[0].mYOffset = shadow.offset_y.0; + gecko_shadow.mArray[0].mRadius = shadow.blur_radius.0; // mSpread is not supported in the spec, so we leave it as 0 gecko_shadow.mArray[0].mInset = false; // Not supported in spec level 1 - gecko_shadow.mArray[0].mColor = match *color { + gecko_shadow.mArray[0].mColor = match shadow.color { Color::RGBA(rgba) => { gecko_shadow.mArray[0].mHasColor = true; convert_rgba_to_nscolor(&rgba) @@ -2346,7 +2438,9 @@ clip-path for i in 0..v.images.len() { let image = &v.images[i]; let extra_data = image.url.extra_data(); - let (ptr, len) = image.url.as_slice_components(); + let (ptr, len) = match image.url.as_slice_components() { + Ok(value) | Err(value) => value, + }; unsafe { Gecko_SetCursorImage(&mut self.gecko.mCursorImages[i], ptr, len as u32, @@ -2370,7 +2464,7 @@ clip-path </%self:impl_trait> <%self:impl_trait style_struct_name="Column" - skip_longhands="column-count column-gap -moz-column-rule-width"> + skip_longhands="column-count column-gap column-rule-width"> #[allow(unused_unsafe)] pub fn set_column_count(&mut self, v: longhands::column_count::computed_value::T) { @@ -2387,15 +2481,17 @@ clip-path ${impl_simple_copy('column_count', 'mColumnCount')} pub fn set_column_gap(&mut self, v: longhands::column_gap::computed_value::T) { - match v.0 { - Some(len) => self.gecko.mColumnGap.set(len), - None => self.gecko.mColumnGap.set_value(CoordDataValue::Normal), + use values::Either; + + match v { + Either::First(len) => self.gecko.mColumnGap.set(len), + Either::Second(_normal) => self.gecko.mColumnGap.set_value(CoordDataValue::Normal), } } <%call expr="impl_coord_copy('column_gap', 'mColumnGap')"></%call> - <% impl_app_units("_moz_column_rule_width", "mColumnRuleWidth", need_clone=True, + <% impl_app_units("column_rule_width", "mColumnRuleWidth", need_clone=True, round_to_pixels=True) %> </%self:impl_trait> diff --git a/components/style/properties/helpers.mako.rs b/components/style/properties/helpers.mako.rs index 5d58fd6db5c..5efeac958fe 100644 --- a/components/style/properties/helpers.mako.rs +++ b/components/style/properties/helpers.mako.rs @@ -68,7 +68,7 @@ pub mod single_value { use cssparser::Parser; use parser::{Parse, ParserContext, ParserContextExtraData}; - use properties::{CSSWideKeyword, DeclaredValue, Shorthand}; + use properties::{CSSWideKeyword, DeclaredValue, ShorthandId}; use values::computed::{Context, ToComputedValue}; use values::{computed, specified}; ${caller.body()} @@ -182,7 +182,7 @@ % if not property.derived_from: use cssparser::Parser; use parser::{Parse, ParserContext, ParserContextExtraData}; - use properties::{CSSWideKeyword, DeclaredValue, Shorthand}; + use properties::{CSSWideKeyword, DeclaredValue, ShorthandId}; % endif use values::{Auto, Either, None_, Normal}; use cascade_info::CascadeInfo; @@ -245,6 +245,9 @@ % endif } DeclaredValue::WithVariables { .. } => unreachable!(), + % if not data.current_style_struct.inherited: + DeclaredValue::Unset | + % endif DeclaredValue::Initial => { // We assume that it's faster to use copy_*_from rather than // set_*(get_initial_value()); @@ -253,6 +256,9 @@ context.mutate_style().mutate_${data.current_style_struct.name_lower}() .copy_${property.ident}_from(initial_struct ${maybe_wm}); }, + % if data.current_style_struct.inherited: + DeclaredValue::Unset | + % endif DeclaredValue::Inherit => { // This is a bit slow, but this is rare so it shouldn't // matter. @@ -286,8 +292,7 @@ match input.try(|i| CSSWideKeyword::parse(context, i)) { Ok(CSSWideKeyword::InheritKeyword) => Ok(DeclaredValue::Inherit), Ok(CSSWideKeyword::InitialKeyword) => Ok(DeclaredValue::Initial), - Ok(CSSWideKeyword::UnsetKeyword) => Ok(DeclaredValue::${ - "Inherit" if data.current_style_struct.inherited else "Initial"}), + Ok(CSSWideKeyword::UnsetKeyword) => Ok(DeclaredValue::Unset), Err(()) => { input.look_for_var_functions(); let start = input.position(); @@ -380,9 +385,10 @@ #[allow(unused_imports)] use cssparser::Parser; use parser::ParserContext; - use properties::{longhands, PropertyDeclaration, DeclaredValue, Shorthand}; + use properties::{longhands, PropertyDeclaration, DeclaredValue, ShorthandId}; use std::fmt; use style_traits::ToCss; + use super::{SerializeFlags, ALL_INHERIT, ALL_INITIAL, ALL_UNSET}; pub struct Longhands { % for sub_property in shorthand.sub_properties: @@ -441,17 +447,16 @@ impl<'a> ToCss for LonghandsToSerialize<'a> { fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write { - let mut all_inherit = true; - let mut all_initial = true; + let mut all_flags = SerializeFlags::all(); let mut with_variables = false; % for sub_property in shorthand.sub_properties: match *self.${sub_property.ident} { - DeclaredValue::Initial => all_inherit = false, - DeclaredValue::Inherit => all_initial = false, + DeclaredValue::Initial => all_flags &= ALL_INITIAL, + DeclaredValue::Inherit => all_flags &= ALL_INHERIT, + DeclaredValue::Unset => all_flags &= ALL_UNSET, DeclaredValue::WithVariables {..} => with_variables = true, DeclaredValue::Value(..) => { - all_initial = false; - all_inherit = false; + all_flags = SerializeFlags::empty(); } } % endfor @@ -459,10 +464,12 @@ if with_variables { // We don't serialize shorthands with variables dest.write_str("") - } else if all_inherit { + } else if all_flags == ALL_INHERIT { dest.write_str("inherit") - } else if all_initial { + } else if all_flags == ALL_INITIAL { dest.write_str("initial") + } else if all_flags == ALL_UNSET { + dest.write_str("unset") } else { self.to_css_declared(dest) } @@ -500,7 +507,7 @@ css: css.clone().into_owned(), first_token_type: first_token_type, base_url: context.base_url.clone(), - from_shorthand: Some(Shorthand::${shorthand.camel_case}), + from_shorthand: Some(ShorthandId::${shorthand.camel_case}), } )); % endfor diff --git a/components/style/properties/helpers/animated_properties.mako.rs b/components/style/properties/helpers/animated_properties.mako.rs index 1053e8e6958..1e813ba78e1 100644 --- a/components/style/properties/helpers/animated_properties.mako.rs +++ b/components/style/properties/helpers/animated_properties.mako.rs @@ -7,7 +7,8 @@ use cssparser::{Color as CSSParserColor, Parser, RGBA}; use euclid::{Point2D, Size2D}; use properties::PropertyDeclaration; use properties::longhands; -use properties::longhands::background_position::computed_value::T as BackgroundPosition; +use properties::longhands::background_position_x::computed_value::T as BackgroundPositionX; +use properties::longhands::background_position_y::computed_value::T as BackgroundPositionY; use properties::longhands::background_size::computed_value::T as BackgroundSize; use properties::longhands::font_weight::computed_value::T as FontWeight; use properties::longhands::line_height::computed_value::T as LineHeight; @@ -26,7 +27,7 @@ use values::Either; use values::computed::{Angle, LengthOrPercentageOrAuto, LengthOrPercentageOrNone}; use values::computed::{BorderRadiusSize, LengthOrNone}; use values::computed::{CalcLengthOrPercentage, LengthOrPercentage}; -use values::computed::position::Position; +use values::computed::position::{HorizontalPosition, Position, VerticalPosition}; use values::computed::ToComputedValue; @@ -574,10 +575,37 @@ impl Interpolate for Position { impl RepeatableListInterpolate for Position {} -impl Interpolate for BackgroundPosition { +/// https://drafts.csswg.org/css-transitions/#animtype-simple-list +impl Interpolate for HorizontalPosition { + #[inline] + fn interpolate(&self, other: &Self, progress: f64) -> Result<Self, ()> { + Ok(HorizontalPosition(try!(self.0.interpolate(&other.0, progress)))) + } +} + +impl RepeatableListInterpolate for HorizontalPosition {} + +/// https://drafts.csswg.org/css-transitions/#animtype-simple-list +impl Interpolate for VerticalPosition { + #[inline] + fn interpolate(&self, other: &Self, progress: f64) -> Result<Self, ()> { + Ok(VerticalPosition(try!(self.0.interpolate(&other.0, progress)))) + } +} + +impl RepeatableListInterpolate for VerticalPosition {} + +impl Interpolate for BackgroundPositionX { + #[inline] + fn interpolate(&self, other: &Self, progress: f64) -> Result<Self, ()> { + Ok(BackgroundPositionX(try!(self.0.interpolate(&other.0, progress)))) + } +} + +impl Interpolate for BackgroundPositionY { #[inline] fn interpolate(&self, other: &Self, progress: f64) -> Result<Self, ()> { - Ok(BackgroundPosition(try!(self.0.interpolate(&other.0, progress)))) + Ok(BackgroundPositionY(try!(self.0.interpolate(&other.0, progress)))) } } diff --git a/components/style/properties/longhand/background.mako.rs b/components/style/properties/longhand/background.mako.rs index adc7e44e0a9..645e9666c63 100644 --- a/components/style/properties/longhand/background.mako.rs +++ b/components/style/properties/longhand/background.mako.rs @@ -86,43 +86,89 @@ ${helpers.predefined_type("background-color", "CSSColor", } </%helpers:vector_longhand> -<%helpers:vector_longhand name="background-position" animatable="True"> +<%helpers:vector_longhand name="background-position-x" animatable="True"> use std::fmt; use style_traits::ToCss; use values::HasViewportPercentage; - use values::specified::position::Position; + use values::specified::position::HorizontalPosition; pub mod computed_value { - use values::computed::position::Position; + use values::computed::position::HorizontalPosition; use properties::animated_properties::{Interpolate, RepeatableListInterpolate}; - pub type T = Position; + pub type T = HorizontalPosition; } - pub type SpecifiedValue = Position; + pub type SpecifiedValue = HorizontalPosition; #[inline] pub fn get_initial_value() -> computed_value::T { - use values::computed::position::Position; - Position { - horizontal: computed::LengthOrPercentage::Percentage(0.0), - vertical: computed::LengthOrPercentage::Percentage(0.0), + use values::computed::position::HorizontalPosition; + HorizontalPosition(computed::LengthOrPercentage::Percentage(0.0)) + } + #[inline] + pub fn get_initial_specified_value() -> SpecifiedValue { + use values::specified::position::Keyword; + HorizontalPosition { + keyword: Some(Keyword::Left), + position: None, } } #[inline] + pub fn get_initial_position_value() -> SpecifiedValue { + use values::specified::{LengthOrPercentage, Percentage}; + HorizontalPosition { + keyword: None, + position: Some(LengthOrPercentage::Percentage(Percentage(0.0))), + } + } + + pub fn parse(context: &ParserContext, input: &mut Parser) + -> Result<SpecifiedValue, ()> { + HorizontalPosition::parse(context, input) + } +</%helpers:vector_longhand> + +<%helpers:vector_longhand name="background-position-y" animatable="True"> + use std::fmt; + use style_traits::ToCss; + use values::HasViewportPercentage; + use values::specified::position::VerticalPosition; + + pub mod computed_value { + use values::computed::position::VerticalPosition; + use properties::animated_properties::{Interpolate, RepeatableListInterpolate}; + + pub type T = VerticalPosition; + } + + pub type SpecifiedValue = VerticalPosition; + + #[inline] + pub fn get_initial_value() -> computed_value::T { + use values::computed::position::VerticalPosition; + VerticalPosition(computed::LengthOrPercentage::Percentage(0.0)) + } + #[inline] pub fn get_initial_specified_value() -> SpecifiedValue { - use values::specified::Percentage; - Position { - horiz_keyword: None, - horiz_position: Some(specified::LengthOrPercentage::Percentage(Percentage(0.0))), - vert_keyword: None, - vert_position: Some(specified::LengthOrPercentage::Percentage(Percentage(0.0))), + use values::specified::position::Keyword; + VerticalPosition { + keyword: Some(Keyword::Top), + position: None, + } + } + #[inline] + pub fn get_initial_position_value() -> SpecifiedValue { + use values::specified::{LengthOrPercentage, Percentage}; + VerticalPosition { + keyword: None, + position: Some(LengthOrPercentage::Percentage(Percentage(0.0))), } } pub fn parse(context: &ParserContext, input: &mut Parser) -> Result<SpecifiedValue, ()> { - Ok(try!(Position::parse(context, input))) + VerticalPosition::parse(context, input) } </%helpers:vector_longhand> diff --git a/components/style/properties/longhand/box.mako.rs b/components/style/properties/longhand/box.mako.rs index 818ed9316e1..a47b7d590a2 100644 --- a/components/style/properties/longhand/box.mako.rs +++ b/components/style/properties/longhand/box.mako.rs @@ -18,8 +18,7 @@ values = """inline block inline-block table inline-table table-row-group table-header-group table-footer-group table-row table-column-group table-column table-cell table-caption - list-item flex - none + list-item flex none """.split() if product == "gecko": values += """inline-flex grid inline-grid ruby ruby-base ruby-base-container @@ -1560,3 +1559,11 @@ ${helpers.predefined_type("-moz-binding", "UrlOrNone", "Either::Second(None_)", products="gecko", animatable="False", disable_when_testing="True")} + +// Non-standard: https://developer.mozilla.org/en-US/docs/Web/CSS/-moz-orient +${helpers.single_keyword("-moz-orient", + "inline block horizontal vertical", + products="gecko", + gecko_ffi_name="mOrient", + gecko_enum_prefix="StyleOrient", + animatable=False)} diff --git a/components/style/properties/longhand/column.mako.rs b/components/style/properties/longhand/column.mako.rs index a9e0880664e..ef2802be00d 100644 --- a/components/style/properties/longhand/column.mako.rs +++ b/components/style/properties/longhand/column.mako.rs @@ -96,92 +96,18 @@ ${helpers.predefined_type("column-width", </%helpers:longhand> // FIXME: This prop should be animatable. -<%helpers:longhand name="column-gap" experimental="True" animatable="False"> - use std::fmt; - use style_traits::ToCss; - use values::HasViewportPercentage; - - impl HasViewportPercentage for SpecifiedValue { - fn has_viewport_percentage(&self) -> bool { - match *self { - SpecifiedValue::Specified(length) => length.has_viewport_percentage(), - _ => false - } - } - } - - #[derive(Debug, Clone, Copy, PartialEq)] - #[cfg_attr(feature = "servo", derive(HeapSizeOf))] - pub enum SpecifiedValue { - Normal, - Specified(specified::Length), - } - - impl ToCss for SpecifiedValue { - fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write { - match *self { - SpecifiedValue::Normal => dest.write_str("normal"), - SpecifiedValue::Specified(l) => l.to_css(dest), - } - } - } - - pub mod computed_value { - use app_units::Au; - #[derive(Debug, Clone, PartialEq)] - #[cfg_attr(feature = "servo", derive(HeapSizeOf))] - pub struct T(pub Option<Au>); - } - - impl ToCss for computed_value::T { - fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write { - match self.0 { - None => dest.write_str("normal"), - Some(l) => l.to_css(dest), - } - } - } - - #[inline] - pub fn get_initial_value() -> computed_value::T { - computed_value::T(None) - } - - impl ToComputedValue for SpecifiedValue { - type ComputedValue = computed_value::T; - - #[inline] - fn to_computed_value(&self, context: &Context) -> computed_value::T { - match *self { - SpecifiedValue::Normal => computed_value::T(None), - SpecifiedValue::Specified(l) => - computed_value::T(Some(l.to_computed_value(context))) - } - } - #[inline] - fn from_computed_value(computed: &computed_value::T) -> Self { - match *computed { - computed_value::T(None) => SpecifiedValue::Normal, - computed_value::T(Some(l)) => - SpecifiedValue::Specified(ToComputedValue::from_computed_value(&l)) - } - } - } - - pub fn parse(_context: &ParserContext, input: &mut Parser) -> Result<SpecifiedValue, ()> { - if input.try(|input| input.expect_ident_matching("normal")).is_ok() { - Ok(SpecifiedValue::Normal) - } else { - specified::Length::parse_non_negative(input).map(SpecifiedValue::Specified) - } - } -</%helpers:longhand> +${helpers.predefined_type("column-gap", + "length::LengthOrNormal", + "Either::Second(Normal)", + parse_method='parse_non_negative_length', + experimental=True, + animatable=False)} ${helpers.single_keyword("column-fill", "auto balance", products="gecko", animatable=False)} // https://drafts.csswg.org/css-multicol-1/#propdef-column-rule-width -<%helpers:longhand name="-moz-column-rule-width" products="gecko" animatable="True"> +<%helpers:longhand name="column-rule-width" products="gecko" animatable="True"> use app_units::Au; use std::fmt; use style_traits::ToCss; @@ -211,19 +137,18 @@ ${helpers.single_keyword("column-fill", "auto balance", </%helpers:longhand> // https://drafts.csswg.org/css-multicol-1/#crc -${helpers.predefined_type("-moz-column-rule-color", "CSSColor", +${helpers.predefined_type("column-rule-color", "CSSColor", "::cssparser::Color::CurrentColor", - products="gecko", gecko_ffi_name="mColumnRuleColor", - animatable=True, complex_color=True, need_clone=True)} + products="gecko", animatable=True, + complex_color=True, need_clone=True)} // It's not implemented in servo or gecko yet. // https://drafts.csswg.org/css-multicol-1/#column-span ${helpers.single_keyword("column-span", "none all", products="none", animatable=False)} -${helpers.single_keyword("-moz-column-rule-style", +${helpers.single_keyword("column-rule-style", "none hidden dotted dashed solid double groove ridge inset outset", products="gecko", - gecko_ffi_name="mColumnRuleStyle", gecko_constant_prefix="NS_STYLE_BORDER_STYLE", animatable=False)} diff --git a/components/style/properties/longhand/effects.mako.rs b/components/style/properties/longhand/effects.mako.rs index 2ce79bea20c..718c447e6c8 100644 --- a/components/style/properties/longhand/effects.mako.rs +++ b/components/style/properties/longhand/effects.mako.rs @@ -18,25 +18,7 @@ ${helpers.predefined_type("opacity", use style_traits::ToCss; use values::HasViewportPercentage; - #[derive(Debug, Clone, PartialEq)] - #[cfg_attr(feature = "servo", derive(HeapSizeOf))] - pub struct SpecifiedValue { - pub offset_x: specified::Length, - pub offset_y: specified::Length, - pub blur_radius: specified::Length, - pub spread_radius: specified::Length, - pub color: Option<specified::CSSColor>, - pub inset: bool, - } - - impl HasViewportPercentage for SpecifiedValue { - fn has_viewport_percentage(&self) -> bool { - self.offset_x.has_viewport_percentage() || - self.offset_y.has_viewport_percentage() || - self.blur_radius.has_viewport_percentage() || - self.spread_radius.has_viewport_percentage() - } - } + pub type SpecifiedValue = specified::Shadow; impl ToCss for SpecifiedValue { fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write { @@ -63,17 +45,9 @@ ${helpers.predefined_type("opacity", use app_units::Au; use std::fmt; use values::computed; + use values::computed::Shadow; - #[derive(Clone, PartialEq, Copy, Debug)] - #[cfg_attr(feature = "servo", derive(HeapSizeOf))] - pub struct T { - pub offset_x: Au, - pub offset_y: Au, - pub blur_radius: Au, - pub spread_radius: Au, - pub color: computed::CSSColor, - pub inset: bool, - } + pub type T = Shadow; } impl ToCss for computed_value::T { @@ -94,95 +68,8 @@ ${helpers.predefined_type("opacity", } } - impl ToComputedValue for SpecifiedValue { - type ComputedValue = computed_value::T; - - #[inline] - fn to_computed_value(&self, context: &Context) -> computed_value::T { - computed_value::T { - offset_x: self.offset_x.to_computed_value(context), - offset_y: self.offset_y.to_computed_value(context), - blur_radius: self.blur_radius.to_computed_value(context), - spread_radius: self.spread_radius.to_computed_value(context), - color: self.color - .as_ref() - .map(|color| color.parsed) - .unwrap_or(cssparser::Color::CurrentColor), - inset: self.inset, - } - } - - #[inline] - fn from_computed_value(computed: &computed_value::T) -> Self { - SpecifiedValue { - offset_x: ToComputedValue::from_computed_value(&computed.offset_x), - offset_y: ToComputedValue::from_computed_value(&computed.offset_y), - blur_radius: ToComputedValue::from_computed_value(&computed.blur_radius), - spread_radius: ToComputedValue::from_computed_value(&computed.spread_radius), - color: Some(ToComputedValue::from_computed_value(&computed.color)), - inset: computed.inset, - } - } - } - - pub fn parse(context: &ParserContext, input: &mut Parser) -> Result<SpecifiedValue, ()> { - use app_units::Au; - let mut lengths = [specified::Length::Absolute(Au(0)); 4]; - let mut lengths_parsed = false; - let mut color = None; - let mut inset = false; - - loop { - if !inset { - if input.try(|input| input.expect_ident_matching("inset")).is_ok() { - inset = true; - continue - } - } - if !lengths_parsed { - if let Ok(value) = input.try(|i| specified::Length::parse(context, i)) { - lengths[0] = value; - let mut length_parsed_count = 1; - while length_parsed_count < 4 { - if let Ok(value) = input.try(|i| specified::Length::parse(context, i)) { - lengths[length_parsed_count] = value - } else { - break - } - length_parsed_count += 1; - } - - // The first two lengths must be specified. - if length_parsed_count < 2 { - return Err(()) - } - - lengths_parsed = true; - continue - } - } - if color.is_none() { - if let Ok(value) = input.try(|i| specified::CSSColor::parse(context, i)) { - color = Some(value); - continue - } - } - break - } - - // Lengths must be specified. - if !lengths_parsed { - return Err(()) - } - - Ok(SpecifiedValue { - offset_x: lengths[0], - offset_y: lengths[1], - blur_radius: lengths[2], - spread_radius: lengths[3], - color: color, - inset: inset, - }) + pub fn parse(context: &ParserContext, input: &mut Parser) -> Result<specified::Shadow, ()> { + specified::Shadow::parse(context, input, false) } </%helpers:vector_longhand> @@ -406,7 +293,7 @@ ${helpers.predefined_type("opacity", use std::fmt; use style_traits::{self, ToCss}; use values::{CSSFloat, HasViewportPercentage}; - use values::specified::{Angle, CSSColor, Length}; + use values::specified::{Angle, CSSColor, Length, Shadow}; impl HasViewportPercentage for SpecifiedValue { fn has_viewport_percentage(&self) -> bool { @@ -442,14 +329,14 @@ ${helpers.predefined_type("opacity", Saturate(CSSFloat), Sepia(CSSFloat), % if product == "gecko": - DropShadow(Length, Length, Length, Option<CSSColor>), + DropShadow(Shadow), % endif } pub mod computed_value { use app_units::Au; use values::CSSFloat; - use values::computed::CSSColor; + use values::computed::{CSSColor, Shadow}; use values::specified::{Angle}; #[derive(Clone, PartialEq, Debug)] @@ -465,7 +352,7 @@ ${helpers.predefined_type("opacity", Saturate(CSSFloat), Sepia(CSSFloat), % if product == "gecko": - DropShadow(Au, Au, Au, CSSColor), + DropShadow(Shadow), % endif } @@ -565,15 +452,15 @@ ${helpers.predefined_type("opacity", computed_value::Filter::Saturate(value) => try!(write!(dest, "saturate({})", value)), computed_value::Filter::Sepia(value) => try!(write!(dest, "sepia({})", value)), % if product == "gecko": - computed_value::Filter::DropShadow(offset_x, offset_y, blur_radius, ref color) => { + computed_value::Filter::DropShadow(shadow) => { try!(dest.write_str("drop-shadow(")); - try!(offset_x.to_css(dest)); + try!(shadow.offset_x.to_css(dest)); try!(dest.write_str(", ")); - try!(offset_y.to_css(dest)); + try!(shadow.offset_y.to_css(dest)); try!(dest.write_str(", ")); - try!(blur_radius.to_css(dest)); + try!(shadow.blur_radius.to_css(dest)); try!(dest.write_str(", ")); - try!(color.to_css(dest)); + try!(shadow.color.to_css(dest)); try!(dest.write_str(")")); } % endif @@ -603,14 +490,14 @@ ${helpers.predefined_type("opacity", SpecifiedFilter::Saturate(value) => try!(write!(dest, "saturate({})", value)), SpecifiedFilter::Sepia(value) => try!(write!(dest, "sepia({})", value)), % if product == "gecko": - SpecifiedFilter::DropShadow(offset_x, offset_y, blur_radius, ref color) => { + SpecifiedFilter::DropShadow(ref shadow) => { try!(dest.write_str("drop-shadow(")); - try!(offset_x.to_css(dest)); + try!(shadow.offset_x.to_css(dest)); try!(dest.write_str(", ")); - try!(offset_y.to_css(dest)); + try!(shadow.offset_y.to_css(dest)); try!(dest.write_str(", ")); - try!(blur_radius.to_css(dest)); - if let &Some(ref color) = color { + try!(shadow.blur_radius.to_css(dest)); + if let Some(ref color) = shadow.color { try!(dest.write_str(", ")); try!(color.to_css(dest)); } @@ -646,7 +533,8 @@ ${helpers.predefined_type("opacity", "saturate" => parse_factor(input).map(SpecifiedFilter::Saturate), "sepia" => parse_factor(input).map(SpecifiedFilter::Sepia), % if product == "gecko": - "drop-shadow" => parse_drop_shadow(context, input), + "drop-shadow" => specified::Shadow::parse(context, input, true) + .map(SpecifiedFilter::DropShadow), % endif _ => Err(()) } @@ -668,17 +556,6 @@ ${helpers.predefined_type("opacity", } } - % if product == "gecko": - fn parse_drop_shadow(context: &ParserContext, input: &mut Parser) -> Result<SpecifiedFilter, ()> { - let offset_x = try!(specified::Length::parse(context, input)); - let offset_y = try!(specified::Length::parse(context, input)); - let blur_radius = input.try(|i| specified::Length::parse(context, i)) - .unwrap_or(specified::Length::from_px(0.0)); - let color = input.try(|i| specified::CSSColor::parse(context, i)).ok(); - Ok(SpecifiedFilter::DropShadow(offset_x, offset_y, blur_radius, color)) - } - % endif - impl ToComputedValue for SpecifiedValue { type ComputedValue = computed_value::T; @@ -696,16 +573,9 @@ ${helpers.predefined_type("opacity", SpecifiedFilter::Saturate(factor) => computed_value::Filter::Saturate(factor), SpecifiedFilter::Sepia(factor) => computed_value::Filter::Sepia(factor), % if product == "gecko": - SpecifiedFilter::DropShadow(offset_x, offset_y, blur_radius, ref color) => { - computed_value::Filter::DropShadow( - offset_x.to_computed_value(context), - offset_y.to_computed_value(context), - blur_radius.to_computed_value(context), - color.as_ref() - .map(|color| color.parsed) - .unwrap_or(cssparser::Color::CurrentColor), - ) - } + SpecifiedFilter::DropShadow(ref shadow) => { + computed_value::Filter::DropShadow(shadow.to_computed_value(context)) + }, % endif } }).collect() } @@ -725,12 +595,9 @@ ${helpers.predefined_type("opacity", computed_value::Filter::Saturate(factor) => SpecifiedFilter::Saturate(factor), computed_value::Filter::Sepia(factor) => SpecifiedFilter::Sepia(factor), % if product == "gecko": - computed_value::Filter::DropShadow(offset_x, offset_y, blur_radius, color) => { + computed_value::Filter::DropShadow(shadow) => { SpecifiedFilter::DropShadow( - ToComputedValue::from_computed_value(&offset_x), - ToComputedValue::from_computed_value(&offset_y), - ToComputedValue::from_computed_value(&blur_radius), - Some(ToComputedValue::from_computed_value(&color)), + ToComputedValue::from_computed_value(&shadow), ) } % endif diff --git a/components/style/properties/longhand/font.mako.rs b/components/style/properties/longhand/font.mako.rs index 17cd56a3163..ee9ae6a4470 100644 --- a/components/style/properties/longhand/font.mako.rs +++ b/components/style/properties/longhand/font.mako.rs @@ -140,6 +140,21 @@ ${helpers.single_keyword("font-variant", "normal small-caps", animatable=False)} + +<% font_variant_caps_custom_consts= { "small-caps": "SMALLCAPS", + "all-small": "ALLSMALL", + "petite-caps": "PETITECAPS", + "all-petite": "ALLPETITE", + "titling-caps": "TITLING" } %> + +${helpers.single_keyword("font-variant-caps", + "normal small-caps all-small petite-caps unicase titling-caps", + gecko_constant_prefix="NS_FONT_VARIANT_CAPS", + gecko_ffi_name="mFont.variantCaps", + products="gecko", + custom_consts=font_variant_caps_custom_consts, + animatable=False)} + <%helpers:longhand name="font-weight" need_clone="True" animatable="True"> use std::fmt; use style_traits::ToCss; diff --git a/components/style/properties/longhand/inherited_box.mako.rs b/components/style/properties/longhand/inherited_box.mako.rs index 15b65ee418d..7eca5ab0ee5 100644 --- a/components/style/properties/longhand/inherited_box.mako.rs +++ b/components/style/properties/longhand/inherited_box.mako.rs @@ -50,6 +50,139 @@ ${helpers.single_keyword("image-rendering", custom_consts=image_rendering_custom_consts, animatable=False)} +// Image Orientation +// https://drafts.csswg.org/css-images/#the-image-orientation +<%helpers:longhand name="image-orientation" + products="None" + animatable="False"> + use std::fmt; + use style_traits::ToCss; + use values::specified::Angle; + + use values::NoViewportPercentage; + impl NoViewportPercentage for SpecifiedValue {} + + use std::f32::consts::PI; + use values::CSSFloat; + const TWO_PI: CSSFloat = 2.0*PI; + + #[derive(Clone, PartialEq, Copy, Debug)] + #[cfg_attr(feature = "servo", derive(HeapSizeOf))] + pub struct SpecifiedValue { + pub angle: Option<Angle>, + pub flipped: bool + } + + impl ToCss for SpecifiedValue { + fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write { + if let Some(angle) = self.angle { + try!(angle.to_css(dest)); + if self.flipped { + dest.write_str(" flipped") + } else { + Ok(()) + } + } else { + if self.flipped { + dest.write_str("flipped") + } else { + dest.write_str("from-image") + } + } + } + } + + pub mod computed_value { + use values::specified::Angle; + + #[derive(Clone, PartialEq, Copy, Debug)] + #[cfg_attr(feature = "servo", derive(HeapSizeOf))] + pub enum T { + FromImage, + AngleWithFlipped(Angle, bool), + } + } + + const INITIAL_ANGLE: Angle = Angle(0.0); + + #[inline] + pub fn get_initial_value() -> computed_value::T { + computed_value::T::AngleWithFlipped(INITIAL_ANGLE, false) + } + + // According to CSS Content Module Level 3: + // The computed value of the property is calculated by rounding the specified angle + // to the nearest quarter-turn, rounding away from 0, then moduloing the value by 1 turn. + #[inline] + fn normalize_angle(angle: &Angle) -> Angle { + let radians = angle.radians(); + let rounded_quarter_turns = (4.0 * radians / TWO_PI).round(); + let normalized_quarter_turns = (rounded_quarter_turns % 4.0 + 4.0) % 4.0; + let normalized_radians = normalized_quarter_turns/4.0 * TWO_PI; + Angle::from_radians(normalized_radians) + } + + impl ToComputedValue for SpecifiedValue { + type ComputedValue = computed_value::T; + + #[inline] + fn to_computed_value(&self, _: &Context) -> computed_value::T { + if let Some(ref angle) = self.angle { + let normalized_angle = normalize_angle(angle); + computed_value::T::AngleWithFlipped(normalized_angle, self.flipped) + } else { + if self.flipped { + computed_value::T::AngleWithFlipped(INITIAL_ANGLE, true) + } else { + computed_value::T::FromImage + } + } + } + + #[inline] + fn from_computed_value(computed: &computed_value::T) -> Self { + match *computed { + computed_value::T::FromImage => SpecifiedValue { angle: None, flipped: false }, + computed_value::T::AngleWithFlipped(angle, flipped) => + SpecifiedValue { angle: Some(angle), flipped: flipped }, + } + } + } + + impl ToCss for computed_value::T { + fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write { + match *self { + computed_value::T::FromImage => dest.write_str("from-image"), + computed_value::T::AngleWithFlipped(angle, flipped) => { + try!(angle.to_css(dest)); + if flipped { + try!(dest.write_str(" flipped")); + } + Ok(()) + }, + } + } + } + + pub fn parse(context: &ParserContext, input: &mut Parser) -> Result<SpecifiedValue, ()> { + if input.try(|input| input.expect_ident_matching("from-image")).is_ok() { + // Handle from-image + Ok(SpecifiedValue { angle: None, flipped: false }) + } else { + // Handle <angle> | <angle>? flip + let angle = input.try(|input| Angle::parse(context, input)).ok(); + let flipped = input.try(|input| input.expect_ident_matching("flip")).is_ok(); + let explicit_angle = if angle.is_none() && !flipped { + Some(INITIAL_ANGLE) + } else { + angle + }; + + Ok(SpecifiedValue { angle: explicit_angle, flipped: flipped }) + } + } +</%helpers:longhand> + // Used in the bottom-up flow construction traversal to avoid constructing flows for // descendants of nodes with `display: none`. <%helpers:longhand name="-servo-under-display-none" diff --git a/components/style/properties/longhand/list.mako.rs b/components/style/properties/longhand/list.mako.rs index d979685101d..b62e7222cb8 100644 --- a/components/style/properties/longhand/list.mako.rs +++ b/components/style/properties/longhand/list.mako.rs @@ -17,12 +17,12 @@ ${helpers.single_keyword("list-style-position", "outside inside", animatable=Fal // // [1]: http://dev.w3.org/csswg/css-counter-styles/ ${helpers.single_keyword("list-style-type", """ - disc none circle square decimal lower-alpha upper-alpha disclosure-open disclosure-closed + disc none circle square decimal disclosure-open disclosure-closed """, extra_servo_values="""arabic-indic bengali cambodian cjk-decimal devanagari gujarati gurmukhi kannada khmer lao malayalam mongolian myanmar oriya persian telugu thai tibetan cjk-earthly-branch cjk-heavenly-stem lower-greek hiragana hiragana-iroha katakana - katakana-iroha""", + katakana-iroha lower-alpha upper-alpha""", gecko_constant_prefix="NS_STYLE_LIST_STYLE", animatable=False)} diff --git a/components/style/properties/longhand/position.mako.rs b/components/style/properties/longhand/position.mako.rs index 529dce1e9d0..f025e658c5b 100644 --- a/components/style/properties/longhand/position.mako.rs +++ b/components/style/properties/longhand/position.mako.rs @@ -2,6 +2,7 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ +<%! from data import to_rust_ident %> <%namespace name="helpers" file="/helpers.mako.rs" /> <% from data import ALL_SIZES, PHYSICAL_SIDES, LOGICAL_SIDES %> @@ -180,3 +181,14 @@ ${helpers.single_keyword("box-sizing", // https://drafts.csswg.org/css-images-3/ ${helpers.single_keyword("object-fit", "fill contain cover none scale-down", products="gecko", animatable=False)} + +// https://drafts.csswg.org/css-grid/#propdef-grid-row-start +<% grid_longhands = ["grid-row-start", "grid-row-end", "grid-column-start", "grid-column-end"] %> + +% for longhand in grid_longhands: + ${helpers.predefined_type("%s" % longhand, + "GridLine", + "Default::default()", + animatable=False, + products="gecko")} +% endfor diff --git a/components/style/properties/longhand/svg.mako.rs b/components/style/properties/longhand/svg.mako.rs index a0d107f6326..dcab70f6b34 100644 --- a/components/style/properties/longhand/svg.mako.rs +++ b/components/style/properties/longhand/svg.mako.rs @@ -91,21 +91,59 @@ ${helpers.single_keyword("mask-repeat", products="gecko", animatable=False)} -<%helpers:longhand name="mask-position" products="gecko" animatable="True"> - use properties::longhands::background_position; - pub use ::properties::longhands::background_position::SpecifiedValue; - pub use ::properties::longhands::background_position::single_value as single_value; - pub use ::properties::longhands::background_position::computed_value as computed_value; +<%helpers:vector_longhand name="mask-position" products="gecko" animatable="True"> + use std::fmt; + use style_traits::ToCss; + use values::HasViewportPercentage; + use values::specified::position::Position; + + pub mod computed_value { + use values::computed::position::Position; + use properties::animated_properties::{Interpolate, RepeatableListInterpolate}; + use properties::longhands::mask_position::computed_value::T as MaskPosition; + + pub type T = Position; + + impl RepeatableListInterpolate for MaskPosition {} + + impl Interpolate for MaskPosition { + fn interpolate(&self, other: &Self, progress: f64) -> Result<Self, ()> { + Ok(MaskPosition(try!(self.0.interpolate(&other.0, progress)))) + } + } + } + + pub type SpecifiedValue = Position; #[inline] pub fn get_initial_value() -> computed_value::T { - background_position::get_initial_value() + use values::computed::position::Position; + Position { + horizontal: computed::LengthOrPercentage::Percentage(0.0), + vertical: computed::LengthOrPercentage::Percentage(0.0), + } + } + #[inline] + pub fn get_initial_specified_value() -> SpecifiedValue { + use values::specified::Percentage; + use values::specified::position::{HorizontalPosition, VerticalPosition}; + Position { + horizontal: HorizontalPosition { + keyword: None, + position: Some(specified::LengthOrPercentage::Percentage(Percentage(0.0))), + }, + vertical: VerticalPosition { + keyword: None, + position: Some(specified::LengthOrPercentage::Percentage(Percentage(0.0))), + }, + } } - pub fn parse(context: &ParserContext, input: &mut Parser) -> Result<SpecifiedValue, ()> { - background_position::parse(context, input) + pub fn parse(context: &ParserContext, input: &mut Parser) + -> Result<SpecifiedValue, ()> { + Position::parse(context, input) } -</%helpers:longhand> +</%helpers:vector_longhand> // missing: margin-box fill-box stroke-box view-box no-clip // (gecko doesn't implement these) diff --git a/components/style/properties/properties.mako.rs b/components/style/properties/properties.mako.rs index 46688434651..fbd3c611143 100644 --- a/components/style/properties/properties.mako.rs +++ b/components/style/properties/properties.mako.rs @@ -10,13 +10,12 @@ <%namespace name="helpers" file="/helpers.mako.rs" /> -use std::ascii::AsciiExt; +use std::borrow::Cow; use std::boxed::Box as StdBox; use std::collections::HashSet; use std::fmt::{self, Write}; use std::sync::Arc; -use Atom; use app_units::Au; #[cfg(feature = "servo")] use cssparser::{Color as CSSParserColor, RGBA}; use cssparser::{Parser, TokenSerializationType}; @@ -25,9 +24,11 @@ use error_reporting::ParseErrorReporter; use euclid::size::Size2D; use computed_values; use font_metrics::FontMetricsProvider; +#[cfg(feature = "gecko")] use gecko_bindings::structs::nsCSSPropertyID; #[cfg(feature = "servo")] use logical_geometry::{LogicalMargin, PhysicalSide}; use logical_geometry::WritingMode; use parser::{Parse, ParserContext, ParserContextExtraData}; +#[cfg(feature = "servo")] use servo_config::prefs::PREFS; use servo_url::ServoUrl; use style_traits::ToCss; use stylesheets::Origin; @@ -40,6 +41,12 @@ use rule_tree::StrongRuleNode; use self::property_bit_field::PropertyBitField; pub use self::declaration_block::*; +#[cfg(feature = "gecko")] +#[macro_export] +macro_rules! property_name { + ($s: tt) => { atom!($s) } +} + <%! from data import Method, Keyword, to_rust_ident import os.path @@ -83,6 +90,14 @@ pub mod shorthands { use parser::{Parse, ParserContext}; use values::specified; + bitflags! { + flags SerializeFlags: u8 { + const ALL_INHERIT = 0b001, + const ALL_INITIAL = 0b010, + const ALL_UNSET = 0b100, + } + } + pub fn parse_four_sides<F, T>(input: &mut Parser, parse_one: F) -> Result<(T, T, T, T), ()> where F: Fn(&mut Parser) -> Result<T, ()>, T: Clone { @@ -242,7 +257,7 @@ mod property_bit_field { css: &String, first_token_type: TokenSerializationType, base_url: &ServoUrl, - from_shorthand: Option<Shorthand>, + from_shorthand: Option<ShorthandId>, custom_properties: &Option<Arc<::custom_properties::ComputedValuesMap>>, f: F, error_reporter: &mut StdBox<ParseErrorReporter + Send>, @@ -265,7 +280,7 @@ mod property_bit_field { } % for shorthand in data.shorthands: % if property in shorthand.sub_properties: - Some(Shorthand::${shorthand.camel_case}) => { + Some(ShorthandId::${shorthand.camel_case}) => { shorthands::${shorthand.ident}::parse_value(&context, input) .map(|result| match result.${property.ident} { Some(value) => DeclaredValue::Value(value), @@ -378,41 +393,56 @@ impl Parse for CSSWideKeyword { #[derive(Clone, Copy, Eq, PartialEq, Debug)] #[cfg_attr(feature = "servo", derive(HeapSizeOf))] -pub enum Shorthand { - % for property in data.shorthands: - ${property.camel_case}, +pub enum LonghandId { + % for i, property in enumerate(data.longhands): + ${property.camel_case} = ${i}, % endfor } -impl Shorthand { - pub fn from_name(name: &str) -> Option<Shorthand> { - match_ignore_ascii_case! { name, - % for property in data.shorthands: - "${property.name}" => Some(Shorthand::${property.camel_case}), +impl LonghandId { + pub fn name(&self) -> &'static str { + match *self { + % for property in data.longhands: + LonghandId::${property.camel_case} => "${property.name}", % endfor - _ => None } } +} + +#[derive(Clone, Copy, Eq, PartialEq, Debug)] +#[cfg_attr(feature = "servo", derive(HeapSizeOf))] +pub enum ShorthandId { + % for property in data.shorthands: + ${property.camel_case}, + % endfor +} + +impl ToCss for ShorthandId { + fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write { + dest.write_str(self.name()) + } +} +impl ShorthandId { pub fn name(&self) -> &'static str { match *self { % for property in data.shorthands: - Shorthand::${property.camel_case} => "${property.name}", + ShorthandId::${property.camel_case} => "${property.name}", % endfor } } - pub fn longhands(&self) -> &'static [&'static str] { + pub fn longhands(&self) -> &'static [LonghandId] { % for property in data.shorthands: - static ${property.ident.upper()}: &'static [&'static str] = &[ + static ${property.ident.upper()}: &'static [LonghandId] = &[ % for sub in property.sub_properties: - "${sub.name}", + LonghandId::${sub.camel_case}, % endfor ]; % endfor match *self { % for property in data.shorthands: - Shorthand::${property.camel_case} => ${property.ident.upper()}, + ShorthandId::${property.camel_case} => ${property.ident.upper()}, % endfor } } @@ -421,7 +451,7 @@ impl Shorthand { where W: fmt::Write, I: Iterator<Item=&'a PropertyDeclaration> { match *self { % for property in data.shorthands: - Shorthand::${property.camel_case} => { + ShorthandId::${property.camel_case} => { match shorthands::${property.ident}::LonghandsToSerialize::from_iter(declarations) { Ok(longhands) => longhands.to_css(dest), Err(_) => Err(fmt::Error) @@ -443,11 +473,9 @@ impl Shorthand { match self.get_shorthand_appendable_value(declarations) { None => Ok(false), Some(appendable_value) => { - let property_name = self.name(); - append_serialization( dest, - property_name, + &self, appendable_value, importance, is_first_serialization @@ -496,13 +524,11 @@ pub enum DeclaredValue<T> { css: String, first_token_type: TokenSerializationType, base_url: ServoUrl, - from_shorthand: Option<Shorthand>, + from_shorthand: Option<ShorthandId>, }, Initial, Inherit, - // There is no Unset variant here. - // The 'unset' keyword is represented as either Initial or Inherit, - // depending on whether the property is inherited. + Unset, } impl<T: HasViewportPercentage> HasViewportPercentage for DeclaredValue<T> { @@ -513,7 +539,8 @@ impl<T: HasViewportPercentage> HasViewportPercentage for DeclaredValue<T> { DeclaredValue::WithVariables { .. } => panic!("DeclaredValue::has_viewport_percentage without resolving variables!"), DeclaredValue::Initial | - DeclaredValue::Inherit => false, + DeclaredValue::Inherit | + DeclaredValue::Unset => false, } } } @@ -529,6 +556,130 @@ impl<T: ToCss> ToCss for DeclaredValue<T> { DeclaredValue::WithVariables { .. } => Ok(()), DeclaredValue::Initial => dest.write_str("initial"), DeclaredValue::Inherit => dest.write_str("inherit"), + DeclaredValue::Unset => dest.write_str("unset"), + } + } +} + +#[derive(PartialEq, Clone)] +#[cfg_attr(feature = "servo", derive(HeapSizeOf))] +pub enum PropertyDeclarationId<'a> { + Longhand(LonghandId), + Custom(&'a ::custom_properties::Name), +} + +impl<'a> ToCss for PropertyDeclarationId<'a> { + fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write { + match *self { + PropertyDeclarationId::Longhand(id) => dest.write_str(id.name()), + PropertyDeclarationId::Custom(name) => write!(dest, "--{}", name), + } + } +} + +impl<'a> PropertyDeclarationId<'a> { + pub fn is_or_is_longhand_of(&self, other: &PropertyId) -> bool { + match *self { + PropertyDeclarationId::Longhand(id) => { + match *other { + PropertyId::Longhand(other_id) => id == other_id, + PropertyId::Shorthand(shorthand) => shorthand.longhands().contains(&id), + PropertyId::Custom(_) => false, + } + } + PropertyDeclarationId::Custom(name) => { + matches!(*other, PropertyId::Custom(ref other_name) if name == other_name) + } + } + } + + pub fn is_longhand_of(&self, shorthand: ShorthandId) -> bool { + match *self { + PropertyDeclarationId::Longhand(ref id) => shorthand.longhands().contains(id), + _ => false, + } + } +} + +#[derive(Eq, PartialEq, Clone)] +pub enum PropertyId { + Longhand(LonghandId), + Shorthand(ShorthandId), + Custom(::custom_properties::Name), +} + +impl fmt::Debug for PropertyId { + fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + self.to_css(formatter) + } +} + +impl ToCss for PropertyId { + fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write { + match *self { + PropertyId::Longhand(id) => dest.write_str(id.name()), + PropertyId::Shorthand(id) => dest.write_str(id.name()), + PropertyId::Custom(ref name) => write!(dest, "--{}", name), + } + } +} + +// FIXME(https://github.com/rust-lang/rust/issues/33156): remove this enum and use PropertyId +// when stable Rust allows destructors in statics. +enum StaticId { + Longhand(LonghandId), + Shorthand(ShorthandId), +} +include!(concat!(env!("OUT_DIR"), "/static_ids.rs")); + +impl PropertyId { + /// Returns Err(()) for unknown non-custom properties + pub fn parse(s: Cow<str>) -> Result<Self, ()> { + if let Ok(name) = ::custom_properties::parse_name(&s) { + return Ok(PropertyId::Custom(::custom_properties::Name::from(name))) + } + + let lower_case = ::str::cow_into_ascii_lowercase(s); + match STATIC_IDS.get(&*lower_case) { + Some(&StaticId::Longhand(id)) => Ok(PropertyId::Longhand(id)), + Some(&StaticId::Shorthand(id)) => Ok(PropertyId::Shorthand(id)), + None => Err(()), + } + } + + #[cfg(feature = "gecko")] + #[allow(non_upper_case_globals)] + pub fn from_nscsspropertyid(id: nsCSSPropertyID) -> Result<Self, ()> { + use gecko_bindings::structs::*; + <% + def to_nscsspropertyid(ident): + if ident == "word_wrap": + return "nsCSSPropertyID_eCSSPropertyAlias_WordWrap" + + if ident == "float": + ident = "float_" + return "nsCSSPropertyID::eCSSProperty_" + ident + %> + match id { + % for property in data.longhands: + ${to_nscsspropertyid(property.ident)} => { + Ok(PropertyId::Longhand(LonghandId::${property.camel_case})) + } + % endfor + % for property in data.shorthands: + ${to_nscsspropertyid(property.ident)} => { + Ok(PropertyId::Shorthand(ShorthandId::${property.camel_case})) + } + % endfor + _ => Err(()) + } + } + + pub fn as_shorthand(&self) -> Result<ShorthandId, PropertyDeclarationId> { + match *self { + PropertyId::Shorthand(id) => Ok(id), + PropertyId::Longhand(id) => Err(PropertyDeclarationId::Longhand(id)), + PropertyId::Custom(ref name) => Err(PropertyDeclarationId::Custom(name)), } } } @@ -566,51 +717,10 @@ pub enum PropertyDeclarationParseResult { ValidOrIgnoredDeclaration, } -#[derive(Eq, PartialEq, Clone)] -pub enum PropertyDeclarationName { - Longhand(&'static str), - Custom(::custom_properties::Name), - Internal -} - -impl PropertyDeclarationName { - pub fn eq_str_ignore_ascii_case(&self, other: &str) -> bool { - match *self { - PropertyDeclarationName::Longhand(s) => s.eq_ignore_ascii_case(other), - PropertyDeclarationName::Custom(ref n) => n.eq_str_ignore_ascii_case(other), - PropertyDeclarationName::Internal => false - } - } -} - -impl PartialEq<str> for PropertyDeclarationName { - fn eq(&self, other: &str) -> bool { - match *self { - PropertyDeclarationName::Longhand(n) => n == other, - PropertyDeclarationName::Custom(ref n) => { - n.with_str(|s| ::custom_properties::parse_name(other) == Ok(s)) - } - PropertyDeclarationName::Internal => false, - } - } -} - -impl fmt::Display for PropertyDeclarationName { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - match *self { - PropertyDeclarationName::Longhand(n) => f.write_str(n), - PropertyDeclarationName::Custom(ref n) => { - try!(f.write_str("--")); - n.with_str(|s| f.write_str(s)) - } - PropertyDeclarationName::Internal => Ok(()), - } - } -} - impl fmt::Debug for PropertyDeclaration { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - try!(write!(f, "{}: ", self.name())); + try!(self.id().to_css(f)); + try!(f.write_str(": ")); match *self { % for property in data.longhands: % if not property.derived_from: @@ -643,45 +753,20 @@ impl ToCss for PropertyDeclaration { } impl PropertyDeclaration { - pub fn name(&self) -> PropertyDeclarationName { + pub fn id(&self) -> PropertyDeclarationId { match *self { % for property in data.longhands: - PropertyDeclaration::${property.camel_case}(..) => - % if not property.derived_from: - PropertyDeclarationName::Longhand("${property.name}"), - % else: - PropertyDeclarationName::Internal, - % endif + PropertyDeclaration::${property.camel_case}(..) => { + PropertyDeclarationId::Longhand(LonghandId::${property.camel_case}) + } % endfor PropertyDeclaration::Custom(ref name, _) => { - PropertyDeclarationName::Custom(name.clone()) + PropertyDeclarationId::Custom(name) } } } - #[inline] - pub fn discriminant_value(&self) -> usize { - match *self { - % for i, property in enumerate(data.longhands): - PropertyDeclaration::${property.camel_case}(..) => ${i}, - % endfor - PropertyDeclaration::Custom(..) => ${len(data.longhands)} - } - } - - pub fn value(&self) -> String { - let mut value = String::new(); - if let Err(_) = self.to_css(&mut value) { - panic!("unsupported property declaration: {}", self.name()); - } - - value - } - - /// If this is a pending-substitution value from the given shorthand, return that value - // Extra space here because < seems to be removed by Mako when immediately followed by &. - // ↓ - pub fn with_variables_from_shorthand(&self, shorthand: Shorthand) -> Option< &str> { + pub fn with_variables_from_shorthand(&self, shorthand: ShorthandId) -> Option< &str> { match *self { % for property in data.longhands: PropertyDeclaration::${property.camel_case}(ref value) => match *value { @@ -727,49 +812,34 @@ impl PropertyDeclaration { } } - pub fn matches(&self, name: &str) -> bool { - match *self { - % for property in data.longhands: - PropertyDeclaration::${property.camel_case}(..) => - % if not property.derived_from: - name.eq_ignore_ascii_case("${property.name}"), - % else: - false, - % endif - % endfor - PropertyDeclaration::Custom(ref declaration_name, _) => { - declaration_name.with_str(|s| ::custom_properties::parse_name(name) == Ok(s)) - } - } - } - /// The `in_keyframe_block` parameter controls this: /// /// https://drafts.csswg.org/css-animations/#keyframes /// > The <declaration-list> inside of <keyframe-block> accepts any CSS property /// > except those defined in this specification, /// > but does accept the `animation-play-state` property and interprets it specially. - pub fn parse(name: &str, context: &ParserContext, input: &mut Parser, + pub fn parse(id: PropertyId, context: &ParserContext, input: &mut Parser, result_list: &mut Vec<PropertyDeclaration>, in_keyframe_block: bool) -> PropertyDeclarationParseResult { - if let Ok(name) = ::custom_properties::parse_name(name) { - let value = match input.try(|i| CSSWideKeyword::parse(context, i)) { - Ok(CSSWideKeyword::UnsetKeyword) | // Custom properties are alawys inherited - Ok(CSSWideKeyword::InheritKeyword) => DeclaredValue::Inherit, - Ok(CSSWideKeyword::InitialKeyword) => DeclaredValue::Initial, - Err(()) => match ::custom_properties::SpecifiedValue::parse(context, input) { - Ok(value) => DeclaredValue::Value(value), - Err(()) => return PropertyDeclarationParseResult::InvalidValue, - } - }; - result_list.push(PropertyDeclaration::Custom(Atom::from(name), value)); - return PropertyDeclarationParseResult::ValidOrIgnoredDeclaration; - } - match_ignore_ascii_case! { name, + match id { + PropertyId::Custom(name) => { + let value = match input.try(|i| CSSWideKeyword::parse(context, i)) { + Ok(CSSWideKeyword::UnsetKeyword) => DeclaredValue::Unset, + Ok(CSSWideKeyword::InheritKeyword) => DeclaredValue::Inherit, + Ok(CSSWideKeyword::InitialKeyword) => DeclaredValue::Initial, + Err(()) => match ::custom_properties::SpecifiedValue::parse(context, input) { + Ok(value) => DeclaredValue::Value(value), + Err(()) => return PropertyDeclarationParseResult::InvalidValue, + } + }; + result_list.push(PropertyDeclaration::Custom(name, value)); + return PropertyDeclarationParseResult::ValidOrIgnoredDeclaration; + } + PropertyId::Longhand(id) => match id { % for property in data.longhands: - % if not property.derived_from: - "${property.name}" => { + LonghandId::${property.camel_case} => { + % if not property.derived_from: % if not property.allowed_in_keyframe_block: if in_keyframe_block { return PropertyDeclarationParseResult::AnimationPropertyInKeyframeBlock @@ -781,7 +851,7 @@ impl PropertyDeclaration { } % endif % if property.experimental and product == "servo": - if !::util::prefs::PREFS.get("${property.experimental}") + if !PREFS.get("${property.experimental}") .as_boolean().unwrap_or(false) { return PropertyDeclarationParseResult::ExperimentalProperty } @@ -793,13 +863,15 @@ impl PropertyDeclaration { }, Err(()) => PropertyDeclarationParseResult::InvalidValue, } - }, - % else: - "${property.name}" => PropertyDeclarationParseResult::UnknownProperty, - % endif + % else: + PropertyDeclarationParseResult::UnknownProperty + % endif + } % endfor + }, + PropertyId::Shorthand(id) => match id { % for shorthand in data.shorthands: - "${shorthand.name}" => { + ShorthandId::${shorthand.camel_case} => { % if not shorthand.allowed_in_keyframe_block: if in_keyframe_block { return PropertyDeclarationParseResult::AnimationPropertyInKeyframeBlock @@ -811,7 +883,7 @@ impl PropertyDeclaration { } % endif % if shorthand.experimental and product == "servo": - if !::util::prefs::PREFS.get("${shorthand.experimental}") + if !PREFS.get("${shorthand.experimental}") .as_boolean().unwrap_or(false) { return PropertyDeclarationParseResult::ExperimentalProperty } @@ -836,8 +908,7 @@ impl PropertyDeclaration { Ok(CSSWideKeyword::UnsetKeyword) => { % for sub_property in shorthand.sub_properties: result_list.push(PropertyDeclaration::${sub_property.camel_case}( - DeclaredValue::${"Inherit" if sub_property.style_struct.inherited else "Initial"} - )); + DeclaredValue::Unset)); % endfor PropertyDeclarationParseResult::ValidOrIgnoredDeclaration }, @@ -846,19 +917,13 @@ impl PropertyDeclaration { Err(()) => PropertyDeclarationParseResult::InvalidValue, } } - }, - % endfor - - _ => { - if cfg!(all(debug_assertions, feature = "gecko")) && !name.starts_with('-') { - println!("stylo: Unimplemented property setter: {}", name); } - PropertyDeclarationParseResult::UnknownProperty + % endfor } } } - pub fn shorthands(&self) -> &'static [Shorthand] { + pub fn shorthands(&self) -> &'static [ShorthandId] { // first generate longhand to shorthands lookup map <% longhand_to_shorthand_map = {} @@ -875,9 +940,9 @@ impl PropertyDeclaration { // based on lookup results for each longhand, create result arrays % for property in data.longhands: - static ${property.ident.upper()}: &'static [Shorthand] = &[ + static ${property.ident.upper()}: &'static [ShorthandId] = &[ % for shorthand in longhand_to_shorthand_map.get(property.ident, []): - Shorthand::${shorthand}, + ShorthandId::${shorthand}, % endfor ]; % endfor @@ -1138,6 +1203,8 @@ impl ComputedValues { self.custom_properties.as_ref().map(|x| x.clone()) } + pub fn has_moz_binding(&self) -> bool { false } + pub fn root_font_size(&self) -> Au { self.root_font_size } pub fn set_root_font_size(&mut self, size: Au) { self.root_font_size = size } pub fn set_writing_mode(&mut self, mode: WritingMode) { self.writing_mode = mode; } @@ -1321,18 +1388,21 @@ impl ComputedValues { false } - pub fn computed_value_to_string(&self, name: &str) -> Result<String, ()> { - match name { + pub fn computed_value_to_string(&self, property: PropertyDeclarationId) -> String { + match property { % for style_struct in data.active_style_structs(): % for longhand in style_struct.longhands: - "${longhand.name}" => Ok(self.${style_struct.ident}.${longhand.ident}.to_css_string()), + PropertyDeclarationId::Longhand(LonghandId::${longhand.camel_case}) => { + self.${style_struct.ident}.${longhand.ident}.to_css_string() + } % endfor % endfor - _ => { - let name = try!(::custom_properties::parse_name(name)); - let map = try!(self.custom_properties.as_ref().ok_or(())); - let value = try!(map.get(&Atom::from(name)).ok_or(())); - Ok(value.to_css_string()) + PropertyDeclarationId::Custom(name) => { + self.custom_properties + .as_ref() + .and_then(|map| map.get(name)) + .map(|value| value.to_css_string()) + .unwrap_or(String::new()) } } } @@ -1576,9 +1646,11 @@ pub fn apply_declarations<'a, F, I>(viewport_size: Size2D<Au>, ComputedValues::do_cascade_property(|cascade_property| { % for category_to_cascade_now in ["early", "other"]: for declaration in iter_declarations() { - if let PropertyDeclaration::Custom(..) = *declaration { - continue - } + let longhand_id = match declaration.id() { + PropertyDeclarationId::Longhand(id) => id, + PropertyDeclarationId::Custom(..) => continue, + }; + // The computed value of some properties depends on the // (sometimes computed) value of *other* properties. // @@ -1610,7 +1682,7 @@ pub fn apply_declarations<'a, F, I>(viewport_size: Size2D<Au>, continue } - let discriminant = declaration.discriminant_value(); + let discriminant = longhand_id as usize; (cascade_property[discriminant])(declaration, inherited_style, &mut context, @@ -1948,31 +2020,21 @@ pub fn modify_style_for_inline_absolute_hypothetical_fragment(style: &mut Arc<Co } } -// FIXME: https://github.com/w3c/csswg-drafts/issues/580 -pub fn is_supported_property(property: &str) -> bool { - match_ignore_ascii_case! { property, - % for property in data.shorthands + data.longhands: - "${property.name}" => true, - % endfor - _ => property.starts_with("--") - } -} - #[macro_export] macro_rules! css_properties_accessors { ($macro_name: ident) => { $macro_name! { - % for property in data.shorthands + data.longhands: - % if not property.derived_from and not property.internal: - % if '-' in property.name: - [${property.ident.capitalize()}, Set${property.ident.capitalize()}, "${property.name}"], - % endif - % if property != data.longhands[-1]: - [${property.camel_case}, Set${property.camel_case}, "${property.name}"], - % else: - [${property.camel_case}, Set${property.camel_case}, "${property.name}"] + % for kind, props in [("Longhand", data.longhands), ("Shorthand", data.shorthands)]: + % for property in props: + % if not property.derived_from and not property.internal: + % if '-' in property.name: + [${property.ident.capitalize()}, Set${property.ident.capitalize()}, + PropertyId::${kind}(${kind}Id::${property.camel_case})], + % endif + [${property.camel_case}, Set${property.camel_case}, + PropertyId::${kind}(${kind}Id::${property.camel_case})], % endif - % endif + % endfor % endfor } } diff --git a/components/style/properties/shorthand/background.mako.rs b/components/style/properties/shorthand/background.mako.rs index 2537a71c29f..d6ba7da83b8 100644 --- a/components/style/properties/shorthand/background.mako.rs +++ b/components/style/properties/shorthand/background.mako.rs @@ -6,10 +6,14 @@ // TODO: other background-* properties <%helpers:shorthand name="background" - sub_properties="background-color background-position background-repeat background-attachment - background-image background-size background-origin background-clip"> - use properties::longhands::{background_color, background_position, background_repeat, background_attachment}; - use properties::longhands::{background_image, background_size, background_origin, background_clip}; + sub_properties="background-color background-position-x background-position-y background-repeat + background-attachment background-image background-size background-origin + background-clip"> + use properties::longhands::{background_color, background_position_x, background_position_y, background_repeat}; + use properties::longhands::{background_attachment, background_image, background_size, background_origin}; + use properties::longhands::background_clip; + use values::specified::position::Position; + use parser::Parse; impl From<background_origin::single_value::SpecifiedValue> for background_clip::single_value::SpecifiedValue { fn from(origin: background_origin::single_value::SpecifiedValue) -> @@ -28,11 +32,11 @@ pub fn parse_value(context: &ParserContext, input: &mut Parser) -> Result<Longhands, ()> { let mut background_color = None; - % for name in "image position repeat size attachment origin clip".split(): + % for name in "image position_x position_y repeat size attachment origin clip".split(): let mut background_${name} = background_${name}::SpecifiedValue(Vec::new()); % endfor try!(input.parse_comma_separated(|input| { - % for name in "image position repeat size attachment origin clip".split(): + % for name in "image position_x position_y repeat size attachment origin clip".split(): let mut ${name} = None; % endfor loop { @@ -45,10 +49,10 @@ return Err(()) } } - if position.is_none() { - if let Ok(value) = input.try(|input| background_position::single_value - ::parse(context, input)) { - position = Some(value); + if position_x.is_none() && position_y.is_none() { + if let Ok(value) = input.try(|input| Position::parse(context, input)) { + position_x = Some(value.horizontal); + position_y = Some(value.vertical); // Parse background size, if applicable. size = input.try(|input| { @@ -76,12 +80,24 @@ } } let mut any = false; - % for name in "image position repeat size attachment origin clip".split(): + % for name in "image position_x position_y repeat size attachment origin clip".split(): any = any || ${name}.is_some(); % endfor any = any || background_color.is_some(); if any { - % for name in "image position repeat size attachment origin clip".split(): + if position_x.is_some() || position_y.is_some() { + % for name in "position_x position_y".split(): + if let Some(bg_${name}) = ${name} { + background_${name}.0.push(bg_${name}); + } + % endfor + } else { + % for name in "position_x position_y".split(): + background_${name}.0.push(background_${name}::single_value + ::get_initial_position_value()); + % endfor + } + % for name in "image repeat size attachment origin clip".split(): if let Some(bg_${name}) = ${name} { background_${name}.0.push(bg_${name}); } else { @@ -98,7 +114,8 @@ Ok(Longhands { background_color: background_color, background_image: Some(background_image), - background_position: Some(background_position), + background_position_x: Some(background_position_x), + background_position_y: Some(background_position_y), background_repeat: Some(background_repeat), background_attachment: Some(background_attachment), background_size: Some(background_size), @@ -118,7 +135,7 @@ } use std::cmp; let mut len = 0; - % for name in "image position repeat size attachment origin clip".split(): + % for name in "image position_x position_y repeat size attachment origin clip".split(): len = cmp::max(len, extract_value(self.background_${name}).map(|i| i.0.len()) .unwrap_or(0)); % endfor @@ -130,7 +147,7 @@ let mut first = true; for i in 0..len { - % for name in "image position repeat size attachment origin clip".split(): + % for name in "image position_x position_y repeat size attachment origin clip".split(): let ${name} = if let DeclaredValue::Value(ref arr) = *self.background_${name} { arr.0.get(i % arr.0.len()) } else { @@ -185,8 +202,14 @@ try!(write!(dest, " ")); - try!(position.unwrap_or(&background_position::single_value - ::get_initial_specified_value()) + try!(position_x.unwrap_or(&background_position_x::single_value + ::get_initial_position_value()) + .to_css(dest)); + + try!(write!(dest, " ")); + + try!(position_y.unwrap_or(&background_position_y::single_value + ::get_initial_position_value()) .to_css(dest)); if let Some(size) = size { @@ -227,3 +250,84 @@ } } </%helpers:shorthand> + +<%helpers:shorthand name="background-position" + sub_properties="background-position-x background-position-y"> + use properties::longhands::{background_position_x,background_position_y}; + use values::specified::position::Position; + use parser::Parse; + + pub fn parse_value(context: &ParserContext, input: &mut Parser) -> Result<Longhands, ()> { + let mut position_x = background_position_x::SpecifiedValue(Vec::new()); + let mut position_y = background_position_y::SpecifiedValue(Vec::new()); + let mut any = false; + + try!(input.parse_comma_separated(|input| { + loop { + if let Ok(value) = input.try(|input| Position::parse(context, input)) { + position_x.0.push(value.horizontal); + position_y.0.push(value.vertical); + any = true; + continue + } + break + } + Ok(()) + })); + if any == false { + return Err(()); + } + + Ok(Longhands { + background_position_x: Some(position_x), + background_position_y: Some(position_y), + }) + } + + impl<'a> LonghandsToSerialize<'a> { + fn to_css_declared<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write { + // mako doesn't like ampersands following `<` + fn extract_value<T>(x: &DeclaredValue<T>) -> Option< &T> { + match *x { + DeclaredValue::Value(ref val) => Some(val), + _ => None, + } + } + use std::cmp; + let mut len = 0; + % for name in "x y".split(): + len = cmp::max(len, extract_value(self.background_position_${name}) + .map(|i| i.0.len()) + .unwrap_or(0)); + % endfor + + // There should be at least one declared value + if len == 0 { + return dest.write_str("") + } + + for i in 0..len { + % for name in "x y".split(): + let position_${name} = if let DeclaredValue::Value(ref arr) = + *self.background_position_${name} { + arr.0.get(i % arr.0.len()) + } else { + None + }; + % endfor + + try!(position_x.unwrap_or(&background_position_x::single_value + ::get_initial_position_value()) + .to_css(dest)); + + try!(write!(dest, " ")); + + try!(position_y.unwrap_or(&background_position_y::single_value + ::get_initial_position_value()) + .to_css(dest)); + } + + Ok(()) + } + } +</%helpers:shorthand> diff --git a/components/style/properties/shorthand/border.mako.rs b/components/style/properties/shorthand/border.mako.rs index 05efc2c5303..e324e690c70 100644 --- a/components/style/properties/shorthand/border.mako.rs +++ b/components/style/properties/shorthand/border.mako.rs @@ -40,6 +40,7 @@ ${helpers.four_sides_shorthand("border-style", "border-%s-style", }, &DeclaredValue::Initial => DeclaredValue::Initial, &DeclaredValue::Inherit => DeclaredValue::Inherit, + &DeclaredValue::Unset => DeclaredValue::Unset, }; % endfor diff --git a/components/style/properties/shorthand/box.mako.rs b/components/style/properties/shorthand/box.mako.rs index e991d5787c0..08e27c0bde6 100644 --- a/components/style/properties/shorthand/box.mako.rs +++ b/components/style/properties/shorthand/box.mako.rs @@ -28,6 +28,7 @@ (&DeclaredValue::WithVariables { .. }, &DeclaredValue::WithVariables { .. }) => true, (&DeclaredValue::Initial, &DeclaredValue::Initial) => true, (&DeclaredValue::Inherit, &DeclaredValue::Inherit) => true, + (&DeclaredValue::Unset, &DeclaredValue::Unset) => true, _ => false }; @@ -331,6 +332,7 @@ macro_rules! try_parse_one { }, (&DeclaredValue::Initial, &DeclaredValue::Initial) => true, (&DeclaredValue::Inherit, &DeclaredValue::Inherit) => true, + (&DeclaredValue::Unset, &DeclaredValue::Unset) => true, (x, y) => { *x == *y }, }; diff --git a/components/style/properties/shorthand/column.mako.rs b/components/style/properties/shorthand/column.mako.rs index 037154e4afe..e2b6f2ac5a7 100644 --- a/components/style/properties/shorthand/column.mako.rs +++ b/components/style/properties/shorthand/column.mako.rs @@ -59,10 +59,10 @@ </%helpers:shorthand> // https://drafts.csswg.org/css-multicol/#column-rule -<%helpers:shorthand name="-moz-column-rule" products="gecko" - sub_properties="-moz-column-rule-width -moz-column-rule-style -moz-column-rule-color"> - use properties::longhands::{_moz_column_rule_width, _moz_column_rule_style}; - use properties::longhands::_moz_column_rule_color; +<%helpers:shorthand name="column-rule" products="gecko" + sub_properties="column-rule-width column-rule-style column-rule-color"> + use properties::longhands::{column_rule_width, column_rule_style}; + use properties::longhands::column_rule_color; pub fn parse_value(context: &ParserContext, input: &mut Parser) -> Result<Longhands, ()> { % for name in "width style color".split(): @@ -74,7 +74,7 @@ % for name in "width style color".split(): if column_rule_${name}.is_none() { if let Ok(value) = input.try(|input| - _moz_column_rule_${name}::parse(context, input)) { + column_rule_${name}::parse(context, input)) { column_rule_${name} = Some(value); any = true; continue @@ -87,10 +87,10 @@ if any { Ok(Longhands { % for name in "width style".split(): - _moz_column_rule_${name}: column_rule_${name} - .or(Some(_moz_column_rule_${name}::get_initial_specified_value())), + column_rule_${name}: column_rule_${name} + .or(Some(column_rule_${name}::get_initial_specified_value())), % endfor - _moz_column_rule_color: column_rule_color, + column_rule_color: column_rule_color, }) } else { Err(()) @@ -100,14 +100,14 @@ impl<'a> LonghandsToSerialize<'a> { fn to_css_declared<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write { let mut need_space = false; - try!(self._moz_column_rule_width.to_css(dest)); + try!(self.column_rule_width.to_css(dest)); - if let DeclaredValue::Value(ref width) = *self._moz_column_rule_width { + if let DeclaredValue::Value(ref width) = *self.column_rule_width { try!(width.to_css(dest)); need_space = true; } - if let DeclaredValue::Value(ref style) = *self._moz_column_rule_style { + if let DeclaredValue::Value(ref style) = *self.column_rule_style { if need_space { try!(write!(dest, " ")); } @@ -115,7 +115,7 @@ need_space = true; } - if let DeclaredValue::Value(ref color) = *self._moz_column_rule_color { + if let DeclaredValue::Value(ref color) = *self.column_rule_color { if need_space { try!(write!(dest, " ")); } diff --git a/components/style/properties/shorthand/serialize.mako.rs b/components/style/properties/shorthand/serialize.mako.rs index e061796b80d..3dbf39a8ac3 100644 --- a/components/style/properties/shorthand/serialize.mako.rs +++ b/components/style/properties/shorthand/serialize.mako.rs @@ -2,7 +2,7 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -use properties::{AppendableValue, DeclaredValue, PropertyDeclaration, Shorthand}; +use properties::{AppendableValue, DeclaredValue, PropertyDeclaration, ShorthandId}; use style_traits::ToCss; use values::specified::{BorderStyle, CSSColor}; use std::fmt; @@ -88,7 +88,7 @@ fn serialize_directional_border<W, I>(dest: &mut W, pub fn is_overflow_shorthand<'a, I>(appendable_value: &AppendableValue<'a, I>) -> bool where I: Iterator<Item=&'a PropertyDeclaration> { if let AppendableValue::DeclarationsForShorthand(shorthand, _) = *appendable_value { - if let Shorthand::Overflow = shorthand { + if let ShorthandId::Overflow = shorthand { return true; } } diff --git a/components/style/refcell.rs b/components/style/refcell.rs deleted file mode 100644 index a41fa2b63b1..00000000000 --- a/components/style/refcell.rs +++ /dev/null @@ -1,647 +0,0 @@ -// Copyright 2012-2014 The Rust Project Developers. -// See http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or -// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license -// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -//! A fork of std::cell::RefCell that makes `as_unsafe_cell` usable on stable Rust. -//! -//! FIXME(https://github.com/rust-lang/rust/issues/27708): Remove this -//! (revert commit f7f81e0ed0b62402db291e28a9bb16f7194ebf78 / PR #11835) -//! when `std::cell::RefCell::as_unsafe_cell` is in Rust’s stable channel. - -#![allow(unsafe_code)] - -use std::cell::{UnsafeCell, Cell}; -use std::cmp::Ordering; -use std::fmt::{self, Debug, Display}; -use std::marker::PhantomData; -use std::ops::{Deref, DerefMut}; - -/// A fork of std::cell::RefCell that makes `as_unsafe_cell` usable on stable Rust. -/// -/// FIXME(https://github.com/rust-lang/rust/issues/27708): Remove this -/// (revert commit f7f81e0ed0b62402db291e28a9bb16f7194ebf78 / PR #11835) -/// when `std::cell::RefCell::as_unsafe_cell` is in Rust’s stable channel. -pub struct RefCell<T: ?Sized> { - borrow: Cell<BorrowFlag>, - value: UnsafeCell<T>, -} - -/// An enumeration of values returned from the `state` method on a `RefCell<T>`. -#[derive(Copy, Clone, PartialEq, Eq, Debug)] -pub enum BorrowState { - /// The cell is currently being read, there is at least one active `borrow`. - Reading, - /// The cell is currently being written to, there is an active `borrow_mut`. - Writing, - /// There are no outstanding borrows on this cell. - Unused, -} - -/// An error returned by [`RefCell::try_borrow`](struct.RefCell.html#method.try_borrow). -pub struct BorrowError<'a, T: 'a + ?Sized> { - marker: PhantomData<&'a RefCell<T>>, -} - -impl<'a, T: ?Sized> Debug for BorrowError<'a, T> { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - f.debug_struct("BorrowError").finish() - } -} - -impl<'a, T: ?Sized> Display for BorrowError<'a, T> { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - Display::fmt("already mutably borrowed", f) - } -} - -/// An error returned by [`RefCell::try_borrow_mut`](struct.RefCell.html#method.try_borrow_mut). -pub struct BorrowMutError<'a, T: 'a + ?Sized> { - marker: PhantomData<&'a RefCell<T>>, -} - -impl<'a, T: ?Sized> Debug for BorrowMutError<'a, T> { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - f.debug_struct("BorrowMutError").finish() - } -} - -impl<'a, T: ?Sized> Display for BorrowMutError<'a, T> { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - Display::fmt("already borrowed", f) - } -} - -// Values [1, MAX-1] represent the number of `Ref` active -// (will not outgrow its range since `usize` is the size of the address space) -type BorrowFlag = usize; -const UNUSED: BorrowFlag = 0; -const WRITING: BorrowFlag = !0; - -impl<T> RefCell<T> { - /// Creates a new `RefCell` containing `value`. - /// - /// # Examples - /// - /// ``` - /// use std::cell::RefCell; - /// - /// let c = RefCell::new(5); - /// ``` - #[inline] - pub fn new(value: T) -> RefCell<T> { - RefCell { - value: UnsafeCell::new(value), - borrow: Cell::new(UNUSED), - } - } - - /// Consumes the `RefCell`, returning the wrapped value. - /// - /// # Examples - /// - /// ``` - /// use std::cell::RefCell; - /// - /// let c = RefCell::new(5); - /// - /// let five = c.into_inner(); - /// ``` - #[inline] - pub fn into_inner(self) -> T { - // Since this function takes `self` (the `RefCell`) by value, the - // compiler statically verifies that it is not currently borrowed. - // Therefore the following assertion is just a `debug_assert!`. - debug_assert!(self.borrow.get() == UNUSED); - unsafe { self.value.into_inner() } - } -} - -impl<T: ?Sized> RefCell<T> { - /// Query the current state of this `RefCell` - /// - /// The returned value can be dispatched on to determine if a call to - /// `borrow` or `borrow_mut` would succeed. - /// - /// # Examples - /// - /// ``` - /// #![feature(borrow_state)] - /// - /// use std::cell::{BorrowState, RefCell}; - /// - /// let c = RefCell::new(5); - /// - /// match c.borrow_state() { - /// BorrowState::Writing => println!("Cannot be borrowed"), - /// BorrowState::Reading => println!("Cannot be borrowed mutably"), - /// BorrowState::Unused => println!("Can be borrowed (mutably as well)"), - /// } - /// ``` - #[inline] - pub fn borrow_state(&self) -> BorrowState { - match self.borrow.get() { - WRITING => BorrowState::Writing, - UNUSED => BorrowState::Unused, - _ => BorrowState::Reading, - } - } - - /// Immutably borrows the wrapped value. - /// - /// The borrow lasts until the returned `Ref` exits scope. Multiple - /// immutable borrows can be taken out at the same time. - /// - /// # Panics - /// - /// Panics if the value is currently mutably borrowed. For a non-panicking variant, use - /// [`try_borrow`](#method.try_borrow). - /// - /// # Examples - /// - /// ``` - /// use std::cell::RefCell; - /// - /// let c = RefCell::new(5); - /// - /// let borrowed_five = c.borrow(); - /// let borrowed_five2 = c.borrow(); - /// ``` - /// - /// An example of panic: - /// - /// ``` - /// use std::cell::RefCell; - /// use std::thread; - /// - /// let result = thread::spawn(move || { - /// let c = RefCell::new(5); - /// let m = c.borrow_mut(); - /// - /// let b = c.borrow(); // this causes a panic - /// }).join(); - /// - /// assert!(result.is_err()); - /// ``` - #[inline] - pub fn borrow(&self) -> Ref<T> { - self.try_borrow().expect("already mutably borrowed") - } - - /// Immutably borrows the wrapped value, returning an error if the value is currently mutably - /// borrowed. - /// - /// The borrow lasts until the returned `Ref` exits scope. Multiple immutable borrows can be - /// taken out at the same time. - /// - /// This is the non-panicking variant of [`borrow`](#method.borrow). - /// - /// # Examples - /// - /// ``` - /// #![feature(try_borrow)] - /// - /// use std::cell::RefCell; - /// - /// let c = RefCell::new(5); - /// - /// { - /// let m = c.borrow_mut(); - /// assert!(c.try_borrow().is_err()); - /// } - /// - /// { - /// let m = c.borrow(); - /// assert!(c.try_borrow().is_ok()); - /// } - /// ``` - #[inline] - pub fn try_borrow(&self) -> Result<Ref<T>, BorrowError<T>> { - match BorrowRef::new(&self.borrow) { - Some(b) => Ok(Ref { - value: unsafe { &*self.value.get() }, - borrow: b, - }), - None => Err(BorrowError { marker: PhantomData }), - } - } - - /// Mutably borrows the wrapped value. - /// - /// The borrow lasts until the returned `RefMut` exits scope. The value - /// cannot be borrowed while this borrow is active. - /// - /// # Panics - /// - /// Panics if the value is currently borrowed. For a non-panicking variant, use - /// [`try_borrow_mut`](#method.try_borrow_mut). - /// - /// # Examples - /// - /// ``` - /// use std::cell::RefCell; - /// - /// let c = RefCell::new(5); - /// - /// *c.borrow_mut() = 7; - /// - /// assert_eq!(*c.borrow(), 7); - /// ``` - /// - /// An example of panic: - /// - /// ``` - /// use std::cell::RefCell; - /// use std::thread; - /// - /// let result = thread::spawn(move || { - /// let c = RefCell::new(5); - /// let m = c.borrow(); - /// - /// let b = c.borrow_mut(); // this causes a panic - /// }).join(); - /// - /// assert!(result.is_err()); - /// ``` - #[inline] - pub fn borrow_mut(&self) -> RefMut<T> { - self.try_borrow_mut().expect("already borrowed") - } - - /// Mutably borrows the wrapped value, returning an error if the value is currently borrowed. - /// - /// The borrow lasts until the returned `RefMut` exits scope. The value cannot be borrowed - /// while this borrow is active. - /// - /// This is the non-panicking variant of [`borrow_mut`](#method.borrow_mut). - /// - /// # Examples - /// - /// ``` - /// #![feature(try_borrow)] - /// - /// use std::cell::RefCell; - /// - /// let c = RefCell::new(5); - /// - /// { - /// let m = c.borrow(); - /// assert!(c.try_borrow_mut().is_err()); - /// } - /// - /// assert!(c.try_borrow_mut().is_ok()); - /// ``` - #[inline] - pub fn try_borrow_mut(&self) -> Result<RefMut<T>, BorrowMutError<T>> { - match BorrowRefMut::new(&self.borrow) { - Some(b) => Ok(RefMut { - value: unsafe { &mut *self.value.get() }, - borrow: b, - }), - None => Err(BorrowMutError { marker: PhantomData }), - } - } - - /// Returns a reference to the underlying `UnsafeCell`. - /// - /// This can be used to circumvent `RefCell`'s safety checks. - /// - /// This function is `unsafe` because `UnsafeCell`'s field is public. - /// - /// # Examples - /// - /// ``` - /// #![feature(as_unsafe_cell)] - /// - /// use std::cell::RefCell; - /// - /// let c = RefCell::new(5); - /// let c = unsafe { c.as_unsafe_cell() }; - /// ``` - #[inline] - pub unsafe fn as_unsafe_cell(&self) -> &UnsafeCell<T> { - &self.value - } - - /// Returns a raw pointer to the underlying data in this cell. - /// - /// # Examples - /// - /// ``` - /// use std::cell::RefCell; - /// - /// let c = RefCell::new(5); - /// - /// let ptr = c.as_ptr(); - /// ``` - #[inline] - pub fn as_ptr(&self) -> *mut T { - self.value.get() - } - - /// Returns a mutable reference to the underlying data. - /// - /// This call borrows `RefCell` mutably (at compile-time) so there is no - /// need for dynamic checks. - /// - /// # Examples - /// - /// ``` - /// use std::cell::RefCell; - /// - /// let mut c = RefCell::new(5); - /// *c.get_mut() += 1; - /// - /// assert_eq!(c, RefCell::new(6)); - /// ``` - #[inline] - pub fn get_mut(&mut self) -> &mut T { - unsafe { - &mut *self.value.get() - } - } -} - -unsafe impl<T: ?Sized> Send for RefCell<T> where T: Send {} - -impl<T: Clone> Clone for RefCell<T> { - #[inline] - fn clone(&self) -> RefCell<T> { - RefCell::new(self.borrow().clone()) - } -} - -impl<T: Default> Default for RefCell<T> { - #[inline] - fn default() -> RefCell<T> { - RefCell::new(Default::default()) - } -} - -impl<T: ?Sized + PartialEq> PartialEq for RefCell<T> { - #[inline] - fn eq(&self, other: &RefCell<T>) -> bool { - *self.borrow() == *other.borrow() - } -} - -impl<T: ?Sized + Eq> Eq for RefCell<T> {} - -impl<T: ?Sized + PartialOrd> PartialOrd for RefCell<T> { - #[inline] - fn partial_cmp(&self, other: &RefCell<T>) -> Option<Ordering> { - self.borrow().partial_cmp(&*other.borrow()) - } - - #[inline] - fn lt(&self, other: &RefCell<T>) -> bool { - *self.borrow() < *other.borrow() - } - - #[inline] - fn le(&self, other: &RefCell<T>) -> bool { - *self.borrow() <= *other.borrow() - } - - #[inline] - fn gt(&self, other: &RefCell<T>) -> bool { - *self.borrow() > *other.borrow() - } - - #[inline] - fn ge(&self, other: &RefCell<T>) -> bool { - *self.borrow() >= *other.borrow() - } -} - -impl<T: ?Sized + Ord> Ord for RefCell<T> { - #[inline] - fn cmp(&self, other: &RefCell<T>) -> Ordering { - self.borrow().cmp(&*other.borrow()) - } -} - -struct BorrowRef<'b> { - borrow: &'b Cell<BorrowFlag>, -} - -impl<'b> BorrowRef<'b> { - #[inline] - fn new(borrow: &'b Cell<BorrowFlag>) -> Option<BorrowRef<'b>> { - match borrow.get() { - WRITING => None, - b => { - borrow.set(b + 1); - Some(BorrowRef { borrow: borrow }) - }, - } - } -} - -impl<'b> Drop for BorrowRef<'b> { - #[inline] - fn drop(&mut self) { - let borrow = self.borrow.get(); - debug_assert!(borrow != WRITING && borrow != UNUSED); - self.borrow.set(borrow - 1); - } -} - -impl<'b> Clone for BorrowRef<'b> { - #[inline] - fn clone(&self) -> BorrowRef<'b> { - // Since this Ref exists, we know the borrow flag - // is not set to WRITING. - let borrow = self.borrow.get(); - debug_assert!(borrow != UNUSED); - // Prevent the borrow counter from overflowing. - assert!(borrow != WRITING); - self.borrow.set(borrow + 1); - BorrowRef { borrow: self.borrow } - } -} - -/// Wraps a borrowed reference to a value in a `RefCell` box. -/// A wrapper type for an immutably borrowed value from a `RefCell<T>`. -/// -/// See the [module-level documentation](index.html) for more. -pub struct Ref<'b, T: ?Sized + 'b> { - value: &'b T, - borrow: BorrowRef<'b>, -} - -impl<'b, T: ?Sized> Deref for Ref<'b, T> { - type Target = T; - - #[inline] - fn deref(&self) -> &T { - self.value - } -} - -impl<'b, T: ?Sized> Ref<'b, T> { - /// Copies a `Ref`. - /// - /// The `RefCell` is already immutably borrowed, so this cannot fail. - /// - /// This is an associated function that needs to be used as - /// `Ref::clone(...)`. A `Clone` implementation or a method would interfere - /// with the widespread use of `r.borrow().clone()` to clone the contents of - /// a `RefCell`. - #[inline] - pub fn clone(orig: &Ref<'b, T>) -> Ref<'b, T> { - Ref { - value: orig.value, - borrow: orig.borrow.clone(), - } - } - - /// Make a new `Ref` for a component of the borrowed data. - /// - /// The `RefCell` is already immutably borrowed, so this cannot fail. - /// - /// This is an associated function that needs to be used as `Ref::map(...)`. - /// A method would interfere with methods of the same name on the contents - /// of a `RefCell` used through `Deref`. - /// - /// # Example - /// - /// ``` - /// use std::cell::{RefCell, Ref}; - /// - /// let c = RefCell::new((5, 'b')); - /// let b1: Ref<(u32, char)> = c.borrow(); - /// let b2: Ref<u32> = Ref::map(b1, |t| &t.0); - /// assert_eq!(*b2, 5) - /// ``` - #[inline] - pub fn map<U: ?Sized, F>(orig: Ref<'b, T>, f: F) -> Ref<'b, U> - where F: FnOnce(&T) -> &U - { - Ref { - value: f(orig.value), - borrow: orig.borrow, - } - } -} - -impl<'b, T: ?Sized> RefMut<'b, T> { - /// Make a new `RefMut` for a component of the borrowed data, e.g. an enum - /// variant. - /// - /// The `RefCell` is already mutably borrowed, so this cannot fail. - /// - /// This is an associated function that needs to be used as - /// `RefMut::map(...)`. A method would interfere with methods of the same - /// name on the contents of a `RefCell` used through `Deref`. - /// - /// # Example - /// - /// ``` - /// use std::cell::{RefCell, RefMut}; - /// - /// let c = RefCell::new((5, 'b')); - /// { - /// let b1: RefMut<(u32, char)> = c.borrow_mut(); - /// let mut b2: RefMut<u32> = RefMut::map(b1, |t| &mut t.0); - /// assert_eq!(*b2, 5); - /// *b2 = 42; - /// } - /// assert_eq!(*c.borrow(), (42, 'b')); - /// ``` - #[inline] - pub fn map<U: ?Sized, F>(orig: RefMut<'b, T>, f: F) -> RefMut<'b, U> - where F: FnOnce(&mut T) -> &mut U - { - RefMut { - value: f(orig.value), - borrow: orig.borrow, - } - } -} - -struct BorrowRefMut<'b> { - borrow: &'b Cell<BorrowFlag>, -} - -impl<'b> Drop for BorrowRefMut<'b> { - #[inline] - fn drop(&mut self) { - let borrow = self.borrow.get(); - debug_assert!(borrow == WRITING); - self.borrow.set(UNUSED); - } -} - -impl<'b> BorrowRefMut<'b> { - #[inline] - fn new(borrow: &'b Cell<BorrowFlag>) -> Option<BorrowRefMut<'b>> { - match borrow.get() { - UNUSED => { - borrow.set(WRITING); - Some(BorrowRefMut { borrow: borrow }) - }, - _ => None, - } - } -} - -/// A wrapper type for a mutably borrowed value from a `RefCell<T>`. -/// -/// See the [module-level documentation](index.html) for more. -pub struct RefMut<'b, T: ?Sized + 'b> { - value: &'b mut T, - borrow: BorrowRefMut<'b>, -} - -impl<'b, T: ?Sized> Deref for RefMut<'b, T> { - type Target = T; - - #[inline] - fn deref(&self) -> &T { - self.value - } -} - -impl<'b, T: ?Sized> DerefMut for RefMut<'b, T> { - #[inline] - fn deref_mut(&mut self) -> &mut T { - self.value - } -} - - -// Imported from src/libcore/fmt/mod.rs - -impl<T: ?Sized + Debug> Debug for RefCell<T> { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - match self.borrow_state() { - BorrowState::Unused | BorrowState::Reading => { - f.debug_struct("RefCell") - .field("value", &self.borrow()) - .finish() - } - BorrowState::Writing => { - f.debug_struct("RefCell") - .field("value", &"<borrowed>") - .finish() - } - } - } -} - -impl<'b, T: ?Sized + Debug> Debug for Ref<'b, T> { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - Debug::fmt(&**self, f) - } -} - -impl<'b, T: ?Sized + Debug> Debug for RefMut<'b, T> { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - Debug::fmt(&*(self.deref()), f) - } -} diff --git a/components/style/restyle_hints.rs b/components/style/restyle_hints.rs index 03dc39d14ec..3f29d437609 100644 --- a/components/style/restyle_hints.rs +++ b/components/style/restyle_hints.rs @@ -446,9 +446,6 @@ impl DependencySet { -> RestyleHint where E: ElementExt + Clone { - debug!("About to calculate restyle hint for element. Deps: {}", - self.len()); - let state_changes = snapshot.state() .map_or_else(ElementState::empty, |old_state| current_state ^ old_state); let attrs_changed = snapshot.has_attrs(); @@ -458,21 +455,25 @@ impl DependencySet { } let mut hint = RestyleHint::empty(); - let snapshot = ElementWrapper::new_with_snapshot(el.clone(), snapshot); + let snapshot_el = ElementWrapper::new_with_snapshot(el.clone(), snapshot); - Self::compute_partial_hint(&self.common_deps, el, &snapshot, + Self::compute_partial_hint(&self.common_deps, el, &snapshot_el, &state_changes, attrs_changed, &mut hint); if !state_changes.is_empty() { - Self::compute_partial_hint(&self.state_deps, el, &snapshot, + Self::compute_partial_hint(&self.state_deps, el, &snapshot_el, &state_changes, attrs_changed, &mut hint); } if attrs_changed { - Self::compute_partial_hint(&self.attr_deps, el, &snapshot, + Self::compute_partial_hint(&self.attr_deps, el, &snapshot_el, &state_changes, attrs_changed, &mut hint); } + debug!("Calculated restyle hint: {:?}. (Element={:?}, State={:?}, Snapshot={:?}, {} Deps)", + hint, el, current_state, snapshot, self.len()); + trace!("Deps: {:?}", self); + hint } diff --git a/components/style/rule_tree/mod.rs b/components/style/rule_tree/mod.rs index 1e9602428c0..1ba4232dd44 100644 --- a/components/style/rule_tree/mod.rs +++ b/components/style/rule_tree/mod.rs @@ -438,27 +438,59 @@ impl StrongRuleNode { // That's... suspicious, but it's fine if it happens for the rule tree // case, so just don't crash in the case we're doing the final GC in // script. - debug_assert!(!thread_state::get().is_worker() && - (thread_state::get().is_layout() || - thread_state::get().is_script())); - let current = me.next_free.load(Ordering::SeqCst); + if !cfg!(feature = "testing") { + debug_assert!(!thread_state::get().is_worker() && + (thread_state::get().is_layout() || + thread_state::get().is_script())); + } + let current = me.next_free.load(Ordering::SeqCst); if current == FREE_LIST_SENTINEL { return None; } - let current = WeakRuleNode { ptr: current }; + debug_assert!(!current.is_null(), + "Multiple threads are operating on the free list at the \ + same time?"); + debug_assert!(current != self.ptr, + "How did the root end up in the free list?"); + + let next = (*current).next_free.swap(ptr::null_mut(), Ordering::SeqCst); + + debug_assert!(!next.is_null(), + "How did a null pointer end up in the free list?"); - let node = &*current.ptr(); - let next = node.next_free.swap(ptr::null_mut(), Ordering::SeqCst); me.next_free.store(next, Ordering::SeqCst); - debug!("Popping from free list: cur: {:?}, next: {:?}", current.ptr(), next); + debug!("Popping from free list: cur: {:?}, next: {:?}", current, next); - Some(current) + Some(WeakRuleNode { ptr: current }) + } + + unsafe fn assert_free_list_has_no_duplicates_or_null(&self) { + assert!(cfg!(debug_assertions), "This is an expensive check!"); + use std::collections::HashSet; + + let me = &*self.ptr; + assert!(me.is_root()); + + let mut current = self.ptr; + let mut seen = HashSet::new(); + while current != FREE_LIST_SENTINEL { + let next = (*current).next_free.load(Ordering::SeqCst); + assert!(!next.is_null()); + assert!(!seen.contains(&next)); + seen.insert(next); + + current = next; + } } unsafe fn gc(&self) { + if cfg!(debug_assertions) { + self.assert_free_list_has_no_duplicates_or_null(); + } + // NB: This can run from the root node destructor, so we can't use // `get()`, since it asserts the refcount is bigger than zero. let me = &*self.ptr; @@ -552,29 +584,41 @@ impl Drop for StrongRuleNode { return; } - // The node is already in the free list, so do nothing. + let root = unsafe { &*node.root.as_ref().unwrap().ptr() }; + let free_list = &root.next_free; + + // We're sure we're already in the free list, don't spinloop. if node.next_free.load(Ordering::SeqCst) != ptr::null_mut() { return; } - let root = unsafe { &*node.root.as_ref().unwrap().ptr() }; - let free_list = &root.next_free; + // Ensure we "lock" the free list head swapping it with a null pointer. + let mut old_head = free_list.load(Ordering::SeqCst); loop { - let next_free = free_list.load(Ordering::SeqCst); - debug_assert!(!next_free.is_null()); - - node.next_free.store(next_free, Ordering::SeqCst); - - let existing = - free_list.compare_and_swap(next_free, - self.ptr(), - Ordering::SeqCst); - if existing == next_free { - // Successfully inserted, yay! Otherwise try again. - root.free_count.fetch_add(1, Ordering::Relaxed); - break; + match free_list.compare_exchange_weak(old_head, + ptr::null_mut(), + Ordering::SeqCst, + Ordering::Relaxed) { + Ok(..) => { + if old_head != ptr::null_mut() { + break; + } + }, + Err(new) => old_head = new, } } + + // If other thread has raced with use while using the same rule node, + // just store the old head again, we're done. + if node.next_free.load(Ordering::SeqCst) != ptr::null_mut() { + free_list.store(old_head, Ordering::SeqCst); + return; + } + + // Else store the old head as the next pointer, and store ourselves as + // the new head of the free list. + node.next_free.store(old_head, Ordering::SeqCst); + free_list.store(self.ptr(), Ordering::SeqCst); } } diff --git a/components/style/scoped_tls.rs b/components/style/scoped_tls.rs new file mode 100644 index 00000000000..1f695aaa4c9 --- /dev/null +++ b/components/style/scoped_tls.rs @@ -0,0 +1,51 @@ +/* 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/. */ + +#![allow(unsafe_code)] + +use rayon; +use std::cell::{Ref, RefCell, RefMut}; + +/// Stack-scoped thread-local storage for rayon thread pools. + +pub struct ScopedTLS<'a, T: Send> { + pool: &'a rayon::ThreadPool, + slots: Box<[RefCell<Option<T>>]>, +} + +unsafe impl<'a, T: Send> Sync for ScopedTLS<'a, T> {} + +impl<'a, T: Send> ScopedTLS<'a, T> { + pub fn new(p: &'a rayon::ThreadPool) -> Self { + let count = p.num_threads(); + let mut v = Vec::with_capacity(count); + for _ in 0..count { + v.push(RefCell::new(None)); + } + + ScopedTLS { + pool: p, + slots: v.into_boxed_slice(), + } + } + + pub fn borrow(&self) -> Ref<Option<T>> { + let idx = self.pool.current_thread_index().unwrap(); + self.slots[idx].borrow() + } + + pub fn borrow_mut(&self) -> RefMut<Option<T>> { + let idx = self.pool.current_thread_index().unwrap(); + self.slots[idx].borrow_mut() + } + + pub fn ensure<F: FnOnce() -> T>(&self, f: F) -> RefMut<T> { + let mut opt = self.borrow_mut(); + if opt.is_none() { + *opt = Some(f()); + } + + RefMut::map(opt, |x| x.as_mut().unwrap()) + } +} diff --git a/components/style/selector_parser.rs b/components/style/selector_parser.rs index 1c281439256..9b444f17474 100644 --- a/components/style/selector_parser.rs +++ b/components/style/selector_parser.rs @@ -8,6 +8,7 @@ use cssparser::Parser as CssParser; use matching::{common_style_affecting_attributes, CommonStyleAffectingAttributeMode}; use selectors::Element; use selectors::parser::{AttrSelector, SelectorList}; +use std::fmt::Debug; use stylesheets::{Origin, Namespaces}; pub type AttrValue = <SelectorImpl as ::selectors::SelectorImpl>::AttrValue; @@ -30,6 +31,12 @@ pub use servo::restyle_damage::ServoRestyleDamage as RestyleDamage; #[cfg(feature = "gecko")] pub use gecko::restyle_damage::GeckoRestyleDamage as RestyleDamage; +#[cfg(feature = "servo")] +pub type PreExistingComputedValues = ::std::sync::Arc<::properties::ServoComputedValues>; + +#[cfg(feature = "gecko")] +pub type PreExistingComputedValues = ::gecko_bindings::structs::nsStyleContext; + #[cfg_attr(feature = "servo", derive(HeapSizeOf))] pub struct SelectorParser<'a> { pub stylesheet_origin: Origin, @@ -99,7 +106,7 @@ impl PseudoElementCascadeType { } } -pub trait ElementExt: Element<Impl=SelectorImpl> { +pub trait ElementExt: Element<Impl=SelectorImpl> + Debug { fn is_link(&self) -> bool; fn matches_user_and_author_rules(&self) -> bool; diff --git a/components/style/sequential.rs b/components/style/sequential.rs index 0e5253b2073..b47d95a8517 100644 --- a/components/style/sequential.rs +++ b/components/style/sequential.rs @@ -4,42 +4,52 @@ //! Implements sequential traversal over the DOM tree. -use dom::TNode; -use traversal::{DomTraversalContext, PerLevelTraversalData}; +use dom::{TElement, TNode}; +use traversal::{DomTraversal, PerLevelTraversalData, PreTraverseToken}; -pub fn traverse_dom<N, C>(root: N, - shared: &C::SharedContext) +pub fn traverse_dom<N, D>(traversal: &D, + root: N::ConcreteElement, + token: PreTraverseToken) where N: TNode, - C: DomTraversalContext<N> + D: DomTraversal<N> { - fn doit<'a, N, C>(context: &'a C, node: N, data: &mut PerLevelTraversalData) + debug_assert!(token.should_traverse()); + + fn doit<N, D>(traversal: &D, traversal_data: &mut PerLevelTraversalData, + thread_local: &mut D::ThreadLocalContext, node: N) where N: TNode, - C: DomTraversalContext<N> + D: DomTraversal<N> { - context.process_preorder(node, data); + traversal.process_preorder(traversal_data, thread_local, node); if let Some(el) = node.as_element() { - if let Some(ref mut depth) = data.current_dom_depth { + if let Some(ref mut depth) = traversal_data.current_dom_depth { *depth += 1; } - C::traverse_children(el, |kid| doit::<N, C>(context, kid, data)); + D::traverse_children(el, |kid| doit(traversal, traversal_data, thread_local, kid)); - if let Some(ref mut depth) = data.current_dom_depth { + if let Some(ref mut depth) = traversal_data.current_dom_depth { *depth -= 1; } } - if context.needs_postorder_traversal() { - context.process_postorder(node); + if D::needs_postorder_traversal() { + traversal.process_postorder(thread_local, node); } } - let mut data = PerLevelTraversalData { + let mut traversal_data = PerLevelTraversalData { current_dom_depth: None, }; - let context = C::new(shared, root.opaque()); - doit::<N, C>(&context, root, &mut data); - // Clear the local LRU cache since we store stateful elements inside. - context.local_context().style_sharing_candidate_cache.borrow_mut().clear(); + let mut tlc = traversal.create_thread_local_context(); + if token.traverse_unstyled_children_only() { + for kid in root.as_node().children() { + if kid.as_element().map_or(false, |el| el.get_data().is_none()) { + doit(traversal, &mut traversal_data, &mut tlc, kid); + } + } + } else { + doit(traversal, &mut traversal_data, &mut tlc, root.as_node()); + } } diff --git a/components/style/servo/restyle_damage.rs b/components/style/servo/restyle_damage.rs index 6cabb7eb485..fb17071321a 100644 --- a/components/style/servo/restyle_damage.rs +++ b/components/style/servo/restyle_damage.rs @@ -3,7 +3,6 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ use computed_values::display; -use dom::TRestyleDamage; use heapsize::HeapSizeOf; use properties::ServoComputedValues; use std::fmt; @@ -53,16 +52,9 @@ impl HeapSizeOf for ServoRestyleDamage { fn heap_size_of_children(&self) -> usize { 0 } } -impl TRestyleDamage for ServoRestyleDamage { - /// For Servo the style source is always the computed values. - type PreExistingComputedValues = Arc<ServoComputedValues>; - - fn empty() -> Self { - ServoRestyleDamage::empty() - } - - fn compute(old: &Arc<ServoComputedValues>, - new: &Arc<ServoComputedValues>) -> ServoRestyleDamage { +impl ServoRestyleDamage { + pub fn compute(old: &Arc<ServoComputedValues>, + new: &Arc<ServoComputedValues>) -> ServoRestyleDamage { compute_damage(old, new) } @@ -72,13 +64,11 @@ impl TRestyleDamage for ServoRestyleDamage { /// Use this instead of `ServoRestyleDamage::all()` because /// `ServoRestyleDamage::all()` will result in unnecessary sequential resolution /// of generated content. - fn rebuild_and_reflow() -> ServoRestyleDamage { + pub fn rebuild_and_reflow() -> ServoRestyleDamage { REPAINT | REPOSITION | STORE_OVERFLOW | BUBBLE_ISIZES | REFLOW_OUT_OF_FLOW | REFLOW | RECONSTRUCT_FLOW } -} -impl ServoRestyleDamage { /// Supposing a flow has the given `position` property and this damage, /// returns the damage that we should add to the *parent* of this flow. pub fn damage_for_parent(self, child_is_absolutely_positioned: bool) -> ServoRestyleDamage { @@ -242,10 +232,10 @@ fn compute_damage(old: &ServoComputedValues, new: &ServoComputedValues) -> Servo ]) || add_if_not_equal!(old, new, damage, [REPAINT], [ get_color.color, get_background.background_color, - get_background.background_image, get_background.background_position, - get_background.background_repeat, get_background.background_attachment, - get_background.background_clip, get_background.background_origin, - get_background.background_size, + get_background.background_image, get_background.background_position_x, + get_background.background_position_y, get_background.background_repeat, + get_background.background_attachment, get_background.background_clip, + get_background.background_origin, get_background.background_size, get_border.border_top_color, get_border.border_right_color, get_border.border_bottom_color, get_border.border_left_color, get_border.border_top_style, get_border.border_right_style, diff --git a/components/style/servo/selector_parser.rs b/components/style/servo/selector_parser.rs index 34eb8c2df7c..2403e702063 100644 --- a/components/style/servo/selector_parser.rs +++ b/components/style/servo/selector_parser.rs @@ -13,6 +13,7 @@ use selectors::{Element, MatchAttrGeneric}; use selectors::parser::AttrSelector; use std::borrow::Cow; use std::fmt; +use std::fmt::Debug; /// NB: If you add to this list, be sure to update `each_pseudo_element` too. #[derive(Clone, Debug, PartialEq, Eq, Hash)] @@ -398,7 +399,7 @@ impl MatchAttrGeneric for ServoElementSnapshot { } } -impl<E: Element<Impl=SelectorImpl>> ElementExt for E { +impl<E: Element<Impl=SelectorImpl> + Debug> ElementExt for E { fn is_link(&self) -> bool { self.match_non_ts_pseudo_class(NonTSPseudoClass::AnyLink) } diff --git a/components/style/str.rs b/components/style/str.rs index 73518625b6e..be763892118 100644 --- a/components/style/str.rs +++ b/components/style/str.rs @@ -3,6 +3,8 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ use num_traits::ToPrimitive; +use std::ascii::AsciiExt; +use std::borrow::Cow; use std::convert::AsRef; use std::iter::{Filter, Peekable}; use std::str::Split; @@ -125,3 +127,13 @@ pub fn str_join<I, T>(strs: I, join: &str) -> String acc }) } + +/// Like AsciiExt::to_ascii_lowercase, but avoids allocating when the input is already lower-case. +pub fn cow_into_ascii_lowercase<'a, S: Into<Cow<'a, str>>>(s: S) -> Cow<'a, str> { + let mut cow = s.into(); + match cow.bytes().position(|byte| byte >= b'A' && byte <= b'Z') { + Some(first_uppercase) => cow.to_mut()[first_uppercase..].make_ascii_lowercase(), + None => {} + } + cow +} diff --git a/components/style/stylesheets.rs b/components/style/stylesheets.rs index 1156b85731c..bc573eb4bfe 100644 --- a/components/style/stylesheets.rs +++ b/components/style/stylesheets.rs @@ -18,6 +18,7 @@ use parser::{ParserContext, ParserContextExtraData, log_css_error}; use properties::{PropertyDeclarationBlock, parse_property_declaration_list}; use selector_parser::{SelectorImpl, SelectorParser}; use selectors::parser::SelectorList; +use servo_config::prefs::PREFS; use servo_url::ServoUrl; use std::cell::Cell; use std::fmt; @@ -25,6 +26,7 @@ use std::sync::Arc; use std::sync::atomic::{AtomicBool, Ordering}; use style_traits::ToCss; use stylist::FnvHashMap; +use values::specified::url::SpecifiedUrl; use viewport::ViewportRule; @@ -54,6 +56,12 @@ pub struct Namespaces { #[derive(Debug)] pub struct CssRules(pub Vec<CssRule>); +impl CssRules { + pub fn is_empty(&self) -> bool { + self.0.is_empty() + } +} + pub enum RulesMutateError { Syntax, IndexSize, @@ -78,7 +86,8 @@ impl CssRules { fn only_ns_or_import(&self) -> bool { self.0.iter().all(|r| { match *r { - CssRule::Namespace(..) /* | CssRule::Import(..) */ => true, + CssRule::Namespace(..) | + CssRule::Import(..) => true, _ => false } }) @@ -103,8 +112,9 @@ impl CssRules { // Step 3, 4 // XXXManishearth should we also store the namespace map? - let (new_rule, new_state) = try!(CssRule::parse(&rule, parent_stylesheet, - ParserContextExtraData::default(), state)); + let (new_rule, new_state) = + try!(CssRule::parse(&rule, parent_stylesheet, + ParserContextExtraData::default(), state)); // Step 5 // Computes the maximum allowed parser state at a given index. @@ -179,6 +189,7 @@ pub enum CssRule { // https://drafts.csswg.org/cssom/#changes-from-5-december-2013 Namespace(Arc<RwLock<NamespaceRule>>), + Import(Arc<RwLock<ImportRule>>), Style(Arc<RwLock<StyleRule>>), Media(Arc<RwLock<MediaRule>>), FontFace(Arc<RwLock<FontFaceRule>>), @@ -234,6 +245,7 @@ impl CssRule { pub fn rule_type(&self) -> CssRuleType { match *self { CssRule::Style(_) => CssRuleType::Style, + CssRule::Import(_) => CssRuleType::Import, CssRule::Media(_) => CssRuleType::Media, CssRule::FontFace(_) => CssRuleType::FontFace, CssRule::Keyframes(_) => CssRuleType::Keyframes, @@ -245,7 +257,7 @@ impl CssRule { fn rule_state(&self) -> State { match *self { // CssRule::Charset(..) => State::Start, - // CssRule::Import(..) => State::Imports, + CssRule::Import(..) => State::Imports, CssRule::Namespace(..) => State::Namespaces, _ => State::Body, } @@ -253,10 +265,19 @@ impl CssRule { /// Call `f` with the slice of rules directly contained inside this rule. /// - /// Note that only some types of rules can contain rules. An empty slice is used for others. + /// Note that only some types of rules can contain rules. An empty slice is + /// used for others. pub fn with_nested_rules_and_mq<F, R>(&self, mut f: F) -> R where F: FnMut(&[CssRule], Option<&MediaList>) -> R { match *self { + CssRule::Import(ref lock) => { + let rule = lock.read(); + let media = rule.stylesheet.media.read(); + let rules = rule.stylesheet.rules.read(); + // FIXME(emilio): Include the nested rules if the stylesheet is + // loaded. + f(&rules.0, Some(&media)) + } CssRule::Namespace(_) | CssRule::Style(_) | CssRule::FontFace(_) | @@ -293,6 +314,7 @@ impl CssRule { let mut rule_parser = TopLevelRuleParser { stylesheet_origin: parent_stylesheet.origin, context: context, + loader: None, state: Cell::new(state), namespaces: &mut namespaces, }; @@ -314,6 +336,7 @@ impl ToCss for CssRule { fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write { match *self { CssRule::Namespace(ref lock) => lock.read().to_css(dest), + CssRule::Import(ref lock) => lock.read().to_css(dest), CssRule::Style(ref lock) => lock.read().to_css(dest), CssRule::FontFace(ref lock) => lock.read().to_css(dest), CssRule::Viewport(ref lock) => lock.read().to_css(dest), @@ -345,6 +368,34 @@ impl ToCss for NamespaceRule { } } + +/// The [`@import`][import] at-rule. +/// +/// [import]: https://drafts.csswg.org/css-cascade-3/#at-import +#[derive(Debug)] +pub struct ImportRule { + pub url: SpecifiedUrl, + + /// The stylesheet is always present. + /// + /// It contains an empty list of rules and namespace set that is updated + /// when it loads. + pub stylesheet: Arc<Stylesheet>, +} + +impl ToCss for ImportRule { + fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write { + try!(dest.write_str("@import ")); + try!(self.url.to_css(dest)); + let media = self.stylesheet.media.read(); + if !media.is_empty() { + try!(dest.write_str(" ")); + try!(media.to_css(dest)); + } + dest.write_str(";") + } +} + #[derive(Debug)] pub struct KeyframesRule { pub name: Atom, @@ -420,54 +471,102 @@ impl Stylesheet { environment_encoding: Option<EncodingRef>, origin: Origin, media: MediaList, + stylesheet_loader: Option<&StylesheetLoader>, error_reporter: Box<ParseErrorReporter + Send>, extra_data: ParserContextExtraData) -> Stylesheet { let (string, _) = decode_stylesheet_bytes( bytes, protocol_encoding_label, environment_encoding); - Stylesheet::from_str(&string, base_url, origin, media, error_reporter, extra_data) + Stylesheet::from_str(&string, + base_url, + origin, + media, + stylesheet_loader, + error_reporter, + extra_data) + } + + pub fn update_from_bytes(existing: &Stylesheet, + bytes: &[u8], + protocol_encoding_label: Option<&str>, + environment_encoding: Option<EncodingRef>, + stylesheet_loader: Option<&StylesheetLoader>, + error_reporter: Box<ParseErrorReporter + Send>, + extra_data: ParserContextExtraData) { + assert!(existing.rules.read().is_empty()); + let (string, _) = decode_stylesheet_bytes( + bytes, protocol_encoding_label, environment_encoding); + Self::update_from_str(existing, + &string, + stylesheet_loader, + error_reporter, + extra_data) } - pub fn from_str(css: &str, base_url: ServoUrl, origin: Origin, media: MediaList, - error_reporter: Box<ParseErrorReporter + Send>, - extra_data: ParserContextExtraData) -> Stylesheet { - let mut namespaces = Namespaces::default(); - let mut rules = vec![]; - let dirty_on_viewport_size_change; + pub fn update_from_str(existing: &Stylesheet, + css: &str, + stylesheet_loader: Option<&StylesheetLoader>, + error_reporter: Box<ParseErrorReporter + Send>, + extra_data: ParserContextExtraData) { + let mut rules = existing.rules.write(); + let mut namespaces = existing.namespaces.write(); + + assert!(rules.is_empty()); + + let mut input = Parser::new(css); + let rule_parser = TopLevelRuleParser { + stylesheet_origin: existing.origin, + namespaces: &mut namespaces, + loader: stylesheet_loader, + context: ParserContext::new_with_extra_data(existing.origin, + &existing.base_url, + error_reporter, + extra_data), + state: Cell::new(State::Start), + }; + + input.look_for_viewport_percentages(); + { - let rule_parser = TopLevelRuleParser { - stylesheet_origin: origin, - namespaces: &mut namespaces, - context: ParserContext::new_with_extra_data(origin, &base_url, error_reporter, extra_data), - state: Cell::new(State::Start), - }; - let mut input = Parser::new(css); - input.look_for_viewport_percentages(); - { - let mut iter = RuleListParser::new_for_stylesheet(&mut input, rule_parser); - while let Some(result) = iter.next() { - match result { - Ok(rule) => rules.push(rule), - Err(range) => { - let pos = range.start; - let message = format!("Invalid rule: '{}'", iter.input.slice(range)); - log_css_error(iter.input, pos, &*message, &iter.parser.context); - } + let mut iter = RuleListParser::new_for_stylesheet(&mut input, rule_parser); + while let Some(result) = iter.next() { + match result { + Ok(rule) => rules.0.push(rule), + Err(range) => { + let pos = range.start; + let message = format!("Invalid rule: '{}'", iter.input.slice(range)); + log_css_error(iter.input, pos, &*message, &iter.parser.context); } } } - dirty_on_viewport_size_change = input.seen_viewport_percentages(); } - Stylesheet { + existing.dirty_on_viewport_size_change + .store(input.seen_viewport_percentages(), Ordering::Release); + } + + pub fn from_str(css: &str, base_url: ServoUrl, origin: Origin, + media: MediaList, + stylesheet_loader: Option<&StylesheetLoader>, + error_reporter: Box<ParseErrorReporter + Send>, + extra_data: ParserContextExtraData) -> Stylesheet { + let s = Stylesheet { origin: origin, base_url: base_url, - namespaces: RwLock::new(namespaces), - rules: CssRules::new(rules), + namespaces: RwLock::new(Namespaces::default()), + rules: CssRules::new(vec![]), media: Arc::new(RwLock::new(media)), - dirty_on_viewport_size_change: AtomicBool::new(dirty_on_viewport_size_change), + dirty_on_viewport_size_change: AtomicBool::new(false), disabled: AtomicBool::new(false), - } + }; + + Self::update_from_str(&s, + css, + stylesheet_loader, + error_reporter, + extra_data); + + s } pub fn dirty_on_viewport_size_change(&self) -> bool { @@ -562,9 +661,20 @@ rule_filter! { effective_keyframes_rules(Keyframes => KeyframesRule), } +/// The stylesheet loader is the abstraction used to trigger network requests +/// for `@import` rules. +pub trait StylesheetLoader { + /// Request a stylesheet after parsing a given `@import` rule. + /// + /// The called code is responsible to update the `stylesheet` rules field + /// when the sheet is done loading. + fn request_stylesheet(&self, import: &Arc<RwLock<ImportRule>>); +} + struct TopLevelRuleParser<'a> { stylesheet_origin: Origin, namespaces: &'a mut Namespaces, + loader: Option<&'a StylesheetLoader>, context: ParserContext<'a>, state: Cell<State>, } @@ -611,8 +721,38 @@ impl<'a> AtRuleParser for TopLevelRuleParser<'a> { "import" => { if self.state.get() <= State::Imports { self.state.set(State::Imports); - // TODO: support @import - return Err(()) // "@import is not supported yet" + let url = try!(input.expect_url_or_string()); + let url = + try!(SpecifiedUrl::parse_from_string(url, + &self.context)); + + let media = + Arc::new(RwLock::new(parse_media_query_list(input))); + + let is_valid_url = url.url().is_some(); + + let import_rule = Arc::new(RwLock::new( + ImportRule { + url: url, + stylesheet: Arc::new(Stylesheet { + rules: Arc::new(RwLock::new(CssRules(vec![]))), + media: media, + origin: self.context.stylesheet_origin, + base_url: self.context.base_url.clone(), + namespaces: RwLock::new(Namespaces::default()), + dirty_on_viewport_size_change: AtomicBool::new(false), + disabled: AtomicBool::new(false), + }) + } + )); + + if is_valid_url { + let loader = self.loader + .expect("Expected a stylesheet loader for @import"); + loader.request_stylesheet(&import_rule); + } + + return Ok(AtRuleType::WithoutBlock(CssRule::Import(import_rule))) } else { self.state.set(State::Invalid); return Err(()) // "@import must be before any rule but @charset" @@ -723,7 +863,7 @@ impl<'a, 'b> AtRuleParser for NestedRuleParser<'a, 'b> { Ok(AtRuleType::WithBlock(AtRulePrelude::FontFace)) }, "viewport" => { - if ::util::prefs::PREFS.get("layout.viewport.enabled").as_boolean().unwrap_or(false) || + if PREFS.get("layout.viewport.enabled").as_boolean().unwrap_or(false) || cfg!(feature = "gecko") { Ok(AtRuleType::WithBlock(AtRulePrelude::Viewport)) } else { diff --git a/components/style/stylist.rs b/components/style/stylist.rs index 11cbdeaa081..4cb4a65b081 100644 --- a/components/style/stylist.rs +++ b/components/style/stylist.rs @@ -49,7 +49,7 @@ pub type FnvHashMap<K, V> = HashMap<K, V, BuildHasherDefault<::fnv::FnvHasher>>; #[cfg_attr(feature = "servo", derive(HeapSizeOf))] pub struct Stylist { /// Device that the stylist is currently evaluating against. - pub device: Device, + pub device: Arc<Device>, /// Viewport constraints based on the current device. viewport_constraints: Option<ViewportConstraints>, @@ -103,7 +103,7 @@ impl Stylist { pub fn new(device: Device) -> Self { let mut stylist = Stylist { viewport_constraints: None, - device: device, + device: Arc::new(device), is_device_dirty: true, quirks_mode: false, @@ -165,6 +165,25 @@ impl Stylist { self.add_stylesheet(stylesheet); } + debug!("Stylist stats:"); + debug!(" - Got {} sibling-affecting selectors", + self.sibling_affecting_selectors.len()); + debug!(" - Got {} non-common-style-attribute-affecting selectors", + self.non_common_style_affecting_attributes_selectors.len()); + debug!(" - Got {} deps for style-hint calculation", + self.state_deps.len()); + + SelectorImpl::each_precomputed_pseudo_element(|pseudo| { + // TODO: Consider not doing this and just getting the rules on the + // fly. It should be a bit slower, but we'd take rid of the + // extra field, and avoid this precomputation entirely. + if let Some(map) = self.pseudos_map.remove(&pseudo) { + let mut declarations = vec![]; + map.user_agent.get_universal_rules(&mut declarations); + self.precomputed_pseudo_element_decls.insert(pseudo, declarations); + } + }); + self.is_device_dirty = false; true } @@ -174,64 +193,59 @@ impl Stylist { return; } - // Work around borrowing all of `self` if `self.something` is used in it - // instead of just `self.something` - macro_rules! borrow_self_field { - ($($x: ident),+) => { - $( - let $x = &mut self.$x; - )+ - } - } - borrow_self_field!(pseudos_map, element_map, state_deps, sibling_affecting_selectors, - non_common_style_affecting_attributes_selectors, rules_source_order, - animations, precomputed_pseudo_element_decls); - stylesheet.effective_rules(&self.device, |rule| { + // Cheap `Arc` clone so that the closure below can borrow `&mut Stylist`. + let device = self.device.clone(); + + stylesheet.effective_rules(&device, |rule| { match *rule { CssRule::Style(ref style_rule) => { let guard = style_rule.read(); for selector in &guard.selectors.0 { let map = if let Some(ref pseudo) = selector.pseudo_element { - pseudos_map + self.pseudos_map .entry(pseudo.clone()) .or_insert_with(PerPseudoElementSelectorMap::new) .borrow_for_origin(&stylesheet.origin) } else { - element_map.borrow_for_origin(&stylesheet.origin) + self.element_map.borrow_for_origin(&stylesheet.origin) }; map.insert(Rule { selector: selector.complex_selector.clone(), style_rule: style_rule.clone(), specificity: selector.specificity, - source_order: *rules_source_order, + source_order: self.rules_source_order, }); } - *rules_source_order += 1; + self.rules_source_order += 1; for selector in &guard.selectors.0 { - state_deps.note_selector(&selector.complex_selector); + self.state_deps.note_selector(&selector.complex_selector); if selector.affects_siblings() { - sibling_affecting_selectors.push(selector.clone()); + self.sibling_affecting_selectors.push(selector.clone()); } if selector.matches_non_common_style_affecting_attribute() { - non_common_style_affecting_attributes_selectors.push(selector.clone()); + self.non_common_style_affecting_attributes_selectors.push(selector.clone()); } } } + CssRule::Import(ref import) => { + let import = import.read(); + self.add_stylesheet(&import.stylesheet) + } CssRule::Keyframes(ref keyframes_rule) => { let keyframes_rule = keyframes_rule.read(); debug!("Found valid keyframes rule: {:?}", *keyframes_rule); if let Some(animation) = KeyframesAnimation::from_keyframes(&keyframes_rule.keyframes) { debug!("Found valid keyframe animation: {:?}", animation); - animations.insert(keyframes_rule.name.clone(), + self.animations.insert(keyframes_rule.name.clone(), animation); } else { // If there's a valid keyframes rule, even if it doesn't // produce an animation, should shadow other animations // with the same name. - animations.remove(&keyframes_rule.name); + self.animations.remove(&keyframes_rule.name); } } // We don't care about any other rule. @@ -241,26 +255,25 @@ impl Stylist { debug!("Stylist stats:"); debug!(" - Got {} sibling-affecting selectors", - sibling_affecting_selectors.len()); + self.sibling_affecting_selectors.len()); debug!(" - Got {} non-common-style-attribute-affecting selectors", - non_common_style_affecting_attributes_selectors.len()); + self.non_common_style_affecting_attributes_selectors.len()); debug!(" - Got {} deps for style-hint calculation", - state_deps.len()); + self.state_deps.len()); SelectorImpl::each_precomputed_pseudo_element(|pseudo| { // TODO: Consider not doing this and just getting the rules on the // fly. It should be a bit slower, but we'd take rid of the // extra field, and avoid this precomputation entirely. - if let Some(map) = pseudos_map.remove(&pseudo) { + if let Some(map) = self.pseudos_map.remove(&pseudo) { let mut declarations = vec![]; - map.user_agent.get_universal_rules(&mut declarations); - - precomputed_pseudo_element_decls.insert(pseudo, declarations); + self.precomputed_pseudo_element_decls.insert(pseudo, declarations); } - }) + }); } + /// Computes the style for a given "precomputed" pseudo-element, taking the /// universal rules and applying them. /// @@ -392,7 +405,7 @@ impl Stylist { mq_eval_changed(&stylesheet.rules.read().0, &self.device, &device) }); - self.device = device; + self.device = Arc::new(device); } pub fn viewport_constraints(&self) -> &Option<ViewportConstraints> { diff --git a/components/style/thread_state.rs b/components/style/thread_state.rs index b0fbd5f4294..9f6dc5df8e8 100644 --- a/components/style/thread_state.rs +++ b/components/style/thread_state.rs @@ -60,10 +60,9 @@ mod imp { pub fn initialize(x: ThreadState) { STATE.with(|ref k| { - match *k.borrow() { - Some(s) => panic!("Thread state already initialized as {:?}", s), - None => () - }; + if let Some(ref s) = *k.borrow() { + panic!("Thread state already initialized as {:?}", s); + } *k.borrow_mut() = Some(x); }); get(); // check the assertion below diff --git a/components/style/tid.rs b/components/style/tid.rs deleted file mode 100644 index a60c321a984..00000000000 --- a/components/style/tid.rs +++ /dev/null @@ -1,26 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -use std::cell::RefCell; -use std::rc::Rc; -use std::sync::atomic::{ATOMIC_USIZE_INIT, AtomicUsize, Ordering}; - -static NEXT_TID: AtomicUsize = ATOMIC_USIZE_INIT; - -thread_local!(static TASK_LOCAL_TID: Rc<RefCell<Option<usize>>> = Rc::new(RefCell::new(None))); - -/// Every thread gets one, that's unique. -pub fn tid() -> usize { - TASK_LOCAL_TID.with(|ref k| { - let ret = - match *k.borrow() { - None => NEXT_TID.fetch_add(1, Ordering::SeqCst), - Some(x) => x, - }; - - *k.borrow_mut() = Some(ret); - - ret - }) -} diff --git a/components/style/traversal.rs b/components/style/traversal.rs index 685c33b265f..a9fd8c57a4d 100644 --- a/components/style/traversal.rs +++ b/components/style/traversal.rs @@ -5,132 +5,229 @@ //! Traversing the DOM tree; the bloom filter. use atomic_refcell::{AtomicRefCell, AtomicRefMut}; -use bloom::StyleBloom; -use context::{LocalStyleContext, SharedStyleContext, StyleContext}; -use data::{ElementData, RestyleData, StoredRestyleHint}; -use dom::{OpaqueNode, StylingMode, TElement, TNode}; +use context::{SharedStyleContext, StyleContext}; +use data::{ElementData, StoredRestyleHint}; +use dom::{TElement, TNode}; use matching::{MatchMethods, StyleSharingResult}; -use restyle_hints::{RESTYLE_DESCENDANTS, RESTYLE_LATER_SIBLINGS, RESTYLE_SELF}; +use restyle_hints::{RESTYLE_DESCENDANTS, RESTYLE_SELF}; +use selector_parser::RestyleDamage; +use selectors::Element; use selectors::matching::StyleRelations; -use std::cell::RefCell; -use std::marker::PhantomData; +use servo_config::opts; +use std::mem; use std::sync::atomic::{AtomicUsize, ATOMIC_USIZE_INIT, Ordering}; -use util::opts; - -/// Every time we do another layout, the old bloom filters are invalid. This is -/// detected by ticking a generation number every layout. -pub type Generation = u32; +use stylist::Stylist; /// Style sharing candidate cache stats. These are only used when /// `-Z style-sharing-stats` is given. pub static STYLE_SHARING_CACHE_HITS: AtomicUsize = ATOMIC_USIZE_INIT; pub static STYLE_SHARING_CACHE_MISSES: AtomicUsize = ATOMIC_USIZE_INIT; -thread_local!( - static STYLE_BLOOM: RefCell<Option<StyleBloom>> = RefCell::new(None)); - -/// Returns the thread local bloom filter. -/// -/// If one does not exist, a new one will be made for you. If it is out of date, -/// it will be cleared and reused. -pub fn take_thread_local_bloom_filter(context: &SharedStyleContext) - -> StyleBloom -{ - debug!("{} taking bf", ::tid::tid()); - - STYLE_BLOOM.with(|style_bloom| { - style_bloom.borrow_mut().take() - .unwrap_or_else(|| StyleBloom::new(context.generation)) - }) +// NB: Keep this as small as possible, please! +#[derive(Clone, Debug)] +pub struct PerLevelTraversalData { + pub current_dom_depth: Option<usize>, } -pub fn put_thread_local_bloom_filter(bf: StyleBloom) { - debug!("[{}] putting bloom filter back", ::tid::tid()); - - STYLE_BLOOM.with(move |style_bloom| { - debug_assert!(style_bloom.borrow().is_none(), - "Putting into a never-taken thread-local bloom filter"); - *style_bloom.borrow_mut() = Some(bf); - }) +/// This structure exists to enforce that callers invoke pre_traverse, and also +/// to pass information from the pre-traversal into the primary traversal. +pub struct PreTraverseToken { + traverse: bool, + unstyled_children_only: bool, } -/// Remove `element` from the bloom filter if it's the last element we inserted. -/// -/// Restores the bloom filter if this is not the root of the reflow. -/// -/// This is mostly useful for sequential traversal, where the element will -/// always be the last one. -pub fn remove_from_bloom_filter<'a, E, C>(context: &C, root: OpaqueNode, element: E) - where E: TElement, - C: StyleContext<'a> -{ - debug!("[{}] remove_from_bloom_filter", ::tid::tid()); - - // We may have arrived to `reconstruct_flows` without entering in style - // recalc at all due to our optimizations, nor that it's up to date, so we - // can't ensure there's a bloom filter at all. - let bf = STYLE_BLOOM.with(|style_bloom| { - style_bloom.borrow_mut().take() - }); - - if let Some(mut bf) = bf { - if context.shared_context().generation == bf.generation() { - bf.maybe_pop(element); - - // If we're the root of the reflow, just get rid of the bloom - // filter. - // - // FIXME: We might want to just leave it in TLS? You don't do 4k - // allocations every day. Also, this just clears one thread's bloom - // filter, which is... not great? - if element.as_node().opaque() != root { - put_thread_local_bloom_filter(bf); - } - } +impl PreTraverseToken { + pub fn should_traverse(&self) -> bool { + self.traverse } -} -// NB: Keep this as small as possible, please! -#[derive(Clone, Debug)] -pub struct PerLevelTraversalData { - pub current_dom_depth: Option<usize>, + pub fn traverse_unstyled_children_only(&self) -> bool { + self.unstyled_children_only + } } -pub trait DomTraversalContext<N: TNode> { - type SharedContext: Sync + 'static; +/// Enum to prevent duplicate logging. +pub enum LogBehavior { + MayLog, + DontLog, +} +use self::LogBehavior::*; +impl LogBehavior { + fn allow(&self) -> bool { match *self { MayLog => true, DontLog => false, } } +} - fn new<'a>(&'a Self::SharedContext, OpaqueNode) -> Self; +pub trait DomTraversal<N: TNode> : Sync { + type ThreadLocalContext: Send; /// Process `node` on the way down, before its children have been processed. - fn process_preorder(&self, node: N, data: &mut PerLevelTraversalData); + fn process_preorder(&self, data: &mut PerLevelTraversalData, + thread_local: &mut Self::ThreadLocalContext, node: N); /// Process `node` on the way up, after its children have been processed. /// /// This is only executed if `needs_postorder_traversal` returns true. - fn process_postorder(&self, node: N); + fn process_postorder(&self, thread_local: &mut Self::ThreadLocalContext, node: N); /// Boolean that specifies whether a bottom up traversal should be /// performed. /// /// If it's false, then process_postorder has no effect at all. - fn needs_postorder_traversal(&self) -> bool { true } + fn needs_postorder_traversal() -> bool { true } + + /// Must be invoked before traversing the root element to determine whether + /// a traversal is needed. Returns a token that allows the caller to prove + /// that the call happened. + /// + /// The unstyled_children_only parameter is used in Gecko to style newly- + /// appended children without restyling the parent. + fn pre_traverse(root: N::ConcreteElement, stylist: &Stylist, + unstyled_children_only: bool) + -> PreTraverseToken + { + if unstyled_children_only { + return PreTraverseToken { + traverse: true, + unstyled_children_only: true, + }; + } + + // Expand the snapshot, if any. This is normally handled by the parent, so + // we need a special case for the root. + // + // Expanding snapshots here may create a LATER_SIBLINGS restyle hint, which + // we will drop on the floor. To prevent missed restyles, we assert against + // restyling a root with later siblings. + if let Some(mut data) = root.mutate_data() { + if let Some(r) = data.as_restyle_mut() { + debug_assert!(root.next_sibling_element().is_none()); + let _later_siblings = r.expand_snapshot(root, stylist); + } + } + + PreTraverseToken { + traverse: Self::node_needs_traversal(root.as_node()), + unstyled_children_only: false, + } + } + + /// Returns true if traversal should visit a text node. The style system never + /// processes text nodes, but Servo overrides this to visit them for flow + /// construction when necessary. + fn text_node_needs_traversal(node: N) -> bool { debug_assert!(node.is_text_node()); false } + + /// Returns true if traversal is needed for the given node and subtree. + fn node_needs_traversal(node: N) -> bool { + // Non-incremental layout visits every node. + if cfg!(feature = "servo") && opts::get().nonincremental_layout { + return true; + } + + match node.as_element() { + None => Self::text_node_needs_traversal(node), + Some(el) => { + // If the dirty descendants bit is set, we need to traverse no + // matter what. Skip examining the ElementData. + if el.has_dirty_descendants() { + return true; + } + + // Check the element data. If it doesn't exist, we need to visit + // the element. + let data = match el.borrow_data() { + Some(d) => d, + None => return true, + }; + + // Check what kind of element data we have. If it's Initial or Persistent, + // we're done. + let restyle = match *data { + ElementData::Initial(ref i) => return i.is_none(), + ElementData::Persistent(_) => return false, + ElementData::Restyle(ref r) => r, + }; + + // Check whether we have any selector matching or re-cascading to + // do in this subtree. + debug_assert!(restyle.snapshot.is_none(), "Snapshots should already be expanded"); + if !restyle.hint.is_empty() || restyle.recascade { + return true; + } + + // Servo uses the post-order traversal for flow construction, so + // we need to traverse any element with damage so that we can perform + // fixup / reconstruction on our way back up the tree. + if cfg!(feature = "servo") && restyle.damage != RestyleDamage::empty() { + return true; + } + + false + }, + } + } + + /// Returns true if traversal of this element's children is allowed. We use + /// this to cull traversal of various subtrees. + /// + /// This may be called multiple times when processing an element, so we pass + /// a parameter to keep the logs tidy. + fn should_traverse_children(parent: N::ConcreteElement, parent_data: &ElementData, + log: LogBehavior) -> bool + { + // See the comment on `cascade_node` for why we allow this on Gecko. + debug_assert!(cfg!(feature = "gecko") || parent_data.has_current_styles()); + + // If the parent computed display:none, we don't style the subtree. + if parent_data.styles().is_display_none() { + if log.allow() { debug!("Parent {:?} is display:none, culling traversal", parent); } + return false; + } + + // Gecko-only XBL handling. + // + // If we're computing initial styles and the parent has a Gecko XBL + // binding, that binding may inject anonymous children and remap the + // explicit children to an insertion point (or hide them entirely). It + // may also specify a scoped stylesheet, which changes the rules that + // apply within the subtree. These two effects can invalidate the result + // of property inheritance and selector matching (respectively) within the + // subtree. + // + // To avoid wasting work, we defer initial styling of XBL subtrees + // until frame construction, which does an explicit traversal of the + // unstyled children after shuffling the subtree. That explicit + // traversal may in turn find other bound elements, which get handled + // in the same way. + // + // We explicitly avoid handling restyles here (explicitly removing or + // changing bindings), since that adds complexity and is rarer. If it + // happens, we may just end up doing wasted work, since Gecko + // recursively drops Servo ElementData when the XBL insertion parent of + // an Element is changed. + if cfg!(feature = "gecko") && parent_data.is_styled_initial() && + parent_data.styles().primary.values.has_moz_binding() { + if log.allow() { debug!("Parent {:?} has XBL binding, deferring traversal", parent); } + return false; + } + + return true; - /// Returns true if traversal should visit the given child. - fn should_traverse_child(child: N) -> bool; + } /// Helper for the traversal implementations to select the children that /// should be enqueued for processing. fn traverse_children<F: FnMut(N)>(parent: N::ConcreteElement, mut f: F) { - use dom::StylingMode::Restyle; - - if parent.is_display_none() { + // Check if we're allowed to traverse past this element. + if !Self::should_traverse_children(parent, &parent.borrow_data().unwrap(), MayLog) { return; } for kid in parent.as_node().children() { - if Self::should_traverse_child(kid) { - if kid.as_element().map_or(false, |el| el.styling_mode() == Restyle) { + if Self::node_needs_traversal(kid) { + let el = kid.as_element(); + if el.as_ref().and_then(|el| el.borrow_data()) + .map_or(false, |d| d.is_restyle()) + { unsafe { parent.set_dirty_descendants(); } } f(kid); @@ -152,7 +249,9 @@ pub trait DomTraversalContext<N: TNode> { /// children of |element|. unsafe fn clear_element_data(element: &N::ConcreteElement); - fn local_context(&self) -> &LocalStyleContext; + fn shared_context(&self) -> &SharedStyleContext; + + fn create_thread_local_context(&self) -> Self::ThreadLocalContext; } /// Determines the amount of relations where we're going to share style. @@ -168,22 +267,22 @@ pub fn relations_are_shareable(relations: &StyleRelations) -> bool { /// Handles lazy resolution of style in display:none subtrees. See the comment /// at the callsite in query.rs. -pub fn style_element_in_display_none_subtree<'a, E, C, F>(element: E, - init_data: &F, - context: &'a C) -> E +pub fn style_element_in_display_none_subtree<E, F>(context: &StyleContext<E>, + element: E, init_data: &F) -> E where E: TElement, - C: StyleContext<'a>, F: Fn(E), { // Check the base case. if element.get_data().is_some() { - debug_assert!(element.is_display_none()); + // See the comment on `cascade_node` for why we allow this on Gecko. + debug_assert!(cfg!(feature = "gecko") || element.borrow_data().unwrap().has_current_styles()); + debug_assert!(element.borrow_data().unwrap().styles().is_display_none()); return element; } // Ensure the parent is styled. let parent = element.parent_element().unwrap(); - let display_none_root = style_element_in_display_none_subtree(parent, init_data, context); + let display_none_root = style_element_in_display_none_subtree(context, parent, init_data); // Initialize our data. init_data(element); @@ -205,70 +304,79 @@ pub fn style_element_in_display_none_subtree<'a, E, C, F>(element: E, /// Calculates the style for a single node. #[inline] #[allow(unsafe_code)] -pub fn recalc_style_at<'a, E, C, D>(context: &'a C, - data: &mut PerLevelTraversalData, - element: E) +pub fn recalc_style_at<E, D>(traversal: &D, + traversal_data: &mut PerLevelTraversalData, + context: &mut StyleContext<E>, + element: E, + mut data: &mut AtomicRefMut<ElementData>) where E: TElement, - C: StyleContext<'a>, - D: DomTraversalContext<E::ConcreteNode> + D: DomTraversal<E::ConcreteNode> { - let mode = element.styling_mode(); - let should_compute = element.borrow_data().map_or(true, |d| d.get_current_styles().is_none()); - debug!("recalc_style_at: {:?} (should_compute={:?} mode={:?}, data={:?})", - element, should_compute, mode, element.borrow_data()); + debug_assert!(data.as_restyle().map_or(true, |r| r.snapshot.is_none()), + "Snapshots should be expanded by the caller"); - let (computed_display_none, propagated_hint) = if should_compute { - compute_style::<_, _, D>(context, data, element) - } else { - (false, StoredRestyleHint::empty()) + let compute_self = !data.has_current_styles(); + let mut inherited_style_changed = false; + + debug!("recalc_style_at: {:?} (compute_self={:?}, dirty_descendants={:?}, data={:?})", + element, compute_self, element.has_dirty_descendants(), data); + + // Compute style for this element if necessary. + if compute_self { + inherited_style_changed = compute_style(traversal, traversal_data, context, element, &mut data); + } + + // Now that matching and cascading is done, clear the bits corresponding to + // those operations and compute the propagated restyle hint. + let empty_hint = StoredRestyleHint::empty(); + let propagated_hint = match data.as_restyle_mut() { + None => empty_hint, + Some(r) => { + r.recascade = false; + mem::replace(&mut r.hint, empty_hint).propagate() + }, }; + debug_assert!(data.has_current_styles()); + trace!("propagated_hint={:?}, inherited_style_changed={:?}", propagated_hint, inherited_style_changed); - // Preprocess children, computing restyle hints and handling sibling relationships. - // - // We don't need to do this if we're not traversing children, or if we're performing - // initial styling. - let will_traverse_children = !computed_display_none && - (mode == StylingMode::Restyle || - mode == StylingMode::Traverse); - if will_traverse_children { - preprocess_children::<_, _, D>(context, element, propagated_hint, - mode == StylingMode::Restyle); + // Preprocess children, propagating restyle hints and handling sibling relationships. + if D::should_traverse_children(element, &data, DontLog) && + (element.has_dirty_descendants() || !propagated_hint.is_empty() || inherited_style_changed) { + preprocess_children(traversal, element, propagated_hint, inherited_style_changed); } } -fn compute_style<'a, E, C, D>(context: &'a C, - data: &mut PerLevelTraversalData, - element: E) -> (bool, StoredRestyleHint) +// Computes style, returning true if the inherited styles changed for this +// element. +// +// FIXME(bholley): This should differentiate between matching and cascading, +// since we have separate bits for each now. +fn compute_style<E, D>(_traversal: &D, + traversal_data: &mut PerLevelTraversalData, + context: &mut StyleContext<E>, + element: E, + mut data: &mut AtomicRefMut<ElementData>) -> bool where E: TElement, - C: StyleContext<'a>, - D: DomTraversalContext<E::ConcreteNode> + D: DomTraversal<E::ConcreteNode>, { - let shared_context = context.shared_context(); - let mut bf = take_thread_local_bloom_filter(shared_context); + let shared_context = context.shared; // Ensure the bloom filter is up to date. - let dom_depth = bf.insert_parents_recovering(element, - data.current_dom_depth, - shared_context.generation); + let dom_depth = context.thread_local.bloom_filter + .insert_parents_recovering(element, traversal_data.current_dom_depth); // Update the dom depth with the up-to-date dom depth. // // Note that this is always the same than the pre-existing depth, but it can // change from unknown to known at this step. - data.current_dom_depth = Some(dom_depth); + traversal_data.current_dom_depth = Some(dom_depth); - bf.assert_complete(element); - - let mut data = unsafe { D::ensure_element_data(&element).borrow_mut() }; - debug_assert!(!data.is_persistent()); + context.thread_local.bloom_filter.assert_complete(element); // Check to see whether we can share a style with someone. - let style_sharing_candidate_cache = - &mut context.local_context().style_sharing_candidate_cache.borrow_mut(); - let sharing_result = if element.parent_element().is_none() { StyleSharingResult::CannotShare } else { - unsafe { element.share_style_if_possible(style_sharing_candidate_cache, + unsafe { element.share_style_if_possible(&mut context.thread_local.style_sharing_candidate_cache, shared_context, &mut data) } }; @@ -282,7 +390,8 @@ fn compute_style<'a, E, C, D>(context: &'a C, } // Perform the CSS selector matching. - match_results = element.match_element(context, Some(bf.filter())); + let filter = context.thread_local.bloom_filter.filter(); + match_results = element.match_element(context, Some(filter)); if match_results.primary_is_shareable() { Some(element) } else { @@ -303,44 +412,39 @@ fn compute_style<'a, E, C, D>(context: &'a C, // Add ourselves to the LRU cache. if let Some(element) = shareable_element { - style_sharing_candidate_cache.insert_if_possible(&element, - &data.current_styles().primary.values, - relations); + context.thread_local + .style_sharing_candidate_cache + .insert_if_possible(&element, &data.styles().primary.values, relations); } } StyleSharingResult::StyleWasShared(index) => { if opts::get().style_sharing_stats { STYLE_SHARING_CACHE_HITS.fetch_add(1, Ordering::Relaxed); } - style_sharing_candidate_cache.touch(index); + context.thread_local.style_sharing_candidate_cache.touch(index); } } // If we're restyling this element to display:none, throw away all style data // in the subtree, notify the caller to early-return. - let display_none = data.current_styles().is_display_none(); + let display_none = data.styles().is_display_none(); if display_none { debug!("New element style is display:none - clearing data from descendants."); clear_descendant_data(element, &|e| unsafe { D::clear_element_data(&e) }); } - // TODO(emilio): It's pointless to insert the element in the parallel - // traversal, but it may be worth todo it for sequential restyling. What we - // do now is trying to recover it which in that case is really cheap, so - // we'd save a few instructions, but probably not worth given the added - // complexity. - put_thread_local_bloom_filter(bf); + // FIXME(bholley): Compute this accurately from the call to CalcStyleDifference. + let inherited_styles_changed = true; - (display_none, data.as_restyle().map_or(StoredRestyleHint::empty(), |r| r.hint.propagate())) + inherited_styles_changed } -fn preprocess_children<'a, E, C, D>(context: &'a C, - element: E, - mut propagated_hint: StoredRestyleHint, - restyled_parent: bool) +fn preprocess_children<E, D>(traversal: &D, + element: E, + mut propagated_hint: StoredRestyleHint, + parent_inherited_style_changed: bool) where E: TElement, - C: StyleContext<'a>, - D: DomTraversalContext<E::ConcreteNode> + D: DomTraversal<E::ConcreteNode> { // Loop over all the children. for child in element.as_node().children() { @@ -350,41 +454,33 @@ fn preprocess_children<'a, E, C, D>(context: &'a C, None => continue, }; - // Set up our lazy child restyle data. - let mut child_data = unsafe { LazyRestyleData::<E, D>::new(&child) }; + let mut child_data = unsafe { D::ensure_element_data(&child).borrow_mut() }; + if child_data.is_unstyled_initial() { + continue; + } + + let mut restyle_data = match child_data.restyle() { + Some(d) => d, + None => continue, + }; // Propagate the parent and sibling restyle hint. if !propagated_hint.is_empty() { - child_data.ensure().map(|d| d.hint.insert(&propagated_hint)); + restyle_data.hint.insert(&propagated_hint); } - // Handle element snashots. - if child_data.has_snapshot() { - // Compute the restyle hint. - let mut restyle_data = child_data.ensure().unwrap(); - let mut hint = context.shared_context().stylist - .compute_restyle_hint(&child, - restyle_data.snapshot.as_ref().unwrap(), - child.get_state()); - - // If the hint includes a directive for later siblings, strip - // it out and modify the base hint for future siblings. - if hint.contains(RESTYLE_LATER_SIBLINGS) { - hint.remove(RESTYLE_LATER_SIBLINGS); - propagated_hint.insert(&(RESTYLE_SELF | RESTYLE_DESCENDANTS).into()); - } - - // Insert the hint. - if !hint.is_empty() { - restyle_data.hint.insert(&hint.into()); - } + // Handle element snapshots. + let stylist = &traversal.shared_context().stylist; + let later_siblings = restyle_data.expand_snapshot(child, stylist); + if later_siblings { + propagated_hint.insert(&(RESTYLE_SELF | RESTYLE_DESCENDANTS).into()); } - // If we restyled this node, conservatively mark all our children as - // needing a re-cascade. Once we have the rule tree, we will be able - // to distinguish between re-matching and re-cascading. - if restyled_parent { - child_data.ensure(); + // If properties that we inherited from the parent changed, we need to recascade. + // + // FIXME(bholley): Need to handle explicitly-inherited reset properties somewhere. + if parent_inherited_style_changed { + restyle_data.recascade = true; } } } @@ -404,60 +500,3 @@ pub fn clear_descendant_data<E: TElement, F: Fn(E)>(el: E, clear_data: &F) { unsafe { el.unset_dirty_descendants(); } } - -/// Various steps in the child preparation algorithm above may cause us to lazily -/// instantiate the ElementData on the child. Encapsulate that logic into a -/// convenient abstraction. -struct LazyRestyleData<'b, E: TElement + 'b, D: DomTraversalContext<E::ConcreteNode>> { - data: Option<AtomicRefMut<'b, ElementData>>, - element: &'b E, - phantom: PhantomData<D>, -} - -impl<'b, E: TElement, D: DomTraversalContext<E::ConcreteNode>> LazyRestyleData<'b, E, D> { - /// This may lazily instantiate ElementData, and is therefore only safe to - /// call on an element for which we have exclusive access. - unsafe fn new(element: &'b E) -> Self { - LazyRestyleData { - data: None, - element: element, - phantom: PhantomData, - } - } - - fn ensure(&mut self) -> Option<&mut RestyleData> { - if self.data.is_none() { - let mut d = unsafe { D::ensure_element_data(self.element).borrow_mut() }; - d.restyle(); - self.data = Some(d); - } - - self.data.as_mut().unwrap().as_restyle_mut() - } - - /// Checks for the existence of an element snapshot without lazily instantiating - /// anything. This allows the traversal to cheaply pass through already-styled - /// nodes when they don't need a restyle. - fn has_snapshot(&self) -> bool { - // If there's no element data, we're done. - let raw_data = self.element.get_data(); - if raw_data.is_none() { - debug_assert!(self.data.is_none()); - return false; - } - - // If there is element data, we still may not have committed to processing - // the node. Carefully get a reference to the data. - let maybe_tmp_borrow; - let borrow_ref = match self.data { - Some(ref d) => d, - None => { - maybe_tmp_borrow = raw_data.unwrap().borrow_mut(); - &maybe_tmp_borrow - } - }; - - // Check for a snapshot. - borrow_ref.as_restyle().map_or(false, |d| d.snapshot.is_some()) - } -} diff --git a/components/style/values/computed/image.rs b/components/style/values/computed/image.rs index f99ed74ac5e..007cbdad9df 100644 --- a/components/style/values/computed/image.rs +++ b/components/style/values/computed/image.rs @@ -8,11 +8,12 @@ //! [image]: https://drafts.csswg.org/css-images/#image-values use cssparser::Color as CSSColor; +use std::f32::consts::PI; use std::fmt; use style_traits::ToCss; -use values::computed::{Context, Length, LengthOrPercentage, ToComputedValue}; +use values::computed::{Angle, Context, Length, LengthOrPercentage, ToComputedValue}; use values::computed::position::Position; -use values::specified::{self, AngleOrCorner, SizeKeyword}; +use values::specified::{self, HorizontalDirection, SizeKeyword, VerticalDirection}; use values::specified::url::SpecifiedUrl; @@ -185,7 +186,7 @@ impl ToComputedValue for specified::GradientKind { fn to_computed_value(&self, context: &Context) -> GradientKind { match *self { specified::GradientKind::Linear(angle_or_corner) => { - GradientKind::Linear(angle_or_corner) + GradientKind::Linear(angle_or_corner.to_computed_value(context)) }, specified::GradientKind::Radial(ref shape, position) => { GradientKind::Radial(shape.to_computed_value(context), @@ -454,3 +455,75 @@ impl ToComputedValue for specified::LengthOrPercentageOrKeyword { } } } + +#[derive(Clone, Copy, Debug, PartialEq)] +#[cfg_attr(feature = "servo", derive(HeapSizeOf))] +pub enum AngleOrCorner { + Angle(Angle), + Corner(HorizontalDirection, VerticalDirection) +} + +impl ToComputedValue for specified::AngleOrCorner { + type ComputedValue = AngleOrCorner; + + #[inline] + fn to_computed_value(&self, _: &Context) -> AngleOrCorner { + match *self { + specified::AngleOrCorner::None => { + AngleOrCorner::Angle(Angle(0.0)) + }, + specified::AngleOrCorner::Angle(angle) => { + AngleOrCorner::Angle(angle) + }, + specified::AngleOrCorner::Corner(horizontal, vertical) => { + match (horizontal, vertical) { + (None, Some(VerticalDirection::Top)) => { + AngleOrCorner::Angle(Angle(0.0)) + }, + (Some(HorizontalDirection::Right), None) => { + AngleOrCorner::Angle(Angle(PI * 0.5)) + }, + (None, Some(VerticalDirection::Bottom)) => { + AngleOrCorner::Angle(Angle(PI)) + }, + (Some(HorizontalDirection::Left), None) => { + AngleOrCorner::Angle(Angle(PI * 1.5)) + }, + (Some(horizontal), Some(vertical)) => { + AngleOrCorner::Corner(horizontal, vertical) + }, + (None, None) => { + unreachable!() + } + } + } + } + } + + #[inline] + fn from_computed_value(computed: &AngleOrCorner) -> Self { + match *computed { + AngleOrCorner::Angle(angle) => { + specified::AngleOrCorner::Angle(angle) + }, + AngleOrCorner::Corner(horizontal, vertical) => { + specified::AngleOrCorner::Corner(Some(horizontal), Some(vertical)) + } + } + } +} + +impl ToCss for AngleOrCorner { + fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write { + match *self { + AngleOrCorner::Angle(angle) => angle.to_css(dest), + AngleOrCorner::Corner(horizontal, vertical) => { + try!(dest.write_str("to ")); + try!(horizontal.to_css(dest)); + try!(dest.write_str(" ")); + try!(vertical.to_css(dest)); + Ok(()) + } + } + } +} diff --git a/components/style/values/computed/length.rs b/components/style/values/computed/length.rs index 3ba131409f8..a7ec7f5ba22 100644 --- a/components/style/values/computed/length.rs +++ b/components/style/values/computed/length.rs @@ -7,7 +7,7 @@ use ordered_float::NotNaN; use std::fmt; use style_traits::ToCss; use super::{Number, ToComputedValue, Context}; -use values::{Auto, CSSFloat, Either, None_, specified}; +use values::{Auto, CSSFloat, Either, None_, Normal, specified}; pub use cssparser::Color as CSSColor; pub use super::image::{EndingShape as GradientShape, Gradient, GradientKind, Image}; @@ -475,4 +475,6 @@ pub type LengthOrAuto = Either<Length, Auto>; pub type LengthOrNumber = Either<Length, Number>; +pub type LengthOrNormal = Either<Length, Normal>; + pub type Length = Au; diff --git a/components/style/values/computed/mod.rs b/components/style/values/computed/mod.rs index 7dfbb901ee8..a22a799206f 100644 --- a/components/style/values/computed/mod.rs +++ b/components/style/values/computed/mod.rs @@ -11,10 +11,10 @@ use style_traits::ToCss; use super::{CSSFloat, specified}; pub use cssparser::Color as CSSColor; -pub use self::image::{EndingShape as GradientShape, Gradient, GradientKind, Image}; +pub use self::image::{AngleOrCorner, EndingShape as GradientShape, Gradient, GradientKind, Image}; pub use self::image::{LengthOrKeyword, LengthOrPercentageOrKeyword}; pub use super::{Either, None_}; -pub use super::specified::{Angle, BorderStyle, Time, UrlOrNone}; +pub use super::specified::{Angle, BorderStyle, GridLine, Time, UrlOrNone}; pub use super::specified::url::UrlExtraData; pub use self::length::{CalcLengthOrPercentage, Length, LengthOrNumber, LengthOrPercentage, LengthOrPercentageOrAuto}; pub use self::length::{LengthOrPercentageOrAutoOrContent, LengthOrPercentageOrNone, LengthOrNone}; @@ -167,5 +167,16 @@ impl ToCss for BorderRadiusSize { } } +#[derive(Debug, PartialEq, Clone, Copy)] +#[cfg_attr(feature = "servo", derive(HeapSizeOf))] +pub struct Shadow { + pub offset_x: Au, + pub offset_y: Au, + pub blur_radius: Au, + pub spread_radius: Au, + pub color: CSSColor, + pub inset: bool, +} + pub type Number = CSSFloat; pub type Opacity = CSSFloat; diff --git a/components/style/values/computed/position.rs b/components/style/values/computed/position.rs index d2a561639f4..f93d59db99c 100644 --- a/components/style/values/computed/position.rs +++ b/components/style/values/computed/position.rs @@ -26,3 +26,23 @@ impl ToCss for Position { Ok(()) } } + +#[derive(Debug, Clone, PartialEq, Copy)] +#[cfg_attr(feature = "servo", derive(HeapSizeOf))] +pub struct HorizontalPosition(pub LengthOrPercentage); + +impl ToCss for HorizontalPosition { + fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write { + self.0.to_css(dest) + } +} + +#[derive(Debug, Clone, PartialEq, Copy)] +#[cfg_attr(feature = "servo", derive(HeapSizeOf))] +pub struct VerticalPosition(pub LengthOrPercentage); + +impl ToCss for VerticalPosition { + fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write { + self.0.to_css(dest) + } +} diff --git a/components/style/values/specified/basic_shape.rs b/components/style/values/specified/basic_shape.rs index b754eefde69..a943d4ec7da 100644 --- a/components/style/values/specified/basic_shape.rs +++ b/components/style/values/specified/basic_shape.rs @@ -15,7 +15,7 @@ use style_traits::ToCss; use values::computed::{ComputedValueAsSpecified, Context, ToComputedValue}; use values::computed::basic_shape as computed_basic_shape; use values::specified::{BorderRadiusSize, LengthOrPercentage, Percentage}; -use values::specified::position::{Keyword, Position}; +use values::specified::position::{Keyword, Position, HorizontalPosition, VerticalPosition}; use values::specified::url::SpecifiedUrl; /// A shape source, for some reference box @@ -313,6 +313,7 @@ fn serialize_basicshape_position<W>(position: &Position, dest: &mut W) }, Some(Keyword::Left) | Some(Keyword::Top) | None => pc, Some(Keyword::Right) | Some(Keyword::Bottom) => Percentage(1.0 - pc.0), + _ => return None, }; Some(LengthOrPercentage::Percentage(percent)) } @@ -336,8 +337,8 @@ fn serialize_basicshape_position<W>(position: &Position, dest: &mut W) replace_with_percent(y).to_css(dest) } - match (position.horiz_keyword, position.horiz_position, - position.vert_keyword, position.vert_position) { + match (position.horizontal.keyword, position.horizontal.position, + position.vertical.keyword, position.vertical.position) { (Some(hk), None, Some(vk), None) => { // two keywords: serialize as two lengths serialize_position_pair(hk.to_length_or_percentage(), @@ -385,10 +386,14 @@ impl Circle { } else { // Defaults to origin Position { - horiz_keyword: Some(Keyword::Center), - horiz_position: None, - vert_keyword: Some(Keyword::Center), - vert_position: None, + horizontal: HorizontalPosition { + keyword: Some(Keyword::Center), + position: None, + }, + vertical: VerticalPosition { + keyword: Some(Keyword::Center), + position: None, + }, } }; Ok(Circle { @@ -462,10 +467,14 @@ impl Ellipse { } else { // Defaults to origin Position { - horiz_keyword: Some(Keyword::Center), - horiz_position: None, - vert_keyword: Some(Keyword::Center), - vert_position: None, + horizontal: HorizontalPosition { + keyword: Some(Keyword::Center), + position: None, + }, + vertical: VerticalPosition { + keyword: Some(Keyword::Center), + position: None, + }, } }; Ok(Ellipse { diff --git a/components/style/values/specified/grid.rs b/components/style/values/specified/grid.rs new file mode 100644 index 00000000000..8e6eca56372 --- /dev/null +++ b/components/style/values/specified/grid.rs @@ -0,0 +1,96 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +use cssparser::Parser; +use parser::{Parse, ParserContext}; +use std::fmt; +use style_traits::ToCss; +use values::NoViewportPercentage; +use values::computed::ComputedValueAsSpecified; + +// https://drafts.csswg.org/css-grid/#typedef-grid-row-start-grid-line +#[derive(PartialEq, Clone, Debug)] +#[cfg_attr(feature = "servo", derive(HeapSizeOf))] +pub struct GridLine { + pub is_span: bool, + pub ident: Option<String>, + pub integer: Option<i32>, +} + +impl Default for GridLine { + fn default() -> Self { + GridLine { + is_span: false, + ident: None, + integer: None, + } + } +} + +impl ToCss for GridLine { + fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write { + if !self.is_span && self.ident.is_none() && self.integer.is_none() { + return dest.write_str("auto") + } + + if self.is_span { + try!(dest.write_str("span")); + } + + if let Some(i) = self.integer { + try!(write!(dest, " {}", i)); + } + + if let Some(ref s) = self.ident { + try!(write!(dest, " {}", s)); + } + + Ok(()) + } +} + +impl Parse for GridLine { + fn parse(_context: &ParserContext, input: &mut Parser) -> Result<Self, ()> { + let mut grid_line = Default::default(); + if input.try(|i| i.expect_ident_matching("auto")).is_ok() { + return Ok(grid_line) + } + + for _ in 0..3 { // Maximum possible entities for <grid-line> + if input.try(|i| i.expect_ident_matching("span")).is_ok() { + if grid_line.is_span { + return Err(()) + } + grid_line.is_span = true; + } else if let Ok(i) = input.try(|i| i.expect_integer()) { + if i == 0 || grid_line.integer.is_some() { + return Err(()) + } + grid_line.integer = Some(i); + } else if let Ok(name) = input.try(|i| i.expect_ident()) { + if grid_line.ident.is_some() { + return Err(()) + } + grid_line.ident = Some(name.into_owned()); + } else { + break + } + } + + if grid_line.is_span { + if let Some(i) = grid_line.integer { + if i < 0 { // disallow negative integers for grid spans + return Err(()) + } + } else { + grid_line.integer = Some(1); + } + } + + Ok(grid_line) + } +} + +impl ComputedValueAsSpecified for GridLine {} +impl NoViewportPercentage for GridLine {} diff --git a/components/style/values/specified/image.rs b/components/style/values/specified/image.rs index 94a56d73541..af0ed3a2baf 100644 --- a/components/style/values/specified/image.rs +++ b/components/style/values/specified/image.rs @@ -10,10 +10,8 @@ use cssparser::Parser; use parser::{Parse, ParserContext}; use servo_url::ServoUrl; -use std::f32::consts::PI; use std::fmt; use style_traits::ToCss; -use values::computed::ComputedValueAsSpecified; use values::specified::{Angle, CSSColor, Length, LengthOrPercentage}; use values::specified::position::Position; use values::specified::url::{SpecifiedUrl, UrlExtraData}; @@ -47,7 +45,7 @@ impl Image { /// Creates an already specified image value from an already resolved URL /// for insertion in the cascade. - pub fn for_cascade(url: Option<ServoUrl>, extra_data: UrlExtraData) -> Self { + pub fn for_cascade(url: ServoUrl, extra_data: UrlExtraData) -> Self { Image::Url(SpecifiedUrl::for_cascade(url, extra_data)) } } @@ -70,10 +68,14 @@ impl ToCss for Gradient { if self.repeating { try!(dest.write_str("repeating-")); } + let mut skipcomma = false; match self.gradient_kind { GradientKind::Linear(angle_or_corner) => { try!(dest.write_str("linear-gradient(")); try!(angle_or_corner.to_css(dest)); + if angle_or_corner == AngleOrCorner::None { + skipcomma = true; + } }, GradientKind::Radial(ref shape, position) => { try!(dest.write_str("radial-gradient(")); @@ -83,7 +85,11 @@ impl ToCss for Gradient { }, } for stop in &self.stops { - try!(dest.write_str(", ")); + if !skipcomma { + try!(dest.write_str(", ")); + } else { + skipcomma = false; + } try!(stop.to_css(dest)); } dest.write_str(")") @@ -230,18 +236,28 @@ fn parse_position(context: &ParserContext, input: &mut Parser) -> Result<Positio #[cfg_attr(feature = "servo", derive(HeapSizeOf))] pub enum AngleOrCorner { Angle(Angle), - Corner(HorizontalDirection, VerticalDirection), + Corner(Option<HorizontalDirection>, Option<VerticalDirection>), + None, } impl ToCss for AngleOrCorner { fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write { match *self { + AngleOrCorner::None => Ok(()), AngleOrCorner::Angle(angle) => angle.to_css(dest), AngleOrCorner::Corner(horizontal, vertical) => { try!(dest.write_str("to ")); - try!(horizontal.to_css(dest)); - try!(dest.write_str(" ")); - try!(vertical.to_css(dest)); + let mut horizontal_present = false; + if let Some(horizontal) = horizontal { + try!(horizontal.to_css(dest)); + horizontal_present = true; + } + if let Some(vertical) = vertical { + if horizontal_present { + try!(dest.write_str(" ")); + } + try!(vertical.to_css(dest)); + } Ok(()) } } @@ -259,35 +275,16 @@ impl Parse for AngleOrCorner { (input.try(HorizontalDirection::parse).ok(), Some(value)) }; try!(input.expect_comma()); - match (horizontal, vertical) { - (None, Some(VerticalDirection::Top)) => { - Ok(AngleOrCorner::Angle(Angle(0.0))) - }, - (Some(HorizontalDirection::Right), None) => { - Ok(AngleOrCorner::Angle(Angle(PI * 0.5))) - }, - (None, Some(VerticalDirection::Bottom)) => { - Ok(AngleOrCorner::Angle(Angle(PI))) - }, - (Some(HorizontalDirection::Left), None) => { - Ok(AngleOrCorner::Angle(Angle(PI * 1.5))) - }, - (Some(horizontal), Some(vertical)) => { - Ok(AngleOrCorner::Corner(horizontal, vertical)) - } - (None, None) => unreachable!(), - } + Ok(AngleOrCorner::Corner(horizontal, vertical)) } else if let Ok(angle) = input.try(|i| Angle::parse(context, i)) { try!(input.expect_comma()); Ok(AngleOrCorner::Angle(angle)) } else { - Ok(AngleOrCorner::Angle(Angle(PI))) + Ok(AngleOrCorner::None) } } } -impl ComputedValueAsSpecified for AngleOrCorner {} - /// Specified values for one color stop in a linear gradient. /// https://drafts.csswg.org/css-images/#typedef-color-stop-list #[derive(Clone, PartialEq, Debug)] diff --git a/components/style/values/specified/length.rs b/components/style/values/specified/length.rs index f8f237ab401..40fb57a4963 100644 --- a/components/style/values/specified/length.rs +++ b/components/style/values/specified/length.rs @@ -14,7 +14,7 @@ use std::ops::Mul; use style_traits::ToCss; use style_traits::values::specified::AllowedNumericType; use super::{Angle, Number, SimplifiedValueNode, SimplifiedSumNode, Time}; -use values::{Auto, CSSFloat, Either, FONT_MEDIUM_PX, HasViewportPercentage, None_}; +use values::{Auto, CSSFloat, Either, FONT_MEDIUM_PX, HasViewportPercentage, None_, Normal}; use values::computed::Context; pub use super::image::{AngleOrCorner, ColorStop, EndingShape as GradientEndingShape, Gradient}; @@ -952,6 +952,8 @@ impl Parse for LengthOrPercentageOrNone { pub type LengthOrNone = Either<Length, None_>; +pub type LengthOrNormal = Either<Length, Normal>; + pub type LengthOrAuto = Either<Length, Auto>; #[derive(Clone, PartialEq, Copy, Debug)] diff --git a/components/style/values/specified/mod.rs b/components/style/values/specified/mod.rs index b71eb8140bf..3b0dd2011b3 100644 --- a/components/style/values/specified/mod.rs +++ b/components/style/values/specified/mod.rs @@ -14,7 +14,9 @@ use std::ops::Mul; use style_traits::ToCss; use super::{CSSFloat, HasViewportPercentage, NoViewportPercentage, Either, None_}; use super::computed::{ComputedValueAsSpecified, Context, ToComputedValue}; +use super::computed::Shadow as ComputedShadow; +pub use self::grid::GridLine; pub use self::image::{AngleOrCorner, ColorStop, EndingShape as GradientEndingShape, Gradient}; pub use self::image::{GradientKind, HorizontalDirection, Image, LengthOrKeyword, LengthOrPercentageOrKeyword}; pub use self::image::{SizeKeyword, VerticalDirection}; @@ -23,6 +25,7 @@ pub use self::length::{Percentage, LengthOrNone, LengthOrNumber, LengthOrPercent pub use self::length::{LengthOrPercentageOrNone, LengthOrPercentageOrAutoOrContent, CalcUnit}; pub mod basic_shape; +pub mod grid; pub mod image; pub mod length; pub mod position; @@ -517,3 +520,117 @@ impl ToCss for Opacity { pub type UrlOrNone = Either<SpecifiedUrl, None_>; +#[derive(Debug, Clone, PartialEq)] +#[cfg_attr(feature = "servo", derive(HeapSizeOf))] +pub struct Shadow { + pub offset_x: Length, + pub offset_y: Length, + pub blur_radius: Length, + pub spread_radius: Length, + pub color: Option<CSSColor>, + pub inset: bool, +} + +impl HasViewportPercentage for Shadow { + fn has_viewport_percentage(&self) -> bool { + self.offset_x.has_viewport_percentage() || + self.offset_y.has_viewport_percentage() || + self.blur_radius.has_viewport_percentage() || + self.spread_radius.has_viewport_percentage() + } +} + +impl ToComputedValue for Shadow { + type ComputedValue = ComputedShadow; + + #[inline] + fn to_computed_value(&self, context: &Context) -> Self::ComputedValue { + ComputedShadow { + offset_x: self.offset_x.to_computed_value(context), + offset_y: self.offset_y.to_computed_value(context), + blur_radius: self.blur_radius.to_computed_value(context), + spread_radius: self.spread_radius.to_computed_value(context), + color: self.color + .as_ref() + .map(|color| color.parsed) + .unwrap_or(cssparser::Color::CurrentColor), + inset: self.inset, + } + } + + #[inline] + fn from_computed_value(computed: &ComputedShadow) -> Self { + Shadow { + offset_x: ToComputedValue::from_computed_value(&computed.offset_x), + offset_y: ToComputedValue::from_computed_value(&computed.offset_y), + blur_radius: ToComputedValue::from_computed_value(&computed.blur_radius), + spread_radius: ToComputedValue::from_computed_value(&computed.spread_radius), + color: Some(ToComputedValue::from_computed_value(&computed.color)), + inset: computed.inset, + } + } +} + +impl Shadow { + // disable_spread_and_inset is for filter: drop-shadow(...) + pub fn parse(context: &ParserContext, input: &mut Parser, disable_spread_and_inset: bool) -> Result<Shadow, ()> { + use app_units::Au; + let length_count = if disable_spread_and_inset { 3 } else { 4 }; + let mut lengths = [Length::Absolute(Au(0)); 4]; + let mut lengths_parsed = false; + let mut color = None; + let mut inset = false; + + loop { + if !inset && !disable_spread_and_inset { + if input.try(|input| input.expect_ident_matching("inset")).is_ok() { + inset = true; + continue + } + } + if !lengths_parsed { + if let Ok(value) = input.try(|i| Length::parse(context, i)) { + lengths[0] = value; + let mut length_parsed_count = 1; + while length_parsed_count < length_count { + if let Ok(value) = input.try(|i| Length::parse(context, i)) { + lengths[length_parsed_count] = value + } else { + break + } + length_parsed_count += 1; + } + + // The first two lengths must be specified. + if length_parsed_count < 2 { + return Err(()) + } + + lengths_parsed = true; + continue + } + } + if color.is_none() { + if let Ok(value) = input.try(|i| CSSColor::parse(context, i)) { + color = Some(value); + continue + } + } + break + } + + // Lengths must be specified. + if !lengths_parsed { + return Err(()) + } + + Ok(Shadow { + offset_x: lengths[0], + offset_y: lengths[1], + blur_radius: lengths[2], + spread_radius: if disable_spread_and_inset { Length::Absolute(Au(0)) } else { lengths[3] }, + color: color, + inset: inset, + }) + } +} diff --git a/components/style/values/specified/position.rs b/components/style/values/specified/position.rs index ed9813cf02c..d572e076f6f 100644 --- a/components/style/values/specified/position.rs +++ b/components/style/values/specified/position.rs @@ -21,31 +21,29 @@ use values::specified::{LengthOrPercentage, Percentage}; #[derive(Debug, Clone, PartialEq, Copy)] #[cfg_attr(feature = "servo", derive(HeapSizeOf))] pub struct Position { - pub horiz_keyword: Option<Keyword>, - pub horiz_position: Option<LengthOrPercentage>, - pub vert_keyword: Option<Keyword>, - pub vert_position: Option<LengthOrPercentage>, + pub horizontal: HorizontalPosition, + pub vertical: VerticalPosition, } impl ToCss for Position { fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write { - let mut space_at_last = false; - if let Some(horiz_key) = self.horiz_keyword { + let mut space_present = false; + if let Some(horiz_key) = self.horizontal.keyword { try!(horiz_key.to_css(dest)); try!(dest.write_str(" ")); - space_at_last = true; + space_present = true; }; - if let Some(horiz_pos) = self.horiz_position { + if let Some(horiz_pos) = self.horizontal.position { try!(horiz_pos.to_css(dest)); try!(dest.write_str(" ")); - space_at_last = true; + space_present = true; }; - if let Some(vert_key) = self.vert_keyword { + if let Some(vert_key) = self.vertical.keyword { try!(vert_key.to_css(dest)); - space_at_last = false; + space_present = false; }; - if let Some(vert_pos) = self.vert_position { - if space_at_last == false { + if let Some(vert_pos) = self.vertical.position { + if space_present == false { try!(dest.write_str(" ")); } try!(vert_pos.to_css(dest)); @@ -56,38 +54,10 @@ impl ToCss for Position { impl HasViewportPercentage for Position { fn has_viewport_percentage(&self) -> bool { - let horiz_viewport = if let Some(horiz_pos) = self.horiz_position { - horiz_pos.has_viewport_percentage() - } else { - false - }; - - let vert_viewport = if let Some(vert_pos) = self.vert_position { - vert_pos.has_viewport_percentage() - } else { - false - }; - horiz_viewport || vert_viewport + self.horizontal.has_viewport_percentage() || self.vertical.has_viewport_percentage() } } -#[derive(Debug, Clone, PartialEq, Copy)] -#[cfg_attr(feature = "servo", derive(HeapSizeOf))] -pub enum Keyword { - Center, - Left, - Right, - Top, - Bottom, -} - -// http://dev.w3.org/csswg/css2/colors.html#propdef-background-position -#[derive(Clone, PartialEq, Copy)] -pub enum PositionComponent { - Length(LengthOrPercentage), - Keyword(Keyword), -} - impl Position { pub fn new(mut first_position: Option<PositionComponent>, mut second_position: Option<PositionComponent>, first_keyword: Option<PositionComponent>, second_keyword: Option<PositionComponent>) @@ -117,6 +87,12 @@ impl Position { (PositionCategory::LengthOrPercentage, PositionCategory::HorizontalKeyword) | (PositionCategory::VerticalKeyword, PositionCategory::LengthOrPercentage) => return Err(()), + // FIXME(canaltinova): Allow logical keywords for Position. They are not in current spec yet. + (PositionCategory::HorizontalLogicalKeyword, _) | + (PositionCategory::VerticalLogicalKeyword, _) | + (_, PositionCategory::HorizontalLogicalKeyword) | + (_, PositionCategory::VerticalLogicalKeyword) => return Err(()), + // Swap if both are keywords and vertical precedes horizontal. (PositionCategory::VerticalKeyword, PositionCategory::HorizontalKeyword) | (PositionCategory::VerticalKeyword, PositionCategory::OtherKeyword) | @@ -163,19 +139,27 @@ impl Position { }; Ok(Position { - horiz_keyword: horizontal_keyword, - horiz_position: first_position, - vert_keyword: vertical_keyword, - vert_position: second_position, + horizontal: HorizontalPosition { + keyword: horizontal_keyword, + position: first_position, + }, + vertical: VerticalPosition { + keyword: vertical_keyword, + position: second_position, + }, }) } pub fn center() -> Position { Position { - horiz_keyword: Some(Keyword::Center), - horiz_position: None, - vert_keyword: Some(Keyword::Center), - vert_position: None, + horizontal: HorizontalPosition { + keyword: Some(Keyword::Center), + position: None, + }, + vertical: VerticalPosition { + keyword: Some(Keyword::Center), + position: None, + }, } } } @@ -230,66 +214,126 @@ impl Parse for Position { } } -impl Keyword { - pub fn to_length_or_percentage(self) -> LengthOrPercentage { - match self { - Keyword::Center => LengthOrPercentage::Percentage(Percentage(0.5)), - Keyword::Left | Keyword::Top => LengthOrPercentage::Percentage(Percentage(0.0)), - Keyword::Right | Keyword::Bottom => LengthOrPercentage::Percentage(Percentage(1.0)), +impl ToComputedValue for Position { + type ComputedValue = computed_position::Position; + + #[inline] + fn to_computed_value(&self, context: &Context) -> computed_position::Position { + computed_position::Position { + horizontal: self.horizontal.to_computed_value(context).0, + vertical: self.vertical.to_computed_value(context).0, } } -} -impl ToCss for Keyword { - fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write { - match *self { - Keyword::Center => try!(dest.write_str("center")), - Keyword::Left => try!(dest.write_str("left")), - Keyword::Right => try!(dest.write_str("right")), - Keyword::Top => try!(dest.write_str("top")), - Keyword::Bottom => try!(dest.write_str("bottom")), + #[inline] + fn from_computed_value(computed: &computed_position::Position) -> Position { + Position { + horizontal: HorizontalPosition { + keyword: None, + position: Some(ToComputedValue::from_computed_value(&computed.horizontal)), + }, + vertical: VerticalPosition { + keyword: None, + position: Some(ToComputedValue::from_computed_value(&computed.vertical)), + }, } - Ok(()) } } -// Collapse `Position` into a few categories to simplify the above `match` expression. -enum PositionCategory { - HorizontalKeyword, - VerticalKeyword, - OtherKeyword, - LengthOrPercentage, +#[derive(Debug, Clone, PartialEq, Copy)] +#[cfg_attr(feature = "servo", derive(HeapSizeOf))] +pub struct HorizontalPosition { + pub keyword: Option<Keyword>, + pub position: Option<LengthOrPercentage>, } -fn category(p: PositionComponent) -> PositionCategory { - if let PositionComponent::Keyword(keyword) = p { - match keyword { - Keyword::Left | - Keyword::Right => - PositionCategory::HorizontalKeyword, - Keyword::Top | - Keyword::Bottom => - PositionCategory::VerticalKeyword, - Keyword::Center => - PositionCategory::OtherKeyword, +impl HasViewportPercentage for HorizontalPosition { + fn has_viewport_percentage(&self) -> bool { + if let Some(pos) = self.position { + pos.has_viewport_percentage() + } else { + false } - } else { - PositionCategory::LengthOrPercentage } } -impl ToComputedValue for Position { - type ComputedValue = computed_position::Position; +impl ToCss for HorizontalPosition { + fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write { + let mut keyword_present = false; + if let Some(keyword) = self.keyword { + try!(keyword.to_css(dest)); + keyword_present = true; + }; + if let Some(position) = self.position { + if keyword_present { + try!(dest.write_str(" ")); + } + try!(position.to_css(dest)); + }; + Ok(()) + } +} + +impl Parse for HorizontalPosition { #[inline] - fn to_computed_value(&self, context: &Context) -> computed_position::Position { - let horiz_keyword = self.horiz_keyword.unwrap_or(Keyword::Left); - let vert_keyword = self.vert_keyword.unwrap_or(Keyword::Top); + fn parse(context: &ParserContext, input: &mut Parser) -> Result<Self, ()> { + let first = try!(PositionComponent::parse(context, input)); + let second = input.try(|i| PositionComponent::parse(context, i)).ok(); + + let (keyword, position) = if let PositionCategory::LengthOrPercentage = category(first) { + // "length keyword?" + (second, Some(first)) + } else { + // "keyword length?" + (Some(first), second) + }; + + // Unwrapping and checking keyword. + let keyword = match keyword { + Some(PositionComponent::Keyword(key)) => { + match category(keyword.unwrap()) { + PositionCategory::VerticalKeyword | + PositionCategory::VerticalLogicalKeyword => return Err(()), + _ => Some(key), + } + }, + Some(_) => return Err(()), + None => None, + }; + + // Unwrapping and checking position. + let position = match position { + Some(PositionComponent::Length(pos)) => { + // "center <length>" is not allowed + if let Some(Keyword::Center) = keyword { + return Err(()); + } + Some(pos) + }, + Some(_) => return Err(()), + None => None, + }; + + Ok(HorizontalPosition { + keyword: keyword, + position: position, + }) + } +} + +impl ToComputedValue for HorizontalPosition { + type ComputedValue = computed_position::HorizontalPosition; + + #[inline] + fn to_computed_value(&self, context: &Context) -> computed_position::HorizontalPosition { + let keyword = self.keyword.unwrap_or(Keyword::Left); // Construct horizontal computed LengthOrPercentage - let horizontal = match horiz_keyword { - Keyword::Right => { - if let Some(x) = self.horiz_position { + let horizontal = match keyword { + // FIXME(canaltinova): Support logical keywords. + Keyword::Right | Keyword::XEnd => { + if let Some(x) = self.position { let (length, percentage) = match x { LengthOrPercentage::Percentage(Percentage(y)) => (Au(0), Some(1.0 - y)), LengthOrPercentage::Length(y) => (-y.to_computed_value(context), Some(1.0)), @@ -304,18 +348,121 @@ impl ToComputedValue for Position { } }, Keyword::Center => { - horiz_keyword.to_length_or_percentage().to_computed_value(context) + keyword.to_length_or_percentage().to_computed_value(context) }, _ => { - let horiz = self.horiz_position.unwrap_or(LengthOrPercentage::Percentage(Percentage(0.0))); + let horiz = self.position + .unwrap_or(LengthOrPercentage::Percentage(Percentage(0.0))); horiz.to_computed_value(context) }, }; + computed_position::HorizontalPosition(horizontal) + } + + #[inline] + fn from_computed_value(computed: &computed_position::HorizontalPosition) -> HorizontalPosition { + HorizontalPosition { + keyword: None, + position: Some(ToComputedValue::from_computed_value(&computed.0)), + } + } +} + +#[derive(Debug, Clone, PartialEq, Copy)] +#[cfg_attr(feature = "servo", derive(HeapSizeOf))] +pub struct VerticalPosition { + pub keyword: Option<Keyword>, + pub position: Option<LengthOrPercentage>, +} + +impl HasViewportPercentage for VerticalPosition { + fn has_viewport_percentage(&self) -> bool { + if let Some(pos) = self.position { + pos.has_viewport_percentage() + } else { + false + } + } +} + +impl ToCss for VerticalPosition { + fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write { + let mut keyword_present = false; + if let Some(keyword) = self.keyword { + try!(keyword.to_css(dest)); + keyword_present = true; + }; + + if let Some(position) = self.position { + if keyword_present { + try!(dest.write_str(" ")); + } + try!(position.to_css(dest)); + }; + Ok(()) + } +} + +impl Parse for VerticalPosition { + #[inline] + fn parse(context: &ParserContext, input: &mut Parser) -> Result<Self, ()> { + let first = try!(PositionComponent::parse(context, input)); + let second = input.try(|i| PositionComponent::parse(context, i)).ok(); + + let (keyword, position) = if let PositionCategory::LengthOrPercentage = category(first) { + // "length keyword?" + (second, Some(first)) + } else { + // "keyword length?" + (Some(first), second) + }; + + // Unwrapping and checking keyword. + let keyword = match keyword { + Some(PositionComponent::Keyword(key)) => { + match category(keyword.unwrap()) { + PositionCategory::HorizontalKeyword | + PositionCategory::HorizontalLogicalKeyword => return Err(()), + _ => Some(key), + } + }, + Some(_) => return Err(()), + None => None, + }; + + // Unwrapping and checking position. + let position = match position { + Some(PositionComponent::Length(pos)) => { + // "center <length>" is not allowed + if let Some(Keyword::Center) = keyword { + return Err(()); + } + Some(pos) + }, + Some(_) => return Err(()), + None => None, + }; + + Ok(VerticalPosition { + keyword: keyword, + position: position, + }) + } +} + +impl ToComputedValue for VerticalPosition { + type ComputedValue = computed_position::VerticalPosition; + + #[inline] + fn to_computed_value(&self, context: &Context) -> computed_position::VerticalPosition { + let keyword = self.keyword.unwrap_or(Keyword::Left); + // Construct vertical computed LengthOrPercentage - let vertical = match vert_keyword { - Keyword::Bottom => { - if let Some(x) = self.vert_position { + let vertical = match keyword { + // FIXME(canaltinova): Support logical keywords. + Keyword::Bottom | Keyword::YEnd => { + if let Some(x) = self.position { let (length, percentage) = match x { LengthOrPercentage::Percentage(Percentage(y)) => (Au(0), Some(1.0 - y)), LengthOrPercentage::Length(y) => (-y.to_computed_value(context), Some(1.0)), @@ -330,31 +477,87 @@ impl ToComputedValue for Position { } }, Keyword::Center => { - vert_keyword.to_length_or_percentage().to_computed_value(context) + keyword.to_length_or_percentage().to_computed_value(context) }, _ => { - let vert = self.vert_position.unwrap_or(LengthOrPercentage::Percentage(Percentage(0.0))); + let vert = self.position + .unwrap_or(LengthOrPercentage::Percentage(Percentage(0.0))); vert.to_computed_value(context) }, }; - computed_position::Position { - horizontal: horizontal, - vertical: vertical, - } + computed_position::VerticalPosition(vertical) } #[inline] - fn from_computed_value(computed: &computed_position::Position) -> Position { - Position { - horiz_keyword: None, - horiz_position: Some(ToComputedValue::from_computed_value(&computed.horizontal)), - vert_keyword: None, - vert_position: Some(ToComputedValue::from_computed_value(&computed.vertical)), + fn from_computed_value(computed: &computed_position::VerticalPosition) -> VerticalPosition { + VerticalPosition { + keyword: None, + position: Some(ToComputedValue::from_computed_value(&computed.0)), + } + } +} + +define_css_keyword_enum!(Keyword: + "center" => Center, + "left" => Left, + "right" => Right, + "top" => Top, + "bottom" => Bottom, + "x-start" => XStart, + "x-end" => XEnd, + "y-start" => YStart, + "y-end" => YEnd); + +impl Keyword { + pub fn to_length_or_percentage(self) -> LengthOrPercentage { + match self { + Keyword::Center => LengthOrPercentage::Percentage(Percentage(0.5)), + Keyword::Left | Keyword::Top => LengthOrPercentage::Percentage(Percentage(0.0)), + Keyword::Right | Keyword::Bottom => LengthOrPercentage::Percentage(Percentage(1.0)), + // FIXME(canaltinova): Support logical keywords + Keyword::XStart | Keyword::YStart => LengthOrPercentage::Percentage(Percentage(0.0)), + Keyword::XEnd | Keyword::YEnd => LengthOrPercentage::Percentage(Percentage(1.0)), } } } +// Collapse `Position` into a few categories to simplify the above `match` expression. +enum PositionCategory { + HorizontalKeyword, + VerticalKeyword, + HorizontalLogicalKeyword, + VerticalLogicalKeyword, + OtherKeyword, + LengthOrPercentage, +} + +// http://dev.w3.org/csswg/css2/colors.html#propdef-background-position +#[derive(Clone, PartialEq, Copy)] +pub enum PositionComponent { + Length(LengthOrPercentage), + Keyword(Keyword), +} + +fn category(p: PositionComponent) -> PositionCategory { + if let PositionComponent::Keyword(keyword) = p { + match keyword { + Keyword::Left | Keyword::Right => + PositionCategory::HorizontalKeyword, + Keyword::Top | Keyword::Bottom => + PositionCategory::VerticalKeyword, + Keyword::XStart | Keyword::XEnd => + PositionCategory::HorizontalLogicalKeyword, + Keyword::YStart | Keyword::YEnd => + PositionCategory::VerticalLogicalKeyword, + Keyword::Center => + PositionCategory::OtherKeyword, + } + } else { + PositionCategory::LengthOrPercentage + } +} + impl HasViewportPercentage for PositionComponent { fn has_viewport_percentage(&self) -> bool { match *self { @@ -387,6 +590,10 @@ impl Parse for PositionComponent { "right" => Ok(PositionComponent::Keyword(Keyword::Right)), "top" => Ok(PositionComponent::Keyword(Keyword::Top)), "bottom" => Ok(PositionComponent::Keyword(Keyword::Bottom)), + "x-start" => Ok(PositionComponent::Keyword(Keyword::XStart)), + "x-end" => Ok(PositionComponent::Keyword(Keyword::XEnd)), + "y-start" => Ok(PositionComponent::Keyword(Keyword::YStart)), + "y-end" => Ok(PositionComponent::Keyword(Keyword::YEnd)), _ => Err(()) } }, diff --git a/components/style/values/specified/url.rs b/components/style/values/specified/url.rs index d3100586c52..d856aac924a 100644 --- a/components/style/values/specified/url.rs +++ b/components/style/values/specified/url.rs @@ -11,8 +11,8 @@ use parser::{Parse, ParserContext}; #[cfg(feature = "gecko")] use parser::ParserContextExtraData; use servo_url::ServoUrl; +use std::borrow::Cow; use std::fmt::{self, Write}; -use std::ptr; use std::sync::Arc; use style_traits::ToCss; use values::NoViewportPercentage; @@ -76,7 +76,14 @@ pub struct SpecifiedUrl { impl Parse for SpecifiedUrl { fn parse(context: &ParserContext, input: &mut Parser) -> Result<Self, ()> { let url = try!(input.expect_url()); + Self::parse_from_string(url, context) + } +} +impl SpecifiedUrl { + pub fn parse_from_string<'a>(url: Cow<'a, str>, + context: &ParserContext) + -> Result<Self, ()> { let extra_data = match UrlExtraData::make_from(context) { Some(extra_data) => extra_data, None => { @@ -96,9 +103,7 @@ impl Parse for SpecifiedUrl { extra_data: extra_data, }) } -} -impl SpecifiedUrl { pub fn extra_data(&self) -> &UrlExtraData { &self.extra_data } @@ -115,19 +120,24 @@ impl SpecifiedUrl { } /// Little helper for Gecko's ffi. - pub fn as_slice_components(&self) -> (*const u8, usize) { + #[cfg(feature = "gecko")] + pub fn as_slice_components(&self) -> Result<(*const u8, usize), (*const u8, usize)> { match self.resolved { - Some(ref url) => (url.as_str().as_ptr(), url.as_str().len()), - None => (ptr::null(), 0), + Some(ref url) => Ok((url.as_str().as_ptr(), url.as_str().len())), + None => { + let url = self.original.as_ref() + .expect("We should always have either the original or the resolved value"); + Err((url.as_str().as_ptr(), url.as_str().len())) + } } } /// Creates an already specified url value from an already resolved URL /// for insertion in the cascade. - pub fn for_cascade(url: Option<ServoUrl>, extra_data: UrlExtraData) -> Self { + pub fn for_cascade(url: ServoUrl, extra_data: UrlExtraData) -> Self { SpecifiedUrl { original: None, - resolved: url, + resolved: Some(url), extra_data: extra_data, } } diff --git a/components/style/viewport.rs b/components/style/viewport.rs index bbdd3a2ed35..2e965da4e54 100644 --- a/components/style/viewport.rs +++ b/components/style/viewport.rs @@ -69,7 +69,7 @@ macro_rules! declare_viewport_descriptor_inner { const VIEWPORT_DESCRIPTOR_VARIANTS: usize = $number_of_variants; impl ViewportDescriptor { - fn discriminant_value(&self) -> usize { + pub fn discriminant_value(&self) -> usize { match *self { $( ViewportDescriptor::$assigned_variant(..) => $assigned_discriminant, diff --git a/components/url/Cargo.toml b/components/url/Cargo.toml index 48184fb702c..11c0cd71a8b 100644 --- a/components/url/Cargo.toml +++ b/components/url/Cargo.toml @@ -11,7 +11,7 @@ path = "lib.rs" [features] servo = ["heapsize", "heapsize_derive", "serde", "serde_derive", - "url/heap_size"] + "url/heap_size", "url/serde"] [dependencies] diff --git a/components/url/lib.rs b/components/url/lib.rs index 415b2dd4ea6..43498444a54 100644 --- a/components/url/lib.rs +++ b/components/url/lib.rs @@ -79,6 +79,11 @@ impl ServoUrl { self.0.scheme() } + pub fn is_secure_scheme(&self) -> bool { + let scheme = self.scheme(); + scheme == "https" || scheme == "wss" + } + pub fn as_str(&self) -> &str { self.0.as_str() } diff --git a/components/util/thread.rs b/components/util/thread.rs deleted file mode 100644 index 130187244db..00000000000 --- a/components/util/thread.rs +++ /dev/null @@ -1,11 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -use std::thread; - -pub fn spawn_named<F>(name: String, f: F) - where F: FnOnce() + Send + 'static -{ - thread::Builder::new().name(name).spawn(f).expect("Thread spawn failed"); -} diff --git a/components/webdriver_server/Cargo.toml b/components/webdriver_server/Cargo.toml index 6bb75d93b60..0cc3b43f637 100644 --- a/components/webdriver_server/Cargo.toml +++ b/components/webdriver_server/Cargo.toml @@ -22,8 +22,8 @@ plugins = {path = "../plugins"} regex = "0.1.55" rustc-serialize = "0.3.4" script_traits = {path = "../script_traits"} +servo_config = {path = "../config", features = ["servo"]} servo_url = {path = "../url", features = ["servo"]} url = {version = "1.2", features = ["heap_size"]} -util = {path = "../util"} uuid = { version = "0.3.1", features = ["v4"] } webdriver = "0.15" diff --git a/components/webdriver_server/lib.rs b/components/webdriver_server/lib.rs index e6cf2ac6f62..7d723813f48 100644 --- a/components/webdriver_server/lib.rs +++ b/components/webdriver_server/lib.rs @@ -22,8 +22,8 @@ extern crate net_traits; extern crate regex; extern crate rustc_serialize; extern crate script_traits; +extern crate servo_config; extern crate servo_url; -extern crate util; extern crate uuid; extern crate webdriver; @@ -42,6 +42,7 @@ use rustc_serialize::json::{Json, ToJson}; use script_traits::{ConstellationMsg, LoadData, WebDriverCommandMsg}; use script_traits::webdriver_msg::{LoadStatus, WebDriverCookieError, WebDriverFrameId}; use script_traits::webdriver_msg::{WebDriverJSError, WebDriverJSResult, WebDriverScriptCommand}; +use servo_config::prefs::{PREFS, PrefValue}; use servo_url::ServoUrl; use std::borrow::ToOwned; use std::collections::BTreeMap; @@ -49,8 +50,6 @@ use std::net::{SocketAddr, SocketAddrV4}; use std::sync::mpsc::Sender; use std::thread; use std::time::Duration; -use util::prefs::{PREFS, PrefValue}; -use util::thread::spawn_named; use uuid::Uuid; use webdriver::command::{AddCookieParameters, GetParameters, JavascriptCommandParameters}; use webdriver::command::{LocatorParameters, Parameters}; @@ -88,13 +87,13 @@ fn cookie_msg_to_cookie(cookie: cookie_rs::Cookie) -> Cookie { pub fn start_server(port: u16, constellation_chan: Sender<ConstellationMsg>) { let handler = Handler::new(constellation_chan); - spawn_named("WebdriverHttpServer".to_owned(), move || { + thread::Builder::new().name("WebdriverHttpServer".to_owned()).spawn(move || { let address = SocketAddrV4::new("0.0.0.0".parse().unwrap(), port); match server::start(SocketAddr::V4(address), handler, extension_routes()) { Ok(listening) => info!("WebDriver server listening on {}", listening.socket), Err(_) => panic!("Unable to start WebDriver HTTPD server"), } - }); + }).expect("Thread spawning failed"); } struct WebDriverSession { @@ -261,7 +260,7 @@ impl Handler { let msg = ConstellationMsg::GetPipeline(frame_id, sender.clone()); self.constellation_chan.send(msg).unwrap(); // Wait until the document is ready before returning the pipeline id. - if let Some((x, true)) = receiver.recv().unwrap() { + if let Some(x) = receiver.recv().unwrap() { return Ok(x); } thread::sleep(Duration::from_millis(interval)); diff --git a/docs/HACKING_QUICKSTART.md b/docs/HACKING_QUICKSTART.md index d391ae5da08..b97d6a5ff4b 100644 --- a/docs/HACKING_QUICKSTART.md +++ b/docs/HACKING_QUICKSTART.md @@ -108,20 +108,29 @@ This is how my projects are laid out: ``` ~/my-projects/servo/ -~/my-projects/cocoa-rs/ -~/my-projects/glutin/ +~/my-projects/mozjs/ ``` +Both folder are git repositories. -These are all git repositories. +To make it so that servo uses `~/my-projects/mozjs/`, first ascertain which version of the crate Servo is using and whether it is a git dependency or one from crates.io. -To make it so that servo uses `~/my-projects/cocoa-rs/` and `~/my-projects/glutin/` , create a `~/my-projects/servo/.cargo/config` file: +Both information can be found using, in this example, `/mach cargo pkgid mozjs_sys`(`mozjs_sys` is the actual crate name, which doesn't necessarily match the repo folder name). -``` shell -$ cat ~/my-projects/servo/.cargo/config -paths = ['../glutin', '../cocoa-rs'] +If the output is in the format `https://github.com/servo/mozjs#mozjs_sys:0.0.0`, you are dealing with a git dependency and you will have to edit the `~/my-projects/servo/Cargo.toml` file and add at the bottom: + +``` toml +[replace] +"https://github.com/servo/mozjs#mozjs_sys:0.0.0" = { path = '../mozjs' } +``` + +If the output is in the format `https://github.com/rust-lang/crates.io-index#mozjs_sys#0.0.0`, you are dealing with a crates.io dependency and you will have to edit the `~/my-projects/servo/Cargo.toml` in the following way: + +``` toml +[replace] +"mozjs_sys:0.0.0" = { path = '../mozjs' } ``` -This will tell any cargo project to not use the online version of the dependency, but your local clone. +Both will tell any cargo project to not use the online version of the dependency, but your local clone. For more details about overriding dependencies, see [Cargo's documentation](http://doc.crates.io/specifying-dependencies.html#overriding-dependencies). diff --git a/etc/ci/buildbot_steps.yml b/etc/ci/buildbot_steps.yml index 69353c304ea..401117d4660 100644 --- a/etc/ci/buildbot_steps.yml +++ b/etc/ci/buildbot_steps.yml @@ -106,7 +106,27 @@ windows-dev: - ./mach test-unit - ./mach build-geckolib +windows-gnu-dev: + - ./mach build --dev + - ./mach test-unit + - ./mach build-geckolib + +windows-msvc-dev: + - mach.bat build --dev + - mach.bat test-unit + - mach.bat build-geckolib + windows-nightly: - ./mach build --release - ./mach package --release - - ./etc/ci/upload_nightly.sh windows + - ./etc/ci/upload_nightly.sh windows-gnu + +windows-gnu-nightly: + - ./mach build --release + - ./mach package --release + - ./etc/ci/upload_nightly.sh windows-gnu + +windows-msvc-nightly: + - mach.bat build --release + - mach.bat package --release + - .\etc\ci\upload_nightly.sh windows-msvc diff --git a/etc/ci/check_dynamic_symbols.py b/etc/ci/check_dynamic_symbols.py index 47d31e46ee4..b6eef1831f6 100644 --- a/etc/ci/check_dynamic_symbols.py +++ b/etc/ci/check_dynamic_symbols.py @@ -15,7 +15,7 @@ import subprocess import sys symbol_regex = re.compile(b"D \*UND\*\t(.*) (.*)$") -allowed_symbols = frozenset([b'unshare', b'malloc_usable_size']) +allowed_symbols = frozenset([b'unshare', b'malloc_usable_size', b'__cxa_type_match']) actual_symbols = set() objdump_output = subprocess.check_output([ diff --git a/etc/ci/upload_nightly.sh b/etc/ci/upload_nightly.sh index 842042ffd62..bc9e82824ee 100755 --- a/etc/ci/upload_nightly.sh +++ b/etc/ci/upload_nightly.sh @@ -11,7 +11,7 @@ shopt -s failglob usage() { - printf "usage: ${0} android|linux|mac|macbrew|windows\n" + printf "usage: ${0} android|linux|mac|macbrew|windows-gnu|windows-msvc\n" } @@ -28,7 +28,7 @@ upload() { main() { - if [[ "${#}" != 1 ]]; then + if (( "${#}" != 1 )); then usage >&2 return 1 fi @@ -41,14 +41,15 @@ main() { package=target/arm-linux-androideabi/release/*."${extension}" elif [[ "${platform}" == "linux" ]]; then extension=tar.gz - package=target/*."${extension}" + package=target/release/*."${extension}" elif [[ "${platform}" == "mac" ]]; then extension=dmg - package=target/*."${extension}" + package=target/release/*."${extension}" elif [[ "${platform}" == "macbrew" ]]; then extension=tar.gz - package=target/brew/*."${extension}" - elif [[ "${platform}" == "windows" ]]; then + package=target/release/brew/*."${extension}" + elif [[ "${platform}" == "windows-gnu" || + "${platform}" == "windows-msvc" ]]; then extension=msi package=target/release/msi/*.msi else diff --git a/ports/cef/Cargo.toml b/ports/cef/Cargo.toml index 3d2625b3aac..6bca49baae4 100644 --- a/ports/cef/Cargo.toml +++ b/ports/cef/Cargo.toml @@ -31,9 +31,10 @@ msg = {path = "../../components/msg"} net_traits = {path = "../../components/net_traits"} plugins = {path = "../../components/plugins"} script_traits = {path = "../../components/script_traits"} +servo_config = {path = "../../components/config"} +servo_geometry = {path = "../../components/geometry"} servo_url = {path = "../../components/url"} style_traits = {path = "../../components/style_traits"} -util = {path = "../../components/util"} [target.'cfg(target_os="macos")'.dependencies] objc = "0.2" diff --git a/ports/cef/browser.rs b/ports/cef/browser.rs index 707c202e545..22affc6f76a 100644 --- a/ports/cef/browser.rs +++ b/ports/cef/browser.rs @@ -10,7 +10,6 @@ use interfaces::{cef_browser_t, cef_browser_host_t, cef_client_t, cef_frame_t}; use interfaces::{cef_request_context_t}; use servo::Browser; use types::{cef_browser_settings_t, cef_string_t, cef_window_info_t, cef_window_handle_t}; -use util::thread::spawn_named; use window; use wrappers::CefWrap; @@ -21,6 +20,7 @@ use std::cell::{Cell, RefCell}; use std::ptr; use std::rc::Rc; use std::sync::atomic::{AtomicIsize, Ordering}; +use std::thread; thread_local!(pub static ID_COUNTER: AtomicIsize = AtomicIsize::new(0)); thread_local!(pub static BROWSERS: RefCell<Vec<CefBrowser>> = RefCell::new(vec!())); @@ -293,9 +293,9 @@ cef_static_method_impls! { let _browser_settings: &cef_browser_settings_t = _browser_settings; let _request_context: CefRequestContext = _request_context; browser_host_create(window_info, client, url, false); - spawn_named("async_browser_creation".to_owned(), move || { + thread::Builder::new().name("async_browser_creation".to_owned()).spawn(move || { window::app_wakeup(); - }); + }).expect("Thread spawning failed"); 1i32 }} fn cef_browser_host_create_browser_sync(window_info: *const cef_window_info_t, @@ -309,4 +309,4 @@ cef_static_method_impls! { let _request_context: CefRequestContext = _request_context; browser_host_create(window_info, client, url, true) }} -}
\ No newline at end of file +} diff --git a/ports/cef/core.rs b/ports/cef/core.rs index e5e70acd7d3..7db9246355c 100644 --- a/ports/cef/core.rs +++ b/ports/cef/core.rs @@ -9,9 +9,9 @@ use window::init_window; use browser; use libc::{c_char, c_int, c_void}; +use servo_config::opts; use std::ffi; use std::str; -use util::opts; const MAX_RENDERING_THREADS: usize = 128; diff --git a/ports/cef/lib.rs b/ports/cef/lib.rs index c0008757dba..3e44e308091 100644 --- a/ports/cef/lib.rs +++ b/ports/cef/lib.rs @@ -6,7 +6,6 @@ #![feature(core_intrinsics)] #![feature(link_args)] #![feature(plugin)] -#![feature(unicode)] #![allow(non_camel_case_types)] @@ -22,14 +21,14 @@ extern crate euclid; extern crate gfx_traits; extern crate gleam; extern crate glutin_app; -extern crate rustc_unicode; extern crate script_traits; +extern crate servo_config; +extern crate servo_geometry; extern crate servo_url; extern crate style_traits; extern crate net_traits; extern crate msg; -extern crate util; extern crate libc; diff --git a/ports/cef/string_list.rs b/ports/cef/string_list.rs index 90ada69267a..fc6de158bd9 100644 --- a/ports/cef/string_list.rs +++ b/ports/cef/string_list.rs @@ -7,8 +7,6 @@ use std::slice; use string::cef_string_utf16_set; use types::{cef_string_list_t,cef_string_t}; -use rustc_unicode::str::Utf16Encoder; - //cef_string_list #[no_mangle] @@ -38,7 +36,7 @@ pub extern "C" fn cef_string_list_value(lt: *mut cef_string_list_t, index: c_int if index < 0 || lt.is_null() { return 0; } if index as usize > (*lt).len() - 1 { return 0; } let ref string = (*lt)[index as usize]; - let utf16_chars: Vec<u16> = Utf16Encoder::new(string.chars()).collect(); + let utf16_chars: Vec<u16> = string.encode_utf16().collect(); cef_string_utf16_set(utf16_chars.as_ptr(), utf16_chars.len(), value, 1) } } diff --git a/ports/cef/window.rs b/ports/cef/window.rs index 33a1c5749c6..ee76ddd3035 100644 --- a/ports/cef/window.rs +++ b/ports/cef/window.rs @@ -14,7 +14,6 @@ use eutil::Downcast; use interfaces::CefApp; use interfaces::CefBrowser; use render_handler::CefRenderHandlerExtensions; -use rustc_unicode::str::Utf16Encoder; use types::{cef_cursor_handle_t, cef_cursor_type_t, cef_rect_t}; use wrappers::CefWrap; @@ -27,6 +26,7 @@ use gfx_traits::DevicePixel; use gleam::gl; use msg::constellation_msg::{Key, KeyModifiers}; use net_traits::net_error_list::NetError; +use servo_geometry::ScreenPx; use std::cell::RefCell; use std::ffi::CString; use std::os::raw::{c_char, c_void}; @@ -35,7 +35,6 @@ use std::rc::Rc; use std::sync::mpsc::{Sender, channel}; use servo_url::ServoUrl; use style_traits::cursor::Cursor; -use util::geometry::ScreenPx; #[cfg(target_os="linux")] extern crate x11; #[cfg(target_os="linux")] @@ -331,10 +330,7 @@ impl WindowMethods for Window { Some(ref browser) => browser, }; let str = match info { - Some(s) => { - let utf16_chars: Vec<u16> = Utf16Encoder::new(s.chars()).collect(); - utf16_chars - } + Some(s) => s.encode_utf16().collect::<Vec<u16>>(), None => vec![] }; @@ -397,7 +393,7 @@ impl WindowMethods for Window { }; if check_ptr_exist!(browser.get_host().get_client(), get_load_handler) && check_ptr_exist!(browser.get_host().get_client().get_load_handler(), on_load_error) { - let utf16_chars: Vec<u16> = Utf16Encoder::new((url).chars()).collect(); + let utf16_chars: Vec<u16> = url.encode_utf16().collect(); browser.get_host() .get_client() .get_load_handler() @@ -428,10 +424,7 @@ impl WindowMethods for Window { let frame = frame.downcast(); let mut title_visitor = frame.title_visitor.borrow_mut(); let str = match string { - Some(s) => { - let utf16_chars: Vec<u16> = Utf16Encoder::new(s.chars()).collect(); - utf16_chars - } + Some(s) => s.encode_utf16().collect(), None => vec![] }; @@ -461,7 +454,7 @@ impl WindowMethods for Window { // FIXME(https://github.com/rust-lang/rust/issues/23338) let mut frame_url = servoframe.url.borrow_mut(); *frame_url = url.into_string(); - let utf16_chars: Vec<u16> = Utf16Encoder::new((*frame_url).chars()).collect(); + let utf16_chars: Vec<u16> = frame_url.encode_utf16().collect(); if check_ptr_exist!(browser.get_host().get_client(), get_display_handler) && check_ptr_exist!(browser.get_host().get_client().get_display_handler(), on_address_change) { browser.get_host().get_client().get_display_handler().on_address_change((*browser).clone(), frame.clone(), utf16_chars.as_slice()); diff --git a/ports/cef/wrappers.rs b/ports/cef/wrappers.rs index fdb2bb96063..e36820ce561 100644 --- a/ports/cef/wrappers.rs +++ b/ports/cef/wrappers.rs @@ -8,7 +8,6 @@ use interfaces::{cef_dialog_handler_t, cef_focus_handler_t}; use interfaces::{cef_download_handler_t, cef_drag_handler_t, cef_context_menu_handler_t}; use interfaces::{cef_geolocation_handler_t, cef_jsdialog_handler_t, cef_keyboard_handler_t}; use interfaces::{cef_load_handler_t, cef_request_handler_t}; -use rustc_unicode::str::Utf16Encoder; use types::{cef_base_t, cef_browser_settings_t, CefBrowserSettings, cef_color_model_t}; use types::{cef_context_menu_edit_state_flags_t}; use types::{cef_context_menu_media_state_flags_t}; @@ -255,7 +254,7 @@ impl<'a,'b> CefWrap<*mut *const c_char> for &'a mut &'b str { impl<'a> CefWrap<cef_string_userfree_t> for String { fn to_c(string: String) -> cef_string_userfree_t { - let utf16_chars: Vec<u16> = Utf16Encoder::new(string.chars()).collect(); + let utf16_chars: Vec<u16> = string.encode_utf16().collect(); let boxed_string; unsafe { diff --git a/ports/geckolib/Cargo.toml b/ports/geckolib/Cargo.toml index 0df70bc465b..23e9db63a13 100644 --- a/ports/geckolib/Cargo.toml +++ b/ports/geckolib/Cargo.toml @@ -9,6 +9,9 @@ name = "geckoservo" path = "lib.rs" crate-type = ["staticlib", "rlib"] +[features] +bindgen = ["style/bindgen"] + [dependencies] app_units = "0.3" cssparser = {version = "0.7"} diff --git a/ports/geckolib/glue.rs b/ports/geckolib/glue.rs index 36c309dcdd0..e59013a931d 100644 --- a/ports/geckolib/glue.rs +++ b/ports/geckolib/glue.rs @@ -10,18 +10,18 @@ use euclid::Size2D; use parking_lot::RwLock; use selectors::Element; use servo_url::ServoUrl; +use std::borrow::Cow; use std::fmt::Write; use std::mem::transmute; use std::ptr; use std::sync::{Arc, Mutex}; use style::arc_ptr_eq; use style::atomic_refcell::AtomicRefMut; -use style::context::{LocalStyleContextCreationInfo, ReflowGoal, SharedStyleContext}; -use style::data::{ElementData, RestyleData}; -use style::dom::{StylingMode, TElement, TNode, TRestyleDamage}; +use style::context::{QuirksMode, ReflowGoal, SharedStyleContext, StyleContext}; +use style::context::{ThreadLocalStyleContext, ThreadLocalStyleContextCreationInfo}; +use style::data::{ElementData, ElementStyles, RestyleData}; +use style::dom::{ShowSubtreeData, TElement, TNode}; use style::error_reporting::StdoutErrorReporter; -use style::gecko::context::StandaloneStyleContext; -use style::gecko::context::clear_local_context; use style::gecko::data::{NUM_THREADS, PerDocumentStyleData, PerDocumentStyleDataImpl}; use style::gecko::restyle_damage::GeckoRestyleDamage; use style::gecko::selector_parser::{SelectorImpl, PseudoElement}; @@ -39,7 +39,7 @@ use style::gecko_bindings::bindings::RawGeckoElementBorrowed; use style::gecko_bindings::bindings::ServoComputedValuesBorrowedOrNull; use style::gecko_bindings::bindings::nsTArrayBorrowed_uintptr_t; use style::gecko_bindings::structs; -use style::gecko_bindings::structs::{SheetParsingMode, nsIAtom}; +use style::gecko_bindings::structs::{SheetParsingMode, nsIAtom, nsCSSPropertyID}; use style::gecko_bindings::structs::{ThreadSafePrincipalHolder, ThreadSafeURIHolder}; use style::gecko_bindings::structs::{nsRestyleHint, nsChangeHint}; use style::gecko_bindings::structs::nsresult; @@ -49,7 +49,7 @@ use style::gecko_bindings::sugar::refptr::{GeckoArcPrincipal, GeckoArcURI}; use style::parallel; use style::parser::{ParserContext, ParserContextExtraData}; use style::properties::{CascadeFlags, ComputedValues, Importance, PropertyDeclaration}; -use style::properties::{PropertyDeclarationParseResult, PropertyDeclarationBlock}; +use style::properties::{PropertyDeclarationParseResult, PropertyDeclarationBlock, PropertyId}; use style::properties::{apply_declarations, parse_one_declaration}; use style::restyle_hints::RestyleHint; use style::selector_parser::PseudoElementCascadeType; @@ -58,8 +58,9 @@ use style::string_cache::Atom; use style::stylesheets::{CssRule, CssRules, Origin, Stylesheet, StyleRule}; use style::thread_state; use style::timer::Timer; -use style::traversal::{recalc_style_at, PerLevelTraversalData}; +use style::traversal::{recalc_style_at, DomTraversal, PerLevelTraversalData}; use style_traits::ToCss; +use stylesheet_loader::StylesheetLoader; /* * For Gecko->Servo function calls, we need to redeclare the same signature that was declared in @@ -87,27 +88,16 @@ pub extern "C" fn Servo_Initialize() -> () { pub extern "C" fn Servo_Shutdown() -> () { // Destroy our default computed values. unsafe { ComputedValues::shutdown(); } - - // In general, LocalStyleContexts will get destroyed when the worker thread - // is joined and the TLS is dropped. However, under some configurations we - // may do sequential style computation on the main thread, so we need to be - // sure to clear the main thread TLS entry as well. - clear_local_context(); } -fn create_shared_context(mut per_doc_data: &mut AtomicRefMut<PerDocumentStyleDataImpl>) -> SharedStyleContext { - // The stylist consumes stylesheets lazily. - per_doc_data.flush_stylesheets(); - +fn create_shared_context(per_doc_data: &PerDocumentStyleDataImpl) -> SharedStyleContext { let local_context_data = - LocalStyleContextCreationInfo::new(per_doc_data.new_animations_sender.clone()); + ThreadLocalStyleContextCreationInfo::new(per_doc_data.new_animations_sender.clone()); SharedStyleContext { // FIXME (bug 1303229): Use the actual viewport size here viewport_size: Size2D::new(Au(0), Au(0)), screen_size_changed: false, - skip_root: false, - generation: 0, goal: ReflowGoal::ForScriptQuery, stylist: per_doc_data.stylist.clone(), running_animations: per_doc_data.running_animations.clone(), @@ -115,11 +105,13 @@ fn create_shared_context(mut per_doc_data: &mut AtomicRefMut<PerDocumentStyleDat error_reporter: Box::new(StdoutErrorReporter), local_context_creation_data: Mutex::new(local_context_data), timer: Timer::new(), + // FIXME Find the real QuirksMode information for this document + quirks_mode: QuirksMode::NoQuirks, } } fn traverse_subtree(element: GeckoElement, raw_data: RawServoStyleSetBorrowed, - skip_root: bool) { + unstyled_children_only: bool) { // Force the creation of our lazily-constructed initial computed values on // the main thread, since it's not safe to call elsewhere. // @@ -132,37 +124,43 @@ fn traverse_subtree(element: GeckoElement, raw_data: RawServoStyleSetBorrowed, // When new content is inserted in a display:none subtree, we will call into // servo to try to style it. Detect that here and bail out. if let Some(parent) = element.parent_element() { - if parent.get_data().is_none() || parent.is_display_none() { + if parent.borrow_data().map_or(true, |d| d.styles().is_display_none()) { debug!("{:?} has unstyled parent - ignoring call to traverse_subtree", parent); return; } } - if !skip_root && element.styling_mode() == StylingMode::Stop { + let mut per_doc_data = PerDocumentStyleData::from_ffi(raw_data).borrow_mut(); + + let token = RecalcStyleOnly::pre_traverse(element, &per_doc_data.stylist, unstyled_children_only); + if !token.should_traverse() { error!("Unnecessary call to traverse_subtree"); return; } - let mut per_doc_data = PerDocumentStyleData::from_ffi(raw_data).borrow_mut(); - let mut shared_style_context = create_shared_context(&mut per_doc_data); - shared_style_context.skip_root = skip_root; + debug!("Traversing subtree:"); + debug!("{:?}", ShowSubtreeData(element.as_node())); + + let shared_style_context = create_shared_context(&per_doc_data); + let traversal = RecalcStyleOnly::new(shared_style_context); let known_depth = None; if per_doc_data.num_threads == 1 || per_doc_data.work_queue.is_none() { - sequential::traverse_dom::<_, RecalcStyleOnly>(element.as_node(), &shared_style_context); + sequential::traverse_dom(&traversal, element, token); } else { - parallel::traverse_dom::<_, RecalcStyleOnly>(element.as_node(), known_depth, &shared_style_context, - per_doc_data.work_queue.as_mut().unwrap()); + parallel::traverse_dom(&traversal, element, known_depth, token, + per_doc_data.work_queue.as_mut().unwrap()); } } #[no_mangle] pub extern "C" fn Servo_TraverseSubtree(root: RawGeckoElementBorrowed, raw_data: RawServoStyleSetBorrowed, - skip_root: structs::SkipRootBehavior) -> () { + behavior: structs::TraversalRootBehavior) -> () { let element = GeckoElement(root); debug!("Servo_TraverseSubtree: {:?}", element); - traverse_subtree(element, raw_data, skip_root == structs::SkipRootBehavior::Skip); + traverse_subtree(element, raw_data, + behavior == structs::TraversalRootBehavior::UnstyledChildrenOnly); } #[no_mangle] @@ -227,8 +225,10 @@ pub extern "C" fn Servo_StyleSheet_Empty(mode: SheetParsingMode) -> RawServoStyl SheetParsingMode::eUserSheetFeatures => Origin::User, SheetParsingMode::eAgentSheetFeatures => Origin::UserAgent, }; + let loader = StylesheetLoader::new(); let sheet = Arc::new(Stylesheet::from_str( - "", url, origin, Default::default(), Box::new(StdoutErrorReporter), extra_data)); + "", url, origin, Default::default(), Some(&loader), + Box::new(StdoutErrorReporter), extra_data)); unsafe { transmute(sheet) } @@ -257,8 +257,10 @@ pub extern "C" fn Servo_StyleSheet_FromUTF8Bytes(data: *const nsACString, referrer: Some(GeckoArcURI::new(referrer)), principal: Some(GeckoArcPrincipal::new(principal)), }}; + let loader = StylesheetLoader::new(); let sheet = Arc::new(Stylesheet::from_str( - input, url, origin, Default::default(), Box::new(StdoutErrorReporter), extra_data)); + input, url, origin, Default::default(), Some(&loader), + Box::new(StdoutErrorReporter), extra_data)); unsafe { transmute(sheet) } @@ -266,28 +268,37 @@ pub extern "C" fn Servo_StyleSheet_FromUTF8Bytes(data: *const nsACString, #[no_mangle] pub extern "C" fn Servo_StyleSet_AppendStyleSheet(raw_data: RawServoStyleSetBorrowed, - raw_sheet: RawServoStyleSheetBorrowed) { + raw_sheet: RawServoStyleSheetBorrowed, + flush: bool) { let mut data = PerDocumentStyleData::from_ffi(raw_data).borrow_mut(); let sheet = HasArcFFI::as_arc(&raw_sheet); data.stylesheets.retain(|x| !arc_ptr_eq(x, sheet)); data.stylesheets.push(sheet.clone()); data.stylesheets_changed = true; + if flush { + data.flush_stylesheets(); + } } #[no_mangle] pub extern "C" fn Servo_StyleSet_PrependStyleSheet(raw_data: RawServoStyleSetBorrowed, - raw_sheet: RawServoStyleSheetBorrowed) { + raw_sheet: RawServoStyleSheetBorrowed, + flush: bool) { let mut data = PerDocumentStyleData::from_ffi(raw_data).borrow_mut(); let sheet = HasArcFFI::as_arc(&raw_sheet); data.stylesheets.retain(|x| !arc_ptr_eq(x, sheet)); data.stylesheets.insert(0, sheet.clone()); data.stylesheets_changed = true; + if flush { + data.flush_stylesheets(); + } } #[no_mangle] pub extern "C" fn Servo_StyleSet_InsertStyleSheetBefore(raw_data: RawServoStyleSetBorrowed, raw_sheet: RawServoStyleSheetBorrowed, - raw_reference: RawServoStyleSheetBorrowed) { + raw_reference: RawServoStyleSheetBorrowed, + flush: bool) { let mut data = PerDocumentStyleData::from_ffi(raw_data).borrow_mut(); let sheet = HasArcFFI::as_arc(&raw_sheet); let reference = HasArcFFI::as_arc(&raw_reference); @@ -295,15 +306,34 @@ pub extern "C" fn Servo_StyleSet_InsertStyleSheetBefore(raw_data: RawServoStyleS let index = data.stylesheets.iter().position(|x| arc_ptr_eq(x, reference)).unwrap(); data.stylesheets.insert(index, sheet.clone()); data.stylesheets_changed = true; + if flush { + data.flush_stylesheets(); + } } #[no_mangle] pub extern "C" fn Servo_StyleSet_RemoveStyleSheet(raw_data: RawServoStyleSetBorrowed, - raw_sheet: RawServoStyleSheetBorrowed) { + raw_sheet: RawServoStyleSheetBorrowed, + flush: bool) { let mut data = PerDocumentStyleData::from_ffi(raw_data).borrow_mut(); let sheet = HasArcFFI::as_arc(&raw_sheet); data.stylesheets.retain(|x| !arc_ptr_eq(x, sheet)); data.stylesheets_changed = true; + if flush { + data.flush_stylesheets(); + } +} + +#[no_mangle] +pub extern "C" fn Servo_StyleSet_FlushStyleSheets(raw_data: RawServoStyleSetBorrowed) { + let mut data = PerDocumentStyleData::from_ffi(raw_data).borrow_mut(); + data.flush_stylesheets(); +} + +#[no_mangle] +pub extern "C" fn Servo_StyleSet_NoteStyleSheetsChanged(raw_data: RawServoStyleSetBorrowed) { + let mut data = PerDocumentStyleData::from_ffi(raw_data).borrow_mut(); + data.stylesheets_changed = true; } #[no_mangle] @@ -432,10 +462,7 @@ pub extern "C" fn Servo_ComputedValues_GetForAnonymousBox(parent_style_or_null: pseudo_tag: *mut nsIAtom, raw_data: RawServoStyleSetBorrowed) -> ServoComputedValuesStrong { - // The stylist consumes stylesheets lazily. - let mut data = PerDocumentStyleData::from_ffi(raw_data).borrow_mut(); - data.flush_stylesheets(); - + let data = PerDocumentStyleData::from_ffi(raw_data).borrow_mut(); let atom = Atom::from(pseudo_tag); let pseudo = PseudoElement::from_atom_unchecked(atom, /* anon_box = */ true); @@ -447,48 +474,46 @@ pub extern "C" fn Servo_ComputedValues_GetForAnonymousBox(parent_style_or_null: } #[no_mangle] -pub extern "C" fn Servo_ComputedValues_GetForPseudoElement(parent_style: ServoComputedValuesBorrowed, - match_element: RawGeckoElementBorrowed, - pseudo_tag: *mut nsIAtom, - raw_data: RawServoStyleSetBorrowed, - is_probe: bool) - -> ServoComputedValuesStrong { - debug_assert!(!(match_element as *const _).is_null()); +pub extern "C" fn Servo_ResolvePseudoStyle(element: RawGeckoElementBorrowed, + pseudo_tag: *mut nsIAtom, is_probe: bool, + raw_data: RawServoStyleSetBorrowed) + -> ServoComputedValuesStrong +{ + let element = GeckoElement(element); + let data = unsafe { element.ensure_data() }.borrow_mut(); - let parent_or_null = || { - if is_probe { + // FIXME(bholley): Assert against this. + if data.get_styles().is_none() { + error!("Calling Servo_ResolvePseudoStyle on unstyled element"); + return if is_probe { Strong::null() } else { - ComputedValues::as_arc(&parent_style).clone().into_strong() - } - }; - - let atom = Atom::from(pseudo_tag); - let pseudo = PseudoElement::from_atom_unchecked(atom, /* anon_box = */ false); - - // The stylist consumes stylesheets lazily. - let mut data = PerDocumentStyleData::from_ffi(raw_data).borrow_mut(); - data.flush_stylesheets(); - - let element = GeckoElement(match_element); + Arc::new(ComputedValues::initial_values().clone()).into_strong() + }; + } + let doc_data = PerDocumentStyleData::from_ffi(raw_data); + match get_pseudo_style(element, pseudo_tag, data.styles(), doc_data) { + Some(values) => values.into_strong(), + None if !is_probe => data.styles().primary.values.clone().into_strong(), + None => Strong::null(), + } +} +fn get_pseudo_style(element: GeckoElement, pseudo_tag: *mut nsIAtom, + styles: &ElementStyles, doc_data: &PerDocumentStyleData) + -> Option<Arc<ComputedValues>> +{ + let pseudo = PseudoElement::from_atom_unchecked(Atom::from(pseudo_tag), false); match SelectorImpl::pseudo_element_cascade_type(&pseudo) { - PseudoElementCascadeType::Eager => { - let maybe_computed = element.get_pseudo_style(&pseudo); - maybe_computed.map_or_else(parent_or_null, FFIArcHelpers::into_strong) - } + PseudoElementCascadeType::Eager => styles.pseudos.get(&pseudo).map(|s| s.values.clone()), + PseudoElementCascadeType::Precomputed => unreachable!("No anonymous boxes"), PseudoElementCascadeType::Lazy => { - let parent = ComputedValues::as_arc(&parent_style); - data.stylist - .lazily_compute_pseudo_element_style(&element, &pseudo, parent) - .map(|styles| styles.values) - .map_or_else(parent_or_null, FFIArcHelpers::into_strong) - } - PseudoElementCascadeType::Precomputed => { - unreachable!("Anonymous pseudo found in \ - Servo_GetComputedValuesForPseudoElement"); - } + let d = doc_data.borrow_mut(); + let base = &styles.primary.values; + d.stylist.lazily_compute_pseudo_element_style(&element, &pseudo, base) + .map(|s| s.values.clone()) + }, } } @@ -533,6 +558,11 @@ pub extern "C" fn Servo_ParseProperty(property: *const nsACString, value: *const principal: *mut ThreadSafePrincipalHolder) -> RawServoDeclarationBlockStrong { let name = unsafe { property.as_ref().unwrap().as_str_unchecked() }; + let id = if let Ok(id) = PropertyId::parse(name.into()) { + id + } else { + return RawServoDeclarationBlockStrong::null() + }; let value = unsafe { value.as_ref().unwrap().as_str_unchecked() }; let base_str = unsafe { base_url.as_ref().unwrap().as_str_unchecked() }; let base_url = ServoUrl::parse(base_str).unwrap(); @@ -547,7 +577,7 @@ pub extern "C" fn Servo_ParseProperty(property: *const nsACString, value: *const extra_data); let mut results = vec![]; - match PropertyDeclaration::parse(name, &context, &mut Parser::new(value), + match PropertyDeclaration::parse(id, &context, &mut Parser::new(value), &mut results, false) { PropertyDeclarationParseResult::ValidOrIgnoredDeclaration => {}, _ => return RawServoDeclarationBlockStrong::null(), @@ -603,16 +633,24 @@ pub extern "C" fn Servo_DeclarationBlock_GetCssText(declarations: RawServoDeclar declarations.read().to_css(unsafe { result.as_mut().unwrap() }).unwrap(); } +macro_rules! get_property_id_from_nscsspropertyid { + ($property_id: ident, $ret: expr) => {{ + match PropertyId::from_nscsspropertyid($property_id) { + Ok(property_id) => property_id, + Err(()) => { return $ret; } + } + }} +} + #[no_mangle] pub extern "C" fn Servo_DeclarationBlock_SerializeOneValue( declarations: RawServoDeclarationBlockBorrowed, - property: *mut nsIAtom, is_custom: bool, - buffer: *mut nsAString) + property_id: nsCSSPropertyID, buffer: *mut nsAString) { + let property_id = get_property_id_from_nscsspropertyid!(property_id, ()); let declarations = RwLock::<PropertyDeclarationBlock>::as_arc(&declarations); - let property = get_property_name_from_atom(property, is_custom); let mut string = String::new(); - let rv = declarations.read().single_value_to_css(&property, &mut string); + let rv = declarations.read().single_value_to_css(&property_id, &mut string); debug_assert!(rv.is_ok()); write!(unsafe { &mut *buffer }, "{}", string).expect("Failed to copy string"); @@ -630,53 +668,56 @@ pub extern "C" fn Servo_DeclarationBlock_GetNthProperty(declarations: RawServoDe let declarations = RwLock::<PropertyDeclarationBlock>::as_arc(&declarations); if let Some(&(ref decl, _)) = declarations.read().declarations.get(index as usize) { let result = unsafe { result.as_mut().unwrap() }; - write!(result, "{}", decl.name()).unwrap(); + decl.id().to_css(result).unwrap(); true } else { false } } -// FIXME Methods of PropertyDeclarationBlock should take atoms directly. -// This function is just a temporary workaround before that finishes. -fn get_property_name_from_atom(atom: *mut nsIAtom, is_custom: bool) -> String { - let atom = Atom::from(atom); - if !is_custom { - atom.to_string() - } else { - let mut result = String::with_capacity(atom.len() as usize + 2); - write!(result, "--{}", atom).unwrap(); - result - } +macro_rules! get_property_id_from_property { + ($property: ident, $ret: expr) => {{ + let property = unsafe { $property.as_ref().unwrap().as_str_unchecked() }; + match PropertyId::parse(Cow::Borrowed(property)) { + Ok(property_id) => property_id, + Err(()) => { return $ret; } + } + }} +} + +fn get_property_value(declarations: RawServoDeclarationBlockBorrowed, + property_id: PropertyId, value: *mut nsAString) { + let declarations = RwLock::<PropertyDeclarationBlock>::as_arc(&declarations); + declarations.read().property_value_to_css(&property_id, unsafe { value.as_mut().unwrap() }).unwrap(); } #[no_mangle] pub extern "C" fn Servo_DeclarationBlock_GetPropertyValue(declarations: RawServoDeclarationBlockBorrowed, - property: *mut nsIAtom, is_custom: bool, - value: *mut nsAString) { - let declarations = RwLock::<PropertyDeclarationBlock>::as_arc(&declarations); - let property = get_property_name_from_atom(property, is_custom); - declarations.read().property_value_to_css(&property, unsafe { value.as_mut().unwrap() }).unwrap(); + property: *const nsACString, value: *mut nsAString) { + get_property_value(declarations, get_property_id_from_property!(property, ()), value) +} + +#[no_mangle] +pub extern "C" fn Servo_DeclarationBlock_GetPropertyValueById(declarations: RawServoDeclarationBlockBorrowed, + property: nsCSSPropertyID, value: *mut nsAString) { + get_property_value(declarations, get_property_id_from_nscsspropertyid!(property, ()), value) } #[no_mangle] pub extern "C" fn Servo_DeclarationBlock_GetPropertyIsImportant(declarations: RawServoDeclarationBlockBorrowed, - property: *mut nsIAtom, is_custom: bool) -> bool { + property: *const nsACString) -> bool { + let property_id = get_property_id_from_property!(property, false); let declarations = RwLock::<PropertyDeclarationBlock>::as_arc(&declarations); - let property = get_property_name_from_atom(property, is_custom); - declarations.read().property_priority(&property).important() + declarations.read().property_priority(&property_id).important() } -#[no_mangle] -pub extern "C" fn Servo_DeclarationBlock_SetProperty(declarations: RawServoDeclarationBlockBorrowed, - property: *mut nsIAtom, is_custom: bool, - value: *mut nsACString, is_important: bool) -> bool { - let property = get_property_name_from_atom(property, is_custom); +fn set_property(declarations: RawServoDeclarationBlockBorrowed, property_id: PropertyId, + value: *mut nsACString, is_important: bool) -> bool { let value = unsafe { value.as_ref().unwrap().as_str_unchecked() }; // FIXME Needs real URL and ParserContextExtraData. let base_url = &*DUMMY_BASE_URL; let extra_data = ParserContextExtraData::default(); - if let Ok(decls) = parse_one_declaration(&property, value, &base_url, + if let Ok(decls) = parse_one_declaration(property_id, value, &base_url, Box::new(StdoutErrorReporter), extra_data) { let mut declarations = RwLock::<PropertyDeclarationBlock>::as_arc(&declarations).write(); let importance = if is_important { Importance::Important } else { Importance::Normal }; @@ -690,22 +731,50 @@ pub extern "C" fn Servo_DeclarationBlock_SetProperty(declarations: RawServoDecla } #[no_mangle] -pub extern "C" fn Servo_DeclarationBlock_RemoveProperty(declarations: RawServoDeclarationBlockBorrowed, - property: *mut nsIAtom, is_custom: bool) { +pub extern "C" fn Servo_DeclarationBlock_SetProperty(declarations: RawServoDeclarationBlockBorrowed, + property: *const nsACString, value: *mut nsACString, + is_important: bool) -> bool { + set_property(declarations, get_property_id_from_property!(property, false), value, is_important) +} + +#[no_mangle] +pub extern "C" fn Servo_DeclarationBlock_SetPropertyById(declarations: RawServoDeclarationBlockBorrowed, + property: nsCSSPropertyID, value: *mut nsACString, + is_important: bool) -> bool { + set_property(declarations, get_property_id_from_nscsspropertyid!(property, false), value, is_important) +} + +fn remove_property(declarations: RawServoDeclarationBlockBorrowed, property_id: PropertyId) { let declarations = RwLock::<PropertyDeclarationBlock>::as_arc(&declarations); - let property = get_property_name_from_atom(property, is_custom); - declarations.write().remove_property(&property); + declarations.write().remove_property(&property_id); +} + +#[no_mangle] +pub extern "C" fn Servo_DeclarationBlock_RemoveProperty(declarations: RawServoDeclarationBlockBorrowed, + property: *const nsACString) { + remove_property(declarations, get_property_id_from_property!(property, ())) +} + +#[no_mangle] +pub extern "C" fn Servo_DeclarationBlock_RemovePropertyById(declarations: RawServoDeclarationBlockBorrowed, + property: nsCSSPropertyID) { + remove_property(declarations, get_property_id_from_nscsspropertyid!(property, ())) } #[no_mangle] pub extern "C" fn Servo_CSSSupports(property: *const nsACString, value: *const nsACString) -> bool { let property = unsafe { property.as_ref().unwrap().as_str_unchecked() }; + let id = if let Ok(id) = PropertyId::parse(property.into()) { + id + } else { + return false + }; let value = unsafe { value.as_ref().unwrap().as_str_unchecked() }; let base_url = &*DUMMY_BASE_URL; let extra_data = ParserContextExtraData::default(); - match parse_one_declaration(&property, &value, &base_url, Box::new(StdoutErrorReporter), extra_data) { + match parse_one_declaration(id, &value, &base_url, Box::new(StdoutErrorReporter), extra_data) { Ok(decls) => !decls.is_empty(), Err(()) => false, } @@ -735,10 +804,7 @@ pub extern "C" fn Servo_Element_GetSnapshot(element: RawGeckoElementBorrowed) -> let element = GeckoElement(element); let mut data = unsafe { element.ensure_data().borrow_mut() }; let snapshot = if let Some(restyle_data) = unsafe { maybe_restyle(&mut data, element) } { - if restyle_data.snapshot.is_none() { - restyle_data.snapshot = Some(element.create_snapshot()); - } - restyle_data.snapshot.as_mut().unwrap().borrow_mut_raw() + restyle_data.snapshot.ensure(|| element.create_snapshot()).borrow_mut_raw() } else { ptr::null_mut() }; @@ -757,8 +823,6 @@ pub extern "C" fn Servo_NoteExplicitHints(element: RawGeckoElementBorrowed, debug!("Servo_NoteExplicitHints: {:?}, restyle_hint={:?}, change_hint={:?}", element, restyle_hint, change_hint); - let restore_current_style = restyle_hint.0 == 0 && data.get_current_styles().is_some(); - if let Some(restyle_data) = unsafe { maybe_restyle(&mut data, element) } { let restyle_hint: RestyleHint = restyle_hint.into(); restyle_data.hint.insert(&restyle_hint.into()); @@ -766,21 +830,6 @@ pub extern "C" fn Servo_NoteExplicitHints(element: RawGeckoElementBorrowed, } else { debug!("(Element not styled, discarding hints)"); } - - // If we had up-to-date style before and only posted a change hint, - // avoid invalidating that style. - // - // This allows for posting explicit change hints during restyle between - // the servo style traversal and the gecko post-traversal (i.e. during the - // call to CreateNeedeFrames in ServoRestyleManager::ProcessPendingRestyles). - // - // FIXME(bholley): The is a very inefficient and hacky way of doing this, - // we should fix the ElementData restyle() API to be more granular so that it - // does the right thing automatically. - if restore_current_style { - let styles = data.previous_styles().unwrap().clone(); - data.finish_styling(styles, GeckoRestyleDamage::empty()); - } } #[no_mangle] @@ -817,25 +866,34 @@ pub extern "C" fn Servo_ResolveStyle(element: RawGeckoElementBorrowed, let element = GeckoElement(element); debug!("Servo_ResolveStyle: {:?}, consume={:?}, compute={:?}", element, consume, compute); + let mut data = unsafe { element.ensure_data() }.borrow_mut(); + if compute == structs::LazyComputeBehavior::Allow { - let should_compute = unsafe { element.ensure_data() }.borrow().get_current_styles().is_none(); + let should_compute = !data.has_current_styles(); if should_compute { debug!("Performing manual style computation"); if let Some(parent) = element.parent_element() { - if parent.borrow_data().map_or(true, |d| d.get_current_styles().is_none()) { + if parent.borrow_data().map_or(true, |d| !d.has_current_styles()) { error!("Attempting manual style computation with unstyled parent"); return Arc::new(ComputedValues::initial_values().clone()).into_strong(); } } - let mut per_doc_data = PerDocumentStyleData::from_ffi(raw_data).borrow_mut(); - let shared_style_context = create_shared_context(&mut per_doc_data); - let context = StandaloneStyleContext::new(&shared_style_context); + let per_doc_data = PerDocumentStyleData::from_ffi(raw_data).borrow_mut(); + let shared_style_context = create_shared_context(&per_doc_data); + let traversal = RecalcStyleOnly::new(shared_style_context); - let mut data = PerLevelTraversalData { + let mut traversal_data = PerLevelTraversalData { current_dom_depth: None, }; - recalc_style_at::<_, _, RecalcStyleOnly>(&context, &mut data, element); + + let mut tlc = ThreadLocalStyleContext::new(traversal.shared_context()); + let mut context = StyleContext { + shared: traversal.shared_context(), + thread_local: &mut tlc, + }; + + recalc_style_at(&traversal, &mut traversal_data, &mut context, element, &mut data); // The element was either unstyled or needed restyle. If it was unstyled, it may have // additional unstyled children that subsequent traversals won't find now that the style @@ -846,19 +904,17 @@ pub extern "C" fn Servo_ResolveStyle(element: RawGeckoElementBorrowed, } } - let data = element.mutate_data(); - let values = match data.as_ref().and_then(|d| d.get_current_styles()) { - Some(x) => x.primary.values.clone(), - None => { - error!("Resolving style on unstyled element with lazy computation forbidden."); - return Arc::new(ComputedValues::initial_values().clone()).into_strong(); - } - }; + if !data.has_current_styles() { + error!("Resolving style on unstyled element with lazy computation forbidden."); + return Arc::new(ComputedValues::initial_values().clone()).into_strong(); + } + + let values = data.styles().primary.values.clone(); if consume == structs::ConsumeStyleBehavior::Consume { // FIXME(bholley): Once we start storing style data on frames, we'll want to // drop the data here instead. - data.unwrap().persist(); + data.persist(); } values.into_strong() diff --git a/ports/geckolib/lib.rs b/ports/geckolib/lib.rs index 0087e6aece6..1225045e45c 100644 --- a/ports/geckolib/lib.rs +++ b/ports/geckolib/lib.rs @@ -18,6 +18,7 @@ extern crate style_traits; #[allow(non_snake_case)] pub mod glue; +mod stylesheet_loader; // FIXME(bholley): This should probably go away once we harmonize the allocators. #[no_mangle] diff --git a/ports/geckolib/stylesheet_loader.rs b/ports/geckolib/stylesheet_loader.rs new file mode 100644 index 00000000000..9db89333747 --- /dev/null +++ b/ports/geckolib/stylesheet_loader.rs @@ -0,0 +1,21 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +use parking_lot::RwLock; +use std::sync::Arc; +use style::stylesheets::{ImportRule, StylesheetLoader as StyleStylesheetLoader}; + +pub struct StylesheetLoader; + +impl StylesheetLoader { + pub fn new() -> Self { + StylesheetLoader + } +} + +impl StyleStylesheetLoader for StylesheetLoader { + fn request_stylesheet(&self, _import: &Arc<RwLock<ImportRule>>) { + // FIXME(emilio): Implement `@import` in stylo. + } +} diff --git a/ports/glutin/Cargo.toml b/ports/glutin/Cargo.toml index e18061babe0..9afffe6dc66 100644 --- a/ports/glutin/Cargo.toml +++ b/ports/glutin/Cargo.toml @@ -19,9 +19,10 @@ msg = {path = "../../components/msg"} net_traits = {path = "../../components/net_traits"} script_traits = {path = "../../components/script_traits"} servo-glutin = "0.6" +servo_geometry = {path = "../../components/geometry"} +servo_config = {path = "../../components/config"} servo_url = {path = "../../components/url"} style_traits = {path = "../../components/style_traits"} -util = {path = "../../components/util"} [target.'cfg(any(target_os = "linux", target_os = "macos"))'.dependencies] osmesa-sys = "0.1.2" diff --git a/ports/glutin/lib.rs b/ports/glutin/lib.rs index d44e8952530..3d1bb34a258 100644 --- a/ports/glutin/lib.rs +++ b/ports/glutin/lib.rs @@ -19,16 +19,17 @@ extern crate msg; extern crate net_traits; #[cfg(any(target_os = "linux", target_os = "macos"))] extern crate osmesa_sys; extern crate script_traits; +extern crate servo_config; +extern crate servo_geometry; extern crate servo_url; extern crate style_traits; -extern crate util; #[cfg(target_os = "windows")] extern crate winapi; #[cfg(target_os = "windows")] extern crate user32; #[cfg(target_os = "windows")] extern crate gdi32; use compositing::windowing::WindowEvent; +use servo_config::opts; use std::rc::Rc; -use util::opts; use window::Window; pub mod window; diff --git a/ports/glutin/window.rs b/ports/glutin/window.rs index c19836cb4f4..bba97dad8f2 100644 --- a/ports/glutin/window.rs +++ b/ports/glutin/window.rs @@ -26,6 +26,10 @@ use net_traits::net_error_list::NetError; #[cfg(any(target_os = "linux", target_os = "macos"))] use osmesa_sys; use script_traits::{TouchEventType, TouchpadPressurePhase}; +use servo_config::opts; +use servo_config::prefs::PREFS; +use servo_config::resource_files; +use servo_geometry::ScreenPx; use servo_url::ServoUrl; use std::cell::{Cell, RefCell}; #[cfg(any(target_os = "linux", target_os = "macos"))] @@ -39,10 +43,6 @@ use std::sync::mpsc::{Sender, channel}; use style_traits::cursor::Cursor; #[cfg(target_os = "windows")] use user32; -use util::geometry::ScreenPx; -use util::opts; -use util::prefs::PREFS; -use util::resource_files; #[cfg(target_os = "windows")] use winapi; @@ -303,12 +303,9 @@ impl Window { fn nested_window_resize(width: u32, height: u32) { unsafe { - match G_NESTED_EVENT_LOOP_LISTENER { - None => {} - Some(listener) => { - (*listener).handle_event_from_nested_event_loop( - WindowEvent::Resize(TypedSize2D::new(width, height))); - } + if let Some(listener) = G_NESTED_EVENT_LOOP_LISTENER { + (*listener).handle_event_from_nested_event_loop( + WindowEvent::Resize(TypedSize2D::new(width, height))); } } } diff --git a/ports/servo/Cargo.toml b/ports/servo/Cargo.toml index 016824642b8..23f12909766 100644 --- a/ports/servo/Cargo.toml +++ b/ports/servo/Cargo.toml @@ -22,8 +22,9 @@ net_traits_tests = {path = "../../tests/unit/net_traits"} plugin_compiletest = {path = "../../tests/compiletest/plugin"} profile_tests = {path = "../../tests/unit/profile"} script_tests = {path = "../../tests/unit/script"} +servo_config_tests = {path = "../../tests/unit/servo_config"} +servo_remutex_tests = {path = "../../tests/unit/servo_remutex"} style_tests = {path = "../../tests/unit/style"} -util_tests = {path = "../../tests/unit/util"} [features] default = ["webdriver", "max_log_level"] @@ -54,3 +55,4 @@ sig = "0.1" [target.'cfg(target_os = "android")'.dependencies] libc = "0.2" android_glue = "0.2" +android_injected_glue = {git = "https://github.com/mmatyas/android-rs-injected-glue"} diff --git a/ports/servo/main.rs b/ports/servo/main.rs index 228e4ec2447..cefc093af7a 100644 --- a/ports/servo/main.rs +++ b/ports/servo/main.rs @@ -20,6 +20,8 @@ #[cfg(target_os = "android")] #[macro_use] extern crate android_glue; +#[cfg(target_os = "android")] +extern crate android_injected_glue; extern crate backtrace; // The window backed by glutin extern crate glutin_app as app; @@ -36,8 +38,8 @@ extern crate sig; use backtrace::Backtrace; use servo::Browser; use servo::compositing::windowing::WindowEvent; -use servo::util::opts::{self, ArgumentParsingResult}; -use servo::util::servo_version; +use servo::config::opts::{self, ArgumentParsingResult}; +use servo::config::servo_version; use std::env; use std::panic; use std::process; @@ -247,18 +249,19 @@ fn args() -> Vec<String> { } -// This extern definition ensures that the linker will not discard -// the static native lib bits, which are brought in from the NDK libraries -// we link in from build.rs. #[cfg(target_os = "android")] -extern { - fn app_dummy() -> libc::c_void; +#[no_mangle] +#[inline(never)] +#[allow(non_snake_case)] +pub extern "C" fn android_main(app: *mut ()) { + android_injected_glue::android_main2(app as *mut _, move |_, _| { main() }); } #[cfg(target_os = "android")] mod android { extern crate android_glue; + extern crate android_injected_glue; extern crate libc; use self::libc::c_int; @@ -272,7 +275,7 @@ mod android { redirect_output(STDERR_FILENO); redirect_output(STDOUT_FILENO); - unsafe { super::app_dummy(); } + unsafe { android_injected_glue::ffi::app_dummy() }; } struct FilePtr(*mut self::libc::FILE); @@ -283,10 +286,10 @@ mod android { use self::libc::{pipe, dup2}; use self::libc::fdopen; use self::libc::fgets; - use servo::util::thread::spawn_named; use std::ffi::CStr; use std::ffi::CString; use std::str::from_utf8; + use std::thread; unsafe { let mut pipes: [c_int; 2] = [ 0, 0 ]; @@ -294,7 +297,7 @@ mod android { dup2(pipes[1], file_no); let mode = CString::new("r").unwrap(); let input_file = FilePtr(fdopen(pipes[0], mode.as_ptr())); - spawn_named("android-logger".to_owned(), move || { + thread::Builder::new().name("android-logger".to_owned()).spawn(move || { static READ_SIZE: usize = 1024; let mut read_buffer = vec![0; READ_SIZE]; let FilePtr(input_file) = input_file; diff --git a/python/requirements.txt b/python/requirements.txt index 34794fd5031..8248a21e930 100644 --- a/python/requirements.txt +++ b/python/requirements.txt @@ -4,7 +4,7 @@ mozdebug == 0.1 mozinfo == 0.8 mozlog == 3.3 setuptools == 18.5 -toml == 0.9.1 +toml == 0.9.2 Mako == 1.0.4 # For Python linting diff --git a/python/servo/build_commands.py b/python/servo/build_commands.py index 514a8f87e69..bd09221d56f 100644 --- a/python/servo/build_commands.py +++ b/python/servo/build_commands.py @@ -24,7 +24,7 @@ from mach.decorators import ( Command, ) -from servo.command_base import CommandBase, cd, call, BIN_SUFFIX, host_triple +from servo.command_base import CommandBase, cd, call, BIN_SUFFIX, host_triple, find_dep_path_newest def format_duration(seconds): @@ -384,6 +384,9 @@ class MachCommands(CommandBase): @Command('build-geckolib', description='Build a static library of components used by Gecko', category='build') + @CommandArgument('--with-gecko', + default=None, + help='Build with Gecko dist directory') @CommandArgument('--jobs', '-j', default=None, help='Number of jobs to run in parallel') @@ -393,12 +396,19 @@ class MachCommands(CommandBase): @CommandArgument('--release', '-r', action='store_true', help='Build in release mode') - def build_geckolib(self, jobs=None, verbose=False, release=False): + def build_geckolib(self, with_gecko=None, jobs=None, verbose=False, release=False): self.set_use_stable_rust() self.ensure_bootstrapped() + env = self.build_env(is_build=True) + geckolib_build_path = path.join(self.context.topdir, "target", "geckolib").encode("UTF-8") + env["CARGO_TARGET_DIR"] = geckolib_build_path + ret = None opts = [] + if with_gecko is not None: + opts += ["--features", "bindgen"] + env["MOZ_DIST"] = path.abspath(with_gecko) if jobs is not None: opts += ["-j", jobs] if verbose: @@ -406,8 +416,13 @@ class MachCommands(CommandBase): if release: opts += ["--release"] - env = self.build_env(is_build=True) - env["CARGO_TARGET_DIR"] = path.join(self.context.topdir, "target", "geckolib").encode("UTF-8") + if with_gecko is not None: + print("Generating atoms data...") + run_file = path.join(self.context.topdir, "components", + "style", "binding_tools", "regen_atoms.py") + run_globals = {"__file__": run_file} + execfile(run_file, run_globals) + run_globals["generate_atoms"](env["MOZ_DIST"]) build_start = time() with cd(path.join("ports", "geckolib")): @@ -419,6 +434,15 @@ class MachCommands(CommandBase): print("GeckoLib build completed in %s" % format_duration(elapsed)) + if with_gecko is not None: + print("Copying binding files to style/gecko_bindings...") + build_path = path.join(geckolib_build_path, "release" if release else "debug", "") + target_style_path = find_dep_path_newest("style", build_path) + out_gecko_path = path.join(target_style_path, "out", "gecko") + bindings_path = path.join(self.context.topdir, "components", "style", "gecko_bindings") + for f in ["bindings.rs", "structs_debug.rs", "structs_release.rs"]: + shutil.copy(path.join(out_gecko_path, f), bindings_path) + return ret @Command('clean', diff --git a/python/servo/command_base.py b/python/servo/command_base.py index 9fc797b28f9..b0f62e65061 100644 --- a/python/servo/command_base.py +++ b/python/servo/command_base.py @@ -50,12 +50,14 @@ def setlocale(name): def find_dep_path_newest(package, bin_path): deps_path = path.join(path.split(bin_path)[0], "build") + candidates = [] with cd(deps_path): - candidates = glob(package + '-*') - candidates = (path.join(deps_path, c) for c in candidates) - candidate_times = sorted(((path.getmtime(c), c) for c in candidates), reverse=True) - if len(candidate_times) > 0: - return candidate_times[0][1] + for c in glob(package + '-*'): + candidate_path = path.join(deps_path, c) + if path.exists(path.join(candidate_path, "output")): + candidates.append(candidate_path) + if candidates: + return max(candidates, key=lambda c: path.getmtime(path.join(c, "output"))) return None @@ -216,7 +218,10 @@ def is_linux(): def set_osmesa_env(bin_path, env): """Set proper LD_LIBRARY_PATH and DRIVE for software rendering on Linux and OSX""" if is_linux(): - osmesa_path = path.join(find_dep_path_newest('osmesa-src', bin_path), "out", "lib", "gallium") + dep_path = find_dep_path_newest('osmesa-src', bin_path) + if not dep_path: + return None + osmesa_path = path.join(dep_path, "out", "lib", "gallium") env["LD_LIBRARY_PATH"] = osmesa_path env["GALLIUM_DRIVER"] = "softpipe" elif is_macosx(): @@ -224,6 +229,8 @@ def set_osmesa_env(bin_path, env): "out", "src", "gallium", "targets", "osmesa", ".libs") glapi_path = path.join(find_dep_path_newest('osmesa-src', bin_path), "out", "src", "mapi", "shared-glapi", ".libs") + if not (osmesa_path and glapi_path): + return None env["DYLD_LIBRARY_PATH"] = osmesa_path + ":" + glapi_path env["GALLIUM_DRIVER"] = "softpipe" return env @@ -297,6 +304,7 @@ class CommandBase(object): self.config["build"].setdefault("mode", "") self.config["build"].setdefault("debug-mozjs", False) self.config["build"].setdefault("ccache", "") + self.config["build"].setdefault("rustflags", "") self.config.setdefault("android", {}) self.config["android"].setdefault("sdk", "") @@ -420,6 +428,10 @@ class CommandBase(object): # Link moztools env["MOZTOOLS_PATH"] = path.join(msvc_deps_dir, "moztools", "bin") + if is_windows(): + if not os.environ.get("NATIVE_WIN32_PYTHON"): + env["NATIVE_WIN32_PYTHON"] = sys.executable + if not self.config["tools"]["system-rust"] \ or self.config["tools"]["rust-root"]: env["RUST_ROOT"] = self.config["tools"]["rust-root"] @@ -486,6 +498,9 @@ class CommandBase(object): env['RUSTDOC'] = path.join(self.context.topdir, 'etc', 'rustdoc-with-private') + if self.config["build"]["rustflags"]: + env['RUSTFLAGS'] = env.get('RUSTFLAGS', "") + " " + self.config["build"]["rustflags"] + # Don't run the gold linker if on Windows https://github.com/servo/servo/issues/9499 if self.config["tools"]["rustc-with-gold"] and sys.platform not in ("win32", "msys"): if subprocess.call(['which', 'ld.gold'], stdout=PIPE, stderr=PIPE) == 0: diff --git a/python/servo/package_commands.py b/python/servo/package_commands.py index 103238a6e55..19935e13f4a 100644 --- a/python/servo/package_commands.py +++ b/python/servo/package_commands.py @@ -152,13 +152,13 @@ class PackageCommands(CommandBase): return e.returncode elif is_macosx(): - dir_to_build = '/'.join(binary_path.split('/')[:-1]) - dir_to_root = '/'.join(binary_path.split('/')[:-3]) + dir_to_build = path.dirname(binary_path) + dir_to_root = self.get_top_dir() print("Creating Servo.app") - dir_to_dmg = '/'.join(binary_path.split('/')[:-2]) + '/dmg' - dir_to_app = dir_to_dmg + '/Servo.app' - dir_to_resources = dir_to_app + '/Contents/Resources/' + dir_to_dmg = path.join(dir_to_build, 'dmg') + dir_to_app = path.join(dir_to_dmg, 'Servo.app') + dir_to_resources = path.join(dir_to_app, 'Contents', 'Resources') if path.exists(dir_to_dmg): print("Cleaning up from previous packaging") delete(dir_to_dmg) @@ -168,19 +168,23 @@ class PackageCommands(CommandBase): return 1 print("Copying files") - shutil.copytree(dir_to_root + '/resources', dir_to_resources) - shutil.copytree(browserhtml_path, dir_to_resources + browserhtml_path.split('/')[-1]) - shutil.copy2(dir_to_root + '/Info.plist', dir_to_app + '/Contents/Info.plist') - os.makedirs(dir_to_app + '/Contents/MacOS/') - shutil.copy2(dir_to_build + '/servo', dir_to_app + '/Contents/MacOS/') + shutil.copytree(path.join(dir_to_root, 'resources'), dir_to_resources) + shutil.copytree(browserhtml_path, path.join(dir_to_resources, path.basename(browserhtml_path))) + shutil.copy2(path.join(dir_to_root, 'Info.plist'), path.join(dir_to_app, 'Contents', 'Info.plist')) + + content_dir = path.join(dir_to_app, 'Contents', 'MacOS') + os.makedirs(content_dir) + shutil.copy2(binary_path, content_dir) print("Swapping prefs") - delete(dir_to_resources + '/prefs.json') - shutil.copy2(dir_to_resources + 'package-prefs.json', dir_to_resources + 'prefs.json') - delete(dir_to_resources + '/package-prefs.json') + package_prefs_path = path.join(dir_to_resources, 'package-prefs.json') + prefs_path = path.join(dir_to_resources, 'prefs.json') + delete(prefs_path) + shutil.copy2(package_prefs_path, prefs_path) + delete(package_prefs_path) print("Finding dylibs and relinking") - copy_dependencies(dir_to_app + '/Contents/MacOS/servo', dir_to_app + '/Contents/MacOS/') + copy_dependencies(path.join(content_dir, 'servo'), content_dir) print("Adding version to Credits.rtf") version_command = [binary_path, '--version'] @@ -193,8 +197,8 @@ class PackageCommands(CommandBase): raise Exception("Error occurred when getting Servo version: " + stderr) version = "Nightly version: " + version - template_path = os.path.join(dir_to_resources, 'Credits.rtf.mako') - credits_path = os.path.join(dir_to_resources, 'Credits.rtf') + template_path = path.join(dir_to_resources, 'Credits.rtf.mako') + credits_path = path.join(dir_to_resources, 'Credits.rtf') with open(template_path) as template_file: template = mako.template.Template(template_file.read()) with open(credits_path, "w") as credits_file: @@ -202,15 +206,19 @@ class PackageCommands(CommandBase): delete(template_path) print("Writing run-servo") - bhtml_path = path.join('${0%/*}/../Resources', browserhtml_path.split('/')[-1], 'out', 'index.html') - runservo = os.open(dir_to_app + '/Contents/MacOS/run-servo', os.O_WRONLY | os.O_CREAT, int("0755", 8)) + bhtml_path = path.join('${0%/*}', '..', 'Resources', path.basename(browserhtml_path), 'out', 'index.html') + runservo = os.open( + path.join(content_dir, 'run-servo'), + os.O_WRONLY | os.O_CREAT, + int("0755", 8) + ) os.write(runservo, '#!/bin/bash\nexec ${0%/*}/servo ' + bhtml_path) os.close(runservo) print("Creating dmg") - os.symlink('/Applications', dir_to_dmg + '/Applications') - dmg_path = '/'.join(dir_to_build.split('/')[:-1]) + '/' - dmg_path += "servo-tech-demo.dmg" + os.symlink('/Applications', path.join(dir_to_dmg, 'Applications')) + dmg_path = path.join(dir_to_build, "servo-tech-demo.dmg") + try: subprocess.check_call(['hdiutil', 'create', '-volname', 'Servo', dmg_path, '-srcfolder', dir_to_dmg]) except subprocess.CalledProcessError as e: @@ -221,24 +229,24 @@ class PackageCommands(CommandBase): print("Packaged Servo into " + dmg_path) print("Creating brew package") - dir_to_brew = '/'.join(binary_path.split('/')[:-2]) + '/brew_tmp/' - dir_to_tar = '/'.join(dir_to_build.split('/')[:-1]) + '/brew/' + dir_to_brew = path.join(dir_to_build, 'brew_tmp') + dir_to_tar = path.join(dir_to_build, 'brew') if not path.exists(dir_to_tar): os.makedirs(dir_to_tar) - tar_path = dir_to_tar + "servo.tar.gz" + tar_path = path.join(dir_to_tar, "servo.tar.gz") if path.exists(dir_to_brew): print("Cleaning up from previous packaging") delete(dir_to_brew) if path.exists(tar_path): print("Deleting existing package") os.remove(tar_path) - shutil.copytree(dir_to_root + '/resources', dir_to_brew + "/resources/") - os.makedirs(dir_to_brew + '/bin/') - shutil.copy2(dir_to_build + '/servo', dir_to_brew + '/bin/servo') + shutil.copytree(path.join(dir_to_root, 'resources'), path.join(dir_to_brew, 'resources')) + os.makedirs(path.join(dir_to_brew, 'bin')) + shutil.copy2(binary_path, path.join(dir_to_brew, 'bin', 'servo')) # Note that in the context of Homebrew, libexec is reserved for private use by the formula # and therefore is not symlinked into HOMEBREW_PREFIX. - os.makedirs(dir_to_brew + '/libexec/') - copy_dependencies(dir_to_brew + '/bin/servo', dir_to_brew + '/libexec/') + os.makedirs(path.join(dir_to_brew, 'libexec')) + copy_dependencies(path.join(dir_to_brew, 'bin', 'servo'), path.join(dir_to_brew, 'libexec')) archive_deterministically(dir_to_brew, tar_path, prepend_path='servo/') delete(dir_to_brew) print("Packaged Servo into " + tar_path) @@ -283,7 +291,7 @@ class PackageCommands(CommandBase): msi_path = path.join(dir_to_msi, "Servo.msi") print("Packaged Servo into {}".format(msi_path)) else: - dir_to_temp = path.join(os.path.dirname(binary_path), 'packaging-temp') + dir_to_temp = path.join(path.dirname(binary_path), 'packaging-temp') browserhtml_path = find_dep_path_newest('browserhtml', binary_path) if browserhtml_path is None: print("Could not find browserhtml package; perhaps you haven't built Servo.") @@ -307,12 +315,12 @@ class PackageCommands(CommandBase): '--pref', 'shell.builtin-key-shortcuts.enabled=false', path.join('./browserhtml', 'out', 'index.html')] - runservo = os.open(dir_to_temp + '/runservo.sh', os.O_WRONLY | os.O_CREAT, int("0755", 8)) + runservo = os.open(path.join(dir_to_temp, 'runservo.sh'), os.O_WRONLY | os.O_CREAT, int("0755", 8)) os.write(runservo, "#!/usr/bin/env sh\n./servo " + ' '.join(servo_args)) os.close(runservo) print("Creating tarball") - tar_path = path.join(self.get_target_dir(), 'servo-tech-demo.tar.gz') + tar_path = path.join(path.dirname(binary_path), 'servo-tech-demo.tar.gz') archive_deterministically(dir_to_temp, tar_path, prepend_path='servo/') @@ -321,33 +329,44 @@ class PackageCommands(CommandBase): print("Packaged Servo into " + tar_path) @Command('install', - description='Install Servo (currently, Android only)', + description='Install Servo (currently, Android and Windows only)', category='package') @CommandArgument('--release', '-r', action='store_true', help='Install the release build') @CommandArgument('--dev', '-d', action='store_true', help='Install the dev build') - def install(self, release=False, dev=False): + @CommandArgument('--android', + action='store_true', + help='Install on Android') + def install(self, release=False, dev=False, android=False): try: - binary_path = self.get_binary_path(release, dev, android=True) + binary_path = self.get_binary_path(release, dev, android=android) except BuildNotFound: print("Servo build not found. Building servo...") result = Registrar.dispatch( - "build", context=self.context, release=release, dev=dev + "build", context=self.context, release=release, dev=dev, android=android ) if result: return result try: - binary_path = self.get_binary_path(release, dev, android=True) + binary_path = self.get_binary_path(release, dev, android=android) except BuildNotFound: print("Rebuilding Servo did not solve the missing build problem.") return 1 - apk_path = binary_path + ".apk" - if not path.exists(apk_path): - result = Registrar.dispatch("package", context=self.context, release=release, dev=dev) + if android: + pkg_path = binary_path + ".apk" + exec_command = ["adb", "install", "-r", pkg_path] + elif is_windows(): + pkg_path = path.join(path.dirname(binary_path), 'msi', 'Servo.msi') + exec_command = ["msiexec", "/i", pkg_path] + + if not path.exists(pkg_path): + result = Registrar.dispatch( + "package", context=self.context, release=release, dev=dev, android=android + ) if result != 0: return result - print(["adb", "install", "-r", apk_path]) - return subprocess.call(["adb", "install", "-r", apk_path], env=self.build_env()) + print(" ".join(exec_command)) + return subprocess.call(exec_command, env=self.build_env()) diff --git a/python/servo/testing_commands.py b/python/servo/testing_commands.py index a2c752aeebc..3351984290d 100644 --- a/python/servo/testing_commands.py +++ b/python/servo/testing_commands.py @@ -734,8 +734,9 @@ class MachCommands(CommandBase): # On Linux and mac, find the OSMesa software rendering library and # add it to the dynamic linker search path. try: - args = [self.get_binary_path(use_release, not use_release)] - set_osmesa_env(args[0], os.environ) + bin_path = self.get_binary_path(use_release, not use_release) + if not set_osmesa_env(bin_path, os.environ): + print("Warning: Cannot set the path to OSMesa library.") except BuildNotFound: # This can occur when cross compiling (e.g. arm64), in which case # we won't run the tests anyway so can safely ignore this step. diff --git a/python/tidy/servo_tidy/tidy.py b/python/tidy/servo_tidy/tidy.py index b40bdd67194..cae431205f8 100644 --- a/python/tidy/servo_tidy/tidy.py +++ b/python/tidy/servo_tidy/tidy.py @@ -33,10 +33,10 @@ config = { "lint-scripts": [], "ignore": { "files": [ - "./.", # ignore hidden files + os.path.join(".", "."), # ignore hidden files ], "directories": [ - "./.", # ignore hidden directories + os.path.join(".", "."), # ignore hidden directories ], "packages": [], }, @@ -90,6 +90,10 @@ def is_iter_empty(iterator): return False, iterator +def normilize_paths(paths): + return [os.path.join(*path.split('/')) for path in paths] + + # A simple wrapper for iterators to show progress # (Note that it's inefficient for giant iterators, since it iterates once to get the upper bound) def progress_wrapper(iterator): @@ -123,11 +127,9 @@ class FileList(object): args = ["git", "log", "-n1", "--merges", "--format=%H"] last_merge = subprocess.check_output(args).strip() args = ["git", "diff", "--name-only", last_merge, self.directory] - file_list = subprocess.check_output(args) + file_list = normilize_paths(subprocess.check_output(args).splitlines()) - for f in file_list.splitlines(): - if sys.platform == 'win32': - os.path.join(*f.split('/')) + for f in file_list: if not any(os.path.join('.', os.path.dirname(f)).startswith(path) for path in self.excluded): yield os.path.join('.', f) @@ -299,61 +301,42 @@ def check_flake8(file_name, contents): def check_lock(file_name, contents): - def find_reverse_dependencies(dependency, version, content): - dependency_prefix = "{} {}".format(dependency, version) + def find_reverse_dependencies(name, content): for package in itertools.chain([content["root"]], content["package"]): for dependency in package.get("dependencies", []): - if dependency.startswith(dependency_prefix): - yield package["name"] + if dependency.startswith("{} ".format(name)): + yield package["name"], dependency if not file_name.endswith(".lock"): raise StopIteration - # package names to be neglected (as named by cargo) + # Package names to be neglected (as named by cargo) exceptions = config["ignore"]["packages"] - # toml.py has a bug(?) that we trip up in [metadata] sections; - # see https://github.com/uiri/toml/issues/61 - # This should only affect a very few lines (that have embedded ?branch=...), - # and most of them won't be in the repo - try: - content = toml.loads(contents) - except: - print "WARNING!" - print "WARNING! toml parsing failed for Cargo.lock, but ignoring..." - print "WARNING!" - raise StopIteration + content = toml.loads(contents) - packages = {} + packages_by_name = {} for package in content.get("package", []): - packages.setdefault(package["name"], []).append(package["version"]) + source = package.get("source", "") + if source == r"registry+https://github.com/rust-lang/crates.io-index": + source = "crates.io" + packages_by_name.setdefault(package["name"], []).append((package["version"], source)) - for (name, versions) in packages.iteritems(): - if name in exceptions or len(versions) <= 1: + for (name, packages) in packages_by_name.iteritems(): + if name in exceptions or len(packages) <= 1: continue - highest = max(versions) - for version in versions: - if version != highest: - reverse_dependencies = "\n".join( - "\t\t{}".format(n) - for n in find_reverse_dependencies(name, version, content) - ) - substitutions = { - "package": name, - "old_version": version, - "new_version": highest, - "reverse_dependencies": reverse_dependencies - } - message = """ -duplicate versions for package "{package}" -\t\033[93mfound dependency on version {old_version}\033[0m -\t\033[91mbut highest version is {new_version}\033[0m -\t\033[93mtry upgrading with\033[0m \033[96m./mach cargo-update -p {package}:{old_version}\033[0m -\tThe following packages depend on version {old_version}: -{reverse_dependencies} -""".format(**substitutions).strip() - yield (1, message) + message = "duplicate versions for package `{}`".format(name) + packages.sort() + packages_dependencies = list(find_reverse_dependencies(name, content)) + for version, source in packages: + short_source = source.split("#")[0].replace("git+", "") + message += "\n\t\033[93mThe following packages depend on version {} from '{}':\033[0m" \ + .format(version, short_source) + for name, dependency in packages_dependencies: + if version in dependency and short_source in dependency: + message += "\n\t\t" + name + yield (1, message) def check_toml(file_name, lines): @@ -542,6 +525,9 @@ def check_rust(file_name, lines): lambda match, line: line.startswith('use ')), (r"^\s*else {", "else braces should be on the same line", no_filter), (r"[^$ ]\([ \t]", "extra space after (", no_filter), + # This particular pattern is not reentrant-safe in script_thread.rs + (r"match self.documents.borrow", "use a separate variable for the match expression", + lambda match, line: file_name.endswith('script_thread.rs')), ] for pattern, message, filter_func in regex_rules: @@ -859,23 +845,17 @@ def parse_config(content): config_file = toml.loads(content) exclude = config_file.get("ignore", {}) # Add list of ignored directories to config - config["ignore"]["directories"] += exclude.get("directories", []) + config["ignore"]["directories"] += normilize_paths(exclude.get("directories", [])) # Add list of ignored files to config - config["ignore"]["files"] += exclude.get("files", []) + config["ignore"]["files"] += normilize_paths(exclude.get("files", [])) # Add list of ignored packages to config config["ignore"]["packages"] = exclude.get("packages", []) - # Fix the paths (OS-dependent) - config['ignore']['files'] = map(lambda path: os.path.join(*path.split('/')), - config['ignore']['files']) - config['ignore']['directories'] = map(lambda path: os.path.join(*path.split('/')), - config['ignore']['directories']) # Add dict of dir, list of expected ext to config dirs_to_check = config_file.get("check_ext", {}) # Fix the paths (OS-dependent) for path, exts in dirs_to_check.items(): - fixed_path = os.path.join(*path.split('/')) - config['check_ext'][fixed_path] = exts + config['check_ext'][normilize_paths([path])[0]] = exts # Override default configs user_configs = config_file.get("configs", []) diff --git a/python/tidy/servo_tidy_tests/duplicated_package.lock b/python/tidy/servo_tidy_tests/duplicated_package.lock index 77777fdd82c..6075f99164c 100644 --- a/python/tidy/servo_tidy_tests/duplicated_package.lock +++ b/python/tidy/servo_tidy_tests/duplicated_package.lock @@ -15,7 +15,33 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "test2" version = "0.1.0" -source = "git+https://github.com/" +source = "git+https://github.com/user/test2#c54edsf" dependencies = [ "test 0.4.9 (registry+https://github.com/rust-lang/crates.io-index)", ] + +[[package]] +name = "test3" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "test3" +version = "0.5.1" +source = "git+https://github.com/user/test3#c54edsf" + +[[package]] +name = "test4" +version = "0.1.0" +source = "git+https://github.com/user/test4#c54edsf" +dependencies = [ + "test3 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "test5" +version = "0.1.0" +source = "git+https://github.com/" +dependencies = [ + "test3 0.5.1 (git+https://github.com/user/test3)", +] diff --git a/python/tidy/servo_tidy_tests/script_thread.rs b/python/tidy/servo_tidy_tests/script_thread.rs new file mode 100644 index 00000000000..5dbeaec0e17 --- /dev/null +++ b/python/tidy/servo_tidy_tests/script_thread.rs @@ -0,0 +1,18 @@ +fn main() { + // This should trigger an error. + match self.documents.borrow_mut() { + _ => {} + } + // This should trigger an error. + match self.documents.borrow() { + _ => {} + } + // This should not trigger an error. + match { self.documents.borrow().find_window(id) } { + => {} + } + // This should not trigger an error. + match self.documents_status.borrow() { + => {} + } +} diff --git a/python/tidy/servo_tidy_tests/test_tidy.py b/python/tidy/servo_tidy_tests/test_tidy.py index c6fe8bd83fa..7adcbda2dfe 100644 --- a/python/tidy/servo_tidy_tests/test_tidy.py +++ b/python/tidy/servo_tidy_tests/test_tidy.py @@ -141,6 +141,12 @@ class CheckTidiness(unittest.TestCase): self.assertEqual('method declared in webidl is missing a comment with a specification link', errors.next()[2]) self.assertNoMoreErrors(errors) + def test_script_thread(self): + errors = tidy.collect_errors_for_files(iterFile('script_thread.rs'), [], [tidy.check_rust], print_text=False) + self.assertEqual('use a separate variable for the match expression', errors.next()[2]) + self.assertEqual('use a separate variable for the match expression', errors.next()[2]) + self.assertNoMoreErrors(errors) + def test_webidl(self): errors = tidy.collect_errors_for_files(iterFile('spec.webidl'), [tidy.check_webidl_spec], [], print_text=False) self.assertEqual('No specification link found.', errors.next()[2]) @@ -194,13 +200,17 @@ class CheckTidiness(unittest.TestCase): def test_lock(self): errors = tidy.collect_errors_for_files(iterFile('duplicated_package.lock'), [tidy.check_lock], [], print_text=False) - msg = """duplicate versions for package "test" -\t\033[93mfound dependency on version 0.4.9\033[0m -\t\033[91mbut highest version is 0.5.1\033[0m -\t\033[93mtry upgrading with\033[0m \033[96m./mach cargo-update -p test:0.4.9\033[0m -\tThe following packages depend on version 0.4.9: -\t\ttest2""" + msg = """duplicate versions for package `test` +\t\x1b[93mThe following packages depend on version 0.4.9 from 'crates.io':\x1b[0m +\t\ttest2 +\t\x1b[93mThe following packages depend on version 0.5.1 from 'crates.io':\x1b[0m""" self.assertEqual(msg, errors.next()[2]) + msg2 = """duplicate versions for package `test3` +\t\x1b[93mThe following packages depend on version 0.5.1 from 'crates.io':\x1b[0m +\t\ttest4 +\t\x1b[93mThe following packages depend on version 0.5.1 from 'https://github.com/user/test3':\x1b[0m +\t\ttest5""" + self.assertEqual(msg2, errors.next()[2]) self.assertNoMoreErrors(errors) def test_lint_runner(self): diff --git a/rust-nightly-date b/rust-nightly-date index 1cd945ea8b5..0e3f208c6c6 100644 --- a/rust-nightly-date +++ b/rust-nightly-date @@ -1 +1 @@ -2016-11-29 +2016-12-19 diff --git a/servo-tidy.toml b/servo-tidy.toml index 194a1658a3c..c5d64c6f30b 100644 --- a/servo-tidy.toml +++ b/servo-tidy.toml @@ -11,7 +11,7 @@ lint-scripts = [ [ignore] # Ignored packages with duplicated versions -packages = ["bitflags", "lazy_static", "semver"] +packages = ["bitflags", "lazy_static", "semver", "libloading"] # Files that are ignored for all tidy and lint checks. files = [ # Generated and upstream code combined with our own. Could use cleanup @@ -29,6 +29,7 @@ files = [ "./tests/unit/net/parsable_mime/text", "./tests/wpt/mozilla/tests/css/fonts", "./tests/wpt/mozilla/tests/css/pre_with_tab.html", + "./tests/wpt/mozilla/tests/mozilla/textarea_placeholder.html", # FIXME(pcwalton, #11679): This is a workaround for a tidy error on the quoted string # `"__TEXT,_info_plist"` inside an attribute. "./components/servo/platform/macos/mod.rs", @@ -58,4 +59,4 @@ directories = [ # Directories that are checked for correct file extension [check_ext] # directory, list of expected file extensions -"components/script/dom/webidls" = [".webidl"] +"./components/script/dom/webidls" = [".webidl"] diff --git a/servobuild.example b/servobuild.example index 1b6848315ec..df0e1d7f732 100644 --- a/servobuild.example +++ b/servobuild.example @@ -38,6 +38,8 @@ android = false debug-mozjs = false # Set to the path to your ccache binary to enable caching of compiler outputs #ccache = "/usr/local/bin/ccache" +# Any optional flags that will be added to $RUSTFLAGS +#rustflags = "" # Android information [android] diff --git a/support/android/build-apk/src/main.rs b/support/android/build-apk/src/main.rs index 234a37e9b51..0f2ad0f2e13 100644 --- a/support/android/build-apk/src/main.rs +++ b/support/android/build-apk/src/main.rs @@ -17,7 +17,7 @@ fn main() { let (args, passthrough) = parse_arguments(); // Find all the native shared libraries that exist in the target directory. - let native_shared_libs = find_native_libs(&args); + let mut native_shared_libs = find_native_libs(&args); // Get the SDK path from the ANDROID_HOME env. let sdk_path = env::var("ANDROID_HOME").ok().expect("Please set the ANDROID_HOME environment variable"); @@ -32,6 +32,14 @@ fn main() { .ok() .expect("Please set the ANDROID_PLATFORM environment variable"); + // Add the C++ runtime .so + { + let libcpp_base_path = ndk_path.join("sources").join("cxx-stl").join("llvm-libc++").join("libs"); + let libcpp_filename = "libc++_shared.so"; + let libcpp_path = libcpp_base_path.join("armeabi").join(libcpp_filename); + native_shared_libs.insert(libcpp_filename.to_string(), libcpp_path); + } + // Get the standalone NDK path from NDK_STANDALONE env. // let standalone_path = env::var("NDK_STANDALONE").ok().unwrap_or("/opt/ndk_standalone".to_string()); // let standalone_path = Path::new(&standalone_path); diff --git a/support/windows/Servo.wxs.mako b/support/windows/Servo.wxs.mako index a4b58892eef..d25a3f9a3c6 100644 --- a/support/windows/Servo.wxs.mako +++ b/support/windows/Servo.wxs.mako @@ -1,8 +1,8 @@ <?xml version="1.0" encoding="utf-8"?> <Wix xmlns="http://schemas.microsoft.com/wix/2006/wi"> - <Product Name="Servo Tech Demo" + <Product Id="*" + Name="Servo Tech Demo" Manufacturer="Mozilla Research" - Id="5807391a-3a17-476b-a5d2-5f1912569762" UpgradeCode="060cd15d-eab1-4614-b438-3988e3efdcf1" Language="1033" Codepage="1252" @@ -16,6 +16,7 @@ Languages="1033" SummaryCodepage="1252" Compressed="yes"/> + <MajorUpgrade AllowDowngrades="yes"/> <Media Id="1" Cabinet="Servo.cab" EmbedCab="yes"/> @@ -45,74 +46,7 @@ Source="${windowize(exe_path)}\servo.exe.manifest" DiskId="1"/> - <File Id="StdcxxDLL" - Name="libstdc++-6.dll" - Source="C:\msys64\mingw64\bin\libstdc++-6.dll" - DiskId="1"/> - <File Id="WinpthreadDll" - Name="libwinpthread-1.dll" - Source="C:\msys64\mingw64\bin\libwinpthread-1.dll" - DiskId="1"/> - <File Id="Bzip2Dll" - Name="libbz2-1.dll" - Source="C:\msys64\mingw64\bin\libbz2-1.dll" - DiskId="1"/> - <File Id="GccsehDll" - Name="libgcc_s_seh-1.dll" - Source="C:\msys64\mingw64\bin\libgcc_s_seh-1.dll" - DiskId="1"/> - <File Id="ExpatDll" - Name="libexpat-1.dll" - Source="C:\msys64\mingw64\bin\libexpat-1.dll" - DiskId="1"/> - <File Id="ZlibDll" - Name="zlib1.dll" - Source="C:\msys64\mingw64\bin\zlib1.dll" - DiskId="1"/> - <File Id="PngDll" - Name="libpng16-16.dll" - Source="C:\msys64\mingw64\bin\libpng16-16.dll" - DiskId="1"/> - <File Id="IconvDll" - Name="libiconv-2.dll" - Source="C:\msys64\mingw64\bin\libiconv-2.dll" - DiskId="1"/> - <File Id="GlibDll" - Name="libglib-2.0-0.dll" - Source="C:\msys64\mingw64\bin\libglib-2.0-0.dll" - DiskId="1"/> - <File Id="GraphiteDll" - Name="libgraphite2.dll" - Source="C:\msys64\mingw64\bin\libgraphite2.dll" - DiskId="1"/> - <File Id="IntlDll" - Name="libintl-8.dll" - Source="C:\msys64\mingw64\bin\libintl-8.dll" - DiskId="1"/> - <File Id="PcreDll" - Name="libpcre-1.dll" - Source="C:\msys64\mingw64\bin\libpcre-1.dll" - DiskId="1"/> - <File Id="Eay32Dll" - Name="libeay32.dll" - Source="C:\msys64\mingw64\bin\libeay32.dll" - DiskId="1"/> - <File Id="Ssleay32Dll" - Name="ssleay32.dll" - Source="C:\msys64\mingw64\bin\ssleay32.dll" - DiskId="1"/> - <File Id="HarfbuzzDll" - Name="libharfbuzz-0.dll" - Source="C:\msys64\mingw64\bin\libharfbuzz-0.dll" - DiskId="1"/> - <File Id="FreetypeDll" - Name="libfreetype-6.dll" - Source="C:\msys64\mingw64\bin\libfreetype-6.dll" - DiskId="1"/> - <File Id="FontconfigDll" - Name="libfontconfig-1.dll" - Source="C:\msys64\mingw64\bin\libfontconfig-1.dll" - DiskId="1"/> + ${include_dependencies()} </Component> ${include_directory(path.join(top_path, "resources"), "resources")} @@ -124,7 +58,7 @@ <Directory Id="ProgramMenuFolder" Name="Programs"> <Directory Id="ProgramMenuDir" Name="Servo Tech Demo"> <Component Id="ProgramMenuDir" Guid="e04737ce-16eb-4977-9b4c-ed2db8a5a77d"> - <RemoveFolder Id="ProgramMenuDir" On="uninstall"/> + <RemoveFolder Id="ProgramMenuDir" On="both"/> <RegistryValue Root="HKCU" Key="Software\Mozilla Research\Servo Tech Demo" Type="string" @@ -151,9 +85,13 @@ import os import os.path as path import re import uuid +from servo.command_base import host_triple def make_id(s): - return "Id{}".format(s.replace("-", "_").replace("/", "_")) + s = s.replace(os.getcwd(), "").replace("-", "_").replace("/", "_").replace("\\", "_") + if "browserhtml" in s: + s = "browserhtml_" + s[s.index("out") + 4:] + return "Id{}".format(s) def listfiles(directory): return [f for f in os.listdir(directory) @@ -163,6 +101,31 @@ def listdirs(directory): return [f for f in os.listdir(directory) if path.isdir(path.join(directory, f))] +def listdeps(exe_path): + if "msvc" in host_triple(): + return [path.join(windowize(exe_path), d) for d in ["libeay32md.dll", "ssleay32md.dll"]] + elif "gnu" in host_triple(): + deps = [ + "libstdc++-6.dll", + "libwinpthread-1.dll", + "libbz2-1.dll", + "libgcc_s_seh-1.dll", + "libexpat-1.dll", + "zlib1.dll", + "libpng16-16.dll", + "libiconv-2.dll", + "libglib-2.0-0.dll", + "libgraphite2.dll", + "libfreetype-6.dll", + "libfontconfig-1.dll", + "libintl-8.dll", + "libpcre-1.dll", + "libeay32.dll", + "ssleay32.dll", + "libharfbuzz-0.dll", + ] + return [path.join("C:\\msys64\\mingw64\\bin", d) for d in deps] + def windowize(p): if not p.startswith("/"): return p @@ -170,6 +133,16 @@ def windowize(p): components = [] %> + +<%def name="include_dependencies()"> +% for f in listdeps(exe_path): + <File Id="${make_id(path.basename(f)).replace(".","").replace("+","x")}" + Name="${path.basename(f)}" + Source="${f}" + DiskId="1"/> +% endfor +</%def> + <%def name="include_directory(d, n)"> <Directory Id="${make_id(path.basename(d))}" Name="${n}"> <Component Id="${make_id(path.basename(d))}" diff --git a/tests/compiletest/plugin/compile-fail/ban-domrefcell.rs b/tests/compiletest/plugin/compile-fail/ban-domrefcell.rs index 4e65ad410a6..4ec48545361 100644 --- a/tests/compiletest/plugin/compile-fail/ban-domrefcell.rs +++ b/tests/compiletest/plugin/compile-fail/ban-domrefcell.rs @@ -7,13 +7,13 @@ extern crate script; -use script::dom::bindings::cell::DOMRefCell; -use script::dom::bindings::js::JS; -use script::dom::node::Node; +use script::test::DOMRefCell; +use script::test::JS; +use script::test::Node; struct Foo { bar: DOMRefCell<JS<Node>> - //~^ ERROR Banned type DOMRefCell<JS<T>> detected. Use MutHeap<JS<T>> instead, + //~^ ERROR Banned type DOMRefCell<JS<T>> detected. Use MutJS<JS<T>> instead, } fn main() {} diff --git a/tests/compiletest/plugin/compile-fail/ban.rs b/tests/compiletest/plugin/compile-fail/ban.rs index b789597d59d..b0ea769b4a8 100644 --- a/tests/compiletest/plugin/compile-fail/ban.rs +++ b/tests/compiletest/plugin/compile-fail/ban.rs @@ -12,7 +12,7 @@ use std::cell::Cell; struct Foo { bar: Cell<JSVal> - //~^ ERROR Banned type Cell<JSVal> detected. Use MutHeap<JSVal> instead, + //~^ ERROR Banned type Cell<JSVal> detected. Use MutJS<JSVal> instead, } fn main() {} diff --git a/tests/html/bluetooth/bluetooth_battery_level.html b/tests/html/bluetooth/bluetooth_battery_level.html deleted file mode 100644 index be52f6792d1..00000000000 --- a/tests/html/bluetooth/bluetooth_battery_level.html +++ /dev/null @@ -1,40 +0,0 @@ -<!DOCTYPE html> -<html> -<title>Battery Level</title> -<body> - <button type="button" onclick="onButtonClick()">Get Bluetooth Device's Battery Level</button> - <pre id="log"></pre> - <script src="bluetooth_functions.js"></script> - <script> - function onButtonClick() { - clear(); - var options = {filters: [{services: ['battery_service']}], optionalServices: []}; - - log('Requesting Bluetooth Device...'); - window.navigator.bluetooth.requestDevice(options) - .then(device => { - log('Connecting to GATT Server on device...'); - return device.gatt.connect(); - }) - .then(server => { - log('Getting Battery Service...'); - return server.getPrimaryService('battery_service'); - }) - .then(service => { - log('Getting Battery Level Characteristic...'); - return service.getCharacteristic('battery_level'); - }) - .then(characteristic => { - log('Reading Battery Level...'); - return characteristic.readValue(); - }) - .then(value => { - log('> Battery Level is ' + asciiToDecimal(value) + '%'); - }) - .catch(err => { - log(err); - }); - } - </script> -</body> -</html> diff --git a/tests/html/bluetooth/bluetooth_battery_level_with_filter.html b/tests/html/bluetooth/bluetooth_battery_level_with_filter.html deleted file mode 100644 index 08593eba6da..00000000000 --- a/tests/html/bluetooth/bluetooth_battery_level_with_filter.html +++ /dev/null @@ -1,50 +0,0 @@ -<!DOCTYPE html> -<html> -<title>Battery Level with filters</title> -<body> - <input id="name" type="text" placeholder="Device Name"> - <input id="namePrefix" type="text" placeholder="Device Name Prefix"> - <button type="button" onclick="onButtonClick()">Get Bluetooth Device's Battery Level</button> - <pre id="log"></pre> - <script src="bluetooth_functions.js"></script> - <script> - function onButtonClick() { - clear(); - var options = {filters: [{services: ['battery_service']}], optionalServices: []}; - - var filterName = document.getElementById('name').value; - if (filterName) - options.filters[0].name = filterName; - - var filterNamePrefix = document.getElementById('namePrefix').value; - if (filterNamePrefix) - options.filters[0].namePrefix = filterNamePrefix; - - log('Requesting Bluetooth Device...'); - window.navigator.bluetooth.requestDevice(options) - .then(device => { - log('Connecting to GATT Server on device...'); - return device.gatt.connect(); - }) - .then(server => { - log('Getting Battery Service...'); - return server.getPrimaryService('battery_service'); - }) - .then(service => { - log('Getting Battery Level Characteristic...'); - return service.getCharacteristic('battery_level'); - }) - .then(characteristic => { - log('Reading Battery Level...'); - return characteristic.readValue(); - }) - .then(value => { - log('> Battery Level is ' + asciiToDecimal(value) + '%'); - }) - .catch(err => { - log(err); - }); - } - </script> -</body> -</html> diff --git a/tests/html/bluetooth/bluetooth_characteristic_info.html b/tests/html/bluetooth/bluetooth_characteristic_info.html deleted file mode 100644 index 8370abba825..00000000000 --- a/tests/html/bluetooth/bluetooth_characteristic_info.html +++ /dev/null @@ -1,63 +0,0 @@ -<!DOCTYPE html> -<html> -<title>Characteristic info</title> -<body> - <input id="service" type="text" autofocus placeholder="Bluetooth Service"> - <input id="characteristic" type="text" autofocus placeholder="Bluetooth Characteristic"> - <button type="button" onclick="onButtonClick()">Get Characteristic Info</button> - <pre id="log"></pre> - <script src="bluetooth_functions.js"></script> - <script> - function onButtonClick() { - clear(); - var serviceUuid = document.getElementById('service').value; - var characteristicUuid = document.getElementById('characteristic').value; - - if (!serviceUuid || !characteristicUuid) { - return log('All input field must be filled!'); - } - if (serviceUuid.startsWith('0x')) - serviceUuid = parseInt(serviceUuid, 16); - - if (characteristicUuid.startsWith('0x')) - characteristicUuid = parseInt(characteristicUuid, 16); - - log('Requesting Bluetooth Device...'); - window.navigator.bluetooth.requestDevice({filters: [{services: [serviceUuid]}]}) - .then(device => { - log('Connecting to GATT Server on device...'); - return device.gatt.connect(); - }) - .then(server => { - log('Getting Primary Service...'); - return server.getPrimaryService(serviceUuid); - }) - .then(service => { - log('Getting Characteristic...'); - return service.getCharacteristic(characteristicUuid); - }) - .then(characteristic => { - log('Characteristic found!'); - log('> Characteristic service: ' + characteristic.service.uuid); - log('> Characteristic UUID: ' + characteristic.uuid); - log('> Broadcast: ' + characteristic.properties.broadcast); - log('> Read: ' + characteristic.properties.read); - log('> Write w/o response: ' + characteristic.properties.writeWithoutResponse); - log('> Write: ' + characteristic.properties.write); - log('> Notify: ' + characteristic.properties.notify); - log('> Indicate: ' + characteristic.properties.indicate); - log('> Signed Write: ' + characteristic.properties.authenticatedSignedWrites); - log('> Queued Write: ' + characteristic.properties.reliableWrite); - log('> Writable Auxiliaries: ' + characteristic.properties.writableAuxiliaries); - return characteristic.readValue(); - }) - .then(value => { - log('> Characteristic value: ' + asciiToDecimal(value)); - }) - .catch(err => { - log(err); - }); - } - </script> -</body> -</html> diff --git a/tests/html/bluetooth/bluetooth_characteristic_read_value_test_cases.html b/tests/html/bluetooth/bluetooth_characteristic_read_value_test_cases.html deleted file mode 100644 index 54ef538c6ec..00000000000 --- a/tests/html/bluetooth/bluetooth_characteristic_read_value_test_cases.html +++ /dev/null @@ -1,76 +0,0 @@ -<!DOCTYPE html> -<html> -<title>Characterstic's ReadValue Test Cases</title> -<body> - <div id="buttons"></div> - <pre id="log"></pre> - <script src="bluetooth_functions.js"></script> - <script> - var testCases = []; - //Test 1 - testCases.push({characteristic: 'body_sensor_location', mustDisconnect: true}); - //Test 2 - testCases.push({characteristic: 'gap.reconnection_address', mustDisconnect: false}); - //Test 3 - testCases.push({characteristic: 'serial_number_string', mustDisconnect: false}); - //Test 4 - testCases.push({characteristic: 0x00002a03, mustDisconnect: false}); - //Test 5 - testCases.push({characteristic: 0x00002a25, mustDisconnect: false}); - //Test 6 - testCases.push({characteristic: '00002a03-0000-1000-8000-00805f9b34fb', mustDisconnect: false}); - //Test 7 - testCases.push({characteristic: '00002a25-0000-1000-8000-00805f9b34fb', mustDisconnect: false}); - //Test 8 - testCases.push({characteristic: 'body_sensor_location', mustDisconnect: false}); - //Test 9 - testCases.push({characteristic: 0x00002a38, mustDisconnect: false}); - //Test 10 - testCases.push({characteristic: '00002a38-0000-1000-8000-00805f9b34fb', mustDisconnect: false}); - //Test 11 - testCases.push({characteristic: 'heart_rate_control_point', mustDisconnect: false}); - - function onButtonClick(testNumber) { - clear(); - - var bt_server; - - log('Requesting Bluetooth Device...'); - window.navigator.bluetooth.requestDevice({filters: [{services: ['heart_rate']}]}) - .then(device => { - log('Connecting to GATTserver on device...'); - return device.gatt.connect(); - }) - .then(server => { - bt_server = server; - - log('Getting Primary Service "heart_rate"...'); - return server.getPrimaryService('heart_rate'); - }) - .then(service => { - log('Getting Characteristic "' + testCases[testNumber].characteristic + '"...'); - return service.getCharacteristic(testCases[testNumber].characteristic); - }) - .then(characteristic => { - log('Characteristic found!'); - - if (testCases[testNumber].mustDisconnect) { - log('Disconnecting from server...'); - bt_server.disconnect(); - } - - log('Reading the value of the Characteristic...'); - return characteristic.readValue(); - }) - .then(value => { - log('> Characteristic value: ' + asciiToDecimal(value)); - }) - .catch(err => { - log(err); - }); - } - - populate(testCases); - </script> -</body> -</html> diff --git a/tests/html/bluetooth/bluetooth_characteristic_write_value_test_cases.html b/tests/html/bluetooth/bluetooth_characteristic_write_value_test_cases.html deleted file mode 100644 index 84af2a29af0..00000000000 --- a/tests/html/bluetooth/bluetooth_characteristic_write_value_test_cases.html +++ /dev/null @@ -1,92 +0,0 @@ -<!DOCTYPE html> -<html> -<title>Characterstic's WriteValue Test Cases</title> -<body> - <div id="buttons"></div> - <pre id="log"></pre> - <script src="bluetooth_functions.js"></script> - <script> - var testCases = []; - //Test 1 - testCases.push({characteristic: 0x2345, valueToWrite: [11], mustDisconnect: true}); - //Test 2 - testCases.push({characteristic: 0x2345, valueToWrite: new Array(513), mustDisconnect: false}); - //Test 3 - testCases.push({characteristic: 'gap.reconnection_address', valueToWrite: [1], mustDisconnect: false}); - //Test 4 - testCases.push({characteristic: 'serial_number_string', valueToWrite: [2], mustDisconnect: false}); - //Test 5 - testCases.push({characteristic: 0x00002a02, valueToWrite: [3], mustDisconnect: false}); - //Test 6 - testCases.push({characteristic: 0x00002a03, valueToWrite: [3], mustDisconnect: false}); - //Test 7 - testCases.push({characteristic: 0x00002a25, valueToWrite: [4], mustDisconnect: false}); - //Test 8 - testCases.push({characteristic: '00002a02-0000-1000-8000-00805f9b34fb', valueToWrite: [6], mustDisconnect: false}); - //Test 9 - testCases.push({characteristic: '00002a03-0000-1000-8000-00805f9b34fb', valueToWrite: [5], mustDisconnect: false}); - //Test 10 - testCases.push({characteristic: '00002a25-0000-1000-8000-00805f9b34fb', valueToWrite: [6], mustDisconnect: false}); - //Test 11 - testCases.push({characteristic: 0x2345, valueToWrite: [11]}); - //Test 12 - testCases.push({characteristic: '00002345-0000-1000-8000-00805f9b34fb', valueToWrite: [22], mustDisconnect: false}); - - function onButtonClick(testNumber) { - clear(); - - var bt_server; - - log('Requesting Bluetooth Device...'); - window.navigator.bluetooth.requestDevice({filters: [{services: [0x1234]}]}) - .then(device => { - log('Connecting to GATT Server on device...'); - return device.gatt.connect(); - }) - .then(server => { - bt_server = server; - - log('Getting Primary Service...'); - return server.getPrimaryService(0x1234); - }) - .then(service => { - log('Getting Characteristic "' + testCases[testNumber].characteristic + '"...'); - return service.getCharacteristic(testCases[testNumber].characteristic); - }) - .then(characteristic => { - log('Characteristic found!'); - log('Reading the old value of the Characteristic...'); - return characteristic.readValue(); - }) - .then(value => { - log('> Characteristic value: ' + asciiToDecimal(characteristic.value)); - - if (testCases[testNumber].mustDisconnect) { - log('Disconnecting from server...'); - bt_server.disconnect(); - } - - if (testNumber !== 1) { - log('Writing the value of the Characteristic with: ' + testCases[testNumber].valueToWrite + '...'); - } else { - log('Writing the value of the Characteristic with a 513 long array...'); - } - - return characteristic.writeValue(testCases[testNumber].valueToWrite); - }) - .then(_ => { - log('Reading the new value of the Characteristic...'); - return characteristic.readValue(); - }) - .then(value => { - log('> Characteristic value: ' + asciiToDecimal(value)); - }) - .catch(err => { - log(err); - }); - } - - populate(testCases); - </script> -</body> -</html> diff --git a/tests/html/bluetooth/bluetooth_descriptor_info.html b/tests/html/bluetooth/bluetooth_descriptor_info.html deleted file mode 100644 index 92a9a0504c8..00000000000 --- a/tests/html/bluetooth/bluetooth_descriptor_info.html +++ /dev/null @@ -1,63 +0,0 @@ -<!DOCTYPE html> -<html> -<title>Descriptor info</title> -<body> - <input id="service" type="text" autofocus placeholder="Bluetooth Service"> - <input id="characteristic" type="text" autofocus placeholder="Bluetooth Characteristic"> - <input id="descriptor" type="text" autofocus placeholder="Bluetooth Descriptor"> - <button type="button" onclick="onButtonClick()">Get Descriptor Info</button> - <pre id="log"></pre> - <script src="bluetooth_functions.js"></script> - <script> - function onButtonClick() { - clear(); - var serviceUuid = document.getElementById('service').value; - var characteristicUuid = document.getElementById('characteristic').value; - var descriptorUuid = document.getElementById('descriptor').value; - - if (!serviceUuid || !characteristicUuid || !descriptorUuid) { - return log('All input field must be filled!'); - } - if (serviceUuid.startsWith('0x')) - serviceUuid = parseInt(serviceUuid, 16); - - if (characteristicUuid.startsWith('0x')) - characteristicUuid = parseInt(characteristicUuid, 16); - - if (descriptorUuid.startsWith('0x')) - descriptorUuid = parseInt(descriptorUuid, 16); - - log('Requesting Bluetooth Device...'); - window.navigator.bluetooth.requestDevice({filters: [{services: [serviceUuid]}]}) - .then(device => { - log('Connecting to GATT Server on device...'); - return device.gatt.connect(); - }) - .then(server => { - log('Getting Primary Service...'); - return server.getPrimaryService(serviceUuid); - }) - .then(service => { - log('Getting Characteristic...'); - return service.getCharacteristic(characteristicUuid); - }) - .then(characteristic => { - log('Getting Descriptor...'); - return characteristic.getDescriptor(descriptorUuid); - }) - .then(descriptor => { - log('Descriptor found!'); - log('> Descriptor characteristic: ' + descriptor.characteristic.uuid); - log('> Descriptor UUID: ' + descriptor.uuid); - return descriptor.readValue(); - }) - .then(value => { - log('> Descriptor value: ' + asciiToDecimal(value)); - }) - .catch(err => { - log(err); - }); - } - </script> -</body> -</html> diff --git a/tests/html/bluetooth/bluetooth_descriptor_read_value_test_cases.html b/tests/html/bluetooth/bluetooth_descriptor_read_value_test_cases.html deleted file mode 100644 index 658c6af9583..00000000000 --- a/tests/html/bluetooth/bluetooth_descriptor_read_value_test_cases.html +++ /dev/null @@ -1,70 +0,0 @@ -<!DOCTYPE html> -<html> -<title>Descriptor's ReadValue Test Cases</title> -<body> - <div id="buttons"></div> - <pre id="log"></pre> - <script src="bluetooth_functions.js"></script> - <script> - var testCases = []; - //Test 1 - testCases.push({descriptor: 'gatt.client_characteristic_configuration', mustDisconnect: true}); - //Test 2 - testCases.push({descriptor: 0x2902, mustDisconnect: true}); - //Test 3 - testCases.push({descriptor: '00002902-0000-1000-8000-00805f9b34fb', mustDisconnect: true}); - //Test 4 - testCases.push({descriptor: 'gatt.client_characteristic_configuration', mustDisconnect: false}); - //Test 5 - testCases.push({descriptor: 0x2902, mustDisconnect: false}); - //Test 6 - testCases.push({descriptor: '00002902-0000-1000-8000-00805f9b34fb', mustDisconnect: false}); - - function onButtonClick(testNumber) { - clear(); - - var bt_server; - - log('Requesting Bluetooth Device...'); - window.navigator.bluetooth.requestDevice({filters: [{services: ['heart_rate']}]}) - .then(device => { - log('Connecting to GATTserver on device...'); - return device.gatt.connect(); - }) - .then(server => { - bt_server = server; - - log('Getting Primary Service "heart_rate"...'); - return server.getPrimaryService('heart_rate'); - }) - .then(service => { - log('Getting Characteristic "heart_rate_measurement"...'); - return service.getCharacteristic('heart_rate_measurement'); - }) - .then(characteristic => { - log('Getting Descriptor "' + testCases[testNumber].descriptor + '"...'); - return characteristic.getDescriptor(testCases[testNumber].descriptor); - }) - .then(descriptor => { - log('Descriptor found!'); - - if (testCases[testNumber].mustDisconnect) { - log('Disconecting from GATTserver'); - bt_server.disconnect(); - } - - log("Reading descriptor's value..."); - return descriptor.readValue(); - }) - .then(value => { - log('> Descriptor value: ' + asciiToDecimal(value)); - }) - .catch(err => { - log(err); - }); - } - - populate(testCases); - </script> -</body> -</html> diff --git a/tests/html/bluetooth/bluetooth_descriptor_write_value_test_cases.html b/tests/html/bluetooth/bluetooth_descriptor_write_value_test_cases.html deleted file mode 100644 index d2309726527..00000000000 --- a/tests/html/bluetooth/bluetooth_descriptor_write_value_test_cases.html +++ /dev/null @@ -1,88 +0,0 @@ -<!DOCTYPE html> -<html> -<title>Descriptor's WriteValue Test Cases</title> -<body> - <div id="buttons"></div> - <pre id="log"></pre> - <script src="bluetooth_functions.js"></script> - <script> - var testCases = []; - //Test 1 - testCases.push({descriptor: '00003456-0000-1000-8000-00805f9b34fb', valueToWrite: [11], mustDisconnect: true}); - //Test 2 - testCases.push({descriptor: '00003456-0000-1000-8000-00805f9b34fb', valueToWrite: new Array(513), mustDisconnect: false}); - //Test 3 - testCases.push({descriptor: '00002902-0000-1000-8000-00805f9b34fb', valueToWrite: [1], mustDisconnect: false}); - //Test 4 - testCases.push({descriptor: 0x00002902, valueToWrite: [2], mustDisconnect: false}); - //Test 5 - testCases.push({descriptor: 0x3456, valueToWrite: [11], mustDisconnect: false}); - //Test 6 - testCases.push({descriptor: '00003456-0000-1000-8000-00805f9b34fb', valueToWrite: [22], mustDisconnect: false}); - - function onButtonClick(testNumber) { - clear(); - - var bt_server; - var bt_descriptor; - - log('Requesting Bluetooth Device...'); - window.navigator.bluetooth.requestDevice({filters: [{services: [0x1234]}]}) - .then(device => { - log('Connecting to GATTserver on device...'); - return device.gatt.connect(); - }) - .then(server => { - bt_server = server; - - log('Getting Primary Service "Test Service"...'); - return server.getPrimaryService(0x1234); - }) - .then(service => { - log('Getting Characteristic "Test Characteristic (0x2345)"...'); - return service.getCharacteristic(0x2345); - }) - .then(characteristic => { - log('Characteristic found!'); - - log('Getting Descriptor "' + testCases[testNumber].descriptor + '"...'); - return characteristic.getDescriptor(testCases[testNumber].descriptor); - }) - .then(descriptor => { - bt_descriptor = descriptor; - - log('Reading the old value of the Descriptor...'); - return descriptor.readValue(); - }) - .then(value => { - log('> Descriptor value: ' + asciiToDecimal(value)); - - if (testCases[testNumber].mustDisconnect) { - log('Disconnecting from server...'); - bt_server.disconnect(); - } - - if (testNumber !== 1) { - log('Writing the value of the Descriptor with: ' + testCases[testNumber].valueToWrite + '...'); - } else { - log('Writing the value of the Descriptor with a 513 long array...'); - } - - return bt_descriptor.writeValue(testCases[testNumber].valueToWrite); - }) - .then(_ => { - log('Reading the new value of the Descriptor...'); - return bt_descriptor.readValue(); - }) - .then(value => { - log('> Descriptor value: ' + asciiToDecimal(value)); - }) - .catch(err => { - log(err); - }); - } - - populate(testCases); - </script> -</body> -</html> diff --git a/tests/html/bluetooth/bluetooth_device_disconnect.html b/tests/html/bluetooth/bluetooth_device_disconnect.html deleted file mode 100644 index 15dbb75db05..00000000000 --- a/tests/html/bluetooth/bluetooth_device_disconnect.html +++ /dev/null @@ -1,92 +0,0 @@ -<!DOCTYPE html> -<html> -<title>Device Disconnect</title> -<body> - <input id="service" type="text" autofocus placeholder="Bluetooth Service"> - <input id="name" type="text" placeholder="Device Name"> - <input id="namePrefix" type="text" placeholder="Device Name Prefix"> - <button type="button" onclick="onScanButtonClick()">Scan()</button> - <button type="button" onclick="onDisconnectButtonClick()">Disconnect()</button> - <button type="button" onclick="onReconnectButtonClick()">Reconnect()</button> - <pre id="log"></pre> - <script src="bluetooth_functions.js"></script> - <script> - var bluetoothDevice; - - function onScanButtonClick() { - clear(); - var options = {filters: [{}]}; - - var filterService = document.getElementById('service').value; - if (filterService) { - if (filterService.startsWith('0x')) - filterService = parseInt(filterService, 16); - options.filters[0].services = [filterService]; - } - - var filterName = document.getElementById('name').value; - if (filterName) - options.filters[0].name = filterName; - - var filterNamePrefix = document.getElementById('namePrefix').value; - if (filterNamePrefix) - options.filters[0].namePrefix = filterNamePrefix; - - clear(); - log('Requesting Bluetooth Device...'); - window.navigator.bluetooth.requestDevice(options) - .then(device => { - bluetoothDevice = device; - - log('Connecting to Bluetooth Device...'); - connect(); - }) - .catch(err => { - log(err); - }); - } - - function onDisconnectButtonClick() { - clear(); - if (!bluetoothDevice) - return log('> There is no connected Bluetooth Device instance, from which we can disconnect'); - - try { - log('Disconnecting from Bluetooth Device...'); - if (bluetoothDevice.gatt.connected) { - bluetoothDevice.gatt.disconnect(); - log('> Bluetooth Device connected: ' + bluetoothDevice.gatt.connected); - } else { - log('> Bluetooth Device is already disconnected'); - } - } catch(err) { - log(err); - } - } - - function onReconnectButtonClick() { - clear(); - if (!bluetoothDevice) - log('> There is no connected Bluetooth Device instance, so we cannot reconnect') - if (bluetoothDevice.gatt.connected) { - log('> Bluetooth Device is already connected'); - return; - } else { - log('Connecting to Bluetooth Device...'); - connect(); - } - } - - function connect() { - bluetoothDevice.gatt.connect() - .then(server => { - log('Result of the connect() method of the GATT Server: ' + server); - log('> Bluetooth Device connected: ' + server.connected); - }) - .catch(err => { - log(err); - }); - } - </script> -</body> -</html> diff --git a/tests/html/bluetooth/bluetooth_device_info.html b/tests/html/bluetooth/bluetooth_device_info.html deleted file mode 100644 index b92cd5376cf..00000000000 --- a/tests/html/bluetooth/bluetooth_device_info.html +++ /dev/null @@ -1,47 +0,0 @@ -<!DOCTYPE html> -<html> -<title>Device Info</title> -<body> - <input id="service" type="text" autofocus placeholder="Bluetooth Service"> - <input id="name" type="text" placeholder="Device Name"> - <input id="namePrefix" type="text" placeholder="Device Name Prefix"> - <button type="button" onclick="onButtonClick()">Get Bluetooth Device Info</button> - <pre id="log"></pre> - <script src="bluetooth_functions.js"></script> - <script> - function onButtonClick() { - clear(); - var options = {filters: [], optionalServices: []}; - - var filterService = document.getElementById('service').value; - if (filterService) { - if (filterService.startsWith('0x')) - filterService = parseInt(filterService, 16); - options.filters.push({services: [filterService]}); - } - - var filterName = document.getElementById('name').value; - if (filterName) - options.filters.push({name: filterName}); - - var filterNamePrefix = document.getElementById('namePrefix').value; - if (filterNamePrefix) - options.filters.push({namePrefix: filterNamePrefix}); - - log('Requesting Bluetooth Device...'); - window.navigator.bluetooth.requestDevice(options) - .then(device => { - log('Found a device!'); - log('> Name: ' + device.name); - log('> Id: ' + device.id); - log('> Appearance: ' + device.adData.appearance); - log('> Tx Power: ' + device.adData.txPower + ' dBm'); - log('> RSSI: ' + device.adData.rssi + ' dBm'); - }) - .catch(err => { - log(err); - }); - } - </script> -</body> -</html> diff --git a/tests/html/bluetooth/bluetooth_functions.js b/tests/html/bluetooth/bluetooth_functions.js deleted file mode 100644 index b0f73c79c0a..00000000000 --- a/tests/html/bluetooth/bluetooth_functions.js +++ /dev/null @@ -1,32 +0,0 @@ -function clear() { - document.getElementById("log").textContent = ""; -} - -function log(line) { - document.getElementById("log").textContent += timeStamp() + line + '\n'; -} - -function asciiToDecimal(bytestr) { - var result = []; - for(i = 0; i < bytestr.length; i++) { - result[i] = bytestr.charCodeAt(i) ; - } - return result; -} - -function populate(testCases){ - for(i = 0; i < testCases.length; ++i) { - var btn = document.createElement('button'); - btn.setAttribute('onclick','onButtonClick(' + i + ')'); - btn.innerHTML = 'Test '+ (i+1); - document.getElementById('buttons').appendChild(btn); - } -} - -function timeStamp() { - var date = new Date; - var hours = date.getHours(); - var minutes = "0" + date.getMinutes(); - var seconds = "0" + date.getSeconds(); - return hours + ':' + minutes.substr(-2) + ':' + seconds.substr(-2) + ' '; -} diff --git a/tests/html/bluetooth/bluetooth_get_characteristic_test_cases.html b/tests/html/bluetooth/bluetooth_get_characteristic_test_cases.html deleted file mode 100644 index c711d7c132b..00000000000 --- a/tests/html/bluetooth/bluetooth_get_characteristic_test_cases.html +++ /dev/null @@ -1,88 +0,0 @@ -<!DOCTYPE html> -<html> -<title>GetCharacteristic Test Cases</title> -<body> - <div id="buttons"></div> - <pre id="log"></pre> - <script src="bluetooth_functions.js"></script> - <script> - var testCases = []; - //Test 1 - testCases.push({characteristic: 'not_a_characteristic_name', service: 'battery_service', options: {filters: [{services: ['battery_service']}], optionalServices: ['cycling_power']} }); - //Test 2 - testCases.push({characteristic: 'battery_level', service: 'battery_service', options: {filters: [{services: ['battery_service']}], optionalServices: ['cycling_power']} }); - //Test 3 - testCases.push({characteristic: '1234567891000-1000-8000-00805f9b34fb', service: 'battery_service', options: {filters: [{services: ['battery_service']}], optionalServices: ['cycling_power']} }); - //Test 4 - testCases.push({characteristic: '11', service: 'battery_service', options: {filters: [{services: ['battery_service']}], optionalServices: ['cycling_power']} }); - //Test 5 - testCases.push({characteristic: '12345678-1234-1234-1234-123456789abc', service: 'battery_service', options: {filters: [{services: ['battery_service']}], optionalServices: ['cycling_power']} }); - //Test 6 - testCases.push({characteristic: '00000000-0000-0000-0000-000000000000', service: 'battery_service', options: {filters: [{services: ['battery_service']}], optionalServices: ['cycling_power']} }); - //Test 7 - testCases.push({characteristic: 0x0000, service: 'battery_service', options: {filters: [{services: ['battery_service']}], optionalServices: ['cycling_power']} }); - //Test 8 - testCases.push({characteristic: 0x000000000, service: 'battery_service', options: {filters: [{services: ['battery_service']}], optionalServices: ['cycling_power']} }); - //Test 9 - testCases.push({characteristic: 0x2a19, service: 'battery_service', options: {filters: [{services: ['battery_service']}], optionalServices: ['cycling_power']} }); - //Test 10 - testCases.push({characteristic: 0x12345678, service: 'battery_service', options: {filters: [{services: ['battery_service']}], optionalServices: ['cycling_power']} }); - //Test 11 - testCases.push({characteristic: 0x00002a19, service: 'battery_service', options: {filters: [{services: ['battery_service']}], optionalServices: ['cycling_power']} }); - //Test 12 - testCases.push({characteristic: 0x00002a03, service: 'battery_service', options: {filters: [{services: ['battery_service']}], optionalServices: ['cycling_power']} }); - //Test 13 - testCases.push({characteristic: 0x00002a25, service: 'battery_service', options: {filters: [{services: ['battery_service']}], optionalServices: ['cycling_power']} }); - //Test 14 - testCases.push({characteristic: 0x2a03, service: 'battery_service', options: {filters: [{services: ['battery_service']}], optionalServices: ['cycling_power']} }); - //Test 15 - testCases.push({characteristic: 0x2a25, service: 'battery_service', options: {filters: [{services: ['battery_service']}], optionalServices: ['cycling_power']} }); - //Test 16 - testCases.push({characteristic: '00002a03-0000-1000-8000-00805f9b34fb', service: 'battery_service', options: {filters: [{services: ['battery_service']}], optionalServices: ['cycling_power']} }); - //Test 17 - testCases.push({characteristic: '00002a25-0000-1000-8000-00805f9b34fb', service: 'battery_service', options: {filters: [{services: ['battery_service']}], optionalServices: ['cycling_power']} }); - - function onButtonClick(testNumber) { - clear(); - - log('Requesting Bluetooth Device...'); - window.navigator.bluetooth.requestDevice(testCases[testNumber].options) - .then(device => { - log('Connecting to GATTserver on device...'); - return device.gatt.connect(); - }) - .then(server => { - log('Getting Primary Service "' + testCases[testNumber].service + '"...'); - return server.getPrimaryService(testCases[testNumber].service); - }) - .then(service => { - log('Getting Characteristic "' + testCases[testNumber].characteristic + '"...'); - return service.getCharacteristic(testCases[testNumber].characteristic); - }) - .then(characteristic => { - log('Characteristic found!'); - log('> Characteristic service: ' + characteristic.service.uuid); - log('> Characteristic UUID: ' + characteristic.uuid); - log('> Broadcast: ' + characteristic.properties.broadcast); - log('> Read: ' + characteristic.properties.read); - log('> Write w/o response: ' + characteristic.properties.writeWithoutResponse); - log('> Write: ' + characteristic.properties.write); - log('> Notify: ' + characteristic.properties.notify); - log('> Indicate: ' + characteristic.properties.indicate); - log('> Signed Write: ' + characteristic.properties.authenticatedSignedWrites); - log('> Queued Write: ' + characteristic.properties.reliableWrite); - log('> Writable Auxiliaries: ' + characteristic.properties.writableAuxiliaries); - return characteristic.readValue(); - }) - .then(value => { - log('> Characteristic value: ' + asciiToDecimal(value)); - }) - .catch(err => { - log(err); - }); - } - - populate(testCases); - </script> -</body> -</html> diff --git a/tests/html/bluetooth/bluetooth_get_characteristics_test_cases.html b/tests/html/bluetooth/bluetooth_get_characteristics_test_cases.html deleted file mode 100644 index 073ef4e1b5a..00000000000 --- a/tests/html/bluetooth/bluetooth_get_characteristics_test_cases.html +++ /dev/null @@ -1,94 +0,0 @@ -<!DOCTYPE html> -<html> -<title>GetCharacteristics Test Cases</title> -<body> - <div id="buttons"></div> - <pre id="log"></pre> - <script src="bluetooth_functions.js"></script> - <script> - var testCases = []; - //Test 1 - testCases.push({service: 'battery_service', options: {filters: [{services: ['battery_service']}], optionalServices: ['cycling_power']} }); - //Test 2 - testCases.push({characteristic: 'not_a_characteristic_name', service: 'heart_rate', options: {filters: [{services: ['heart_rate']}], optionalServices: ['cycling_power']} }); - //Test 3 - testCases.push({characteristic: 'body_sensor_location', service: 'heart_rate', options: {filters: [{services: ['heart_rate']}], optionalServices: ['cycling_power']} }); - //Test 4 - testCases.push({characteristic: '1234567891000-1000-8000-00805f9b34fb', service: 'heart_rate', options: {filters: [{services: ['heart_rate']}], optionalServices: ['cycling_power']} }); - //Test 5 - testCases.push({characteristic: '11', service: 'heart_rate', options: {filters: [{services: ['heart_rate']}], optionalServices: ['cycling_power']} }); - //Test 6 - testCases.push({characteristic: '12345678-1234-1234-1234-123456789abc', service: 'heart_rate', options: {filters: [{services: ['heart_rate']}], optionalServices: ['cycling_power']} }); - //Test 7 - testCases.push({characteristic: '00000000-0000-0000-0000-000000000000', service: 'heart_rate', options: {filters: [{services: ['heart_rate']}], optionalServices: ['cycling_power']} }); - //Test 8 - testCases.push({characteristic: 0x0000, service: 'heart_rate', options: {filters: [{services: ['heart_rate']}], optionalServices: ['cycling_power']} }); - //Test 9 - testCases.push({characteristic: 0x000000000, service: 'heart_rate', options: {filters: [{services: ['heart_rate']}], optionalServices: ['cycling_power']} }); - //Test 10 - testCases.push({characteristic: 0x2a38, service: 'heart_rate', options: {filters: [{services: ['heart_rate']}], optionalServices: ['cycling_power']} }); - //Test 11 - testCases.push({characteristic: 0x12345678, service: 'heart_rate', options: {filters: [{services: ['heart_rate']}], optionalServices: ['cycling_power']} }); - //Test 12 - testCases.push({characteristic: 0x00002a38, service: 'heart_rate', options: {filters: [{services: ['heart_rate']}], optionalServices: ['cycling_power']} }); - //Test 13 - testCases.push({characteristic: 0x00002a03, service: 'heart_rate', options: {filters: [{services: ['heart_rate']}], optionalServices: ['cycling_power']} }); - //Test 14 - testCases.push({characteristic: 0x00002a25, service: 'heart_rate', options: {filters: [{services: ['heart_rate']}], optionalServices: ['cycling_power']} }); - //Test 15 - testCases.push({characteristic: 0x2a03, service: 'heart_rate', options: {filters: [{services: ['heart_rate']}], optionalServices: ['cycling_power']} }); - //Test 16 - testCases.push({characteristic: 0x2a25, service: 'heart_rate', options: {filters: [{services: ['heart_rate']}], optionalServices: ['cycling_power']} }); - //Test 17 - testCases.push({characteristic: '00002a03-0000-1000-8000-00805f9b34fb', service: 'heart_rate', options: {filters: [{services: ['heart_rate']}], optionalServices: ['cycling_power']} }); - //Test 18 - testCases.push({characteristic: '00002a25-0000-1000-8000-00805f9b34fb', service: 'heart_rate', options: {filters: [{services: ['heart_rate']}], optionalServices: ['cycling_power']} }); - - function onButtonClick(testNumber) { - clear(); - - log('Requesting Bluetooth Device...'); - window.navigator.bluetooth.requestDevice(testCases[testNumber].options) - .then(device => { - log('Connecting to GATTserver on device...'); - return device.gatt.connect(); - }) - .then(server => { - log('Getting Primary Service "' + testCases[testNumber].service + '"...'); - return server.getPrimaryService(testCases[testNumber].service); - }) - .then(service => { - log('Getting Characteristic "' + testCases[testNumber].characteristic + '"...'); - return service.getCharacteristics(testCases[testNumber].characteristic); - }) - .then(characteristics => { - log('> List of Characteristics on the current device:'); - - for(i = 0; i < characteristics.length; ++i) { - log('> #' + (i+1)); - log('> Characteristic service: ' + characteristics[i].service.uuid); - log('> Characteristic UUID: ' + characteristics[i].uuid); - log('> Broadcast: ' + characteristics[i].properties.broadcast); - log('> Read: ' + characteristics[i].properties.read); - log('> Write w/o response: ' + characteristics[i].properties.writeWithoutResponse); - log('> Write: ' + characteristics[i].properties.write); - log('> Notify: ' + characteristics[i].properties.notify); - log('> Indicate: ' + characteristics[i].properties.indicate); - log('> Signed Write: ' + characteristics[i].properties.authenticatedSignedWrites); - log('> Queued Write: ' + characteristics[i].properties.reliableWrite); - log('> Writable Auxiliaries: ' + characteristics[i].properties.writableAuxiliaries); - characteristics[i].readValue() - .then(value => { - log('> #' + (i+1) + ' Characteristic value: ' + asciiToDecimal(characteristics[i].value)); - }); - } - }) - .catch(err => { - log(err); - }); - } - - populate(testCases); - </script> -</body> -</html> diff --git a/tests/html/bluetooth/bluetooth_get_descriptor_test_cases.html b/tests/html/bluetooth/bluetooth_get_descriptor_test_cases.html deleted file mode 100644 index bd0754c2b44..00000000000 --- a/tests/html/bluetooth/bluetooth_get_descriptor_test_cases.html +++ /dev/null @@ -1,74 +0,0 @@ -<!DOCTYPE html> -<html> -<title>GetDescriptor Test Cases</title> -<body> - <div id="buttons"></div> - <pre id="log"></pre> - <script src="bluetooth_functions.js"></script> - <script> - var testCases = []; - //Test 1 - testCases.push('not_a_descriptor_name'); - //Test 2 - testCases.push('gatt.client_characteristic_configuration'); - //Test 3 - testCases.push('1234567891000-1000-8000-00805f9b34fb'); - //Test 4 - testCases.push('11'); - //Test 5 - testCases.push('12345678-1234-1234-1234-123456789abc'); - //Test 6 - testCases.push('00000000-0000-0000-0000-000000000000'); - //Test 7 - testCases.push(0x0000); - //Test 8 - testCases.push(0x00000000); - //Test 9 - testCases.push(0x2902); - //Test 10 - testCases.push('00002902-0000-1000-8000-00805f9b34fb'); - //Test 11 - testCases.push(0x12345678); - //Test 12 - testCases.push(0x00002902); - - function onButtonClick(testNumber) { - clear(); - - log('Requesting Bluetooth Device...'); - window.navigator.bluetooth.requestDevice({filters: [{services: ['heart_rate']}]}) - .then(device => { - log('Connecting to GATTserver on device...'); - return device.gatt.connect(); - }) - .then(server => { - log('Getting Primary Service "heart_rate"...'); - return server.getPrimaryService('heart_rate'); - }) - .then(service => { - - log('Getting Characteristic "heart_rate_measurement"...'); - return service.getCharacteristic('heart_rate_measurement'); - }) - .then(characteristic => { - log('Getting Descriptor "' + testCases[testNumber] + '"...'); - return characteristic.getDescriptor(testCases[testNumber]); - }) - .then(descriptor => { - log('Descriptor found!'); - log('> Descriptor characteristic: ' + descriptor.characteristic.uuid); - log('> Descriptor UUID: ' + descriptor.uuid); - return descriptor.readValue(); - }) - .then(value => { - log('> Descriptor value: ' + asciiToDecimal(value)); - }) - .catch(err => { - log(err); - }); - } - - populate(testCases); - </script> -</body> -</html> diff --git a/tests/html/bluetooth/bluetooth_get_descriptors_test_cases.html b/tests/html/bluetooth/bluetooth_get_descriptors_test_cases.html deleted file mode 100644 index 66e624637e2..00000000000 --- a/tests/html/bluetooth/bluetooth_get_descriptors_test_cases.html +++ /dev/null @@ -1,76 +0,0 @@ -<!DOCTYPE html> -<html> -<title>GetDescriptors Test Cases</title> -<body> - <div id="buttons"></div> - <button onclick="onButtonClick2()">Test 12</button> - <pre id="log"></pre> - <script src="bluetooth_functions.js"></script> - <script> - var testCases = []; - //Test 1 - testCases.push('not_a_descriptor_name'); - //Test 2 - testCases.push('gatt.client_characteristic_configuration'); - //Test 3 - testCases.push('1234567891000-1000-8000-00805f9b34fb'); - //Test 4 - testCases.push('11'); - //Test 5 - testCases.push('12345678-1234-1234-1234-123456789abc'); - //Test 6 - testCases.push('00000000-0000-0000-0000-000000000000'); - //Test 7 - testCases.push(0x0000); - //Test 8 - testCases.push(0x00000000); - //Test 9 - testCases.push(0x2902); - //Test 10 - testCases.push(0x12345678); - //Test 11 - testCases.push(0x00002902); - //Test 12 - testCases.push(undefined); - - function onButtonClick(testNumber) { - clear(); - - log('Requesting Bluetooth Device...'); - window.navigator.bluetooth.requestDevice({filters: [{services: ['heart_rate']}]}) - .then(device => { - log('Connecting to GATTserver on device...'); - return device.gatt.connect(); - }) - .then(server => { - log('Getting Primary Service "heart_rate"...'); - return server.getPrimaryService('heart_rate'); - }) - .then(service => { - log('Getting Characteristic "heart_rate_measurement"...'); - return service.getCharacteristic('heart_rate_measurement'); - }) - .then(characteristic => { - log('Getting Descriptors "' + testCases[testNumber] + '"...'); - return characteristic.getDescriptors(testCases[testNumber]); - }) - .then(descriptors => { - for(i = 0; i < descriptors.length; ++i) { - log('> #' + (i+1)); - log('> UUID: ' + descriptors[i].uuid); - - descriptors[i].readValue() - .then(value => { - log('> #' + (i+1)) + 'Descriptor value: ' + asciiToDecimal(value); - }); - } - }) - .catch(err => { - log(err); - }); - } - - populate(testCases); - </script> -</body> -</html> diff --git a/tests/html/bluetooth/bluetooth_get_included_service_test_cases.html b/tests/html/bluetooth/bluetooth_get_included_service_test_cases.html deleted file mode 100644 index a4c467187e0..00000000000 --- a/tests/html/bluetooth/bluetooth_get_included_service_test_cases.html +++ /dev/null @@ -1,71 +0,0 @@ -<!DOCTYPE html> -<html> -<title>GetIncludedService Test Cases</title> -<body> - <div id="buttons"></div> - <pre id="log"></pre> - <script src="bluetooth_functions.js"></script> - <script> - var testCases = []; - //Test 1 - testCases.push({ requestedService: 'battery_service', requestedIncludedService: 'not_a_service_name', options: {filters: [{services: ['battery_service']}]} }); - //Test 2 - testCases.push({ requestedService: 'battery_service', requestedIncludedService: '1234567891000-1000-8000-00805f9b34fb', options: {filters: [{services: ['battery_service']}]} }); - //Test 3 - testCases.push({ requestedService: 'battery_service', requestedIncludedService: '11', options: {filters: [{services: ['battery_service']}]} }); - //Test 4 - testCases.push({ requestedService: 'battery_service', requestedIncludedService: '12345678-1234-1234-1234-123456789abc', options: {filters: [{services: ['battery_service']}]} }); - //Test 5 - testCases.push({ requestedService: 'battery_service', requestedIncludedService: '00000000-0000-0000-0000-000000000000', options: {filters: [{services: ['battery_service']}]} }); - //Test 6 - testCases.push({ requestedService: 'battery_service', requestedIncludedService: 0x0000, options: {filters: [{services: ['battery_service']}]} }); - //Test 7 - testCases.push({ requestedService: 'battery_service', requestedIncludedService: 0x00000000, options: {filters: [{services: ['battery_service']}]} }); - //Test 8 - testCases.push({ requestedService: 'battery_service', requestedIncludedService: 0x12345678, options: {filters: [{services: ['battery_service']}]} }); - //Test 9 - testCases.push({ requestedService: 'battery_service', requestedIncludedService: 0x0000180f, options: {filters: [{services: ['battery_service']}]} }); - //Test 10 - testCases.push({ requestedService: 'battery_service', requestedIncludedService: '00001812-0000-1000-8000-00805f9b34fb', options: {filters: [{services: ['battery_service']}]} }); - //Test 11 - testCases.push({ requestedService: 'battery_service', requestedIncludedService: 'f000ffc0-0451-4000-b000-000000000000', options: {filters: [{services: ['battery_service']}]} }); - //Test 12 - testCases.push({ requestedService: 'battery_service', requestedIncludedService: '00001530-1212-efde-1523-785feabcd123', options: {filters: [{services: ['battery_service']}]} }); - //Test 13 - testCases.push({ requestedService: 'battery_service', requestedIncludedService: 0x00001812, options: {filters: [{services: ['battery_service']}]} }); - //Test 14 - testCases.push({ requestedService: 'battery_service', requestedIncludedService: 0xf000ffc0, options: {filters: [{services: ['battery_service']}]} }); - //Test 15 - testCases.push({ requestedService: 'battery_service', requestedIncludedService: 0x00001530, options: {filters: [{services: ['battery_service']}]} }); - - function onButtonClick(testNumber) { - clear(); - - log('Requesting Bluetooth Device...'); - window.navigator.bluetooth.requestDevice(testCases[testNumber].options) - .then(device => { - log('Connecting to GATTserver on device...'); - return device.gatt.connect(); - }) - .then(server => { - log('Getting Primary Service "' + testCases[testNumber].requestedService + '"...'); - return server.getPrimaryService(testCases[testNumber].requestedService); - }) - .then(service => { - log('Getting Included Service "' + testCases[testNumber].requestedIncludedService + '"...') - return service.getIncludedService(testCases[testNumber].requestedIncludedService); - }) - .then(includedService => { - log('Primary Service found on device: ' + includedService.device.name); - log('> UUID: ' + includedService.uuid); - log('> Is primary: ' + includedService.isPrimary); - }) - .catch(err => { - log(err); - }); - } - - populate(testCases); - </script> -</body> -</html> diff --git a/tests/html/bluetooth/bluetooth_get_included_services_test_cases.html b/tests/html/bluetooth/bluetooth_get_included_services_test_cases.html deleted file mode 100644 index 319cea24715..00000000000 --- a/tests/html/bluetooth/bluetooth_get_included_services_test_cases.html +++ /dev/null @@ -1,73 +0,0 @@ -<!DOCTYPE html> -<html> -<title>GetIncludedServices Test Cases</title> -<body> - <div id="buttons"></div> - <pre id="log"></pre> - <script src="bluetooth_functions.js"></script> - <script> - var testCases = []; - //Test 1 - testCases.push({ requestedService: 'battery_service', requestedIncludedService: 'not_a_service_name', options: {filters: [{services: ['battery_service']}]} }); - //Test 2 - testCases.push({ requestedService: 'battery_service', requestedIncludedService: '1234567891000-1000-8000-00805f9b34fb', options: {filters: [{services: ['battery_service']}]} }); - //Test 3 - testCases.push({ requestedService: 'battery_service', requestedIncludedService: '11', options: {filters: [{services: ['battery_service']}]} }); - //Test 4 - testCases.push({ requestedService: 'battery_service', requestedIncludedService: '12345678-1234-1234-1234-123456789abc', options: {filters: [{services: ['battery_service']}]} }); - //Test 5 - testCases.push({ requestedService: 'battery_service', requestedIncludedService: '00000000-0000-0000-0000-000000000000', options: {filters: [{services: ['battery_service']}]} }); - //Test 6 - testCases.push({ requestedService: 'battery_service', requestedIncludedService: 0x0000, options: {filters: [{services: ['battery_service']}]} }); - //Test 7 - testCases.push({ requestedService: 'battery_service', requestedIncludedService: 0x00000000, options: {filters: [{services: ['battery_service']}]} }); - //Test 8 - testCases.push({ requestedService: 'battery_service', requestedIncludedService: 0x12345678, options: {filters: [{services: ['battery_service']}]} }); - //Test 9 - testCases.push({ requestedService: 'battery_service', requestedIncludedService: 0x0000180f, options: {filters: [{services: ['battery_service']}]} }); - //Test 10 - testCases.push({ requestedService: 'battery_service', requestedIncludedService: '00001812-0000-1000-8000-00805f9b34fb', options: {filters: [{services: ['battery_service']}]} }); - //Test 11 - testCases.push({ requestedService: 'battery_service', requestedIncludedService: 'f000ffc0-0451-4000-b000-000000000000', options: {filters: [{services: ['battery_service']}]} }); - //Test 12 - testCases.push({ requestedService: 'battery_service', requestedIncludedService: '00001530-1212-efde-1523-785feabcd123', options: {filters: [{services: ['battery_service']}]} }); - //Test 13 - testCases.push({ requestedService: 'battery_service', requestedIncludedService: 0x00001812, options: {filters: [{services: ['battery_service']}]} }); - //Test 14 - testCases.push({ requestedService: 'battery_service', requestedIncludedService: 0xf000ffc0, options: {filters: [{services: ['battery_service']}]} }); - //Test 15 - testCases.push({ requestedService: 'battery_service', requestedIncludedService: 0x00001530, options: {filters: [{services: ['battery_service']}]} }); - - function onButtonClick(testNumber) { - clear(); - - log('Requesting Bluetooth Device...'); - window.navigator.bluetooth.requestDevice(testCases[testNumber].options) - .then(device => { - log('Connecting to GATTserver on device...'); - return device.gatt.connect(); - }) - .then(server => { - log('Getting Primary Service "' + testCases[testNumber].requestedService + '"...'); - return server.getPrimaryService(testCases[testNumber].requestedService); - }) - .then(service => { - log('Getting Included Service "' + testCases[testNumber].requestedIncludedService + '"...') - return service.getIncludedServices(testCases[testNumber].requestedIncludedService); - }) - .then(includedServices => { - for(i = 0; i < includedServices.length; ++i) { - log('> #' + (i+1)); - log('> UUID: ' + includedServices[i].uuid); - log('> Is primary: ' + includedServices[i].isPrimary); - } - }) - .catch(err => { - log(err); - }); - } - - populate(testCases); - </script> -</body> -</html> diff --git a/tests/html/bluetooth/bluetooth_get_primary_service_test_cases.html b/tests/html/bluetooth/bluetooth_get_primary_service_test_cases.html deleted file mode 100644 index f38da38da3b..00000000000 --- a/tests/html/bluetooth/bluetooth_get_primary_service_test_cases.html +++ /dev/null @@ -1,77 +0,0 @@ -<!DOCTYPE html> -<html> -<title>GetPrimaryService Test Cases</title> -<body> - <div id="buttons"></div> - <pre id="log"></pre> - <script src="bluetooth_functions.js"></script> - <script> - var testCases = []; - //Test 1 - testCases.push({ requestedService: 'heart_rate', options: {filters: [{services: ['battery_service']}]} }); - //Test 2 - testCases.push({ requestedService: 'heart_rate', options: {filters: [{services: ['battery_service', 'heart_rate']}]} }); - //Test 3 - testCases.push({ requestedService: 'not_a_service_name', options: {filters: [{services: ['battery_service']}]} }); - //Test 4 - testCases.push({ requestedService: 'battery_service', options: {filters: [{services: ['battery_service']}]} }); - //Test 5 - testCases.push({ requestedService: '1234567891000-1000-8000-00805f9b34fb', options: {filters: [{services: ['battery_service']}]} }); - //Test 6 - testCases.push({ requestedService: '11', options: {filters: [{services: ['battery_service']}]} }); - //Test 7 - testCases.push({ requestedService: '12345678-1234-1234-1234-123456789abc', options: {filters: [{services: ['battery_service']}]} }); - //Test 8 - testCases.push({ requestedService: 0x0000, options: {filters: [{services: ['battery_service']}]} }); - //Test 9 - testCases.push({ requestedService: 0x00000000, options: {filters: [{services: ['battery_service']}]} }); - //Test 10 - testCases.push({ requestedService: 0x180f, options: {filters: [{services: ['battery_service']}]} }); - //Test 11 - testCases.push({ requestedService: 0x12345678, options: {filters: [{services: ['battery_service']}]} }); - //Test 12 - testCases.push({ requestedService: 0x0000180f, options: {filters: [{services: ['battery_service']}]} }); - //Test 13 - testCases.push({ requestedService: 0x00001812, options: {filters: [{services: ['battery_service']}]} }); - //Test 14 - testCases.push({ requestedService: 'f000ffc0-0451-4000-b000-000000000000', options: {filters: [{services: ['battery_service']}]} }); - //Test 15 - testCases.push({ requestedService: '00001530-1212-efde-1523-785feabcd123', options: {filters: [{services: ['battery_service']}]} }); - //Test 16 - testCases.push({ requestedService: 0xf000ffc0, options: {filters: [{services: ['battery_service']}], optionalServices: [0xf000ffc0]} }); - //Test 17 - testCases.push({ requestedService: 0x00001530, options: {filters: [{services: ['battery_service']}], optionalServices: [0x00001530]} }); - //Test 18 - testCases.push({ requestedService: '0000180f-0000-1000-8000-00805f9b34fb', options: {filters: [{services: ['battery_service']}]} }); - //Test 19 - testCases.push({ requestedService: 'cycling_power', options: {filters: [{services: ['battery_service']}], optionalServices: ['cycling_power']} }); - //Test 20 - testCases.push({ requestedService: '00001818-0000-1000-8000-00805f9b34fb', options: {filters: [{services: ['battery_service']}], optionalServices: ['cycling_power']} }); - - function onButtonClick(testNumber) { - clear(); - - log('Requesting Bluetooth Device...'); - window.navigator.bluetooth.requestDevice(testCases[testNumber].options) - .then(device => { - log('Connecting to GATTserver on device...'); - return device.gatt.connect(); - }) - .then(server => { - log('Getting Primary Service "' + testCases[testNumber].requestedService + '"...'); - return server.getPrimaryService(testCases[testNumber].requestedService); - }) - .then(service => { - log('Primary Service found on device: ' + service.device.name); - log('> UUID: ' + service.uuid); - log('> Is primary: ' + service.isPrimary); - }) - .catch(err => { - log(err); - }); - } - - populate(testCases); - </script> -</body> -</html> diff --git a/tests/html/bluetooth/bluetooth_get_primary_services_test_cases.html b/tests/html/bluetooth/bluetooth_get_primary_services_test_cases.html deleted file mode 100644 index 9c72a074f05..00000000000 --- a/tests/html/bluetooth/bluetooth_get_primary_services_test_cases.html +++ /dev/null @@ -1,79 +0,0 @@ -<!DOCTYPE html> -<html> -<title>GetPrimaryServices Test Cases</title> -<body> - <div id="buttons"></div> - <pre id="log"></pre> - <script src="bluetooth_functions.js"></script> - <script> - var testCases = []; - //Test 1 - testCases.push({ requestedService: 'heart_rate', options: {filters: [{services: ['battery_service']}]} }); - //Test 2 - testCases.push({ requestedService: 'not_a_service_name', options: {filters: [{services: ['battery_service']}]} }); - //Test 3 - testCases.push({ requestedService: 'battery_service', options: {filters: [{services: ['battery_service']}]} }); - //Test 4 - testCases.push({ requestedService: '1234567891000-1000-8000-00805f9b34fb', options: {filters: [{services: ['battery_service']}]} }); - //Test 5 - testCases.push({ requestedService: '11', options: {filters: [{services: ['battery_service']}]} }); - //Test 6 - testCases.push({ requestedService: '12345678-1234-1234-1234-123456789abc', options: {filters: [{services: ['battery_service']}]} }); - //Test 7 - testCases.push({ requestedService: '00000000-0000-0000-0000-000000000000', options: {filters: [{services: ['battery_service']}]} }); - //Test 8 - testCases.push({ requestedService: 0x0000, options: {filters: [{services: ['battery_service']}]} }); - //Test 9 - testCases.push({ requestedService: 0x00000000, options: {filters: [{services: ['battery_service']}]} }); - //Test 10 - testCases.push({ requestedService: 0x180f, options: {filters: [{services: ['battery_service']}]} }); - //Test 11 - testCases.push({ requestedService: 0x12345678, options: {filters: [{services: ['battery_service']}]} }); - //Test 12 - testCases.push({ requestedService: 0x0000180f, options: {filters: [{services: ['battery_service']}]} }); - //Test 13 - testCases.push({ requestedService: 0x00001812, options: {filters: [{services: ['battery_service']}]} }); - //Test 14 - testCases.push({ requestedService: 'f000ffc0-0451-4000-b000-000000000000', options: {filters: [{services: ['battery_service']}]} }); - //Test 15 - testCases.push({ requestedService: '00001530-1212-efde-1523-785feabcd123', options: {filters: [{services: ['battery_service']}]} }); - //Test 16 - testCases.push({ requestedService: 0xf000ffc0, options: {filters: [{services: ['battery_service']}], optionalServices: [0xf000ffc0]} }); - //Test 17 - testCases.push({ requestedService: 0x00001530, options: {filters: [{services: ['battery_service']}], optionalServices: [0x00001530]} }); - //Test 18 - testCases.push({ requestedService: '0000180f-0000-1000-8000-00805f9b34fb', options: {filters: [{services: ['battery_service']}]} }); - //Test 19 - testCases.push({ requestedService: 'cycling_power', options: {filters: [{services: ['battery_service']}], optionalServices: ['cycling_power']} }); - //Test 20 - testCases.push({ requestedService: '00001818-0000-1000-8000-00805f9b34fb', options: {filters: [{services: ['battery_service']}], optionalServices: ['cycling_power']} }); - - function onButtonClick(testNumber) { - clear(); - - log('Requesting Bluetooth Device...'); - window.navigator.bluetooth.requestDevice(testCases[testNumber].options) - .then(device => { - log('Connecting to GATTserver on device...'); - return device.gatt.connect(); - }) - .then(server => { - log('Getting Primary Service "' + testCases[testNumber].requestedService + '"...'); - return server.getPrimaryServices(testCases[testNumber].requestedService); - }) - .then(services => { - for(i = 0; i < services.length; ++i) { - log('> #' + (i+1)); - log('> UUID: ' + services[i].uuid); - log('> Is primary: ' + services[i].isPrimary); - } - }) - .catch(err => { - log(err); - }); - } - - populate(testCases); - </script> -</body> -</html> diff --git a/tests/html/bluetooth/bluetooth_included_service_info.html b/tests/html/bluetooth/bluetooth_included_service_info.html deleted file mode 100644 index 6caff21ae52..00000000000 --- a/tests/html/bluetooth/bluetooth_included_service_info.html +++ /dev/null @@ -1,58 +0,0 @@ -<!DOCTYPE html> -<html> -<title>Included Service info</title> -<body> - <input id="service" type="text" autofocus placeholder="Bluetooth Service"> - <input id="name" type="text" placeholder="Device Name"> - <input id="namePrefix" type="text" placeholder="Device Name Prefix"> - <button type="button" onclick="onButtonClick()">Get Primary Service Info</button> - <pre id="log"></pre> - <script src="bluetooth_functions.js"></script> - <script> - function onButtonClick() { - clear(); - var options = {filters: [], optionalServices: []}; - - var filterService = document.getElementById('service').value; - if (filterService) { - if (filterService.startsWith('0x')) - filterService = parseInt(filterService, 16); - options.filters.push({services: [filterService]}); - } - - var filterName = document.getElementById('name').value; - if (filterName) - options.filters.push({name: filterName}); - - var filterNamePrefix = document.getElementById('namePrefix').value; - if (filterNamePrefix) - options.filters.push({namePrefix: filterNamePrefix}); - - log('Requesting Bluetooth Device...'); - window.navigator.bluetooth.requestDevice(options) - .then(device => { - log('Connecting to GATTserver on device...'); - return device.gatt.connect(); - }) - .then(server => { - log('Getting Primary Service...'); - return server.getPrimaryService(filterService); - }) - .then(service => { - log('Primary Service found on device: ' + service.device.name); - log('> UUID: ' + service.uuid); - - log('Getting Included Services...'); - return service.getIncludedServices(); - }) - .then(includedServices => { - log('> Included Services: ' + - includedServices.map(s => s.uuid).join('\n' + ' '.repeat(21))); - }) - .catch(err => { - log(err); - }); - } - </script> -</body> -</html> diff --git a/tests/html/bluetooth/bluetooth_primary_service_info.html b/tests/html/bluetooth/bluetooth_primary_service_info.html deleted file mode 100644 index 21ea6ff1e16..00000000000 --- a/tests/html/bluetooth/bluetooth_primary_service_info.html +++ /dev/null @@ -1,52 +0,0 @@ -<!DOCTYPE html> -<html> -<title>Primary Service info</title> -<body> - <input id="service" type="text" autofocus placeholder="Bluetooth Service"> - <input id="name" type="text" placeholder="Device Name"> - <input id="namePrefix" type="text" placeholder="Device Name Prefix"> - <button type="button" onclick="onButtonClick()">Get Primary Service Info</button> - <pre id="log"></pre> - <script src="bluetooth_functions.js"></script> - <script> - function onButtonClick() { - clear(); - var options = {filters: [], optionalServices: []}; - - var filterService = document.getElementById('service').value; - if (filterService) { - if (filterService.startsWith('0x')) - filterService = parseInt(filterService, 16); - options.filters.push({services: [filterService]}); - } - - var filterName = document.getElementById('name').value; - if (filterName) - options.filters.push({name: filterName}); - - var filterNamePrefix = document.getElementById('namePrefix').value; - if (filterNamePrefix) - options.filters.push({namePrefix: filterNamePrefix}); - - log('Requesting Bluetooth Device...'); - window.navigator.bluetooth.requestDevice(options) - .then(device => { - log('Connecting to GATTserver on device...'); - return device.gatt.connect(); - }) - .then(server => { - log('Getting Primary Service...'); - return server.getPrimaryService(filterService); - }) - .then(service => { - log('Primary Service found on device: ' + service.device.name); - log('> UUID: ' + service.uuid); - log('> Is primary: ' + service.isPrimary); - }) - .catch(err => { - log(err); - }); - } - </script> -</body> -</html> diff --git a/tests/html/bluetooth/bluetooth_primary_services_info.html b/tests/html/bluetooth/bluetooth_primary_services_info.html deleted file mode 100644 index 67f22e0ef7e..00000000000 --- a/tests/html/bluetooth/bluetooth_primary_services_info.html +++ /dev/null @@ -1,58 +0,0 @@ -<!DOCTYPE html> -<html> -<title>Primary Services info</title> -<body> - <input id="service" type="text" autofocus placeholder="Bluetooth Service"> - <input id="name" type="text" placeholder="Device Name"> - <input id="namePrefix" type="text" placeholder="Device Name Prefix"> - <button type="button" onclick="onButtonClick()">Get Primary Services Info</button> - <pre id="log"></pre> - <script src="bluetooth_functions.js"></script> - <script> - function onButtonClick() { - clear(); - var options = {filters: [], optionalServices: []}; - - var filterService = document.getElementById('service').value; - if (filterService) { - if (filterService.startsWith('0x')) - filterService = parseInt(filterService, 16); - options.filters.push({services: [filterService]}); - } - - var filterName = document.getElementById('name').value; - if (filterName) - options.filters.push({name: filterName}); - - var filterNamePrefix = document.getElementById('namePrefix').value; - if (filterNamePrefix) - options.filters.push({namePrefix: filterNamePrefix}); - - log('Requesting Bluetooth Device...'); - window.navigator.bluetooth.requestDevice(options) - .then(device => { - log('Connecting to GATTserver on device...'); - return device.gatt.connect(); - }) - .then(server => { - log('Getting Primary Service...'); - if (filterService) - return server.getPrimaryServices(filterService); - else - return server.getPrimaryServices(); - }) - .then(services => { - log('> List of Services on the current device:'); - for(i = 0; i < services.length; ++i) { - log('> #' + (i+1)); - log('> UUID: ' + services[i].uuid); - log('> Is primary: ' + services[i].isPrimary); - } - }) - .catch(err => { - log(err); - }); - } - </script> -</body> -</html> diff --git a/tests/html/bluetooth/bluetooth_request_all_devices.html b/tests/html/bluetooth/bluetooth_request_all_devices.html deleted file mode 100644 index 8bf80ab3d28..00000000000 --- a/tests/html/bluetooth/bluetooth_request_all_devices.html +++ /dev/null @@ -1,28 +0,0 @@ -<!DOCTYPE html> -<html> -<title>Request All Devices</title> -<body> - <button type="button" onclick="onButtonClick()">Request All Devices</button> - <pre id="log"></pre> - <script src="bluetooth_functions.js"></script> - <script> - function onButtonClick() { - clear(); - var options = {optionalServices: ['generic_access'], acceptAllDevices:true}; - try { - log('Requesting Bluetooth Device...'); - var bluetooth = window.navigator.bluetooth; - var device = bluetooth.requestDevice(options); - - log('Connecting to GATT Server on device...'); - var server = device.gatt.connect(); - - log('Getting Generic Access Service...'); - var service = server.getPrimaryService('generic_access'); - } catch(err) { - log(err); - } - } - </script> -</body> -</html> diff --git a/tests/html/bluetooth/bluetooth_request_device_test_cases.html b/tests/html/bluetooth/bluetooth_request_device_test_cases.html deleted file mode 100644 index 93d20bec3c9..00000000000 --- a/tests/html/bluetooth/bluetooth_request_device_test_cases.html +++ /dev/null @@ -1,74 +0,0 @@ -<!DOCTYPE html> -<html> -<title>RequestDevice Test Cases</title> -<body> - <div id="buttons"></div> - <pre id="log"></pre> - <script src="bluetooth_functions.js"></script> - <script> - var testCases = []; - //Test 1 - testCases.push({filters: []}); - //Test 2 - testCases.push({filters: [{notExpectedMember: []}]}); - //Test 3 - testCases.push({filters: [{services: ['battery_service']}]}); - //Test 4 - testCases.push({filters: [{name: 'raspberrypi'}]}); - //Test 5 - testCases.push({filters: [{namePrefix: 'rasp'}]}); - //Test 6 - testCases.push({filters:[{services: []}]}); - //Test 7 - testCases.push({filters:[{services: [], namePrefix:'rasp'}]}); - //Test 8 - testCases.push({filters: [{services: ['not_a_service_name']}]}); - //Test 9 - testCases.push({filters: [{services: ['1234567891000-1000-8000-00805f9b34fb']}]}); - //Test 10 - testCases.push({filters: [{services: ['12345678-1234-1234-1234-123456789abc']}]}); - //Test 11 - testCases.push({filters: [{services: [0x0000]}]}); - //Test 12 - testCases.push({filters: [{services: [0x180f]}]}); - //Test 13 - testCases.push({filters: [{services: [0x12345678]}]}); - //Test 14 - testCases.push({filters: [{services: [0x00001812]}]}); - //Test 15 - testCases.push({filters: [{services: ['f000ffc0-0451-4000-b000-000000000000']}]}); - //Test 16 - testCases.push({filters: [{name: 'this_device_name_is_longer_than_29_bytes'}]}); - //Test 17 - testCases.push({filters: [{namePrefix: 'this_device_name_prefix_is_longer_than_29_bytes'}]}); - //Test 18 - testCases.push({filters: [{namePrefix: ''}]}); - //Test 19 - testCases.push({filters: [{namePrefix: 'rasp'}], optionalServices: ['1234567891000-1000-8000-00805f9b34fb']}); - //Test 20 - testCases.push({filters: [{namePrefix: 'rasp'}], optionalServices: ['12345678-1234-1234-1234-123456789abc']}); - //Test 21 - testCases.push({filters: [{namePrefix: 'rasp'}], optionalServices: ['f000ffc0-0451-4000-b000-000000000000', 0x1812]}); - - function onButtonClick(testNumber) { - clear(); - - log('Requesting Bluetooth Device...'); - window.navigator.bluetooth.requestDevice(testCases[testNumber]) - .then(device => { - log('Found a device!'); - log('> Name: ' + device.name); - log('> Id: ' + device.id); - log('> Appearance: ' + device.adData.appearance); - log('> Tx Power: ' + device.adData.txPower + ' dBm'); - log('> RSSI: ' + device.adData.rssi + ' dBm'); - }) - .catch(err => { - log(err); - }); - } - - populate(testCases); - </script> -</body> -</html> diff --git a/tests/unit/net/Cargo.toml b/tests/unit/net/Cargo.toml index aa462c0c156..ea7916b89ef 100644 --- a/tests/unit/net/Cargo.toml +++ b/tests/unit/net/Cargo.toml @@ -22,8 +22,8 @@ net = {path = "../../../components/net"} net_traits = {path = "../../../components/net_traits"} plugins = {path = "../../../components/plugins"} profile_traits = {path = "../../../components/profile_traits"} +servo_config = {path = "../../../components/config"} time = "0.1" unicase = "1.0" url = {version = "1.2", features = ["heap_size"]} servo_url = {path = "../../../components/url"} -util = {path = "../../../components/util"} diff --git a/tests/unit/net/cookie.rs b/tests/unit/net/cookie.rs index aa6519571b8..fbeebab2c5f 100644 --- a/tests/unit/net/cookie.rs +++ b/tests/unit/net/cookie.rs @@ -133,6 +133,119 @@ fn test_sort_order() { assert!(CookieStorage::cookie_comparator(&a, &a) == Ordering::Equal); } +fn add_cookie_to_storage(storage: &mut CookieStorage, url: &ServoUrl, cookie_str: &str) +{ + let source = CookieSource::HTTP; + let cookie = Cookie::new_wrapped(cookie_rs::Cookie::parse(cookie_str).unwrap(), url, source).unwrap(); + storage.push(cookie, url, source); +} + +#[test] +fn test_insecure_cookies_cannot_evict_secure_cookie() { + let mut storage = CookieStorage::new(5); + let secure_url = ServoUrl::parse("https://home.example.org:8888/cookie-parser?0001").unwrap(); + let source = CookieSource::HTTP; + let mut cookies = Vec::new(); + + cookies.push(cookie_rs::Cookie::parse("foo=bar; Secure; Domain=home.example.org").unwrap()); + cookies.push(cookie_rs::Cookie::parse("foo2=bar; Secure; Domain=.example.org").unwrap()); + cookies.push(cookie_rs::Cookie::parse("foo3=bar; Secure; Path=/foo").unwrap()); + cookies.push(cookie_rs::Cookie::parse("foo4=bar; Secure; Path=/foo/bar").unwrap()); + + for bare_cookie in cookies { + let cookie = Cookie::new_wrapped(bare_cookie, &secure_url, source).unwrap(); + storage.push(cookie, &secure_url, source); + } + + let insecure_url = ServoUrl::parse("http://home.example.org:8888/cookie-parser?0001").unwrap(); + + add_cookie_to_storage(&mut storage, &insecure_url, "foo=value; Domain=home.example.org"); + add_cookie_to_storage(&mut storage, &insecure_url, "foo2=value; Domain=.example.org"); + add_cookie_to_storage(&mut storage, &insecure_url, "foo3=value; Path=/foo/bar"); + add_cookie_to_storage(&mut storage, &insecure_url, "foo4=value; Path=/foo"); + + let source = CookieSource::HTTP; + assert_eq!(storage.cookies_for_url(&secure_url, source).unwrap(), "foo=bar; foo2=bar"); + + let url = ServoUrl::parse("https://home.example.org:8888/foo/cookie-parser-result?0001").unwrap(); + let source = CookieSource::HTTP; + assert_eq!(storage.cookies_for_url(&url, source).unwrap(), "foo3=bar; foo4=value; foo=bar; foo2=bar"); + + let url = ServoUrl::parse("https://home.example.org:8888/foo/bar/cookie-parser-result?0001").unwrap(); + let source = CookieSource::HTTP; + assert_eq!(storage.cookies_for_url(&url, source).unwrap(), "foo4=bar; foo3=bar; foo4=value; foo=bar; foo2=bar"); +} + +#[test] +fn test_secure_cookies_eviction() { + let mut storage = CookieStorage::new(5); + let url = ServoUrl::parse("https://home.example.org:8888/cookie-parser?0001").unwrap(); + let source = CookieSource::HTTP; + let mut cookies = Vec::new(); + + cookies.push(cookie_rs::Cookie::parse("foo=bar; Secure; Domain=home.example.org").unwrap()); + cookies.push(cookie_rs::Cookie::parse("foo2=bar; Secure; Domain=.example.org").unwrap()); + cookies.push(cookie_rs::Cookie::parse("foo3=bar; Secure; Path=/foo").unwrap()); + cookies.push(cookie_rs::Cookie::parse("foo4=bar; Secure; Path=/foo/bar").unwrap()); + + for bare_cookie in cookies { + let cookie = Cookie::new_wrapped(bare_cookie, &url, source).unwrap(); + storage.push(cookie, &url, source); + } + + add_cookie_to_storage(&mut storage, &url, "foo=value; Domain=home.example.org"); + add_cookie_to_storage(&mut storage, &url, "foo2=value; Domain=.example.org"); + add_cookie_to_storage(&mut storage, &url, "foo3=value; Path=/foo/bar"); + add_cookie_to_storage(&mut storage, &url, "foo4=value; Path=/foo"); + + let source = CookieSource::HTTP; + assert_eq!(storage.cookies_for_url(&url, source).unwrap(), "foo2=value"); + + let url = ServoUrl::parse("https://home.example.org:8888/foo/cookie-parser-result?0001").unwrap(); + let source = CookieSource::HTTP; + assert_eq!(storage.cookies_for_url(&url, source).unwrap(), "foo3=bar; foo4=value; foo2=value"); + + let url = ServoUrl::parse("https://home.example.org:8888/foo/bar/cookie-parser-result?0001").unwrap(); + let source = CookieSource::HTTP; + assert_eq!(storage.cookies_for_url(&url, source).unwrap(), + "foo4=bar; foo3=value; foo3=bar; foo4=value; foo2=value"); +} + +#[test] +fn test_secure_cookies_eviction_non_http_source() { + let mut storage = CookieStorage::new(5); + let url = ServoUrl::parse("https://home.example.org:8888/cookie-parser?0001").unwrap(); + let source = CookieSource::NonHTTP; + let mut cookies = Vec::new(); + + cookies.push(cookie_rs::Cookie::parse("foo=bar; Secure; Domain=home.example.org").unwrap()); + cookies.push(cookie_rs::Cookie::parse("foo2=bar; Secure; Domain=.example.org").unwrap()); + cookies.push(cookie_rs::Cookie::parse("foo3=bar; Secure; Path=/foo").unwrap()); + cookies.push(cookie_rs::Cookie::parse("foo4=bar; Secure; Path=/foo/bar").unwrap()); + + for bare_cookie in cookies { + let cookie = Cookie::new_wrapped(bare_cookie, &url, source).unwrap(); + storage.push(cookie, &url, source); + } + + add_cookie_to_storage(&mut storage, &url, "foo=value; Domain=home.example.org"); + add_cookie_to_storage(&mut storage, &url, "foo2=value; Domain=.example.org"); + add_cookie_to_storage(&mut storage, &url, "foo3=value; Path=/foo/bar"); + add_cookie_to_storage(&mut storage, &url, "foo4=value; Path=/foo"); + + let source = CookieSource::HTTP; + assert_eq!(storage.cookies_for_url(&url, source).unwrap(), "foo2=value"); + + let url = ServoUrl::parse("https://home.example.org:8888/foo/cookie-parser-result?0001").unwrap(); + let source = CookieSource::HTTP; + assert_eq!(storage.cookies_for_url(&url, source).unwrap(), "foo3=bar; foo4=value; foo2=value"); + + let url = ServoUrl::parse("https://home.example.org:8888/foo/bar/cookie-parser-result?0001").unwrap(); + let source = CookieSource::HTTP; + assert_eq!(storage.cookies_for_url(&url, source).unwrap(), + "foo4=bar; foo3=value; foo3=bar; foo4=value; foo2=value"); +} + fn add_retrieve_cookies(set_location: &str, set_cookies: &[String], @@ -149,7 +262,7 @@ fn add_retrieve_cookies(set_location: &str, let SetCookie(cookies) = header; for bare_cookie in cookies { let cookie = Cookie::new_wrapped(bare_cookie, &url, source).unwrap(); - storage.push(cookie, source); + storage.push(cookie, &url, source); } } diff --git a/tests/unit/net/cookie_http_state.rs b/tests/unit/net/cookie_http_state.rs index 819aaabb5f2..7d5df8b658c 100644 --- a/tests/unit/net/cookie_http_state.rs +++ b/tests/unit/net/cookie_http_state.rs @@ -21,7 +21,7 @@ fn run(set_location: &str, set_cookies: &[&str], final_location: &str) -> String if let Ok(SetCookie(cookies)) = header { for bare_cookie in cookies { if let Some(cookie) = Cookie::new_wrapped(bare_cookie, &url, source) { - storage.push(cookie, source); + storage.push(cookie, &url, source); } } } diff --git a/tests/unit/net/data_loader.rs b/tests/unit/net/data_loader.rs index 93c625f30d9..8cd9ddbb953 100644 --- a/tests/unit/net/data_loader.rs +++ b/tests/unit/net/data_loader.rs @@ -2,7 +2,7 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -use fetch_sync; +use fetch; use hyper::header::ContentType; use hyper::mime::{Attr, Mime, SubLevel, TopLevel, Value}; use hyper_serde::Serde; @@ -21,7 +21,7 @@ fn assert_parse(url: &'static str, let origin = Origin::Origin(url.origin()); let request = Request::new(url, Some(origin), false, None); - let response = fetch_sync(request, None); + let response = fetch(request, None); match data { Some(data) => { diff --git a/tests/unit/net/fetch.rs b/tests/unit/net/fetch.rs index bc8ab6439d0..c88c8b1bf59 100644 --- a/tests/unit/net/fetch.rs +++ b/tests/unit/net/fetch.rs @@ -2,10 +2,12 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -use {DEFAULT_USER_AGENT, FetchResponseCollector, new_fetch_context, fetch_async, fetch_sync, make_server}; +use {DEFAULT_USER_AGENT, new_fetch_context, fetch, make_server}; use devtools_traits::DevtoolsControlMsg; use devtools_traits::HttpRequest as DevtoolsHttpRequest; use devtools_traits::HttpResponse as DevtoolsHttpResponse; +use fetch_with_context; +use fetch_with_cors_cache; use http_loader::{expect_devtools_http_request, expect_devtools_http_response}; use hyper::LanguageTag; use hyper::header::{Accept, AccessControlAllowCredentials, AccessControlAllowHeaders, AccessControlAllowOrigin}; @@ -21,10 +23,11 @@ use hyper::status::StatusCode; use hyper::uri::RequestUri; use msg::constellation_msg::TEST_PIPELINE_ID; use net::fetch::cors_cache::CorsCache; -use net::fetch::methods::{fetch, fetch_with_cors_cache}; +use net_traits::NetworkError; use net_traits::ReferrerPolicy; use net_traits::request::{Origin, RedirectMode, Referrer, Request, RequestMode}; use net_traits::response::{CacheState, Response, ResponseBody, ResponseType}; +use servo_config::resource_files::resources_dir_path; use servo_url::ServoUrl; use std::fs::File; use std::io::Read; @@ -35,7 +38,6 @@ use std::sync::mpsc::{Sender, channel}; use time::{self, Duration}; use unicase::UniCase; use url::Origin as UrlOrigin; -use util::resource_files::resources_dir_path; // TODO write a struct that impls Handler for storing test values @@ -50,7 +52,7 @@ fn test_fetch_response_is_not_network_error() { let origin = Origin::Origin(url.origin()); let request = Request::new(url, Some(origin), false, None); *request.referrer.borrow_mut() = Referrer::NoReferrer; - let fetch_response = fetch_sync(request, None); + let fetch_response = fetch(request, None); let _ = server.close(); if fetch_response.is_network_error() { @@ -59,6 +61,18 @@ fn test_fetch_response_is_not_network_error() { } #[test] +fn test_fetch_on_bad_port_is_network_error() { + let url = ServoUrl::parse("http://www.example.org:6667").unwrap(); + let origin = Origin::Origin(url.origin()); + let request = Request::new(url, Some(origin), false, None); + *request.referrer.borrow_mut() = Referrer::NoReferrer; + let fetch_response = fetch(request, None); + assert!(fetch_response.is_network_error()); + let fetch_error = fetch_response.get_network_error().unwrap(); + assert!(fetch_error == &NetworkError::Internal("Request attempted on bad port".into())) +} + +#[test] fn test_fetch_response_body_matches_const_message() { static MESSAGE: &'static [u8] = b"Hello World!"; let handler = move |_: HyperRequest, response: HyperResponse| { @@ -69,7 +83,7 @@ fn test_fetch_response_body_matches_const_message() { let origin = Origin::Origin(url.origin()); let request = Request::new(url, Some(origin), false, None); *request.referrer.borrow_mut() = Referrer::NoReferrer; - let fetch_response = fetch_sync(request, None); + let fetch_response = fetch(request, None); let _ = server.close(); assert!(!fetch_response.is_network_error()); @@ -89,7 +103,7 @@ fn test_fetch_aboutblank() { let origin = Origin::Origin(url.origin()); let request = Request::new(url, Some(origin), false, None); *request.referrer.borrow_mut() = Referrer::NoReferrer; - let fetch_response = fetch_sync(request, None); + let fetch_response = fetch(request, None); assert!(!fetch_response.is_network_error()); assert!(*fetch_response.body.lock().unwrap() == ResponseBody::Done(vec![])); } @@ -118,7 +132,7 @@ fn test_fetch_blob() { let request = Request::new(url, Some(Origin::Origin(origin.origin())), false, None); - let fetch_response = fetch(Rc::new(request), &mut None, &context); + let fetch_response = fetch_with_context(request, &context); assert!(!fetch_response.is_network_error()); @@ -143,7 +157,7 @@ fn test_fetch_file() { let origin = Origin::Origin(url.origin()); let request = Request::new(url, Some(origin), false, None); - let fetch_response = fetch_sync(request, None); + let fetch_response = fetch(request, None); assert!(!fetch_response.is_network_error()); assert_eq!(fetch_response.headers.len(), 1); let content_type: &ContentType = fetch_response.headers.get().unwrap(); @@ -168,7 +182,7 @@ fn test_fetch_ftp() { let origin = Origin::Origin(url.origin()); let request = Request::new(url, Some(origin), false, None); *request.referrer.borrow_mut() = Referrer::NoReferrer; - let fetch_response = fetch_sync(request, None); + let fetch_response = fetch(request, None); assert!(fetch_response.is_network_error()); } @@ -178,7 +192,7 @@ fn test_fetch_bogus_scheme() { let origin = Origin::Origin(url.origin()); let request = Request::new(url, Some(origin), false, None); *request.referrer.borrow_mut() = Referrer::NoReferrer; - let fetch_response = fetch_sync(request, None); + let fetch_response = fetch(request, None); assert!(fetch_response.is_network_error()); } @@ -209,7 +223,7 @@ fn test_cors_preflight_fetch() { *request.referrer_policy.get_mut() = Some(ReferrerPolicy::Origin); request.use_cors_preflight = true; request.mode = RequestMode::CorsMode; - let fetch_response = fetch_sync(request, None); + let fetch_response = fetch(request, None); let _ = server.close(); assert!(!fetch_response.is_network_error()); @@ -249,10 +263,8 @@ fn test_cors_preflight_cache_fetch() { let wrapped_request0 = Rc::new(request.clone()); let wrapped_request1 = Rc::new(request); - let fetch_response0 = fetch_with_cors_cache(wrapped_request0.clone(), &mut cache, - &mut None, &new_fetch_context(None)); - let fetch_response1 = fetch_with_cors_cache(wrapped_request1.clone(), &mut cache, - &mut None, &new_fetch_context(None)); + let fetch_response0 = fetch_with_cors_cache(wrapped_request0.clone(), &mut cache); + let fetch_response1 = fetch_with_cors_cache(wrapped_request1.clone(), &mut cache); let _ = server.close(); assert!(!fetch_response0.is_network_error() && !fetch_response1.is_network_error()); @@ -298,7 +310,7 @@ fn test_cors_preflight_fetch_network_error() { *request.referrer.borrow_mut() = Referrer::NoReferrer; request.use_cors_preflight = true; request.mode = RequestMode::CorsMode; - let fetch_response = fetch_sync(request, None); + let fetch_response = fetch(request, None); let _ = server.close(); assert!(fetch_response.is_network_error()); @@ -319,7 +331,7 @@ fn test_fetch_response_is_basic_filtered() { let origin = Origin::Origin(url.origin()); let request = Request::new(url, Some(origin), false, None); *request.referrer.borrow_mut() = Referrer::NoReferrer; - let fetch_response = fetch_sync(request, None); + let fetch_response = fetch(request, None); let _ = server.close(); assert!(!fetch_response.is_network_error()); @@ -365,7 +377,7 @@ fn test_fetch_response_is_cors_filtered() { let mut request = Request::new(url, Some(origin), false, None); *request.referrer.borrow_mut() = Referrer::NoReferrer; request.mode = RequestMode::CorsMode; - let fetch_response = fetch_sync(request, None); + let fetch_response = fetch(request, None); let _ = server.close(); assert!(!fetch_response.is_network_error()); @@ -396,7 +408,7 @@ fn test_fetch_response_is_opaque_filtered() { let origin = Origin::Origin(UrlOrigin::new_opaque()); let request = Request::new(url, Some(origin), false, None); *request.referrer.borrow_mut() = Referrer::NoReferrer; - let fetch_response = fetch_sync(request, None); + let fetch_response = fetch(request, None); let _ = server.close(); assert!(!fetch_response.is_network_error()); @@ -444,7 +456,7 @@ fn test_fetch_response_is_opaque_redirect_filtered() { let request = Request::new(url, Some(origin), false, None); *request.referrer.borrow_mut() = Referrer::NoReferrer; request.redirect_mode.set(RedirectMode::Manual); - let fetch_response = fetch_sync(request, None); + let fetch_response = fetch(request, None); let _ = server.close(); assert!(!fetch_response.is_network_error()); @@ -481,7 +493,7 @@ fn test_fetch_with_local_urls_only() { // Set the flag. request.local_urls_only = true; - fetch_sync(request, None) + fetch(request, None) }; let local_url = ServoUrl::parse("about:blank").unwrap(); @@ -518,7 +530,7 @@ fn setup_server_and_fetch(message: &'static [u8], redirect_cap: u32) -> Response let origin = Origin::Origin(url.origin()); let request = Request::new(url, Some(origin), false, None); *request.referrer.borrow_mut() = Referrer::NoReferrer; - let fetch_response = fetch_sync(request, None); + let fetch_response = fetch(request, None); let _ = server.close(); fetch_response } @@ -603,7 +615,7 @@ fn test_fetch_redirect_updates_method_runner(tx: Sender<bool>, status_code: Stat *request.referrer.borrow_mut() = Referrer::NoReferrer; *request.method.borrow_mut() = method; - let _ = fetch_sync(request, None); + let _ = fetch(request, None); let _ = server.close(); } @@ -677,13 +689,8 @@ fn test_fetch_async_returns_complete_response() { let request = Request::new(url, Some(origin), false, None); *request.referrer.borrow_mut() = Referrer::NoReferrer; - let (tx, rx) = channel(); - let listener = Box::new(FetchResponseCollector { - sender: tx.clone() - }); + let fetch_response = fetch(request, None); - fetch_async(request, listener, None); - let fetch_response = rx.recv().unwrap(); let _ = server.close(); assert_eq!(response_is_done(&fetch_response), true); @@ -702,13 +709,8 @@ fn test_opaque_filtered_fetch_async_returns_complete_response() { let request = Request::new(url, Some(origin), false, None); *request.referrer.borrow_mut() = Referrer::NoReferrer; - let (tx, rx) = channel(); - let listener = Box::new(FetchResponseCollector { - sender: tx.clone() - }); + let fetch_response = fetch(request, None); - fetch_async(request, listener, None); - let fetch_response = rx.recv().unwrap(); let _ = server.close(); assert_eq!(fetch_response.response_type, ResponseType::Opaque); @@ -743,13 +745,8 @@ fn test_opaque_redirect_filtered_fetch_async_returns_complete_response() { *request.referrer.borrow_mut() = Referrer::NoReferrer; request.redirect_mode.set(RedirectMode::Manual); - let (tx, rx) = channel(); - let listener = Box::new(FetchResponseCollector { - sender: tx.clone() - }); + let fetch_response = fetch(request, None); - fetch_async(request, listener, None); - let fetch_response = rx.recv().unwrap(); let _ = server.close(); assert_eq!(fetch_response.response_type, ResponseType::OpaqueRedirect); @@ -771,7 +768,7 @@ fn test_fetch_with_devtools() { let (devtools_chan, devtools_port) = channel::<DevtoolsControlMsg>(); - let _ = fetch_sync(request, Some(devtools_chan)); + let _ = fetch(request, Some(devtools_chan)); let _ = server.close(); // notification received from devtools diff --git a/tests/unit/net/http_loader.rs b/tests/unit/net/http_loader.rs index c2af331b348..f31098e793a 100644 --- a/tests/unit/net/http_loader.rs +++ b/tests/unit/net/http_loader.rs @@ -7,7 +7,8 @@ use cookie_rs::Cookie as CookiePair; use devtools_traits::{ChromeToDevtoolsControlMsg, DevtoolsControlMsg, NetworkEvent}; use devtools_traits::HttpRequest as DevtoolsHttpRequest; use devtools_traits::HttpResponse as DevtoolsHttpResponse; -use fetch_sync; +use fetch; +use fetch_with_context; use flate2::Compression; use flate2::write::{DeflateEncoder, GzEncoder}; use hyper::LanguageTag; @@ -24,7 +25,6 @@ use make_server; use msg::constellation_msg::TEST_PIPELINE_ID; use net::cookie::Cookie; use net::cookie_storage::CookieStorage; -use net::fetch::methods::fetch; use net::resource_thread::AuthCacheEntry; use net_traits::{CookieSource, NetworkError}; use net_traits::hosts::replace_host_table; @@ -34,7 +34,6 @@ use new_fetch_context; use servo_url::ServoUrl; use std::collections::HashMap; use std::io::{Read, Write}; -use std::rc::Rc; use std::sync::{Arc, Mutex, RwLock, mpsc}; use std::sync::atomic::{AtomicBool, Ordering}; use std::sync::mpsc::Receiver; @@ -143,7 +142,7 @@ fn test_check_default_headers_loaded_in_every_request() { pipeline_id: Some(TEST_PIPELINE_ID), .. RequestInit::default() }); - let response = fetch_sync(request, None); + let response = fetch(request, None); assert!(response.status.unwrap().is_success()); // Testing for method.POST @@ -157,7 +156,7 @@ fn test_check_default_headers_loaded_in_every_request() { pipeline_id: Some(TEST_PIPELINE_ID), .. RequestInit::default() }); - let response = fetch_sync(request, None); + let response = fetch(request, None); assert!(response.status.unwrap().is_success()); let _ = server.close(); @@ -179,7 +178,7 @@ fn test_load_when_request_is_not_get_or_head_and_there_is_no_body_content_length pipeline_id: Some(TEST_PIPELINE_ID), .. RequestInit::default() }); - let response = fetch_sync(request, None); + let response = fetch(request, None); assert!(response.status.unwrap().is_success()); let _ = server.close(); @@ -206,7 +205,7 @@ fn test_request_and_response_data_with_network_messages() { .. RequestInit::default() }); let (devtools_chan, devtools_port) = mpsc::channel(); - let response = fetch_sync(request, Some(devtools_chan)); + let response = fetch(request, Some(devtools_chan)); assert!(response.status.unwrap().is_success()); let _ = server.close(); @@ -293,7 +292,7 @@ fn test_request_and_response_message_from_devtool_without_pipeline_id() { .. RequestInit::default() }); let (devtools_chan, devtools_port) = mpsc::channel(); - let response = fetch_sync(request, Some(devtools_chan)); + let response = fetch(request, Some(devtools_chan)); assert!(response.status.unwrap().is_success()); let _ = server.close(); @@ -328,7 +327,7 @@ fn test_redirected_request_to_devtools() { .. RequestInit::default() }); let (devtools_chan, devtools_port) = mpsc::channel(); - let response = fetch_sync(request, Some(devtools_chan)); + let response = fetch(request, Some(devtools_chan)); let _ = pre_server.close(); let _ = post_server.close(); @@ -375,7 +374,7 @@ fn test_load_when_redirecting_from_a_post_should_rewrite_next_request_as_get() { pipeline_id: Some(TEST_PIPELINE_ID), .. RequestInit::default() }); - let response = fetch_sync(request, None); + let response = fetch(request, None); let _ = pre_server.close(); let _ = post_server.close(); @@ -403,7 +402,7 @@ fn test_load_should_decode_the_response_as_deflate_when_response_headers_have_co pipeline_id: Some(TEST_PIPELINE_ID), .. RequestInit::default() }); - let response = fetch_sync(request, None); + let response = fetch(request, None); let _ = server.close(); @@ -432,7 +431,7 @@ fn test_load_should_decode_the_response_as_gzip_when_response_headers_have_conte pipeline_id: Some(TEST_PIPELINE_ID), .. RequestInit::default() }); - let response = fetch_sync(request, None); + let response = fetch(request, None); let _ = server.close(); @@ -470,7 +469,7 @@ fn test_load_doesnt_send_request_body_on_any_redirect() { pipeline_id: Some(TEST_PIPELINE_ID), .. RequestInit::default() }); - let response = fetch_sync(request, None); + let response = fetch(request, None); let _ = pre_server.close(); let _ = post_server.close(); @@ -496,7 +495,7 @@ fn test_load_doesnt_add_host_to_sts_list_when_url_is_http_even_if_sts_headers_ar .. RequestInit::default() }); let context = new_fetch_context(None); - let response = fetch(Rc::new(request), &mut None, &context); + let response = fetch_with_context(request, &context); let _ = server.close(); @@ -526,7 +525,7 @@ fn test_load_sets_cookies_in_the_resource_manager_when_it_get_set_cookie_header_ credentials_mode: CredentialsMode::Include, .. RequestInit::default() }); - let response = fetch(Rc::new(request), &mut None, &context); + let response = fetch_with_context(request, &context); let _ = server.close(); @@ -553,7 +552,7 @@ fn test_load_sets_requests_cookies_header_for_url_by_getting_cookies_from_the_re &url, CookieSource::HTTP ).unwrap(); - cookie_jar.push(cookie, CookieSource::HTTP); + cookie_jar.push(cookie, &url, CookieSource::HTTP); } let request = Request::from_init(RequestInit { @@ -566,7 +565,7 @@ fn test_load_sets_requests_cookies_header_for_url_by_getting_cookies_from_the_re credentials_mode: CredentialsMode::Include, .. RequestInit::default() }); - let response = fetch(Rc::new(request), &mut None, &context); + let response = fetch_with_context(request, &context); let _ = server.close(); @@ -591,7 +590,7 @@ fn test_load_sends_cookie_if_nonhttp() { &url, CookieSource::NonHTTP ).unwrap(); - cookie_jar.push(cookie, CookieSource::HTTP); + cookie_jar.push(cookie, &url, CookieSource::HTTP); } let request = Request::from_init(RequestInit { @@ -604,7 +603,7 @@ fn test_load_sends_cookie_if_nonhttp() { credentials_mode: CredentialsMode::Include, .. RequestInit::default() }); - let response = fetch(Rc::new(request), &mut None, &context); + let response = fetch_with_context(request, &context); let _ = server.close(); @@ -635,7 +634,7 @@ fn test_cookie_set_with_httponly_should_not_be_available_using_getcookiesforurl( credentials_mode: CredentialsMode::Include, .. RequestInit::default() }); - let response = fetch(Rc::new(request), &mut None, &context); + let response = fetch_with_context(request, &context); let _ = server.close(); @@ -670,7 +669,7 @@ fn test_when_cookie_received_marked_secure_is_ignored_for_http() { credentials_mode: CredentialsMode::Include, .. RequestInit::default() }); - let response = fetch(Rc::new(request), &mut None, &context); + let response = fetch_with_context(request, &context); let _ = server.close(); @@ -698,7 +697,7 @@ fn test_load_sets_content_length_to_length_of_request_body() { pipeline_id: Some(TEST_PIPELINE_ID), .. RequestInit::default() }); - let response = fetch_sync(request, None); + let response = fetch(request, None); let _ = server.close(); @@ -726,7 +725,7 @@ fn test_load_uses_explicit_accept_from_headers_in_load_data() { pipeline_id: Some(TEST_PIPELINE_ID), .. RequestInit::default() }); - let response = fetch_sync(request, None); + let response = fetch(request, None); let _ = server.close(); @@ -753,7 +752,7 @@ fn test_load_sets_default_accept_to_html_xhtml_xml_and_then_anything_else() { pipeline_id: Some(TEST_PIPELINE_ID), .. RequestInit::default() }); - let response = fetch_sync(request, None); + let response = fetch(request, None); let _ = server.close(); @@ -781,7 +780,7 @@ fn test_load_uses_explicit_accept_encoding_from_load_data_headers() { pipeline_id: Some(TEST_PIPELINE_ID), .. RequestInit::default() }); - let response = fetch_sync(request, None); + let response = fetch(request, None); let _ = server.close(); @@ -808,7 +807,7 @@ fn test_load_sets_default_accept_encoding_to_gzip_and_deflate() { pipeline_id: Some(TEST_PIPELINE_ID), .. RequestInit::default() }); - let response = fetch_sync(request, None); + let response = fetch(request, None); let _ = server.close(); @@ -844,7 +843,7 @@ fn test_load_errors_when_there_a_redirect_loop() { pipeline_id: Some(TEST_PIPELINE_ID), .. RequestInit::default() }); - let response = fetch_sync(request, None); + let response = fetch(request, None); let _ = server_a.close(); let _ = server_b.close(); @@ -887,7 +886,7 @@ fn test_load_succeeds_with_a_redirect_loop() { pipeline_id: Some(TEST_PIPELINE_ID), .. RequestInit::default() }); - let response = fetch_sync(request, None); + let response = fetch(request, None); let _ = server_a.close(); let _ = server_b.close(); @@ -924,7 +923,7 @@ fn test_load_follows_a_redirect() { pipeline_id: Some(TEST_PIPELINE_ID), .. RequestInit::default() }); - let response = fetch_sync(request, None); + let response = fetch(request, None); let _ = pre_server.close(); let _ = post_server.close(); @@ -983,14 +982,14 @@ fn test_redirect_from_x_to_y_provides_y_cookies_from_y() { CookieSource::HTTP ).unwrap(); - cookie_jar.push(cookie_x, CookieSource::HTTP); + cookie_jar.push(cookie_x, &url_x, CookieSource::HTTP); let cookie_y = Cookie::new_wrapped( CookiePair::new("mozillaIs".to_owned(), "theBest".to_owned()), &url_y, CookieSource::HTTP ).unwrap(); - cookie_jar.push(cookie_y, CookieSource::HTTP); + cookie_jar.push(cookie_y, &url_y, CookieSource::HTTP); } let request = Request::from_init(RequestInit { @@ -1002,7 +1001,7 @@ fn test_redirect_from_x_to_y_provides_y_cookies_from_y() { credentials_mode: CredentialsMode::Include, .. RequestInit::default() }); - let response = fetch(Rc::new(request), &mut None, &context); + let response = fetch_with_context(request, &context); let _ = server.close(); @@ -1046,7 +1045,7 @@ fn test_redirect_from_x_to_x_provides_x_with_cookie_from_first_response() { credentials_mode: CredentialsMode::Include, .. RequestInit::default() }); - let response = fetch_sync(request, None); + let response = fetch(request, None); let _ = server.close(); @@ -1087,7 +1086,7 @@ fn test_if_auth_creds_not_in_url_but_in_cache_it_sets_it() { context.state.auth_cache.write().unwrap().entries.insert(url.origin().clone().ascii_serialization(), auth_entry); - let response = fetch(Rc::new(request), &mut None, &context); + let response = fetch_with_context(request, &context); let _ = server.close(); @@ -1113,7 +1112,7 @@ fn test_auth_ui_needs_www_auth() { .. RequestInit::default() }); - let response = fetch_sync(request, None); + let response = fetch(request, None); let _ = server.close(); @@ -1145,7 +1144,7 @@ fn test_content_blocked() { .. RequestInit::default() }); - let response = fetch(Rc::new(request), &mut None, &context); + let response = fetch_with_context(request, &context); let _ = server.close(); @@ -1176,7 +1175,7 @@ fn test_cookies_blocked() { &url, CookieSource::HTTP ).unwrap(); - cookie_jar.push(cookie, CookieSource::HTTP); + cookie_jar.push(cookie, &url, CookieSource::HTTP); } let request = Request::from_init(RequestInit { @@ -1188,7 +1187,7 @@ fn test_cookies_blocked() { .. RequestInit::default() }); - let response = fetch(Rc::new(request), &mut None, &context); + let response = fetch_with_context(request, &context); let _ = server.close(); diff --git a/tests/unit/net/lib.rs b/tests/unit/net/lib.rs index c9890544d94..6c2f8c7036f 100644 --- a/tests/unit/net/lib.rs +++ b/tests/unit/net/lib.rs @@ -16,11 +16,11 @@ extern crate msg; extern crate net; extern crate net_traits; extern crate profile_traits; +extern crate servo_config; extern crate servo_url; extern crate time; extern crate unicase; extern crate url; -extern crate util; #[cfg(test)] mod chrome_loader; #[cfg(test)] mod cookie; @@ -36,7 +36,8 @@ extern crate util; use devtools_traits::DevtoolsControlMsg; use hyper::server::{Handler, Listening, Server}; -use net::fetch::methods::{FetchContext, fetch}; +use net::fetch::cors_cache::CorsCache; +use net::fetch::methods::{self, FetchContext}; use net::filemanager_thread::FileManager; use net::test::HttpState; use net_traits::FetchTaskTarget; @@ -44,8 +45,7 @@ use net_traits::request::Request; use net_traits::response::Response; use servo_url::ServoUrl; use std::rc::Rc; -use std::sync::mpsc::Sender; -use std::thread; +use std::sync::mpsc::{Sender, channel}; const DEFAULT_USER_AGENT: &'static str = "Such Browser. Very Layout. Wow."; @@ -72,14 +72,30 @@ impl FetchTaskTarget for FetchResponseCollector { } } -fn fetch_async(request: Request, target: Box<FetchTaskTarget + Send>, dc: Option<Sender<DevtoolsControlMsg>>) { - thread::spawn(move || { - fetch(Rc::new(request), &mut Some(target), &new_fetch_context(dc)); - }); +fn fetch(request: Request, dc: Option<Sender<DevtoolsControlMsg>>) -> Response { + fetch_with_context(request, &new_fetch_context(dc)) } -fn fetch_sync(request: Request, dc: Option<Sender<DevtoolsControlMsg>>) -> Response { - fetch(Rc::new(request), &mut None, &new_fetch_context(dc)) +fn fetch_with_context(request: Request, context: &FetchContext) -> Response { + let (sender, receiver) = channel(); + let mut target = FetchResponseCollector { + sender: sender, + }; + + methods::fetch(Rc::new(request), &mut target, context); + + receiver.recv().unwrap() +} + +fn fetch_with_cors_cache(request: Rc<Request>, cache: &mut CorsCache) -> Response { + let (sender, receiver) = channel(); + let mut target = FetchResponseCollector { + sender: sender, + }; + + methods::fetch_with_cors_cache(request, cache, &mut target, &new_fetch_context(None)); + + receiver.recv().unwrap() } fn make_server<H: Handler + 'static>(handler: H) -> (Listening, ServoUrl) { diff --git a/tests/unit/script/headers.rs b/tests/unit/script/headers.rs index 5334056ec70..e990b706cdd 100644 --- a/tests/unit/script/headers.rs +++ b/tests/unit/script/headers.rs @@ -2,14 +2,13 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -use script::dom::bindings::str::ByteString; -use script::dom::headers; +use script::test::{ByteString, normalize_value}; #[test] fn test_normalize_empty_bytestring() { // empty ByteString test let empty_bytestring = ByteString::new(vec![]); - let actual = headers::normalize_value(empty_bytestring); + let actual = normalize_value(empty_bytestring); let expected = ByteString::new(vec![]); assert_eq!(actual, expected); } @@ -18,7 +17,7 @@ fn test_normalize_empty_bytestring() { fn test_normalize_all_whitespace_bytestring() { // All whitespace test. A horizontal tab, a line feed, a carriage return , and a space let all_whitespace_bytestring = ByteString::new(vec![b'\t', b'\n', b'\r', b' ']); - let actual = headers::normalize_value(all_whitespace_bytestring); + let actual = normalize_value(all_whitespace_bytestring); let expected = ByteString::new(vec![]); assert_eq!(actual, expected); } @@ -27,7 +26,7 @@ fn test_normalize_all_whitespace_bytestring() { fn test_normalize_non_empty_no_whitespace_bytestring() { // Non-empty, no whitespace ByteString test let no_whitespace_bytestring = ByteString::new(vec![b'S', b'!']); - let actual = headers::normalize_value(no_whitespace_bytestring); + let actual = normalize_value(no_whitespace_bytestring); let expected = ByteString::new(vec![b'S', b'!']); assert_eq!(actual, expected); } @@ -36,7 +35,7 @@ fn test_normalize_non_empty_no_whitespace_bytestring() { fn test_normalize_non_empty_leading_whitespace_bytestring() { // Non-empty, leading whitespace, no trailing whitespace ByteString test let leading_whitespace_bytestring = ByteString::new(vec![b'\t', b'\n', b' ', b'\r', b'S', b'!']); - let actual = headers::normalize_value(leading_whitespace_bytestring); + let actual = normalize_value(leading_whitespace_bytestring); let expected = ByteString::new(vec![b'S', b'!']); assert_eq!(actual, expected); } @@ -45,7 +44,7 @@ fn test_normalize_non_empty_leading_whitespace_bytestring() { fn test_normalize_non_empty_no_leading_whitespace_trailing_whitespace_bytestring() { // Non-empty, no leading whitespace, but with trailing whitespace ByteString test let trailing_whitespace_bytestring = ByteString::new(vec![b'S', b'!', b'\t', b'\n', b' ', b'\r']); - let actual = headers::normalize_value(trailing_whitespace_bytestring); + let actual = normalize_value(trailing_whitespace_bytestring); let expected = ByteString::new(vec![b'S', b'!']); assert_eq!(actual, expected); } @@ -55,7 +54,7 @@ fn test_normalize_non_empty_leading_and_trailing_whitespace_bytestring() { // Non-empty, leading whitespace, and trailing whitespace ByteString test let whitespace_sandwich_bytestring = ByteString::new(vec![b'\t', b'\n', b' ', b'\r', b'S', b'!', b'\t', b'\n', b' ', b'\r']); - let actual = headers::normalize_value(whitespace_sandwich_bytestring); + let actual = normalize_value(whitespace_sandwich_bytestring); let expected = ByteString::new(vec![b'S', b'!']); assert_eq!(actual, expected); } @@ -68,7 +67,7 @@ fn test_normalize_non_empty_leading_trailing_and_internal_whitespace_bytestring( ByteString::new(vec![b'\t', b'\n', b' ', b'\r', b'S', b'\t', b'\n', b' ', b'\r', b'!', b'\t', b'\n', b' ', b'\r']); - let actual = headers::normalize_value(whitespace_bigmac_bytestring); + let actual = normalize_value(whitespace_bigmac_bytestring); let expected = ByteString::new(vec![b'S', b'\t', b'\n', b' ', b'\r', b'!']); assert_eq!(actual, expected); } diff --git a/tests/unit/script/size_of.rs b/tests/unit/script/size_of.rs index 3930180a9cf..a328bcbf6f5 100644 --- a/tests/unit/script/size_of.rs +++ b/tests/unit/script/size_of.rs @@ -2,25 +2,16 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -use script::dom::characterdata::CharacterData; -use script::dom::element::Element; -use script::dom::eventtarget::EventTarget; -use script::dom::htmldivelement::HTMLDivElement; -use script::dom::htmlelement::HTMLElement; -use script::dom::htmlspanelement::HTMLSpanElement; -use script::dom::node::Node; -use script::dom::text::Text; -use script::layout_wrapper::ServoThreadSafeLayoutNode; -use std::mem::size_of; +use script::test::size_of; // Macro so that we can stringify type names // I'd really prefer the tests themselves to be run at plugin time, // however rustc::middle doesn't have access to the full type data macro_rules! sizeof_checker ( - ($testname: ident, $t:ty, $known_size:expr) => ( + ($testname: ident, $t: ident, $known_size: expr) => ( #[test] fn $testname() { - let new = size_of::<$t>(); + let new = size_of::$t(); let old = $known_size; if new < old { panic!("Your changes have decreased the stack size of commonly used DOM struct {} from {} to {}. \ @@ -47,3 +38,7 @@ sizeof_checker!(size_span, HTMLSpanElement, 336); sizeof_checker!(size_text, Text, 184); sizeof_checker!(size_characterdata, CharacterData, 184); sizeof_checker!(size_servothreadsafelayoutnode, ServoThreadSafeLayoutNode, 16); + +// We use these types in the parallel traversal. They should stay pointer-sized. +sizeof_checker!(size_sendelement, SendElement, 8); +sizeof_checker!(size_sendnode, SendNode, 8); diff --git a/tests/unit/script/textinput.rs b/tests/unit/script/textinput.rs index 677132d393c..01e28433ed6 100644 --- a/tests/unit/script/textinput.rs +++ b/tests/unit/script/textinput.rs @@ -13,7 +13,7 @@ use msg::constellation_msg::CONTROL; #[cfg(target_os = "macos")] use msg::constellation_msg::SUPER; use script::clipboard_provider::DummyClipboardContext; -use script::dom::bindings::str::DOMString; +use script::test::DOMString; use script::textinput::{TextInput, TextPoint, Selection, Lines, Direction, SelectionDirection}; fn text_input(lines: Lines, s: &str) -> TextInput<DummyClipboardContext> { diff --git a/tests/unit/util/Cargo.toml b/tests/unit/servo_config/Cargo.toml index 28e5415f417..dec49de186a 100644 --- a/tests/unit/util/Cargo.toml +++ b/tests/unit/servo_config/Cargo.toml @@ -1,14 +1,14 @@ [package] -name = "util_tests" +name = "servo_config_tests" version = "0.0.1" authors = ["The Servo Project Developers"] license = "MPL-2.0" [lib] -name = "util_tests" +name = "servo_config_tests" path = "lib.rs" doctest = false [dependencies] -util = {path = "../../../components/util"} +servo_config = {path = "../../../components/config"} diff --git a/tests/unit/util/lib.rs b/tests/unit/servo_config/lib.rs index 96506d5973c..dc2a6446848 100644 --- a/tests/unit/util/lib.rs +++ b/tests/unit/servo_config/lib.rs @@ -4,9 +4,7 @@ #![cfg(test)] -extern crate util; +extern crate servo_config; mod opts; mod prefs; -mod remutex; -mod thread; diff --git a/tests/unit/util/opts.rs b/tests/unit/servo_config/opts.rs index 8367e1d5117..a6827fd05e9 100644 --- a/tests/unit/util/opts.rs +++ b/tests/unit/servo_config/opts.rs @@ -2,8 +2,8 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ +use servo_config::opts::parse_url_or_filename; use std::path::Path; -use util::opts::parse_url_or_filename; #[cfg(not(target_os = "windows"))] const FAKE_CWD: &'static str = "/fake/cwd"; diff --git a/tests/unit/util/prefs.rs b/tests/unit/servo_config/prefs.rs index 295a3e1fe2c..393b5a358d2 100644 --- a/tests/unit/util/prefs.rs +++ b/tests/unit/servo_config/prefs.rs @@ -2,10 +2,10 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ +use servo_config::basedir; +use servo_config::prefs::{PREFS, PrefValue, read_prefs_from_file}; use std::fs::{self, File}; use std::io::{Read, Write}; -use util::basedir; -use util::prefs::{PREFS, PrefValue, read_prefs_from_file}; #[test] fn test_create_pref() { diff --git a/tests/unit/servo_remutex/Cargo.toml b/tests/unit/servo_remutex/Cargo.toml new file mode 100644 index 00000000000..20782b623e2 --- /dev/null +++ b/tests/unit/servo_remutex/Cargo.toml @@ -0,0 +1,14 @@ +[package] +name = "servo_remutex_tests" +version = "0.0.1" +authors = ["The Servo Project Developers"] +license = "MPL-2.0" + +[lib] +name = "servo_remutex_tests" +path = "lib.rs" +doctest = false + +[dependencies] +servo_remutex = {path = "../../../components/remutex"} + diff --git a/tests/unit/util/remutex.rs b/tests/unit/servo_remutex/lib.rs index a005d761d5f..411c943923c 100644 --- a/tests/unit/util/remutex.rs +++ b/tests/unit/servo_remutex/lib.rs @@ -10,10 +10,14 @@ // These tests came from https://github.com/rust-lang/rust/blob/master/src/libstd/sys/common/remutex.rs +#![cfg(test)] + +extern crate servo_remutex; + +use servo_remutex::{ReentrantMutex, ReentrantMutexGuard}; use std::cell::RefCell; use std::sync::Arc; use std::thread; -use util::remutex::{ReentrantMutex, ReentrantMutexGuard}; #[test] fn smoke() { diff --git a/tests/unit/style/Cargo.toml b/tests/unit/style/Cargo.toml index c2a668caa4c..69e5c3e9991 100644 --- a/tests/unit/style/Cargo.toml +++ b/tests/unit/style/Cargo.toml @@ -16,13 +16,15 @@ testing = ["style/testing"] app_units = "0.3" cssparser = {version = "0.7", features = ["heap_size"]} euclid = "0.10.1" +html5ever-atoms = "0.1" +matches = "0.1" owning_ref = "0.2.2" parking_lot = "0.3" +rayon = "0.6" rustc-serialize = "0.3" selectors = "0.15" -html5ever-atoms = "0.1" servo_atoms = {path = "../../../components/atoms"} +servo_config = {path = "../../../components/config"} style = {path = "../../../components/style"} style_traits = {path = "../../../components/style_traits"} servo_url = {path = "../../../components/url"} -util = {path = "../../../components/util"} diff --git a/tests/unit/style/lib.rs b/tests/unit/style/lib.rs index 1ca7414bf68..f2be3da2307 100644 --- a/tests/unit/style/lib.rs +++ b/tests/unit/style/lib.rs @@ -3,22 +3,24 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #![cfg(test)] -#![feature(core_intrinsics)] -#![feature(plugin)] +#![feature(plugin, test)] extern crate app_units; extern crate cssparser; extern crate euclid; #[macro_use] extern crate html5ever_atoms; +#[macro_use] #[allow(unused_extern_crates)] extern crate matches; extern crate owning_ref; extern crate parking_lot; +extern crate rayon; extern crate rustc_serialize; extern crate selectors; #[macro_use] extern crate servo_atoms; +extern crate servo_config; extern crate servo_url; extern crate style; extern crate style_traits; -extern crate util; +extern crate test; mod atomic_refcell; mod attr; @@ -28,6 +30,7 @@ mod media_queries; mod owning_handle; mod parsing; mod properties; +mod rule_tree; mod str; mod stylesheets; mod stylist; diff --git a/tests/unit/style/media_queries.rs b/tests/unit/style/media_queries.rs index 8c91a5b52bb..ac5a9b501c2 100644 --- a/tests/unit/style/media_queries.rs +++ b/tests/unit/style/media_queries.rs @@ -29,7 +29,8 @@ fn test_media_rule<F>(css: &str, callback: F) where F: Fn(&MediaList, &str) { let url = ServoUrl::parse("http://localhost").unwrap(); let stylesheet = Stylesheet::from_str( css, url, Origin::Author, Default::default(), - Box::new(CSSErrorReporterTest), ParserContextExtraData::default()); + None, Box::new(CSSErrorReporterTest), + ParserContextExtraData::default()); let mut rule_count = 0; media_queries(&stylesheet.rules.read().0, &mut |mq| { rule_count += 1; @@ -53,7 +54,8 @@ fn media_query_test(device: &Device, css: &str, expected_rule_count: usize) { let url = ServoUrl::parse("http://localhost").unwrap(); let ss = Stylesheet::from_str( css, url, Origin::Author, Default::default(), - Box::new(CSSErrorReporterTest), ParserContextExtraData::default()); + None, Box::new(CSSErrorReporterTest), + ParserContextExtraData::default()); let mut rule_count = 0; ss.effective_style_rules(device, |_| rule_count += 1); assert!(rule_count == expected_rule_count, css.to_owned()); diff --git a/tests/unit/style/parsing/background.rs b/tests/unit/style/parsing/background.rs index 278291d70e7..f5a6ceda850 100644 --- a/tests/unit/style/parsing/background.rs +++ b/tests/unit/style/parsing/background.rs @@ -7,7 +7,8 @@ use media_queries::CSSErrorReporterTest; use servo_url::ServoUrl; use style::parser::ParserContext; use style::properties::longhands::{background_attachment, background_clip, background_color, background_image}; -use style::properties::longhands::{background_origin, background_position, background_repeat, background_size}; +use style::properties::longhands::{background_origin, background_position_x, background_position_y, background_repeat}; +use style::properties::longhands::background_size; use style::properties::shorthands::background; use style::stylesheets::Origin; @@ -20,7 +21,8 @@ fn background_shorthand_should_parse_all_available_properties_when_specified() { let result = background::parse_value(&context, &mut parser).unwrap(); assert_eq!(result.background_image.unwrap(), parse_longhand!(background_image, "url(\"http://servo/test.png\")")); - assert_eq!(result.background_position.unwrap(), parse_longhand!(background_position, "top center")); + assert_eq!(result.background_position_x.unwrap(), parse_longhand!(background_position_x, "center")); + assert_eq!(result.background_position_y.unwrap(), parse_longhand!(background_position_y, "top")); assert_eq!(result.background_size.unwrap(), parse_longhand!(background_size, "200px 200px")); assert_eq!(result.background_repeat.unwrap(), parse_longhand!(background_repeat, "repeat-x")); assert_eq!(result.background_attachment.unwrap(), parse_longhand!(background_attachment, "fixed")); @@ -36,7 +38,8 @@ fn background_shorthand_should_parse_when_some_fields_set() { let mut parser = Parser::new("14px 40px repeat-y"); let result = background::parse_value(&context, &mut parser).unwrap(); - assert_eq!(result.background_position.unwrap(), parse_longhand!(background_position, "14px 40px")); + assert_eq!(result.background_position_x.unwrap(), parse_longhand!(background_position_x, "14px")); + assert_eq!(result.background_position_y.unwrap(), parse_longhand!(background_position_y, "40px")); assert_eq!(result.background_repeat.unwrap(), parse_longhand!(background_repeat, "repeat-y")); let mut parser = Parser::new("url(\"http://servo/test.png\") repeat blue"); @@ -68,8 +71,8 @@ fn background_shorthand_should_parse_comma_separated_declarations() { assert_eq!(result.background_image.unwrap(), parse_longhand!(background_image, "url(\"http://servo/test.png\"), \ url(\"http://servo/test.png\"), none")); - assert_eq!(result.background_position.unwrap(), parse_longhand!(background_position, "left top, center center, \ - 0% 0%")); + assert_eq!(result.background_position_x.unwrap(), parse_longhand!(background_position_x, "left, center, 0%")); + assert_eq!(result.background_position_y.unwrap(), parse_longhand!(background_position_y, "top, center, 0%")); assert_eq!(result.background_repeat.unwrap(), parse_longhand!(background_repeat, "no-repeat, no-repeat, repeat")); assert_eq!(result.background_clip.unwrap(), parse_longhand!(background_clip, "border-box, border-box, border-box")); assert_eq!(result.background_origin.unwrap(), parse_longhand!(background_origin, "padding-box, padding-box, \ @@ -86,12 +89,14 @@ fn background_shorthand_should_parse_position_and_size_correctly() { let mut parser = Parser::new("7px 4px"); let result = background::parse_value(&context, &mut parser).unwrap(); - assert_eq!(result.background_position.unwrap(), parse_longhand!(background_position, "7px 4px")); + assert_eq!(result.background_position_x.unwrap(), parse_longhand!(background_position_x, "7px")); + assert_eq!(result.background_position_y.unwrap(), parse_longhand!(background_position_y, "4px")); let mut parser = Parser::new("7px 4px / 30px 20px"); let result = background::parse_value(&context, &mut parser).unwrap(); - assert_eq!(result.background_position.unwrap(), parse_longhand!(background_position, "7px 4px")); + assert_eq!(result.background_position_x.unwrap(), parse_longhand!(background_position_x, "7px")); + assert_eq!(result.background_position_y.unwrap(), parse_longhand!(background_position_y, "4px")); assert_eq!(result.background_size.unwrap(), parse_longhand!(background_size, "30px 20px")); let mut parser = Parser::new("/ 30px 20px"); diff --git a/tests/unit/style/parsing/image.rs b/tests/unit/style/parsing/image.rs index 5565a72dc3e..16eb63b6725 100644 --- a/tests/unit/style/parsing/image.rs +++ b/tests/unit/style/parsing/image.rs @@ -12,12 +12,10 @@ use style_traits::ToCss; #[test] fn test_linear_gradient() { // Parsing from the right - assert_roundtrip_with_context!(Image::parse, "linear-gradient(to left, red, green)", - "linear-gradient(4.712389rad, red, green)"); + assert_roundtrip_with_context!(Image::parse, "linear-gradient(to left, red, green)"); // Parsing from the left - assert_roundtrip_with_context!(Image::parse, "linear-gradient(to right, red, green)", - "linear-gradient(1.5707964rad, red, green)"); + assert_roundtrip_with_context!(Image::parse, "linear-gradient(to right, red, green)"); // Parsing with two values for <side-or-corner> assert_roundtrip_with_context!(Image::parse, "linear-gradient(to right top, red, green)"); @@ -26,17 +24,14 @@ fn test_linear_gradient() { assert_roundtrip_with_context!(Image::parse, "linear-gradient(45deg, red, green)", "linear-gradient(0.7853982rad, red, green)"); - // Parsing with more than two entries in <color-stop-list> - assert_roundtrip_with_context!(Image::parse, "linear-gradient(red, yellow, green)", - "linear-gradient(3.1415927rad, red, yellow, green)"); + // Parsing with more than two entries in <color-stop-list> + assert_roundtrip_with_context!(Image::parse, "linear-gradient(red, yellow, green)"); - // Parsing with percentage in the <color-stop-list> - assert_roundtrip_with_context!(Image::parse, "linear-gradient(red, green, yellow 50%)", - "linear-gradient(3.1415927rad, red, green, yellow 50%)"); + // Parsing with percentage in the <color-stop-list> + assert_roundtrip_with_context!(Image::parse, "linear-gradient(red, green, yellow 50%)"); // Parsing without <angle> and <side-or-corner> - assert_roundtrip_with_context!(Image::parse, "linear-gradient(red, green)", - "linear-gradient(3.1415927rad, red, green)"); + assert_roundtrip_with_context!(Image::parse, "linear-gradient(red, green)"); } #[test] diff --git a/tests/unit/style/parsing/inherited_box.rs b/tests/unit/style/parsing/inherited_box.rs new file mode 100644 index 00000000000..0fc78ed6131 --- /dev/null +++ b/tests/unit/style/parsing/inherited_box.rs @@ -0,0 +1,31 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +use cssparser::Parser; +use media_queries::CSSErrorReporterTest; +use style::parser::ParserContext; +use style::stylesheets::Origin; + +#[test] +fn image_orientation_longhand_should_parse_properly() { + use std::f32::consts::PI; + use style::properties::longhands::image_orientation; + use style::properties::longhands::image_orientation::SpecifiedValue; + use style::values::specified::Angle; + + let from_image = parse_longhand!(image_orientation, "from-image"); + assert_eq!(from_image, SpecifiedValue { angle: None, flipped: false }); + + let flip = parse_longhand!(image_orientation, "flip"); + assert_eq!(flip, SpecifiedValue { angle: None, flipped: true }); + + let zero = parse_longhand!(image_orientation, "0deg"); + assert_eq!(zero, SpecifiedValue { angle: Some(Angle::from_radians(0.0)), flipped: false }); + + let negative_rad = parse_longhand!(image_orientation, "-1rad"); + assert_eq!(negative_rad, SpecifiedValue { angle: Some(Angle::from_radians(-1.0)), flipped: false }); + + let flip_with_180 = parse_longhand!(image_orientation, "180deg flip"); + assert_eq!(flip_with_180, SpecifiedValue { angle: Some(Angle::from_radians(PI)), flipped: true }); +} diff --git a/tests/unit/style/parsing/mod.rs b/tests/unit/style/parsing/mod.rs index 369e0b66bf0..05bd3e8d912 100644 --- a/tests/unit/style/parsing/mod.rs +++ b/tests/unit/style/parsing/mod.rs @@ -52,6 +52,7 @@ mod basic_shape; mod border; mod font; mod image; +mod inherited_box; mod inherited_text; mod mask; mod position; diff --git a/tests/unit/style/parsing/position.rs b/tests/unit/style/parsing/position.rs index 5bb0d414510..34b7528a329 100644 --- a/tests/unit/style/parsing/position.rs +++ b/tests/unit/style/parsing/position.rs @@ -61,4 +61,79 @@ fn test_position() { assert!(parse(Position::parse, "top 10px bottom").is_err()); assert!(parse(Position::parse, "top 10px bottom 15%").is_err()); + // Logical keywords are not supported in Position yet + assert!(parse(Position::parse, "x-start").is_err()); + assert!(parse(Position::parse, "y-end").is_err()); + assert!(parse(Position::parse, "x-start y-end").is_err()); + assert!(parse(Position::parse, "x-end 10px").is_err()); + assert!(parse(Position::parse, "y-start 20px").is_err()); + assert!(parse(Position::parse, "x-start bottom 10%").is_err()); + assert!(parse(Position::parse, "left y-start 10%").is_err()); + assert!(parse(Position::parse, "x-start 20px y-end 10%").is_err()); +} + +#[test] +fn test_horizontal_position() { + // One value serializations. + assert_roundtrip_with_context!(HorizontalPosition::parse, "20px", "20px"); + assert_roundtrip_with_context!(HorizontalPosition::parse, "25%", "25%"); + assert_roundtrip_with_context!(HorizontalPosition::parse, "center", "center"); + assert_roundtrip_with_context!(HorizontalPosition::parse, "left", "left"); + assert_roundtrip_with_context!(HorizontalPosition::parse, "right", "right"); + assert_roundtrip_with_context!(HorizontalPosition::parse, "x-start", "x-start"); + assert_roundtrip_with_context!(HorizontalPosition::parse, "x-end", "x-end"); + + // Two value serializations. + assert_roundtrip_with_context!(HorizontalPosition::parse, "right 10px", "right 10px"); + assert_roundtrip_with_context!(HorizontalPosition::parse, "10px left", "left 10px"); + assert_roundtrip_with_context!(HorizontalPosition::parse, "x-end 20%", "x-end 20%"); + assert_roundtrip_with_context!(HorizontalPosition::parse, "20px x-start", "x-start 20px"); + + // Invalid horizontal positions. + assert!(parse(HorizontalPosition::parse, "top").is_err()); + assert!(parse(HorizontalPosition::parse, "bottom").is_err()); + assert!(parse(HorizontalPosition::parse, "y-start").is_err()); + assert!(parse(HorizontalPosition::parse, "y-end").is_err()); + assert!(parse(HorizontalPosition::parse, "20px y-end").is_err()); + assert!(parse(HorizontalPosition::parse, "y-end 20px ").is_err()); + assert!(parse(HorizontalPosition::parse, "bottom 20px").is_err()); + assert!(parse(HorizontalPosition::parse, "20px top").is_err()); + assert!(parse(HorizontalPosition::parse, "left center").is_err()); + assert!(parse(HorizontalPosition::parse, "bottom top").is_err()); + assert!(parse(HorizontalPosition::parse, "left top").is_err()); + assert!(parse(HorizontalPosition::parse, "left right").is_err()); + assert!(parse(HorizontalPosition::parse, "20px 30px").is_err()); +} + +#[test] +fn test_vertical_position() { + // One value serializations. + assert_roundtrip_with_context!(VerticalPosition::parse, "20px", "20px"); + assert_roundtrip_with_context!(VerticalPosition::parse, "25%", "25%"); + assert_roundtrip_with_context!(VerticalPosition::parse, "center", "center"); + assert_roundtrip_with_context!(VerticalPosition::parse, "top", "top"); + assert_roundtrip_with_context!(VerticalPosition::parse, "bottom", "bottom"); + assert_roundtrip_with_context!(VerticalPosition::parse, "y-start", "y-start"); + assert_roundtrip_with_context!(VerticalPosition::parse, "y-end", "y-end"); + + // Two value serializations. + assert_roundtrip_with_context!(VerticalPosition::parse, "bottom 10px", "bottom 10px"); + assert_roundtrip_with_context!(VerticalPosition::parse, "10px top", "top 10px"); + assert_roundtrip_with_context!(VerticalPosition::parse, "y-end 20%", "y-end 20%"); + assert_roundtrip_with_context!(VerticalPosition::parse, "20px y-start", "y-start 20px"); + + // Invalid vertical positions. + assert!(parse(VerticalPosition::parse, "left").is_err()); + assert!(parse(VerticalPosition::parse, "right").is_err()); + assert!(parse(VerticalPosition::parse, "x-start").is_err()); + assert!(parse(VerticalPosition::parse, "x-end").is_err()); + assert!(parse(VerticalPosition::parse, "20px x-end").is_err()); + assert!(parse(VerticalPosition::parse, "x-end 20px ").is_err()); + assert!(parse(VerticalPosition::parse, "left 20px").is_err()); + assert!(parse(VerticalPosition::parse, "20px right").is_err()); + assert!(parse(VerticalPosition::parse, "left center").is_err()); + assert!(parse(VerticalPosition::parse, "bottom top").is_err()); + assert!(parse(VerticalPosition::parse, "left top").is_err()); + assert!(parse(VerticalPosition::parse, "left right").is_err()); + assert!(parse(VerticalPosition::parse, "20px 30px").is_err()); } diff --git a/tests/unit/style/properties/serialization.rs b/tests/unit/style/properties/serialization.rs index 6780716e876..21e490a86c1 100644 --- a/tests/unit/style/properties/serialization.rs +++ b/tests/unit/style/properties/serialization.rs @@ -4,7 +4,7 @@ pub use std::sync::Arc; pub use style::computed_values::display::T::inline_block; -pub use style::properties::{DeclaredValue, PropertyDeclaration, PropertyDeclarationBlock, Importance}; +pub use style::properties::{DeclaredValue, PropertyDeclaration, PropertyDeclarationBlock, Importance, PropertyId}; pub use style::values::specified::{BorderStyle, BorderWidth, CSSColor, Length}; pub use style::values::specified::{LengthOrPercentage, LengthOrPercentageOrAuto, LengthOrPercentageOrAutoOrContent}; pub use style::properties::longhands::outline_color::computed_value::T as ComputedColor; @@ -688,11 +688,12 @@ mod shorthand_serialization { use style::properties::longhands::background_clip as clip; use style::properties::longhands::background_image as image; use style::properties::longhands::background_origin as origin; - use style::properties::longhands::background_position as position; + use style::properties::longhands::background_position_x as position_x; + use style::properties::longhands::background_position_y as position_y; use style::properties::longhands::background_repeat as repeat; use style::properties::longhands::background_size as size; use style::values::specified::Image; - use style::values::specified::position::Position; + use style::values::specified::position::{HorizontalPosition, VerticalPosition}; use super::*; macro_rules! single_vec_value_typedef { ($name:ident, $path:expr) => { @@ -731,12 +732,17 @@ mod shorthand_serialization { authored: None }); - let position = single_vec_value_typedef!(position, - Position { - horiz_keyword: None, - horiz_position: Some(LengthOrPercentage::Length(Length::from_px(7f32))), - vert_keyword: None, - vert_position: Some(LengthOrPercentage::Length(Length::from_px(4f32))) + let position_x = single_vec_value_typedef!(position_x, + HorizontalPosition { + keyword: None, + position: Some(LengthOrPercentage::Length(Length::from_px(7f32))), + } + ); + + let position_y = single_vec_value_typedef!(position_y, + VerticalPosition { + keyword: None, + position: Some(LengthOrPercentage::Length(Length::from_px(4f32))), } ); @@ -759,7 +765,8 @@ mod shorthand_serialization { let clip = single_vec_keyword_value!(clip, padding_box); properties.push(PropertyDeclaration::BackgroundColor(color)); - properties.push(PropertyDeclaration::BackgroundPosition(position)); + properties.push(PropertyDeclaration::BackgroundPositionX(position_x)); + properties.push(PropertyDeclaration::BackgroundPositionY(position_y)); properties.push(PropertyDeclaration::BackgroundRepeat(repeat)); properties.push(PropertyDeclaration::BackgroundAttachment(attachment)); properties.push(PropertyDeclaration::BackgroundImage(image)); @@ -785,12 +792,17 @@ mod shorthand_serialization { authored: None }); - let position = single_vec_value_typedef!(position, - Position { - horiz_keyword: None, - horiz_position: Some(LengthOrPercentage::Length(Length::from_px(7f32))), - vert_keyword: None, - vert_position: Some(LengthOrPercentage::Length(Length::from_px(4f32))) + let position_x = single_vec_value_typedef!(position_x, + HorizontalPosition { + keyword: None, + position: Some(LengthOrPercentage::Length(Length::from_px(7f32))), + } + ); + + let position_y = single_vec_value_typedef!(position_y, + VerticalPosition { + keyword: None, + position: Some(LengthOrPercentage::Length(Length::from_px(4f32))), } ); @@ -813,7 +825,8 @@ mod shorthand_serialization { let clip = single_vec_keyword_value!(clip, padding_box); properties.push(PropertyDeclaration::BackgroundColor(color)); - properties.push(PropertyDeclaration::BackgroundPosition(position)); + properties.push(PropertyDeclaration::BackgroundPositionX(position_x)); + properties.push(PropertyDeclaration::BackgroundPositionY(position_y)); properties.push(PropertyDeclaration::BackgroundRepeat(repeat)); properties.push(PropertyDeclaration::BackgroundAttachment(attachment)); properties.push(PropertyDeclaration::BackgroundImage(image)); @@ -838,12 +851,17 @@ mod shorthand_serialization { authored: None }); - let position = single_vec_value_typedef!(position, - Position { - horiz_keyword: None, - horiz_position: Some(LengthOrPercentage::Length(Length::from_px(0f32))), - vert_keyword: None, - vert_position: Some(LengthOrPercentage::Length(Length::from_px(0f32))) + let position_x = single_vec_value_typedef!(position_x, + HorizontalPosition { + keyword: None, + position: Some(LengthOrPercentage::Length(Length::from_px(0f32))), + } + ); + + let position_y = single_vec_value_typedef!(position_y, + VerticalPosition { + keyword: None, + position: Some(LengthOrPercentage::Length(Length::from_px(0f32))), } ); @@ -858,7 +876,8 @@ mod shorthand_serialization { let clip = DeclaredValue::Initial; properties.push(PropertyDeclaration::BackgroundColor(color)); - properties.push(PropertyDeclaration::BackgroundPosition(position)); + properties.push(PropertyDeclaration::BackgroundPositionX(position_x)); + properties.push(PropertyDeclaration::BackgroundPositionY(position_y)); properties.push(PropertyDeclaration::BackgroundRepeat(repeat)); properties.push(PropertyDeclaration::BackgroundAttachment(attachment)); properties.push(PropertyDeclaration::BackgroundImage(image)); @@ -881,7 +900,7 @@ mod shorthand_serialization { use style::properties::longhands::mask_repeat as repeat; use style::properties::longhands::mask_size as size; use style::values::specified::Image; - use style::values::specified::position::Position; + use style::values::specified::position::{HorizontalPosition, Position, VerticalPosition}; use super::*; macro_rules! single_vec_value_typedef { @@ -918,10 +937,14 @@ mod shorthand_serialization { let position = single_vec_value_typedef!(position, Position { - horiz_keyword: None, - horiz_position: Some(LengthOrPercentage::Length(Length::from_px(7f32))), - vert_keyword: None, - vert_position: Some(LengthOrPercentage::Length(Length::from_px(4f32))) + horizontal: HorizontalPosition { + keyword: None, + position: Some(LengthOrPercentage::Length(Length::from_px(7f32))), + }, + vertical: VerticalPosition { + keyword: None, + position: Some(LengthOrPercentage::Length(Length::from_px(4f32))), + }, } ); @@ -968,10 +991,14 @@ mod shorthand_serialization { let position = single_vec_value_typedef!(position, Position { - horiz_keyword: None, - horiz_position: Some(LengthOrPercentage::Length(Length::from_px(7f32))), - vert_keyword: None, - vert_position: Some(LengthOrPercentage::Length(Length::from_px(4f32))) + horizontal: HorizontalPosition { + keyword: None, + position: Some(LengthOrPercentage::Length(Length::from_px(7f32))), + }, + vertical: VerticalPosition { + keyword: None, + position: Some(LengthOrPercentage::Length(Length::from_px(4f32))), + }, } ); @@ -1027,7 +1054,8 @@ mod shorthand_serialization { let mut s = String::new(); - let x = block.single_value_to_css("scroll-snap-type", &mut s); + let id = PropertyId::parse("scroll-snap-type".into()).unwrap(); + let x = block.single_value_to_css(&id, &mut s); assert_eq!(x.is_ok(), true); assert_eq!(s, ""); @@ -1049,7 +1077,8 @@ mod shorthand_serialization { let mut s = String::new(); - let x = block.single_value_to_css("scroll-snap-type", &mut s); + let id = PropertyId::parse("scroll-snap-type".into()).unwrap(); + let x = block.single_value_to_css(&id, &mut s); assert_eq!(x.is_ok(), true); assert_eq!(s, "mandatory"); diff --git a/tests/unit/style/rule_tree/bench.rs b/tests/unit/style/rule_tree/bench.rs new file mode 100644 index 00000000000..2504c6f2893 --- /dev/null +++ b/tests/unit/style/rule_tree/bench.rs @@ -0,0 +1,196 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +use cssparser::{Parser, SourcePosition}; +use parking_lot::RwLock; +use rayon; +use servo_url::ServoUrl; +use std::sync::Arc; +use style::error_reporting::ParseErrorReporter; +use style::media_queries::MediaList; +use style::parser::ParserContextExtraData; +use style::properties::{longhands, DeclaredValue, Importance, PropertyDeclaration, PropertyDeclarationBlock}; +use style::rule_tree::{RuleTree, StrongRuleNode, StyleSource}; +use style::stylesheets::{Origin, Stylesheet, CssRule}; +use test::{self, Bencher}; + +struct ErrorringErrorReporter; +impl ParseErrorReporter for ErrorringErrorReporter { + fn report_error(&self, _: &mut Parser, position: SourcePosition, message: &str) { + panic!("CSS error: {:?} {}", position, message); + } + + fn clone(&self) -> Box<ParseErrorReporter + Send + Sync> { + Box::new(ErrorringErrorReporter) + } +} + +struct AutoGCRuleTree<'a>(&'a RuleTree); + +impl<'a> AutoGCRuleTree<'a> { + fn new(r: &'a RuleTree) -> Self { + AutoGCRuleTree(r) + } +} + +impl<'a> Drop for AutoGCRuleTree<'a> { + fn drop(&mut self) { + unsafe { self.0.gc() } + } +} + +fn parse_rules(css: &str) -> Vec<(StyleSource, Importance)> { + let s = Stylesheet::from_str(css, + ServoUrl::parse("http://localhost").unwrap(), + Origin::Author, + MediaList { + media_queries: vec![], + }, + None, + Box::new(ErrorringErrorReporter), + ParserContextExtraData {}); + let rules = s.rules.read(); + rules.0.iter().filter_map(|rule| { + match *rule { + CssRule::Style(ref style_rule) => Some(style_rule), + _ => None, + } + }).cloned().map(StyleSource::Style).map(|s| { + (s, Importance::Normal) + }).collect() +} + +fn test_insertion(rule_tree: &RuleTree, rules: Vec<(StyleSource, Importance)>) -> StrongRuleNode { + rule_tree.insert_ordered_rules(rules.into_iter()) +} + +fn test_insertion_style_attribute(rule_tree: &RuleTree, rules: &[(StyleSource, Importance)]) -> StrongRuleNode { + let mut rules = rules.to_vec(); + rules.push((StyleSource::Declarations(Arc::new(RwLock::new(PropertyDeclarationBlock { + declarations: vec![ + (PropertyDeclaration::Display(DeclaredValue::Value( + longhands::display::SpecifiedValue::block)), + Importance::Normal), + ], + important_count: 0, + }))), Importance::Normal)); + test_insertion(rule_tree, rules) +} + +#[bench] +fn bench_insertion_basic(b: &mut Bencher) { + let r = RuleTree::new(); + + let rules_matched = parse_rules( + ".foo { width: 200px; } \ + .bar { height: 500px; } \ + .baz { display: block; }"); + + b.iter(|| { + let _gc = AutoGCRuleTree::new(&r); + + for _ in 0..(4000 + 400) { + test::black_box(test_insertion(&r, rules_matched.clone())); + } + }) +} + +#[bench] +fn bench_insertion_basic_per_element(b: &mut Bencher) { + let r = RuleTree::new(); + + let rules_matched = parse_rules( + ".foo { width: 200px; } \ + .bar { height: 500px; } \ + .baz { display: block; }"); + + b.iter(|| { + let _gc = AutoGCRuleTree::new(&r); + + test::black_box(test_insertion(&r, rules_matched.clone())); + }); +} + +#[bench] +fn bench_expensive_insertion(b: &mut Bencher) { + let r = RuleTree::new(); + + // This test case tests a case where you style a bunch of siblings + // matching the same rules, with a different style attribute each + // one. + let rules_matched = parse_rules( + ".foo { width: 200px; } \ + .bar { height: 500px; } \ + .baz { display: block; }"); + + b.iter(|| { + let _gc = AutoGCRuleTree::new(&r); + + for _ in 0..(4000 + 400) { + test::black_box(test_insertion_style_attribute(&r, &rules_matched)); + } + }); +} + +#[bench] +fn bench_insertion_basic_parallel(b: &mut Bencher) { + let r = RuleTree::new(); + + let rules_matched = parse_rules( + ".foo { width: 200px; } \ + .bar { height: 500px; } \ + .baz { display: block; }"); + + b.iter(|| { + let _gc = AutoGCRuleTree::new(&r); + + rayon::scope(|s| { + for _ in 0..4 { + s.spawn(|s| { + for _ in 0..1000 { + test::black_box(test_insertion(&r, + rules_matched.clone())); + } + s.spawn(|_| { + for _ in 0..100 { + test::black_box(test_insertion(&r, + rules_matched.clone())); + } + }) + }) + } + }); + }); +} + +#[bench] +fn bench_expensive_insersion_parallel(b: &mut Bencher) { + let r = RuleTree::new(); + + let rules_matched = parse_rules( + ".foo { width: 200px; } \ + .bar { height: 500px; } \ + .baz { display: block; }"); + + b.iter(|| { + let _gc = AutoGCRuleTree::new(&r); + + rayon::scope(|s| { + for _ in 0..4 { + s.spawn(|s| { + for _ in 0..1000 { + test::black_box(test_insertion_style_attribute(&r, + &rules_matched)); + } + s.spawn(|_| { + for _ in 0..100 { + test::black_box(test_insertion_style_attribute(&r, + &rules_matched)); + } + }) + }) + } + }); + }); +} diff --git a/tests/unit/util/thread.rs b/tests/unit/style/rule_tree/mod.rs index e76c39ffd35..c94054a0881 100644 --- a/tests/unit/util/thread.rs +++ b/tests/unit/style/rule_tree/mod.rs @@ -2,12 +2,4 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -use std::borrow::ToOwned; -use util::thread::spawn_named; - -#[test] -fn spawn_named_test() { - spawn_named("Test".to_owned(), move || { - println!("I can run!"); - }); -} +mod bench; diff --git a/tests/unit/style/str.rs b/tests/unit/style/str.rs index dafbd8fb7da..45d747d4da8 100644 --- a/tests/unit/style/str.rs +++ b/tests/unit/style/str.rs @@ -2,7 +2,8 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -use style::str::{split_html_space_chars, str_join}; +use std::borrow::Cow; +use style::str::{split_html_space_chars, str_join, cow_into_ascii_lowercase}; #[test] pub fn split_html_space_chars_whitespace() { @@ -33,3 +34,13 @@ pub fn test_str_join_many() { let expected = "-alpha--beta-gamma-"; assert_eq!(actual, expected); } + +#[test] +pub fn test_cow_into_ascii_lowercase() { + assert!(matches!(cow_into_ascii_lowercase("abc.d"), Cow::Borrowed("abc.d"))); + let string = String::from("abc.d"); + assert!(matches!(cow_into_ascii_lowercase(string), Cow::Owned(ref s) if s == "abc.d")); + assert!(matches!(cow_into_ascii_lowercase("Abc.d"), Cow::Owned(ref s) if s == "abc.d")); + assert!(matches!(cow_into_ascii_lowercase("aBC.D"), Cow::Owned(ref s) if s == "abc.d")); + assert!(matches!(cow_into_ascii_lowercase("abc.D"), Cow::Owned(ref s) if s == "abc.d")); +} diff --git a/tests/unit/style/stylesheets.rs b/tests/unit/style/stylesheets.rs index 476d2d4ecd4..40ad06d8e4f 100644 --- a/tests/unit/style/stylesheets.rs +++ b/tests/unit/style/stylesheets.rs @@ -16,8 +16,8 @@ use std::sync::atomic::AtomicBool; use style::error_reporting::ParseErrorReporter; use style::keyframes::{Keyframe, KeyframeSelector, KeyframePercentage}; use style::parser::ParserContextExtraData; -use style::properties::{PropertyDeclaration, PropertyDeclarationBlock, DeclaredValue, longhands}; use style::properties::Importance; +use style::properties::{PropertyDeclaration, PropertyDeclarationBlock, DeclaredValue, longhands}; use style::properties::longhands::animation_play_state; use style::stylesheets::{Origin, Namespaces}; use style::stylesheets::{Stylesheet, NamespaceRule, CssRule, CssRules, StyleRule, KeyframesRule}; @@ -52,6 +52,7 @@ fn test_parse_stylesheet() { }"; let url = ServoUrl::parse("about::test").unwrap(); let stylesheet = Stylesheet::from_str(css, url.clone(), Origin::UserAgent, Default::default(), + None, Box::new(CSSErrorReporterTest), ParserContextExtraData::default()); let mut namespaces = Namespaces::default(); @@ -190,10 +191,15 @@ fn test_parse_stylesheet() { } )), Importance::Normal), - (PropertyDeclaration::BackgroundPosition(DeclaredValue::Value( - longhands::background_position::SpecifiedValue( - vec![longhands::background_position::single_value - ::get_initial_specified_value()]))), + (PropertyDeclaration::BackgroundPositionX(DeclaredValue::Value( + longhands::background_position_x::SpecifiedValue( + vec![longhands::background_position_x::single_value + ::get_initial_position_value()]))), + Importance::Normal), + (PropertyDeclaration::BackgroundPositionY(DeclaredValue::Value( + longhands::background_position_y::SpecifiedValue( + vec![longhands::background_position_y::single_value + ::get_initial_position_value()]))), Importance::Normal), (PropertyDeclaration::BackgroundRepeat(DeclaredValue::Value( longhands::background_repeat::SpecifiedValue( @@ -327,7 +333,9 @@ fn test_report_error_stylesheet() { let errors = error_reporter.errors.clone(); - Stylesheet::from_str(css, url, Origin::UserAgent, Default::default(), error_reporter, + Stylesheet::from_str(css, url, Origin::UserAgent, Default::default(), + None, + error_reporter, ParserContextExtraData::default()); let mut errors = errors.lock().unwrap(); diff --git a/tests/unit/style/stylist.rs b/tests/unit/style/stylist.rs index 786ce7863f4..98c5b68a2ef 100644 --- a/tests/unit/style/stylist.rs +++ b/tests/unit/style/stylist.rs @@ -101,7 +101,7 @@ fn test_insert() { let rules_list = get_mock_rules(&[".intro.foo", "#top"]); let mut selector_map = SelectorMap::new(); selector_map.insert(rules_list[1][0].clone()); - assert_eq!(1, selector_map.id_hash.get(&atom!("top")).unwrap()[0].source_order); + assert_eq!(1, selector_map.id_hash.get(&Atom::from("top")).unwrap()[0].source_order); selector_map.insert(rules_list[0][0].clone()); assert_eq!(0, selector_map.class_hash.get(&Atom::from("intro")).unwrap()[0].source_order); assert!(selector_map.class_hash.get(&Atom::from("foo")).is_none()); diff --git a/tests/unit/style/viewport.rs b/tests/unit/style/viewport.rs index a430089ba9b..026269421f7 100644 --- a/tests/unit/style/viewport.rs +++ b/tests/unit/style/viewport.rs @@ -6,6 +6,7 @@ use cssparser::Parser; use euclid::scale_factor::ScaleFactor; use euclid::size::TypedSize2D; use media_queries::CSSErrorReporterTest; +use servo_config::prefs::{PREFS, PrefValue}; use servo_url::ServoUrl; use style::error_reporting::ParseErrorReporter; use style::media_queries::{Device, MediaType}; @@ -24,6 +25,7 @@ macro_rules! stylesheet { ServoUrl::parse("http://localhost").unwrap(), Origin::$origin, Default::default(), + None, $error_reporter, ParserContextExtraData::default() )) @@ -35,8 +37,7 @@ fn test_viewport_rule<F>(css: &str, callback: F) where F: Fn(&Vec<ViewportDescriptorDeclaration>, &str) { - ::util::prefs::PREFS.set("layout.viewport.enabled", - ::util::prefs::PrefValue::Boolean(true)); + PREFS.set("layout.viewport.enabled", PrefValue::Boolean(true)); let stylesheet = stylesheet!(css, Author, Box::new(CSSErrorReporterTest)); let mut rule_count = 0; stylesheet.effective_viewport_rules(&device, |rule| { @@ -50,13 +51,11 @@ fn test_meta_viewport<F>(meta: &str, callback: F) where F: Fn(&Vec<ViewportDescriptorDeclaration>, &str) { if let Some(mut rule) = ViewportRule::from_meta(meta) { - use std::intrinsics::discriminant_value; - // from_meta uses a hash-map to collect the declarations, so we need to // sort them in a stable order for the tests rule.declarations.sort_by(|a, b| { - let a = unsafe { discriminant_value(&a.descriptor) }; - let b = unsafe { discriminant_value(&b.descriptor) }; + let a = a.descriptor.discriminant_value(); + let b = b.descriptor.discriminant_value(); a.cmp(&b) }); @@ -250,8 +249,7 @@ fn cascading_within_viewport_rule() { #[test] fn multiple_stylesheets_cascading() { - ::util::prefs::PREFS.set("layout.viewport.enabled", - ::util::prefs::PrefValue::Boolean(true)); + PREFS.set("layout.viewport.enabled", PrefValue::Boolean(true)); let device = Device::new(MediaType::Screen, TypedSize2D::new(800., 600.)); let error_reporter = CSSErrorReporterTest; let stylesheets = vec![ diff --git a/tests/unit/stylo/lib.rs b/tests/unit/stylo/lib.rs index d28f0663d0e..35fcdd01602 100644 --- a/tests/unit/stylo/lib.rs +++ b/tests/unit/stylo/lib.rs @@ -16,5 +16,8 @@ extern crate style_traits; mod sanity_checks; +#[path = "../../../ports/geckolib/stylesheet_loader.rs"] +mod stylesheet_loader; + mod servo_function_signatures; diff --git a/tests/wpt/metadata-css/css-backgrounds-3_dev/html4/background-331.htm.ini b/tests/wpt/metadata-css/css-backgrounds-3_dev/html4/background-331.htm.ini index aeae4c583a2..8d83039b0a6 100644 --- a/tests/wpt/metadata-css/css-backgrounds-3_dev/html4/background-331.htm.ini +++ b/tests/wpt/metadata-css/css-backgrounds-3_dev/html4/background-331.htm.ini @@ -6,3 +6,6 @@ [background_initial_color] expected: FAIL + [background_initial_position] + expected: FAIL + diff --git a/tests/wpt/metadata-css/css-backgrounds-3_dev/html4/background-333.htm.ini b/tests/wpt/metadata-css/css-backgrounds-3_dev/html4/background-333.htm.ini index 04fd52fd845..11c7900a2d9 100644 --- a/tests/wpt/metadata-css/css-backgrounds-3_dev/html4/background-333.htm.ini +++ b/tests/wpt/metadata-css/css-backgrounds-3_dev/html4/background-333.htm.ini @@ -6,3 +6,6 @@ [background_specified_color_color] expected: FAIL + [background_specified_color_position] + expected: FAIL + diff --git a/tests/wpt/metadata-css/css-transitions-1_dev/html/changing-while-transition.htm.ini b/tests/wpt/metadata-css/css-transitions-1_dev/html/changing-while-transition.htm.ini index 4e9f379b7f9..cf6048d1988 100644 --- a/tests/wpt/metadata-css/css-transitions-1_dev/html/changing-while-transition.htm.ini +++ b/tests/wpt/metadata-css/css-transitions-1_dev/html/changing-while-transition.htm.ini @@ -2,7 +2,3 @@ type: testharness [changing transition-property / values] expected: FAIL - - [changing transition-duration / values] - expected: FAIL - diff --git a/tests/wpt/metadata-css/css21_dev/html4/abspos-019.htm.ini b/tests/wpt/metadata-css/css21_dev/html4/abspos-019.htm.ini deleted file mode 100644 index e899657cbfd..00000000000 --- a/tests/wpt/metadata-css/css21_dev/html4/abspos-019.htm.ini +++ /dev/null @@ -1,3 +0,0 @@ -[abspos-019.htm] - type: reftest - expected: FAIL diff --git a/tests/wpt/metadata-css/css21_dev/html4/abspos-020.htm.ini b/tests/wpt/metadata-css/css21_dev/html4/abspos-020.htm.ini deleted file mode 100644 index f631c9486f7..00000000000 --- a/tests/wpt/metadata-css/css21_dev/html4/abspos-020.htm.ini +++ /dev/null @@ -1,3 +0,0 @@ -[abspos-020.htm] - type: reftest - expected: FAIL diff --git a/tests/wpt/metadata-css/css21_dev/html4/at-charset-001.htm.ini b/tests/wpt/metadata-css/css21_dev/html4/at-charset-001.htm.ini deleted file mode 100644 index 0a433e1c565..00000000000 --- a/tests/wpt/metadata-css/css21_dev/html4/at-charset-001.htm.ini +++ /dev/null @@ -1,3 +0,0 @@ -[at-charset-001.htm] - type: reftest - expected: FAIL diff --git a/tests/wpt/metadata-css/css21_dev/html4/at-charset-007.htm.ini b/tests/wpt/metadata-css/css21_dev/html4/at-charset-007.htm.ini deleted file mode 100644 index 0b114bb4226..00000000000 --- a/tests/wpt/metadata-css/css21_dev/html4/at-charset-007.htm.ini +++ /dev/null @@ -1,3 +0,0 @@ -[at-charset-007.htm] - type: reftest - expected: FAIL diff --git a/tests/wpt/metadata-css/css21_dev/html4/at-charset-008.htm.ini b/tests/wpt/metadata-css/css21_dev/html4/at-charset-008.htm.ini deleted file mode 100644 index 6761cde0201..00000000000 --- a/tests/wpt/metadata-css/css21_dev/html4/at-charset-008.htm.ini +++ /dev/null @@ -1,3 +0,0 @@ -[at-charset-008.htm] - type: reftest - expected: FAIL diff --git a/tests/wpt/metadata-css/css21_dev/html4/at-charset-009.htm.ini b/tests/wpt/metadata-css/css21_dev/html4/at-charset-009.htm.ini deleted file mode 100644 index 8fc7f684eac..00000000000 --- a/tests/wpt/metadata-css/css21_dev/html4/at-charset-009.htm.ini +++ /dev/null @@ -1,3 +0,0 @@ -[at-charset-009.htm] - type: reftest - expected: FAIL diff --git a/tests/wpt/metadata-css/css21_dev/html4/at-charset-012.htm.ini b/tests/wpt/metadata-css/css21_dev/html4/at-charset-012.htm.ini deleted file mode 100644 index 095028505c8..00000000000 --- a/tests/wpt/metadata-css/css21_dev/html4/at-charset-012.htm.ini +++ /dev/null @@ -1,3 +0,0 @@ -[at-charset-012.htm] - type: reftest - expected: FAIL diff --git a/tests/wpt/metadata-css/css21_dev/html4/at-charset-014.htm.ini b/tests/wpt/metadata-css/css21_dev/html4/at-charset-014.htm.ini deleted file mode 100644 index 869c7c53ab4..00000000000 --- a/tests/wpt/metadata-css/css21_dev/html4/at-charset-014.htm.ini +++ /dev/null @@ -1,3 +0,0 @@ -[at-charset-014.htm] - type: reftest - expected: FAIL diff --git a/tests/wpt/metadata-css/css21_dev/html4/at-charset-015.htm.ini b/tests/wpt/metadata-css/css21_dev/html4/at-charset-015.htm.ini deleted file mode 100644 index 5049e881c1a..00000000000 --- a/tests/wpt/metadata-css/css21_dev/html4/at-charset-015.htm.ini +++ /dev/null @@ -1,3 +0,0 @@ -[at-charset-015.htm] - type: reftest - expected: FAIL diff --git a/tests/wpt/metadata-css/css21_dev/html4/at-charset-016.htm.ini b/tests/wpt/metadata-css/css21_dev/html4/at-charset-016.htm.ini deleted file mode 100644 index 3b63a1c1f46..00000000000 --- a/tests/wpt/metadata-css/css21_dev/html4/at-charset-016.htm.ini +++ /dev/null @@ -1,3 +0,0 @@ -[at-charset-016.htm] - type: reftest - expected: FAIL diff --git a/tests/wpt/metadata-css/css21_dev/html4/at-charset-019.htm.ini b/tests/wpt/metadata-css/css21_dev/html4/at-charset-019.htm.ini deleted file mode 100644 index b1eed1ecff9..00000000000 --- a/tests/wpt/metadata-css/css21_dev/html4/at-charset-019.htm.ini +++ /dev/null @@ -1,3 +0,0 @@ -[at-charset-019.htm] - type: reftest - expected: FAIL diff --git a/tests/wpt/metadata-css/css21_dev/html4/at-charset-020.htm.ini b/tests/wpt/metadata-css/css21_dev/html4/at-charset-020.htm.ini deleted file mode 100644 index 0503e133961..00000000000 --- a/tests/wpt/metadata-css/css21_dev/html4/at-charset-020.htm.ini +++ /dev/null @@ -1,3 +0,0 @@ -[at-charset-020.htm] - type: reftest - expected: FAIL diff --git a/tests/wpt/metadata-css/css21_dev/html4/at-charset-021.htm.ini b/tests/wpt/metadata-css/css21_dev/html4/at-charset-021.htm.ini deleted file mode 100644 index e8a1c3f0258..00000000000 --- a/tests/wpt/metadata-css/css21_dev/html4/at-charset-021.htm.ini +++ /dev/null @@ -1,3 +0,0 @@ -[at-charset-021.htm] - type: reftest - expected: FAIL diff --git a/tests/wpt/metadata-css/css21_dev/html4/at-charset-024.htm.ini b/tests/wpt/metadata-css/css21_dev/html4/at-charset-024.htm.ini deleted file mode 100644 index 852ecb54c82..00000000000 --- a/tests/wpt/metadata-css/css21_dev/html4/at-charset-024.htm.ini +++ /dev/null @@ -1,3 +0,0 @@ -[at-charset-024.htm] - type: reftest - expected: FAIL diff --git a/tests/wpt/metadata-css/css21_dev/html4/at-charset-025.htm.ini b/tests/wpt/metadata-css/css21_dev/html4/at-charset-025.htm.ini deleted file mode 100644 index dbeb381460f..00000000000 --- a/tests/wpt/metadata-css/css21_dev/html4/at-charset-025.htm.ini +++ /dev/null @@ -1,3 +0,0 @@ -[at-charset-025.htm] - type: reftest - expected: FAIL diff --git a/tests/wpt/metadata-css/css21_dev/html4/at-charset-026.htm.ini b/tests/wpt/metadata-css/css21_dev/html4/at-charset-026.htm.ini deleted file mode 100644 index 863ce667cfa..00000000000 --- a/tests/wpt/metadata-css/css21_dev/html4/at-charset-026.htm.ini +++ /dev/null @@ -1,3 +0,0 @@ -[at-charset-026.htm] - type: reftest - expected: FAIL diff --git a/tests/wpt/metadata-css/css21_dev/html4/at-charset-027.htm.ini b/tests/wpt/metadata-css/css21_dev/html4/at-charset-027.htm.ini deleted file mode 100644 index 43a7809a606..00000000000 --- a/tests/wpt/metadata-css/css21_dev/html4/at-charset-027.htm.ini +++ /dev/null @@ -1,3 +0,0 @@ -[at-charset-027.htm] - type: reftest - expected: FAIL diff --git a/tests/wpt/metadata-css/css21_dev/html4/at-charset-028.htm.ini b/tests/wpt/metadata-css/css21_dev/html4/at-charset-028.htm.ini deleted file mode 100644 index ebf27be93de..00000000000 --- a/tests/wpt/metadata-css/css21_dev/html4/at-charset-028.htm.ini +++ /dev/null @@ -1,3 +0,0 @@ -[at-charset-028.htm] - type: reftest - expected: FAIL diff --git a/tests/wpt/metadata-css/css21_dev/html4/at-charset-029.htm.ini b/tests/wpt/metadata-css/css21_dev/html4/at-charset-029.htm.ini deleted file mode 100644 index 99eee9d118e..00000000000 --- a/tests/wpt/metadata-css/css21_dev/html4/at-charset-029.htm.ini +++ /dev/null @@ -1,3 +0,0 @@ -[at-charset-029.htm] - type: reftest - expected: FAIL diff --git a/tests/wpt/metadata-css/css21_dev/html4/at-charset-030.htm.ini b/tests/wpt/metadata-css/css21_dev/html4/at-charset-030.htm.ini deleted file mode 100644 index 7bb89c7554c..00000000000 --- a/tests/wpt/metadata-css/css21_dev/html4/at-charset-030.htm.ini +++ /dev/null @@ -1,3 +0,0 @@ -[at-charset-030.htm] - type: reftest - expected: FAIL diff --git a/tests/wpt/metadata-css/css21_dev/html4/at-charset-040.htm.ini b/tests/wpt/metadata-css/css21_dev/html4/at-charset-040.htm.ini deleted file mode 100644 index f7815fd6097..00000000000 --- a/tests/wpt/metadata-css/css21_dev/html4/at-charset-040.htm.ini +++ /dev/null @@ -1,3 +0,0 @@ -[at-charset-040.htm] - type: reftest - expected: FAIL diff --git a/tests/wpt/metadata-css/css21_dev/html4/at-charset-041.htm.ini b/tests/wpt/metadata-css/css21_dev/html4/at-charset-041.htm.ini deleted file mode 100644 index 4d4c2c20a7b..00000000000 --- a/tests/wpt/metadata-css/css21_dev/html4/at-charset-041.htm.ini +++ /dev/null @@ -1,3 +0,0 @@ -[at-charset-041.htm] - type: reftest - expected: FAIL diff --git a/tests/wpt/metadata-css/css21_dev/html4/at-charset-042.htm.ini b/tests/wpt/metadata-css/css21_dev/html4/at-charset-042.htm.ini deleted file mode 100644 index b791ae70d87..00000000000 --- a/tests/wpt/metadata-css/css21_dev/html4/at-charset-042.htm.ini +++ /dev/null @@ -1,3 +0,0 @@ -[at-charset-042.htm] - type: reftest - expected: FAIL diff --git a/tests/wpt/metadata-css/css21_dev/html4/at-charset-043.htm.ini b/tests/wpt/metadata-css/css21_dev/html4/at-charset-043.htm.ini deleted file mode 100644 index f7aaa086ec8..00000000000 --- a/tests/wpt/metadata-css/css21_dev/html4/at-charset-043.htm.ini +++ /dev/null @@ -1,3 +0,0 @@ -[at-charset-043.htm] - type: reftest - expected: FAIL diff --git a/tests/wpt/metadata-css/css21_dev/html4/at-charset-044.htm.ini b/tests/wpt/metadata-css/css21_dev/html4/at-charset-044.htm.ini deleted file mode 100644 index 2e344f7582b..00000000000 --- a/tests/wpt/metadata-css/css21_dev/html4/at-charset-044.htm.ini +++ /dev/null @@ -1,3 +0,0 @@ -[at-charset-044.htm] - type: reftest - expected: FAIL diff --git a/tests/wpt/metadata-css/css21_dev/html4/at-charset-045.htm.ini b/tests/wpt/metadata-css/css21_dev/html4/at-charset-045.htm.ini deleted file mode 100644 index 58ec1784998..00000000000 --- a/tests/wpt/metadata-css/css21_dev/html4/at-charset-045.htm.ini +++ /dev/null @@ -1,3 +0,0 @@ -[at-charset-045.htm] - type: reftest - expected: FAIL diff --git a/tests/wpt/metadata-css/css21_dev/html4/at-charset-046.htm.ini b/tests/wpt/metadata-css/css21_dev/html4/at-charset-046.htm.ini deleted file mode 100644 index 7f6c169cc3c..00000000000 --- a/tests/wpt/metadata-css/css21_dev/html4/at-charset-046.htm.ini +++ /dev/null @@ -1,3 +0,0 @@ -[at-charset-046.htm] - type: reftest - expected: FAIL diff --git a/tests/wpt/metadata-css/css21_dev/html4/at-charset-047.htm.ini b/tests/wpt/metadata-css/css21_dev/html4/at-charset-047.htm.ini deleted file mode 100644 index 1f2c8c5fbee..00000000000 --- a/tests/wpt/metadata-css/css21_dev/html4/at-charset-047.htm.ini +++ /dev/null @@ -1,3 +0,0 @@ -[at-charset-047.htm] - type: reftest - expected: FAIL diff --git a/tests/wpt/metadata-css/css21_dev/html4/at-charset-048.htm.ini b/tests/wpt/metadata-css/css21_dev/html4/at-charset-048.htm.ini deleted file mode 100644 index 060244c08b5..00000000000 --- a/tests/wpt/metadata-css/css21_dev/html4/at-charset-048.htm.ini +++ /dev/null @@ -1,3 +0,0 @@ -[at-charset-048.htm] - type: reftest - expected: FAIL diff --git a/tests/wpt/metadata-css/css21_dev/html4/at-charset-053.htm.ini b/tests/wpt/metadata-css/css21_dev/html4/at-charset-053.htm.ini deleted file mode 100644 index 903080bb09b..00000000000 --- a/tests/wpt/metadata-css/css21_dev/html4/at-charset-053.htm.ini +++ /dev/null @@ -1,3 +0,0 @@ -[at-charset-053.htm] - type: reftest - expected: FAIL diff --git a/tests/wpt/metadata-css/css21_dev/html4/at-charset-060.htm.ini b/tests/wpt/metadata-css/css21_dev/html4/at-charset-060.htm.ini deleted file mode 100644 index 76eb1b5c2f4..00000000000 --- a/tests/wpt/metadata-css/css21_dev/html4/at-charset-060.htm.ini +++ /dev/null @@ -1,3 +0,0 @@ -[at-charset-060.htm] - type: reftest - expected: FAIL diff --git a/tests/wpt/metadata-css/css21_dev/html4/at-import-002.htm.ini b/tests/wpt/metadata-css/css21_dev/html4/at-import-002.htm.ini deleted file mode 100644 index e6c008e9939..00000000000 --- a/tests/wpt/metadata-css/css21_dev/html4/at-import-002.htm.ini +++ /dev/null @@ -1,3 +0,0 @@ -[at-import-002.htm] - type: reftest - expected: FAIL diff --git a/tests/wpt/metadata-css/css21_dev/html4/at-import-003.htm.ini b/tests/wpt/metadata-css/css21_dev/html4/at-import-003.htm.ini deleted file mode 100644 index 499e7192843..00000000000 --- a/tests/wpt/metadata-css/css21_dev/html4/at-import-003.htm.ini +++ /dev/null @@ -1,3 +0,0 @@ -[at-import-003.htm] - type: reftest - expected: FAIL diff --git a/tests/wpt/metadata-css/css21_dev/html4/at-import-005.htm.ini b/tests/wpt/metadata-css/css21_dev/html4/at-import-005.htm.ini deleted file mode 100644 index 0f407b5eace..00000000000 --- a/tests/wpt/metadata-css/css21_dev/html4/at-import-005.htm.ini +++ /dev/null @@ -1,3 +0,0 @@ -[at-import-005.htm] - type: reftest - expected: FAIL diff --git a/tests/wpt/metadata-css/css21_dev/html4/at-import-006.htm.ini b/tests/wpt/metadata-css/css21_dev/html4/at-import-006.htm.ini deleted file mode 100644 index a48e83e2109..00000000000 --- a/tests/wpt/metadata-css/css21_dev/html4/at-import-006.htm.ini +++ /dev/null @@ -1,3 +0,0 @@ -[at-import-006.htm] - type: reftest - expected: FAIL diff --git a/tests/wpt/metadata-css/css21_dev/html4/at-import-007.htm.ini b/tests/wpt/metadata-css/css21_dev/html4/at-import-007.htm.ini deleted file mode 100644 index d288b277cfc..00000000000 --- a/tests/wpt/metadata-css/css21_dev/html4/at-import-007.htm.ini +++ /dev/null @@ -1,3 +0,0 @@ -[at-import-007.htm] - type: reftest - expected: FAIL diff --git a/tests/wpt/metadata-css/css21_dev/html4/at-keywords-000.htm.ini b/tests/wpt/metadata-css/css21_dev/html4/at-keywords-000.htm.ini deleted file mode 100644 index dcc06995155..00000000000 --- a/tests/wpt/metadata-css/css21_dev/html4/at-keywords-000.htm.ini +++ /dev/null @@ -1,3 +0,0 @@ -[at-keywords-000.htm] - type: reftest - expected: FAIL diff --git a/tests/wpt/metadata-css/css21_dev/html4/at-rule-005.htm.ini b/tests/wpt/metadata-css/css21_dev/html4/at-rule-005.htm.ini deleted file mode 100644 index 38613180fb3..00000000000 --- a/tests/wpt/metadata-css/css21_dev/html4/at-rule-005.htm.ini +++ /dev/null @@ -1,3 +0,0 @@ -[at-rule-005.htm] - type: reftest - expected: FAIL diff --git a/tests/wpt/metadata-css/css21_dev/html4/at-rule-010.htm.ini b/tests/wpt/metadata-css/css21_dev/html4/at-rule-010.htm.ini deleted file mode 100644 index db7f13e3e70..00000000000 --- a/tests/wpt/metadata-css/css21_dev/html4/at-rule-010.htm.ini +++ /dev/null @@ -1,3 +0,0 @@ -[at-rule-010.htm] - type: reftest - expected: FAIL diff --git a/tests/wpt/metadata-css/css21_dev/html4/block-replaced-height-004.htm.ini b/tests/wpt/metadata-css/css21_dev/html4/block-replaced-height-004.htm.ini deleted file mode 100644 index 77d7591b943..00000000000 --- a/tests/wpt/metadata-css/css21_dev/html4/block-replaced-height-004.htm.ini +++ /dev/null @@ -1,3 +0,0 @@ -[block-replaced-height-004.htm] - type: reftest - expected: FAIL diff --git a/tests/wpt/metadata-css/css21_dev/html4/block-replaced-height-005.htm.ini b/tests/wpt/metadata-css/css21_dev/html4/block-replaced-height-005.htm.ini deleted file mode 100644 index 809b647e787..00000000000 --- a/tests/wpt/metadata-css/css21_dev/html4/block-replaced-height-005.htm.ini +++ /dev/null @@ -1,3 +0,0 @@ -[block-replaced-height-005.htm] - type: reftest - expected: FAIL diff --git a/tests/wpt/metadata-css/css21_dev/html4/block-replaced-height-007.htm.ini b/tests/wpt/metadata-css/css21_dev/html4/block-replaced-height-007.htm.ini deleted file mode 100644 index 4e7ca96d91b..00000000000 --- a/tests/wpt/metadata-css/css21_dev/html4/block-replaced-height-007.htm.ini +++ /dev/null @@ -1,3 +0,0 @@ -[block-replaced-height-007.htm] - type: reftest - expected: FAIL diff --git a/tests/wpt/metadata-css/css21_dev/html4/c11-import-000.htm.ini b/tests/wpt/metadata-css/css21_dev/html4/c11-import-000.htm.ini deleted file mode 100644 index 91cf2f4f4ad..00000000000 --- a/tests/wpt/metadata-css/css21_dev/html4/c11-import-000.htm.ini +++ /dev/null @@ -1,3 +0,0 @@ -[c11-import-000.htm] - type: reftest - expected: FAIL diff --git a/tests/wpt/metadata-css/css21_dev/html4/c43-rpl-bbx-002.htm.ini b/tests/wpt/metadata-css/css21_dev/html4/c43-rpl-bbx-002.htm.ini deleted file mode 100644 index faf1586d11f..00000000000 --- a/tests/wpt/metadata-css/css21_dev/html4/c43-rpl-bbx-002.htm.ini +++ /dev/null @@ -1,3 +0,0 @@ -[c43-rpl-bbx-002.htm] - type: reftest - expected: FAIL diff --git a/tests/wpt/metadata-css/css21_dev/html4/c44-ln-box-003.htm.ini b/tests/wpt/metadata-css/css21_dev/html4/c44-ln-box-003.htm.ini deleted file mode 100644 index 1606d37ec43..00000000000 --- a/tests/wpt/metadata-css/css21_dev/html4/c44-ln-box-003.htm.ini +++ /dev/null @@ -1,3 +0,0 @@ -[c44-ln-box-003.htm] - type: reftest - expected: FAIL diff --git a/tests/wpt/metadata-css/css21_dev/html4/cascade-012.htm.ini b/tests/wpt/metadata-css/css21_dev/html4/cascade-012.htm.ini deleted file mode 100644 index eb899ae0891..00000000000 --- a/tests/wpt/metadata-css/css21_dev/html4/cascade-012.htm.ini +++ /dev/null @@ -1,3 +0,0 @@ -[cascade-012.htm] - type: reftest - expected: FAIL diff --git a/tests/wpt/metadata-css/css21_dev/html4/core-syntax-009.htm.ini b/tests/wpt/metadata-css/css21_dev/html4/core-syntax-009.htm.ini deleted file mode 100644 index 7c398b6a6dd..00000000000 --- a/tests/wpt/metadata-css/css21_dev/html4/core-syntax-009.htm.ini +++ /dev/null @@ -1,3 +0,0 @@ -[core-syntax-009.htm] - type: reftest - expected: FAIL diff --git a/tests/wpt/metadata-css/css21_dev/html4/eof-005.htm.ini b/tests/wpt/metadata-css/css21_dev/html4/eof-005.htm.ini deleted file mode 100644 index 7f7d0a6ba56..00000000000 --- a/tests/wpt/metadata-css/css21_dev/html4/eof-005.htm.ini +++ /dev/null @@ -1,3 +0,0 @@ -[eof-005.htm] - type: reftest - expected: FAIL diff --git a/tests/wpt/metadata-css/css21_dev/html4/eof-006.htm.ini b/tests/wpt/metadata-css/css21_dev/html4/eof-006.htm.ini deleted file mode 100644 index 09102883ad8..00000000000 --- a/tests/wpt/metadata-css/css21_dev/html4/eof-006.htm.ini +++ /dev/null @@ -1,3 +0,0 @@ -[eof-006.htm] - type: reftest - expected: FAIL diff --git a/tests/wpt/metadata-css/css21_dev/html4/float-replaced-height-004.htm.ini b/tests/wpt/metadata-css/css21_dev/html4/float-replaced-height-004.htm.ini deleted file mode 100644 index 79e9eef8833..00000000000 --- a/tests/wpt/metadata-css/css21_dev/html4/float-replaced-height-004.htm.ini +++ /dev/null @@ -1,3 +0,0 @@ -[float-replaced-height-004.htm] - type: reftest - expected: FAIL diff --git a/tests/wpt/metadata-css/css21_dev/html4/float-replaced-height-005.htm.ini b/tests/wpt/metadata-css/css21_dev/html4/float-replaced-height-005.htm.ini deleted file mode 100644 index 2c55c9b3713..00000000000 --- a/tests/wpt/metadata-css/css21_dev/html4/float-replaced-height-005.htm.ini +++ /dev/null @@ -1,3 +0,0 @@ -[float-replaced-height-005.htm] - type: reftest - expected: FAIL diff --git a/tests/wpt/metadata-css/css21_dev/html4/float-replaced-height-007.htm.ini b/tests/wpt/metadata-css/css21_dev/html4/float-replaced-height-007.htm.ini deleted file mode 100644 index 8a2cfba07f0..00000000000 --- a/tests/wpt/metadata-css/css21_dev/html4/float-replaced-height-007.htm.ini +++ /dev/null @@ -1,3 +0,0 @@ -[float-replaced-height-007.htm] - type: reftest - expected: FAIL diff --git a/tests/wpt/metadata-css/css21_dev/html4/inline-block-replaced-height-004.htm.ini b/tests/wpt/metadata-css/css21_dev/html4/inline-block-replaced-height-004.htm.ini deleted file mode 100644 index 1562237ce6e..00000000000 --- a/tests/wpt/metadata-css/css21_dev/html4/inline-block-replaced-height-004.htm.ini +++ /dev/null @@ -1,3 +0,0 @@ -[inline-block-replaced-height-004.htm] - type: reftest - expected: FAIL diff --git a/tests/wpt/metadata-css/css21_dev/html4/inline-block-replaced-height-005.htm.ini b/tests/wpt/metadata-css/css21_dev/html4/inline-block-replaced-height-005.htm.ini deleted file mode 100644 index 5932e779dc7..00000000000 --- a/tests/wpt/metadata-css/css21_dev/html4/inline-block-replaced-height-005.htm.ini +++ /dev/null @@ -1,3 +0,0 @@ -[inline-block-replaced-height-005.htm] - type: reftest - expected: FAIL diff --git a/tests/wpt/metadata-css/css21_dev/html4/inline-block-replaced-height-007.htm.ini b/tests/wpt/metadata-css/css21_dev/html4/inline-block-replaced-height-007.htm.ini deleted file mode 100644 index 5fbf45656e7..00000000000 --- a/tests/wpt/metadata-css/css21_dev/html4/inline-block-replaced-height-007.htm.ini +++ /dev/null @@ -1,3 +0,0 @@ -[inline-block-replaced-height-007.htm] - type: reftest - expected: FAIL diff --git a/tests/wpt/metadata-css/css21_dev/html4/max-height-percentage-003.htm.ini b/tests/wpt/metadata-css/css21_dev/html4/max-height-percentage-003.htm.ini deleted file mode 100644 index 0b2d7e75a54..00000000000 --- a/tests/wpt/metadata-css/css21_dev/html4/max-height-percentage-003.htm.ini +++ /dev/null @@ -1,3 +0,0 @@ -[max-height-percentage-003.htm] - type: reftest - expected: FAIL diff --git a/tests/wpt/metadata-css/css21_dev/html4/media-dependency-002.htm.ini b/tests/wpt/metadata-css/css21_dev/html4/media-dependency-002.htm.ini deleted file mode 100644 index 372354710d3..00000000000 --- a/tests/wpt/metadata-css/css21_dev/html4/media-dependency-002.htm.ini +++ /dev/null @@ -1,3 +0,0 @@ -[media-dependency-002.htm] - type: reftest - expected: FAIL diff --git a/tests/wpt/metadata-css/css21_dev/html4/media-dependency-004.htm.ini b/tests/wpt/metadata-css/css21_dev/html4/media-dependency-004.htm.ini deleted file mode 100644 index a9d7980f8af..00000000000 --- a/tests/wpt/metadata-css/css21_dev/html4/media-dependency-004.htm.ini +++ /dev/null @@ -1,3 +0,0 @@ -[media-dependency-004.htm] - type: reftest - expected: FAIL diff --git a/tests/wpt/metadata-css/css21_dev/html4/media-dependency-005.htm.ini b/tests/wpt/metadata-css/css21_dev/html4/media-dependency-005.htm.ini deleted file mode 100644 index a4860d3d971..00000000000 --- a/tests/wpt/metadata-css/css21_dev/html4/media-dependency-005.htm.ini +++ /dev/null @@ -1,3 +0,0 @@ -[media-dependency-005.htm] - type: reftest - expected: FAIL diff --git a/tests/wpt/metadata-css/css21_dev/html4/uri-001.htm.ini b/tests/wpt/metadata-css/css21_dev/html4/uri-001.htm.ini deleted file mode 100644 index 463a8ada21e..00000000000 --- a/tests/wpt/metadata-css/css21_dev/html4/uri-001.htm.ini +++ /dev/null @@ -1,3 +0,0 @@ -[uri-001.htm] - type: reftest - expected: FAIL diff --git a/tests/wpt/metadata-css/cssom-1_dev/html/cssimportrule.htm.ini b/tests/wpt/metadata-css/cssom-1_dev/html/cssimportrule.htm.ini index b09eb56a50f..b6f619dbf5f 100644 --- a/tests/wpt/metadata-css/cssom-1_dev/html/cssimportrule.htm.ini +++ b/tests/wpt/metadata-css/cssom-1_dev/html/cssimportrule.htm.ini @@ -1,11 +1,5 @@ [cssimportrule.htm] type: testharness - [CSSRule and CSSImportRule types] - expected: FAIL - - [Type of CSSRule#type and constant values] - expected: FAIL - [Existence and writability of CSSRule attributes] expected: FAIL diff --git a/tests/wpt/metadata-css/cssom-1_dev/html/cssstyledeclaration-mutability.htm.ini b/tests/wpt/metadata-css/cssom-1_dev/html/cssstyledeclaration-mutability.htm.ini deleted file mode 100644 index de66afda62d..00000000000 --- a/tests/wpt/metadata-css/cssom-1_dev/html/cssstyledeclaration-mutability.htm.ini +++ /dev/null @@ -1,5 +0,0 @@ -[cssstyledeclaration-mutability.htm] - type: testharness - [StyleSheet's CSSStyleDeclaration is mutable] - expected: FAIL - diff --git a/tests/wpt/metadata-css/cssom-1_dev/html/index-003.htm.ini b/tests/wpt/metadata-css/cssom-1_dev/html/index-003.htm.ini index e6f60a1c5f5..066d022415b 100644 --- a/tests/wpt/metadata-css/cssom-1_dev/html/index-003.htm.ini +++ b/tests/wpt/metadata-css/cssom-1_dev/html/index-003.htm.ini @@ -1,8 +1,5 @@ [index-003.htm] type: testharness - [@import rule is expected to be @import url("main.css")] - expected: FAIL - [page rule is expected to be @page :first] expected: FAIL diff --git a/tests/wpt/metadata-css/cssom-1_dev/html/interfaces.htm.ini b/tests/wpt/metadata-css/cssom-1_dev/html/interfaces.htm.ini index 7747a24e315..820da0ee018 100644 --- a/tests/wpt/metadata-css/cssom-1_dev/html/interfaces.htm.ini +++ b/tests/wpt/metadata-css/cssom-1_dev/html/interfaces.htm.ini @@ -120,30 +120,12 @@ [CSSStyleRule interface: attribute selectorText] expected: FAIL - [CSSStyleRule interface: attribute style] - expected: FAIL - [CSSStyleRule interface: style_element.sheet.cssRules[0\] must inherit property "selectorText" with the proper type (0)] expected: FAIL - [CSSStyleRule interface: style_element.sheet.cssRules[0\] must inherit property "style" with the proper type (1)] - expected: FAIL - [CSSRule interface: style_element.sheet.cssRules[0\] must inherit property "parentRule" with the proper type (10)] expected: FAIL - [CSSImportRule interface: existence and properties of interface object] - expected: FAIL - - [CSSImportRule interface object length] - expected: FAIL - - [CSSImportRule interface: existence and properties of interface prototype object] - expected: FAIL - - [CSSImportRule interface: existence and properties of interface prototype object's "constructor" property] - expected: FAIL - [CSSImportRule interface: attribute href] expected: FAIL diff --git a/tests/wpt/metadata/MANIFEST.json b/tests/wpt/metadata/MANIFEST.json index 3e6746c6922..11844dae048 100644 --- a/tests/wpt/metadata/MANIFEST.json +++ b/tests/wpt/metadata/MANIFEST.json @@ -39677,6 +39677,12 @@ "deleted_reftests": {}, "items": { "testharness": { + "css-values/unset-value-storage.html": [ + { + "path": "css-values/unset-value-storage.html", + "url": "/css-values/unset-value-storage.html" + } + ], "cssom/CSSKeyframesRule.html": [ { "path": "cssom/CSSKeyframesRule.html", @@ -39695,6 +39701,12 @@ "url": "/cssom/CSSRuleList.html" } ], + "cssom/CSSStyleRule.html": [ + { + "path": "cssom/CSSStyleRule.html", + "url": "/cssom/CSSStyleRule.html" + } + ], "cssom/CSSStyleSheet.html": [ { "path": "cssom/CSSStyleSheet.html", @@ -39719,12 +39731,24 @@ "url": "/cssom/shorthand-serialization.html" } ], + "fetch/api/request/request-bad-port.html": [ + { + "path": "fetch/api/request/request-bad-port.html", + "url": "/fetch/api/request/request-bad-port.html" + } + ], "html/semantics/forms/form-submission-0/submit-entity-body.html": [ { "path": "html/semantics/forms/form-submission-0/submit-entity-body.html", "timeout": "long", "url": "/html/semantics/forms/form-submission-0/submit-entity-body.html" } + ], + "html/semantics/forms/the-select-element/select-value.html": [ + { + "path": "html/semantics/forms/the-select-element/select-value.html", + "url": "/html/semantics/forms/the-select-element/select-value.html" + } ] } }, diff --git a/tests/wpt/metadata/fetch/api/request/multi-globals/url-parsing.html.ini b/tests/wpt/metadata/fetch/api/request/multi-globals/url-parsing.html.ini deleted file mode 100644 index a6e5c4f239b..00000000000 --- a/tests/wpt/metadata/fetch/api/request/multi-globals/url-parsing.html.ini +++ /dev/null @@ -1,5 +0,0 @@ -[url-parsing.html] - type: testharness - [should parse the URL relative to the current settings object] - expected: FAIL - diff --git a/tests/wpt/metadata/fetch/api/response/multi-globals/url-parsing.html.ini b/tests/wpt/metadata/fetch/api/response/multi-globals/url-parsing.html.ini deleted file mode 100644 index ebf5ccc16d2..00000000000 --- a/tests/wpt/metadata/fetch/api/response/multi-globals/url-parsing.html.ini +++ /dev/null @@ -1,5 +0,0 @@ -[url-parsing.html] - type: testharness - [should parse the redirect Location URL relative to the current settings object] - expected: FAIL - diff --git a/tests/wpt/metadata/fetch/nosniff/stylesheet.html.ini b/tests/wpt/metadata/fetch/nosniff/stylesheet.html.ini new file mode 100644 index 00000000000..7b0678423d1 --- /dev/null +++ b/tests/wpt/metadata/fetch/nosniff/stylesheet.html.ini @@ -0,0 +1,14 @@ +[stylesheet.html] + type: testharness + [URL query: ] + expected: FAIL + + [URL query: ?type=] + expected: FAIL + + [URL query: ?type=x] + expected: FAIL + + [URL query: ?type=x/x] + expected: FAIL + diff --git a/tests/wpt/metadata/html/semantics/document-metadata/the-link-element/link-style-error-01.html.ini b/tests/wpt/metadata/html/semantics/document-metadata/the-link-element/link-style-error-01.html.ini new file mode 100644 index 00000000000..ed2ecc503bb --- /dev/null +++ b/tests/wpt/metadata/html/semantics/document-metadata/the-link-element/link-style-error-01.html.ini @@ -0,0 +1,5 @@ +[link-style-error-01.html] + type: testharness + [Should get an error event for a text/plain response.] + expected: FAIL + diff --git a/tests/wpt/metadata/html/semantics/document-metadata/the-style-element/style_events.html.ini b/tests/wpt/metadata/html/semantics/document-metadata/the-style-element/style_events.html.ini deleted file mode 100644 index bf45e5bd993..00000000000 --- a/tests/wpt/metadata/html/semantics/document-metadata/the-style-element/style_events.html.ini +++ /dev/null @@ -1,9 +0,0 @@ -[style_events.html] - type: testharness - expected: TIMEOUT - [If the style is loaded successfully, the 'load' event must be fired] - expected: NOTRUN - - [If the style is loaded unsuccessfully, the 'error' event must be fired] - expected: NOTRUN - diff --git a/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/106-import.html.ini b/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/106-import.html.ini deleted file mode 100644 index e138b39ddec..00000000000 --- a/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/106-import.html.ini +++ /dev/null @@ -1,5 +0,0 @@ -[106-import.html] - type: testharness - [ scheduler: stylesheets blocking scripts] - expected: FAIL - diff --git a/tests/wpt/metadata/webgl/conformance-1.0.3/conformance/reading/read-pixels-test.html.ini b/tests/wpt/metadata/webgl/conformance-1.0.3/conformance/reading/read-pixels-test.html.ini index b5f47e0e275..78f5aa7b940 100644 --- a/tests/wpt/metadata/webgl/conformance-1.0.3/conformance/reading/read-pixels-test.html.ini +++ b/tests/wpt/metadata/webgl/conformance-1.0.3/conformance/reading/read-pixels-test.html.ini @@ -1,3 +1,5 @@ [read-pixels-test.html] type: testharness - expected: CRASH + expected: TIMEOUT + bug: https://github.com/servo/servo/issues/14380 + diff --git a/tests/wpt/mozilla/meta/MANIFEST.json b/tests/wpt/mozilla/meta/MANIFEST.json index e91bdccb049..e5f7738ba93 100644 --- a/tests/wpt/mozilla/meta/MANIFEST.json +++ b/tests/wpt/mozilla/meta/MANIFEST.json @@ -6510,6 +6510,18 @@ "url": "/_mozilla/mozilla/table_valign_uneven_height.html" } ], + "mozilla/textarea_placeholder.html": [ + { + "path": "mozilla/textarea_placeholder.html", + "references": [ + [ + "/_mozilla/mozilla/textarea_placeholder_ref.html", + "==" + ] + ], + "url": "/_mozilla/mozilla/textarea_placeholder.html" + } + ], "mozilla/webgl/clearcolor.html": [ { "path": "mozilla/webgl/clearcolor.html", @@ -6638,6 +6650,12 @@ "url": "/_mozilla/css/float_relative_to_position.html" } ], + "css/import_serialization.html": [ + { + "path": "css/import_serialization.html", + "url": "/_mozilla/css/import_serialization.html" + } + ], "css/matchMedia.html": [ { "path": "css/matchMedia.html", @@ -6746,6 +6764,12 @@ "url": "/_mozilla/mozilla/binding_keyword.html" } ], + "mozilla/bluetooth/advertisingEvent/watchAdvertisements-succeeds.html": [ + { + "path": "mozilla/bluetooth/advertisingEvent/watchAdvertisements-succeeds.html", + "url": "/_mozilla/mozilla/bluetooth/advertisingEvent/watchAdvertisements-succeeds.html" + } + ], "mozilla/bluetooth/connect/connection-succeeds.html": [ { "path": "mozilla/bluetooth/connect/connection-succeeds.html", @@ -6782,6 +6806,12 @@ "url": "/_mozilla/mozilla/bluetooth/disconnect/disconnect-twice-in-a-row.html" } ], + "mozilla/bluetooth/disconnect/event-is-fired.html": [ + { + "path": "mozilla/bluetooth/disconnect/event-is-fired.html", + "url": "/_mozilla/mozilla/bluetooth/disconnect/event-is-fired.html" + } + ], "mozilla/bluetooth/getCharacteristic/blocklisted-characteristic.html": [ { "path": "mozilla/bluetooth/getCharacteristic/blocklisted-characteristic.html", @@ -6818,6 +6848,18 @@ "url": "/_mozilla/mozilla/bluetooth/getCharacteristic/disconnect-called-during.html" } ], + "mozilla/bluetooth/getCharacteristic/disconnect-invalidates-object.html": [ + { + "path": "mozilla/bluetooth/getCharacteristic/disconnect-invalidates-object.html", + "url": "/_mozilla/mozilla/bluetooth/getCharacteristic/disconnect-invalidates-object.html" + } + ], + "mozilla/bluetooth/getCharacteristic/get-different-characteristic-after-reconnection.html": [ + { + "path": "mozilla/bluetooth/getCharacteristic/get-different-characteristic-after-reconnection.html", + "url": "/_mozilla/mozilla/bluetooth/getCharacteristic/get-different-characteristic-after-reconnection.html" + } + ], "mozilla/bluetooth/getCharacteristic/get-same-characteristic.html": [ { "path": "mozilla/bluetooth/getCharacteristic/get-same-characteristic.html", @@ -6830,6 +6872,12 @@ "url": "/_mozilla/mozilla/bluetooth/getCharacteristic/invalid-characteristic-name.html" } ], + "mozilla/bluetooth/getCharacteristic/reconnect-during.html": [ + { + "path": "mozilla/bluetooth/getCharacteristic/reconnect-during.html", + "url": "/_mozilla/mozilla/bluetooth/getCharacteristic/reconnect-during.html" + } + ], "mozilla/bluetooth/getCharacteristic/service-is-removed.html": [ { "path": "mozilla/bluetooth/getCharacteristic/service-is-removed.html", @@ -6914,6 +6962,18 @@ "url": "/_mozilla/mozilla/bluetooth/getCharacteristics/disconnect-called-during.html" } ], + "mozilla/bluetooth/getCharacteristics/disconnect-invalidates-objects.html": [ + { + "path": "mozilla/bluetooth/getCharacteristics/disconnect-invalidates-objects.html", + "url": "/_mozilla/mozilla/bluetooth/getCharacteristics/disconnect-invalidates-objects.html" + } + ], + "mozilla/bluetooth/getCharacteristics/get-different-characteristics-after-reconnection.html": [ + { + "path": "mozilla/bluetooth/getCharacteristics/get-different-characteristics-after-reconnection.html", + "url": "/_mozilla/mozilla/bluetooth/getCharacteristics/get-different-characteristics-after-reconnection.html" + } + ], "mozilla/bluetooth/getCharacteristics/get-same-characteristics.html": [ { "path": "mozilla/bluetooth/getCharacteristics/get-same-characteristics.html", @@ -6980,6 +7040,18 @@ "url": "/_mozilla/mozilla/bluetooth/getDescriptor/disconnect-called-during.html" } ], + "mozilla/bluetooth/getDescriptor/disconnect-invalidates-object.html": [ + { + "path": "mozilla/bluetooth/getDescriptor/disconnect-invalidates-object.html", + "url": "/_mozilla/mozilla/bluetooth/getDescriptor/disconnect-invalidates-object.html" + } + ], + "mozilla/bluetooth/getDescriptor/get-different-descriptor-after-reconnection.html": [ + { + "path": "mozilla/bluetooth/getDescriptor/get-different-descriptor-after-reconnection.html", + "url": "/_mozilla/mozilla/bluetooth/getDescriptor/get-different-descriptor-after-reconnection.html" + } + ], "mozilla/bluetooth/getDescriptor/get-same-descriptor.html": [ { "path": "mozilla/bluetooth/getDescriptor/get-same-descriptor.html", @@ -7082,6 +7154,18 @@ "url": "/_mozilla/mozilla/bluetooth/getDescriptors/disconnect-called-during.html" } ], + "mozilla/bluetooth/getDescriptors/disconnect-invalidates-objects.html": [ + { + "path": "mozilla/bluetooth/getDescriptors/disconnect-invalidates-objects.html", + "url": "/_mozilla/mozilla/bluetooth/getDescriptors/disconnect-invalidates-objects.html" + } + ], + "mozilla/bluetooth/getDescriptors/get-different-descriptors-after-reconnection.html": [ + { + "path": "mozilla/bluetooth/getDescriptors/get-different-descriptors-after-reconnection.html", + "url": "/_mozilla/mozilla/bluetooth/getDescriptors/get-different-descriptors-after-reconnection.html" + } + ], "mozilla/bluetooth/getDescriptors/get-same-descriptors.html": [ { "path": "mozilla/bluetooth/getDescriptors/get-same-descriptors.html", @@ -7112,12 +7196,24 @@ "url": "/_mozilla/mozilla/bluetooth/getPrimaryService/disconnect-called-during.html" } ], + "mozilla/bluetooth/getPrimaryService/disconnect-invalidates-object.html": [ + { + "path": "mozilla/bluetooth/getPrimaryService/disconnect-invalidates-object.html", + "url": "/_mozilla/mozilla/bluetooth/getPrimaryService/disconnect-invalidates-object.html" + } + ], "mozilla/bluetooth/getPrimaryService/disconnected-device.html": [ { "path": "mozilla/bluetooth/getPrimaryService/disconnected-device.html", "url": "/_mozilla/mozilla/bluetooth/getPrimaryService/disconnected-device.html" } ], + "mozilla/bluetooth/getPrimaryService/get-different-service-after-reconnection.html": [ + { + "path": "mozilla/bluetooth/getPrimaryService/get-different-service-after-reconnection.html", + "url": "/_mozilla/mozilla/bluetooth/getPrimaryService/get-different-service-after-reconnection.html" + } + ], "mozilla/bluetooth/getPrimaryService/get-same-service.html": [ { "path": "mozilla/bluetooth/getPrimaryService/get-same-service.html", @@ -7208,6 +7304,12 @@ "url": "/_mozilla/mozilla/bluetooth/getPrimaryServices/disconnect-called-during.html" } ], + "mozilla/bluetooth/getPrimaryServices/disconnect-invalidates-objects.html": [ + { + "path": "mozilla/bluetooth/getPrimaryServices/disconnect-invalidates-objects.html", + "url": "/_mozilla/mozilla/bluetooth/getPrimaryServices/disconnect-invalidates-objects.html" + } + ], "mozilla/bluetooth/getPrimaryServices/disconnected-device-with-uuid.html": [ { "path": "mozilla/bluetooth/getPrimaryServices/disconnected-device-with-uuid.html", @@ -7220,6 +7322,18 @@ "url": "/_mozilla/mozilla/bluetooth/getPrimaryServices/disconnected-device.html" } ], + "mozilla/bluetooth/getPrimaryServices/get-different-services-after-reconnection.html": [ + { + "path": "mozilla/bluetooth/getPrimaryServices/get-different-services-after-reconnection.html", + "url": "/_mozilla/mozilla/bluetooth/getPrimaryServices/get-different-services-after-reconnection.html" + } + ], + "mozilla/bluetooth/getPrimaryServices/get-same-service-with-uuid.html": [ + { + "path": "mozilla/bluetooth/getPrimaryServices/get-same-service-with-uuid.html", + "url": "/_mozilla/mozilla/bluetooth/getPrimaryServices/get-same-service-with-uuid.html" + } + ], "mozilla/bluetooth/getPrimaryServices/get-same-service.html": [ { "path": "mozilla/bluetooth/getPrimaryServices/get-same-service.html", @@ -7304,6 +7418,12 @@ "url": "/_mozilla/mozilla/bluetooth/readValue/characteristic/disconnect-called-before.html" } ], + "mozilla/bluetooth/readValue/characteristic/disconnect-called-during.html": [ + { + "path": "mozilla/bluetooth/readValue/characteristic/disconnect-called-during.html", + "url": "/_mozilla/mozilla/bluetooth/readValue/characteristic/disconnect-called-during.html" + } + ], "mozilla/bluetooth/readValue/characteristic/event-is-fired.html": [ { "path": "mozilla/bluetooth/readValue/characteristic/event-is-fired.html", @@ -7376,16 +7496,46 @@ "url": "/_mozilla/mozilla/bluetooth/readValue/descriptor/service-is-removed.html" } ], - "mozilla/bluetooth/requestDevice/accept-all-devices-with-filter.html": [ + "mozilla/bluetooth/requestDevice/acceptAllDevices/accept-all-devices-with-filter.html": [ { - "path": "mozilla/bluetooth/requestDevice/accept-all-devices-with-filter.html", - "url": "/_mozilla/mozilla/bluetooth/requestDevice/accept-all-devices-with-filter.html" + "path": "mozilla/bluetooth/requestDevice/acceptAllDevices/accept-all-devices-with-filter.html", + "url": "/_mozilla/mozilla/bluetooth/requestDevice/acceptAllDevices/accept-all-devices-with-filter.html" } ], - "mozilla/bluetooth/requestDevice/accept-all-devices.html": [ + "mozilla/bluetooth/requestDevice/acceptAllDevices/accept-all-devices.html": [ { - "path": "mozilla/bluetooth/requestDevice/accept-all-devices.html", - "url": "/_mozilla/mozilla/bluetooth/requestDevice/accept-all-devices.html" + "path": "mozilla/bluetooth/requestDevice/acceptAllDevices/accept-all-devices.html", + "url": "/_mozilla/mozilla/bluetooth/requestDevice/acceptAllDevices/accept-all-devices.html" + } + ], + "mozilla/bluetooth/requestDevice/acceptAllDevices/device-with-empty-name.html": [ + { + "path": "mozilla/bluetooth/requestDevice/acceptAllDevices/device-with-empty-name.html", + "url": "/_mozilla/mozilla/bluetooth/requestDevice/acceptAllDevices/device-with-empty-name.html" + } + ], + "mozilla/bluetooth/requestDevice/acceptAllDevices/device-with-name.html": [ + { + "path": "mozilla/bluetooth/requestDevice/acceptAllDevices/device-with-name.html", + "url": "/_mozilla/mozilla/bluetooth/requestDevice/acceptAllDevices/device-with-name.html" + } + ], + "mozilla/bluetooth/requestDevice/acceptAllDevices/device-with-no-name.html": [ + { + "path": "mozilla/bluetooth/requestDevice/acceptAllDevices/device-with-no-name.html", + "url": "/_mozilla/mozilla/bluetooth/requestDevice/acceptAllDevices/device-with-no-name.html" + } + ], + "mozilla/bluetooth/requestDevice/acceptAllDevices/optional-services-missing.html": [ + { + "path": "mozilla/bluetooth/requestDevice/acceptAllDevices/optional-services-missing.html", + "url": "/_mozilla/mozilla/bluetooth/requestDevice/acceptAllDevices/optional-services-missing.html" + } + ], + "mozilla/bluetooth/requestDevice/acceptAllDevices/optional-services-present.html": [ + { + "path": "mozilla/bluetooth/requestDevice/acceptAllDevices/optional-services-present.html", + "url": "/_mozilla/mozilla/bluetooth/requestDevice/acceptAllDevices/optional-services-present.html" } ], "mozilla/bluetooth/requestDevice/adapter-not-present.html": [ @@ -7442,6 +7592,12 @@ "url": "/_mozilla/mozilla/bluetooth/requestDevice/canonicalizeFilter/empty-services-member.html" } ], + "mozilla/bluetooth/requestDevice/canonicalizeFilter/filters-xor-acceptAllDevices.html": [ + { + "path": "mozilla/bluetooth/requestDevice/canonicalizeFilter/filters-xor-acceptAllDevices.html", + "url": "/_mozilla/mozilla/bluetooth/requestDevice/canonicalizeFilter/filters-xor-acceptAllDevices.html" + } + ], "mozilla/bluetooth/requestDevice/canonicalizeFilter/max-length-for-device-name-name.html": [ { "path": "mozilla/bluetooth/requestDevice/canonicalizeFilter/max-length-for-device-name-name.html", @@ -7700,12 +7856,24 @@ "url": "/_mozilla/mozilla/bluetooth/startNotifications/blocklisted-characteristic.html" } ], + "mozilla/bluetooth/startNotifications/characteristic-does-not-support-notifications.html": [ + { + "path": "mozilla/bluetooth/startNotifications/characteristic-does-not-support-notifications.html", + "url": "/_mozilla/mozilla/bluetooth/startNotifications/characteristic-does-not-support-notifications.html" + } + ], "mozilla/bluetooth/startNotifications/characteristic-is-removed.html": [ { "path": "mozilla/bluetooth/startNotifications/characteristic-is-removed.html", "url": "/_mozilla/mozilla/bluetooth/startNotifications/characteristic-is-removed.html" } ], + "mozilla/bluetooth/startNotifications/device-goes-out-of-range.html": [ + { + "path": "mozilla/bluetooth/startNotifications/device-goes-out-of-range.html", + "url": "/_mozilla/mozilla/bluetooth/startNotifications/device-goes-out-of-range.html" + } + ], "mozilla/bluetooth/startNotifications/disconnect-called-before.html": [ { "path": "mozilla/bluetooth/startNotifications/disconnect-called-before.html", @@ -7730,6 +7898,12 @@ "url": "/_mozilla/mozilla/bluetooth/startNotifications/notify-succeeds.html" } ], + "mozilla/bluetooth/startNotifications/service-is-removed.html": [ + { + "path": "mozilla/bluetooth/startNotifications/service-is-removed.html", + "url": "/_mozilla/mozilla/bluetooth/startNotifications/service-is-removed.html" + } + ], "mozilla/bluetooth/stopNotifications/characteristic-is-removed.html": [ { "path": "mozilla/bluetooth/stopNotifications/characteristic-is-removed.html", @@ -7754,6 +7928,24 @@ "url": "/_mozilla/mozilla/bluetooth/stopNotifications/notify-succeeds.html" } ], + "mozilla/bluetooth/stopNotifications/stop-after-start-succeeds.html": [ + { + "path": "mozilla/bluetooth/stopNotifications/stop-after-start-succeeds.html", + "url": "/_mozilla/mozilla/bluetooth/stopNotifications/stop-after-start-succeeds.html" + } + ], + "mozilla/bluetooth/stopNotifications/stop-twice.html": [ + { + "path": "mozilla/bluetooth/stopNotifications/stop-twice.html", + "url": "/_mozilla/mozilla/bluetooth/stopNotifications/stop-twice.html" + } + ], + "mozilla/bluetooth/stopNotifications/stop-without-starting.html": [ + { + "path": "mozilla/bluetooth/stopNotifications/stop-without-starting.html", + "url": "/_mozilla/mozilla/bluetooth/stopNotifications/stop-without-starting.html" + } + ], "mozilla/bluetooth/writeValue/characteristic/blocklisted-characteristic.html": [ { "path": "mozilla/bluetooth/writeValue/characteristic/blocklisted-characteristic.html", @@ -7784,6 +7976,12 @@ "url": "/_mozilla/mozilla/bluetooth/writeValue/characteristic/service-is-removed.html" } ], + "mozilla/bluetooth/writeValue/characteristic/value-too-long.html": [ + { + "path": "mozilla/bluetooth/writeValue/characteristic/value-too-long.html", + "url": "/_mozilla/mozilla/bluetooth/writeValue/characteristic/value-too-long.html" + } + ], "mozilla/bluetooth/writeValue/characteristic/write-succeeds.html": [ { "path": "mozilla/bluetooth/writeValue/characteristic/write-succeeds.html", @@ -8288,6 +8486,12 @@ "url": "/_mozilla/mozilla/iterable.html" } ], + "mozilla/keyframe-infinite-percentage.html": [ + { + "path": "mozilla/keyframe-infinite-percentage.html", + "url": "/_mozilla/mozilla/keyframe-infinite-percentage.html" + } + ], "mozilla/lenient_this.html": [ { "path": "mozilla/lenient_this.html", @@ -14912,6 +15116,12 @@ "url": "/_mozilla/mozilla/textcontent.html" } ], + "mozilla/timeout-in-discarded-document.html": [ + { + "path": "mozilla/timeout-in-discarded-document.html", + "url": "/_mozilla/mozilla/timeout-in-discarded-document.html" + } + ], "mozilla/timer_eventInvalidation.html": [ { "path": "mozilla/timer_eventInvalidation.html", @@ -21582,6 +21792,18 @@ "url": "/_mozilla/mozilla/table_valign_uneven_height.html" } ], + "mozilla/textarea_placeholder.html": [ + { + "path": "mozilla/textarea_placeholder.html", + "references": [ + [ + "/_mozilla/mozilla/textarea_placeholder_ref.html", + "==" + ] + ], + "url": "/_mozilla/mozilla/textarea_placeholder.html" + } + ], "mozilla/webgl/clearcolor.html": [ { "path": "mozilla/webgl/clearcolor.html", diff --git a/tests/wpt/mozilla/meta/mozilla/bluetooth/advertisingEvent/watchAdvertisements-succeeds.html.ini b/tests/wpt/mozilla/meta/mozilla/bluetooth/advertisingEvent/watchAdvertisements-succeeds.html.ini new file mode 100644 index 00000000000..da628804692 --- /dev/null +++ b/tests/wpt/mozilla/meta/mozilla/bluetooth/advertisingEvent/watchAdvertisements-succeeds.html.ini @@ -0,0 +1,4 @@ +[watchAdvertisements-succeeds.html] + type: testharness + [watchAdvertisements should succeed.] + expected: FAIL diff --git a/tests/wpt/mozilla/meta/mozilla/bluetooth/connect/device-goes-out-of-range.html.ini b/tests/wpt/mozilla/meta/mozilla/bluetooth/connect/device-goes-out-of-range.html.ini deleted file mode 100644 index 1ac7e23518b..00000000000 --- a/tests/wpt/mozilla/meta/mozilla/bluetooth/connect/device-goes-out-of-range.html.ini +++ /dev/null @@ -1,5 +0,0 @@ -[device-goes-out-of-range.html] - type: testharness - [Device goes out of range. Reject with NetworkError.] - expected: FAIL - diff --git a/tests/wpt/mozilla/meta/mozilla/bluetooth/getCharacteristic/disconnect-invalidates-object.html.ini b/tests/wpt/mozilla/meta/mozilla/bluetooth/getCharacteristic/disconnect-invalidates-object.html.ini new file mode 100644 index 00000000000..5e864acb72f --- /dev/null +++ b/tests/wpt/mozilla/meta/mozilla/bluetooth/getCharacteristic/disconnect-invalidates-object.html.ini @@ -0,0 +1,5 @@ +[disconnect-invalidates-object.html] + type: testharness + [Calls on a characteristic after we disconnect and connect again. Should reject with InvalidStateError.] + expected: FAIL + diff --git a/tests/wpt/mozilla/meta/mozilla/bluetooth/getCharacteristic/reconnect-during.html.ini b/tests/wpt/mozilla/meta/mozilla/bluetooth/getCharacteristic/reconnect-during.html.ini new file mode 100644 index 00000000000..ebfa902c2c4 --- /dev/null +++ b/tests/wpt/mozilla/meta/mozilla/bluetooth/getCharacteristic/reconnect-during.html.ini @@ -0,0 +1,5 @@ +[reconnect-during.html] + type: testharness + [disconnect() and connect() called during getCharacteristic. Reject with NetworkError.] + expected: FAIL + diff --git a/tests/wpt/mozilla/meta/mozilla/bluetooth/getCharacteristics/disconnect-invalidates-objects.html.ini b/tests/wpt/mozilla/meta/mozilla/bluetooth/getCharacteristics/disconnect-invalidates-objects.html.ini new file mode 100644 index 00000000000..03863760106 --- /dev/null +++ b/tests/wpt/mozilla/meta/mozilla/bluetooth/getCharacteristics/disconnect-invalidates-objects.html.ini @@ -0,0 +1,5 @@ +[disconnect-invalidates-objects.html] + type: testharness + [Calls on characteristics after we disconnect and connect again. Should reject with InvalidStateError.] + expected: FAIL + diff --git a/tests/wpt/mozilla/meta/mozilla/bluetooth/readValue/characteristic/disconnect-called-during.html.ini b/tests/wpt/mozilla/meta/mozilla/bluetooth/readValue/characteristic/disconnect-called-during.html.ini new file mode 100644 index 00000000000..f60c30d9e88 --- /dev/null +++ b/tests/wpt/mozilla/meta/mozilla/bluetooth/readValue/characteristic/disconnect-called-during.html.ini @@ -0,0 +1,5 @@ +[disconnect-called-during.html] + type: testharness + [disconnect() called during readValue. Reject with NetworkError.] + expected: FAIL + diff --git a/tests/wpt/mozilla/meta/mozilla/bluetooth/stopNotifications/disconnect-called-during.html.ini b/tests/wpt/mozilla/meta/mozilla/bluetooth/stopNotifications/disconnect-called-during.html.ini index 6dc580dc253..6cac157c3b2 100644 --- a/tests/wpt/mozilla/meta/mozilla/bluetooth/stopNotifications/disconnect-called-during.html.ini +++ b/tests/wpt/mozilla/meta/mozilla/bluetooth/stopNotifications/disconnect-called-during.html.ini @@ -1,5 +1,5 @@ [disconnect-called-during.html] type: testharness - [disconnect() called during stopNotifications. Reject with NetworkError.] + [disconnect() called during stopNotifications. Reject with InvalidStateError.] expected: FAIL diff --git a/tests/wpt/mozilla/tests/css/import_serialization.html b/tests/wpt/mozilla/tests/css/import_serialization.html new file mode 100644 index 00000000000..44c828db3cb --- /dev/null +++ b/tests/wpt/mozilla/tests/css/import_serialization.html @@ -0,0 +1,16 @@ +<!doctype html> +<meta charset="utf-8"> +<title>CSS Test: @import rules are correctly serialized</title> +<style id="test"> + @import url("foo.css"); + @import url("foo.css") print; +</style> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script> +test(function() { + var rules = document.styleSheets[0].cssRules; + assert_equals(rules[0].cssText, "@import url(\"foo.css\");"); + assert_equals(rules[1].cssText, "@import url(\"foo.css\") print;"); +}) +</script> diff --git a/tests/wpt/mozilla/tests/css/matchMedia.html b/tests/wpt/mozilla/tests/css/matchMedia.html index 0eeb007a49a..45a7ea268b1 100644 --- a/tests/wpt/mozilla/tests/css/matchMedia.html +++ b/tests/wpt/mozilla/tests/css/matchMedia.html @@ -126,12 +126,16 @@ window.onload = function(){ var rmListener = function(x){ + assert_true(x instanceof MediaQueryListEvent, "Check that event is instance of MediaQueryListEvent."); + resizeTest.step(function(){ assert_unreached("removeListener was not successful."); }); }; var dupListener = function(x){ + assert_true(x instanceof MediaQueryListEvent, "Check that event is instance of MediaQueryListEvent."); + duplicateListenerTest.step(function(){ assert_false(mql1.dupListenerCalled, "Check that this listener has not been called before."); mql1.dupListenerCalled = true; @@ -148,6 +152,8 @@ mql1.addListener(dupListener); mql1.addListener(function(x){ + assert_true(x instanceof MediaQueryListEvent, "Check that event is instance of MediaQueryListEvent."); + resizeTest.step(function(){ assert_equals(x, mql1, "Check that the MediaQueryList passed to the handler is the same that addListener was invoked on."); assert_true(x.matches, "(max-height: 50px) should now pass."); @@ -162,6 +168,8 @@ }); mql1.addListener(function(x){ + assert_true(x instanceof MediaQueryListEvent, "Check that event is instance of MediaQueryListEvent."); + listenerOrderTest.step(function(){ assert_true(mql1.firstListenerCalled, "Check that the listener added last is called last."); }); @@ -171,6 +179,8 @@ mql1.removeListener(rmListener); mql2.addListener(function(x){ + assert_true(x instanceof MediaQueryListEvent, "Check that event is instance of MediaQueryListEvent."); + duplicateListenerTest.done(); resizeTest.step(function(){ assert_equals(x, mql2, "Check that the MediaQueryList passed to the handler is the same that addListener was invoked on."); diff --git a/tests/wpt/mozilla/tests/mozilla/bluetooth/advertisingEvent/watchAdvertisements-succeeds.html b/tests/wpt/mozilla/tests/mozilla/bluetooth/advertisingEvent/watchAdvertisements-succeeds.html new file mode 100644 index 00000000000..45b0164a303 --- /dev/null +++ b/tests/wpt/mozilla/tests/mozilla/bluetooth/advertisingEvent/watchAdvertisements-succeeds.html @@ -0,0 +1,14 @@ +<!doctype html> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/_mozilla/mozilla/bluetooth/bluetooth-helpers.js"></script> +<script> +'use strict'; +promise_test(() => { + window.testRunner.setBluetoothMockDataSet(adapter_type.heart_rate); + return window.navigator.bluetooth.requestDevice({ + filters: [{services: [heart_rate.name]}] + }) + .then(device => device.watchAdvertisements()); +}, 'watchAdvertisements should succeed.'); +</script> diff --git a/tests/wpt/mozilla/tests/mozilla/bluetooth/disconnect/event-is-fired.html b/tests/wpt/mozilla/tests/mozilla/bluetooth/disconnect/event-is-fired.html new file mode 100644 index 00000000000..67e146fc956 --- /dev/null +++ b/tests/wpt/mozilla/tests/mozilla/bluetooth/disconnect/event-is-fired.html @@ -0,0 +1,33 @@ +<!doctype html> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/_mozilla/mozilla/bluetooth/bluetooth-helpers.js"></script> +<script> +'use strict'; +promise_test(() => { + window.testRunner.setBluetoothMockDataSet(adapter_type.heart_rate); + return window.navigator.bluetooth.requestDevice({ + filters: [{services: [heart_rate.name]}], + optionalServices: [generic_access.name] + }) + .then(device => { + return device.gatt.connect() + .then(gattServer => { + let event = 'gattserverdisconnected'; + let disconnected = new Promise((resolve, reject) => { + let event_listener = (e) => { + device.removeEventListener(event, event_listener); + resolve(e); + }; + device.addEventListener(event, event_listener); + }); + gattServer.disconnect(); + return disconnected + }) + .then(disconnected => { + assert_equals(disconnected.target.name, mock_device_name.heart_rate); + assert_true(disconnected.bubbles); + }); + }); +}, 'A device disconnecting while connected should fire the gattserverdisconnected event.'); +</script> diff --git a/tests/wpt/mozilla/tests/mozilla/bluetooth/getCharacteristic/disconnect-invalidates-object.html b/tests/wpt/mozilla/tests/mozilla/bluetooth/getCharacteristic/disconnect-invalidates-object.html new file mode 100644 index 00000000000..c1e6a864b0c --- /dev/null +++ b/tests/wpt/mozilla/tests/mozilla/bluetooth/getCharacteristic/disconnect-invalidates-object.html @@ -0,0 +1,36 @@ +<!doctype html> +<meta charset="utf-8"> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/_mozilla/mozilla/bluetooth/bluetooth-helpers.js"></script> +<script> +'use strict'; +promise_test(t => { + window.testRunner.setBluetoothMockDataSet(adapter_type.two_heart_rate); + return window.navigator.bluetooth.requestDevice({ + filters: [{services: [generic_access.name]}] + }) + .then(device => device.gatt.connect()) + .then(gattServer => { + return gattServer.getPrimaryService(generic_access.name) + .then(service => service.getCharacteristic(device_name.name)) + .then(c => { + let characteristic = c; + gattServer.disconnect(); + return gattServer.connect() + .then(() => characteristic); + }); + }) + .then(characteristic => { + let promises = []; + promises.push(promise_rejects(t, 'InvalidStateError', characteristic.getDescriptor(number_of_digitals.name))); + promises.push(promise_rejects(t, 'InvalidStateError', characteristic.getDescriptors(number_of_digitals.name))); + promises.push(promise_rejects(t, 'InvalidStateError', characteristic.getDescriptors())); + promises.push(promise_rejects(t, 'InvalidStateError', characteristic.readValue())); + promises.push(promise_rejects(t, 'InvalidStateError', characteristic.writeValue(new Uint8Array(1)))); + promises.push(promise_rejects(t, 'InvalidStateError', characteristic.startNotifications())); + promises.push(promise_rejects(t, 'InvalidStateError', characteristic.stopNotifications())); + return Promise.all(promises); + }); +}, 'Calls on a characteristic after we disconnect and connect again. Should reject with InvalidStateError.'); +</script> diff --git a/tests/wpt/mozilla/tests/mozilla/bluetooth/getCharacteristic/get-different-characteristic-after-reconnection.html b/tests/wpt/mozilla/tests/mozilla/bluetooth/getCharacteristic/get-different-characteristic-after-reconnection.html new file mode 100644 index 00000000000..b65a9a27836 --- /dev/null +++ b/tests/wpt/mozilla/tests/mozilla/bluetooth/getCharacteristic/get-different-characteristic-after-reconnection.html @@ -0,0 +1,29 @@ +<!doctype html> +<meta charset="utf-8"> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/_mozilla/mozilla/bluetooth/bluetooth-helpers.js"></script> +<script> +'use strict'; +promise_test(t => { + window.testRunner.setBluetoothMockDataSet(adapter_type.two_heart_rate); + return window.navigator.bluetooth.requestDevice({ + filters: [{services: [generic_access.name]}] + }) + .then(device => device.gatt.connect()) + .then(gattServer => { + let characteristic1; + return gattServer.getPrimaryService(generic_access.name) + .then(service => service.getCharacteristic(device_name.name)) + .then(characteristic => characteristic1 = characteristic) + .then(() => gattServer.disconnect()) + .then(() => gattServer.connect()) + .then(() => gattServer.getPrimaryService(generic_access.name)) + .then(service => service.getCharacteristic(device_name.name)) + .then(characteristic2 => [characteristic1, characteristic2]) + }) + .then(characteristics_array => { + assert_not_equals(characteristics_array[0], characteristics_array[1]); + }); +}, 'Calls to getCharacteristic after a disconnection should return a different object.'); +</script> diff --git a/tests/wpt/mozilla/tests/mozilla/bluetooth/getCharacteristic/reconnect-during.html b/tests/wpt/mozilla/tests/mozilla/bluetooth/getCharacteristic/reconnect-during.html new file mode 100644 index 00000000000..3560e874a85 --- /dev/null +++ b/tests/wpt/mozilla/tests/mozilla/bluetooth/getCharacteristic/reconnect-during.html @@ -0,0 +1,23 @@ +<!doctype html> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/_mozilla/mozilla/bluetooth/bluetooth-helpers.js"></script> +<script> +'use strict'; +promise_test(t => { + window.testRunner.setBluetoothMockDataSet(adapter_type.heart_rate); + return window.navigator.bluetooth.requestDevice({ + filters: [{services: [heart_rate.name]}], + }) + .then(device => device.gatt.connect()) + .then(gattServer => { + return gattServer.getPrimaryService(heart_rate.name) + .then(service => { + let promise = promise_rejects(t, 'NetworkError', service.getCharacteristic(heart_rate_measurement.uuid)); + gattServer.disconnect(); + return gattServer.connect() + .then(() => promise); + }); + }); +}, 'disconnect() and connect() called during getCharacteristic. Reject with NetworkError.'); +</script> diff --git a/tests/wpt/mozilla/tests/mozilla/bluetooth/getCharacteristics/disconnect-invalidates-objects.html b/tests/wpt/mozilla/tests/mozilla/bluetooth/getCharacteristics/disconnect-invalidates-objects.html new file mode 100644 index 00000000000..adf607a0954 --- /dev/null +++ b/tests/wpt/mozilla/tests/mozilla/bluetooth/getCharacteristics/disconnect-invalidates-objects.html @@ -0,0 +1,39 @@ +<!doctype html> +<meta charset="utf-8"> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/_mozilla/mozilla/bluetooth/bluetooth-helpers.js"></script> +<script> +'use strict'; +promise_test(t => { + window.testRunner.setBluetoothMockDataSet(adapter_type.heart_rate); + return window.navigator.bluetooth.requestDevice({ + filters: [{services: [heart_rate.name]}] + }) + .then(device => device.gatt.connect()) + .then(gattServer => { + return gattServer.getPrimaryService(heart_rate.name) + .then(service => service.getCharacteristics()) + .then(c => { + let characteristics = c; + assert_greater_than(characteristics.length, 1); + gattServer.disconnect(); + return gattServer.connect() + .then(() => characteristics); + }); + }) + .then(characteristics => { + let promises = []; + for (let characteristic of characteristics) { + promises.push(promise_rejects(t, 'InvalidStateError', characteristic.getDescriptor(number_of_digitals.name))); + promises.push(promise_rejects(t, 'InvalidStateError', characteristic.getDescriptors(number_of_digitals.name))); + promises.push(promise_rejects(t, 'InvalidStateError', characteristic.getDescriptors())); + promises.push(promise_rejects(t, 'InvalidStateError', characteristic.readValue())); + promises.push(promise_rejects(t, 'InvalidStateError', characteristic.writeValue(new Uint8Array(1)))); + promises.push(promise_rejects(t, 'InvalidStateError', characteristic.startNotifications())); + promises.push(promise_rejects(t, 'InvalidStateError', characteristic.stopNotifications())); + } + return Promise.all(promises); + }); +}, 'Calls on characteristics after we disconnect and connect again. Should reject with InvalidStateError.'); +</script> diff --git a/tests/wpt/mozilla/tests/mozilla/bluetooth/getCharacteristics/get-different-characteristics-after-reconnection.html b/tests/wpt/mozilla/tests/mozilla/bluetooth/getCharacteristics/get-different-characteristics-after-reconnection.html new file mode 100644 index 00000000000..0e93083a1cb --- /dev/null +++ b/tests/wpt/mozilla/tests/mozilla/bluetooth/getCharacteristics/get-different-characteristics-after-reconnection.html @@ -0,0 +1,35 @@ +<!doctype html> +<meta charset="utf-8"> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/_mozilla/mozilla/bluetooth/bluetooth-helpers.js"></script> +<script> +'use strict'; +promise_test(t => { + window.testRunner.setBluetoothMockDataSet(adapter_type.heart_rate); + return window.navigator.bluetooth.requestDevice({ + filters: [{services: [heart_rate.name]}], + }) + .then(device => device.gatt.connect()) + .then(gattServer => { + let characteristics1; + return gattServer.getPrimaryService(heart_rate.name) + .then(service => service.getCharacteristics()) + .then(characteristics => characteristics1 = characteristics) + .then(() => gattServer.disconnect()) + .then(() => gattServer.connect()) + .then(() => gattServer.getPrimaryService(heart_rate.name)) + .then(service => service.getCharacteristics()) + .then(characteristics2 => [characteristics1, characteristics2]) + }) + .then(characteristics_arrays => { + for (let i = 1; i < characteristics_arrays.length; i++) { + assert_equals(characteristics_arrays[0].length, characteristics_arrays[i].length); + } + let base_set = new Set(characteristics_arrays.shift()); + for (let characteristics of characteristics_arrays) { + characteristics.forEach(characteristic => assert_false(base_set.has(characteristic))); + } + }); +}, 'Calls to getCharacteristics after a disconnection should return different objects.'); +</script> diff --git a/tests/wpt/mozilla/tests/mozilla/bluetooth/getDescriptor/disconnect-invalidates-object.html b/tests/wpt/mozilla/tests/mozilla/bluetooth/getDescriptor/disconnect-invalidates-object.html new file mode 100644 index 00000000000..b99e877159b --- /dev/null +++ b/tests/wpt/mozilla/tests/mozilla/bluetooth/getDescriptor/disconnect-invalidates-object.html @@ -0,0 +1,32 @@ +<!doctype html> +<meta charset="utf-8"> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/_mozilla/mozilla/bluetooth/bluetooth-helpers.js"></script> +<script> +'use strict'; +promise_test(t => { + window.testRunner.setBluetoothMockDataSet(adapter_type.heart_rate); + return window.navigator.bluetooth.requestDevice({ + filters: [{services: [generic_access.name]}] + }) + .then(device => device.gatt.connect()) + .then(gattServer => { + return gattServer.getPrimaryService(generic_access.name) + .then(service => service.getCharacteristic(device_name.name)) + .then(characteristic => characteristic.getDescriptor(number_of_digitals.name)) + .then(d => { + let descriptor = d; + gattServer.disconnect(); + return gattServer.connect() + .then(() => descriptor); + }); + }) + .then(descriptor => { + let promises = []; + promises.push(promise_rejects(t, 'InvalidStateError', descriptor.readValue())); + promises.push(promise_rejects(t, 'InvalidStateError', descriptor.writeValue(new Uint8Array(1)))); + return Promise.all(promises); + }); +}, 'Calls on a descriptor after we disconnect and connect again. Should reject with InvalidStateError.'); +</script> diff --git a/tests/wpt/mozilla/tests/mozilla/bluetooth/getDescriptor/get-different-descriptor-after-reconnection.html b/tests/wpt/mozilla/tests/mozilla/bluetooth/getDescriptor/get-different-descriptor-after-reconnection.html new file mode 100644 index 00000000000..ea7559415d4 --- /dev/null +++ b/tests/wpt/mozilla/tests/mozilla/bluetooth/getDescriptor/get-different-descriptor-after-reconnection.html @@ -0,0 +1,31 @@ +<!doctype html> +<meta charset="utf-8"> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/_mozilla/mozilla/bluetooth/bluetooth-helpers.js"></script> +<script> +'use strict'; +promise_test(t => { + window.testRunner.setBluetoothMockDataSet(adapter_type.two_heart_rate); + return window.navigator.bluetooth.requestDevice({ + filters: [{services: [generic_access.name]}] + }) + .then(device => device.gatt.connect()) + .then(gattServer => { + let descriptor1; + return gattServer.getPrimaryService(generic_access.name) + .then(service => service.getCharacteristic(device_name.name)) + .then(characteristic => characteristic.getDescriptor(number_of_digitals.name)) + .then(descriptor => descriptor1 = descriptor) + .then(() => gattServer.disconnect()) + .then(() => gattServer.connect()) + .then(() => gattServer.getPrimaryService(generic_access.name)) + .then(service => service.getCharacteristic(device_name.name)) + .then(characteristic => characteristic.getDescriptor(number_of_digitals.name)) + .then(descriptor2 => [descriptor1, descriptor2]) + }) + .then(descriptors_array => { + assert_not_equals(descriptors_array[0], descriptors_array[1]); + }); +}, 'Calls to getDescriptor after a disconnection should return a different object.'); +</script> diff --git a/tests/wpt/mozilla/tests/mozilla/bluetooth/getDescriptors/disconnect-invalidates-objects.html b/tests/wpt/mozilla/tests/mozilla/bluetooth/getDescriptors/disconnect-invalidates-objects.html new file mode 100644 index 00000000000..8f912b06755 --- /dev/null +++ b/tests/wpt/mozilla/tests/mozilla/bluetooth/getDescriptors/disconnect-invalidates-objects.html @@ -0,0 +1,35 @@ +<!doctype html> +<meta charset="utf-8"> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/_mozilla/mozilla/bluetooth/bluetooth-helpers.js"></script> +<script> +'use strict'; +promise_test(t => { + window.testRunner.setBluetoothMockDataSet(adapter_type.heart_rate); + return window.navigator.bluetooth.requestDevice({ + filters: [{services: [generic_access.name]}] + }) + .then(device => device.gatt.connect()) + .then(gattServer => { + return gattServer.getPrimaryService(generic_access.name) + .then(service => service.getCharacteristic(device_name.name)) + .then(characteristic => characteristic.getDescriptors()) + .then(d => { + let descriptors = d; + gattServer.disconnect(); + return gattServer.connect() + .then(() => descriptors); + }); + }) + .then(descriptors => { + let promises = []; + for (let descriptor of descriptors) { + promises.push(promise_rejects(t, 'InvalidStateError', descriptor.readValue())); + if (descriptor.uuid != client_characteristic_configuration.uuid) + promises.push(promise_rejects(t, 'InvalidStateError', descriptor.writeValue(new Uint8Array(1)))); + } + return Promise.all(promises); + }); +}, 'Calls on descriptors after we disconnect and connect again. Should reject with InvalidStateError.'); +</script> diff --git a/tests/wpt/mozilla/tests/mozilla/bluetooth/getDescriptors/get-different-descriptors-after-reconnection.html b/tests/wpt/mozilla/tests/mozilla/bluetooth/getDescriptors/get-different-descriptors-after-reconnection.html new file mode 100644 index 00000000000..4a5ea15f96c --- /dev/null +++ b/tests/wpt/mozilla/tests/mozilla/bluetooth/getDescriptors/get-different-descriptors-after-reconnection.html @@ -0,0 +1,37 @@ +<!doctype html> +<meta charset="utf-8"> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/_mozilla/mozilla/bluetooth/bluetooth-helpers.js"></script> +<script> +'use strict'; +promise_test(t => { + window.testRunner.setBluetoothMockDataSet(adapter_type.two_heart_rate); + return window.navigator.bluetooth.requestDevice({ + filters: [{services: [generic_access.name]}] + }) + .then(device => device.gatt.connect()) + .then(gattServer => { + let descriptors1; + return gattServer.getPrimaryService(generic_access.name) + .then(service => service.getCharacteristic(device_name.name)) + .then(characteristic => characteristic.getDescriptors(number_of_digitals.name)) + .then(descriptors => descriptors1 = descriptors) + .then(() => gattServer.disconnect()) + .then(() => gattServer.connect()) + .then(() => gattServer.getPrimaryService(generic_access.name)) + .then(service => service.getCharacteristic(device_name.name)) + .then(characteristic => characteristic.getDescriptors(number_of_digitals.name)) + .then(descriptors2 => [descriptors1, descriptors2]) + }) + .then(descriptors_arrays => { + for (let i = 1; i < descriptors_arrays.length; i++) { + assert_equals(descriptors_arrays[0].length, descriptors_arrays[i].length); + } + let base_set = new Set(descriptors_arrays.shift()); + for (let descriptors of descriptors_arrays) { + descriptors.forEach(descriptor => assert_false(base_set.has(descriptor))); + } + }); +}, 'Calls to getDescriptors after a disconnection should return a different object.'); +</script> diff --git a/tests/wpt/mozilla/tests/mozilla/bluetooth/getPrimaryService/disconnect-invalidates-object.html b/tests/wpt/mozilla/tests/mozilla/bluetooth/getPrimaryService/disconnect-invalidates-object.html new file mode 100644 index 00000000000..a0254ee32ce --- /dev/null +++ b/tests/wpt/mozilla/tests/mozilla/bluetooth/getPrimaryService/disconnect-invalidates-object.html @@ -0,0 +1,31 @@ +<!doctype html> +<meta charset="utf-8"> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/_mozilla/mozilla/bluetooth/bluetooth-helpers.js"></script> +<script> +'use strict'; +promise_test(t => { + window.testRunner.setBluetoothMockDataSet(adapter_type.two_heart_rate); + return window.navigator.bluetooth.requestDevice({ + filters: [{services: [heart_rate.name]}] + }) + .then(device => device.gatt.connect()) + .then(gattServer => { + return gattServer.getPrimaryService(heart_rate.name) + .then(s => { + let service = s; + gattServer.disconnect(); + return gattServer.connect() + .then(() => service); + }); + }) + .then(service => { + let promises = []; + promises.push(promise_rejects(t, 'InvalidStateError', service.getCharacteristic(body_sensor_location.name))); + promises.push(promise_rejects(t, 'InvalidStateError', service.getCharacteristics(body_sensor_location.name))); + promises.push(promise_rejects(t, 'InvalidStateError', service.getCharacteristics())); + return Promise.all(promises); + }); +}, 'Calls on a service after we disconnect and connect again. Should reject with InvalidStateError.'); +</script> diff --git a/tests/wpt/mozilla/tests/mozilla/bluetooth/getPrimaryService/get-different-service-after-reconnection.html b/tests/wpt/mozilla/tests/mozilla/bluetooth/getPrimaryService/get-different-service-after-reconnection.html new file mode 100644 index 00000000000..4f6e2bbc92a --- /dev/null +++ b/tests/wpt/mozilla/tests/mozilla/bluetooth/getPrimaryService/get-different-service-after-reconnection.html @@ -0,0 +1,27 @@ +<!doctype html> +<meta charset="utf-8"> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/_mozilla/mozilla/bluetooth/bluetooth-helpers.js"></script> +<script> +'use strict'; +promise_test(t => { + window.testRunner.setBluetoothMockDataSet(adapter_type.two_heart_rate); + return window.navigator.bluetooth.requestDevice({ + filters: [{services: [generic_access.name]}] + }) + .then(device => device.gatt.connect()) + .then(gattServer => { + let service1; + return gattServer.getPrimaryService(generic_access.name) + .then(service => service1 = service) + .then(() => gattServer.disconnect()) + .then(() => gattServer.connect()) + .then(() => gattServer.getPrimaryService(generic_access.name)) + .then(service2 => [service1, service2]) + }) + .then(services_array => { + assert_not_equals(services_array[0], services_array[1]); + }); +}, 'Calls to getPrimaryService after a disconnection should return a different object.'); +</script> diff --git a/tests/wpt/mozilla/tests/mozilla/bluetooth/getPrimaryServices/disconnect-invalidates-objects.html b/tests/wpt/mozilla/tests/mozilla/bluetooth/getPrimaryServices/disconnect-invalidates-objects.html new file mode 100644 index 00000000000..6f07ab81d99 --- /dev/null +++ b/tests/wpt/mozilla/tests/mozilla/bluetooth/getPrimaryServices/disconnect-invalidates-objects.html @@ -0,0 +1,34 @@ +<!doctype html> +<meta charset="utf-8"> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/_mozilla/mozilla/bluetooth/bluetooth-helpers.js"></script> +<script> +'use strict'; +promise_test(t => { + window.testRunner.setBluetoothMockDataSet(adapter_type.two_heart_rate); + return window.navigator.bluetooth.requestDevice({ + filters: [{services: [heart_rate.name]}] + }) + .then(device => device.gatt.connect()) + .then(gattServer => { + return gattServer.getPrimaryServices() + .then(s => { + let services = s; + assert_greater_than(services.length, 1); + gattServer.disconnect(); + return gattServer.connect() + .then(() => services); + }); + }) + .then(services => { + let promises = []; + for (let service of services) { + promises.push(promise_rejects(t, 'InvalidStateError', service.getCharacteristic(body_sensor_location.name))); + promises.push(promise_rejects(t, 'InvalidStateError', service.getCharacteristics(body_sensor_location.name))); + promises.push(promise_rejects(t, 'InvalidStateError', service.getCharacteristics())); + } + return Promise.all(promises); + }); +}, 'Calls on services after we disconnect and connect again. Should reject with InvalidStateError.'); +</script> diff --git a/tests/wpt/mozilla/tests/mozilla/bluetooth/getPrimaryServices/get-different-services-after-reconnection.html b/tests/wpt/mozilla/tests/mozilla/bluetooth/getPrimaryServices/get-different-services-after-reconnection.html new file mode 100644 index 00000000000..2ef3da7730d --- /dev/null +++ b/tests/wpt/mozilla/tests/mozilla/bluetooth/getPrimaryServices/get-different-services-after-reconnection.html @@ -0,0 +1,34 @@ +<!doctype html> +<meta charset="utf-8"> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/_mozilla/mozilla/bluetooth/bluetooth-helpers.js"></script> +<script> +'use strict'; +promise_test(t => { + window.testRunner.setBluetoothMockDataSet(adapter_type.two_heart_rate); + return window.navigator.bluetooth.requestDevice({ + filters: [{services: [heart_rate.name]}], + optionalServices: [generic_access.name] + }) + .then(device => device.gatt.connect()) + .then(gattServer => { + let services1; + return gattServer.getPrimaryServices() + .then(services => services1 = services) + .then(() => gattServer.disconnect()) + .then(() => gattServer.connect()) + .then(() => gattServer.getPrimaryServices()) + .then(services2 => [services1, services2]) + }) + .then(services_arrays => { + for (let i = 1; i < services_arrays.length; i++) { + assert_equals(services_arrays[0].length, services_arrays[i].length); + } + let base_set = new Set(services_arrays.shift()); + for (let services of services_arrays) { + services.forEach(service => assert_false(base_set.has(service))); + } + }); +}, 'Calls to getPrimaryServices after a disconnection should return different objects.'); +</script> diff --git a/tests/wpt/mozilla/tests/mozilla/bluetooth/getPrimaryServices/get-same-service-with-uuid.html b/tests/wpt/mozilla/tests/mozilla/bluetooth/getPrimaryServices/get-same-service-with-uuid.html new file mode 100644 index 00000000000..762dcfd1327 --- /dev/null +++ b/tests/wpt/mozilla/tests/mozilla/bluetooth/getPrimaryServices/get-same-service-with-uuid.html @@ -0,0 +1,18 @@ +<!doctype html> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/_mozilla/mozilla/bluetooth/bluetooth-helpers.js"></script> +<script> +'use strict'; +promise_test(() => { + window.testRunner.setBluetoothMockDataSet(adapter_type.two_heart_rate); + return window.navigator.bluetooth.requestDevice({ + filters: [{services: [heart_rate.name]}] + }) + .then(device => device.gatt.connect()) + .then(gattServer => Promise.all([ + gattServer.getPrimaryServices(heart_rate.name), + gattServer.getPrimaryServices(heart_rate.name)])) + .then(services => assert_array_equals(services[0], services[1])); +}, 'Calls to get the same service should return the same object.'); +</script> diff --git a/tests/wpt/mozilla/tests/mozilla/bluetooth/getPrimaryServices/get-same-service.html b/tests/wpt/mozilla/tests/mozilla/bluetooth/getPrimaryServices/get-same-service.html index 762dcfd1327..5f62e34d9f2 100644 --- a/tests/wpt/mozilla/tests/mozilla/bluetooth/getPrimaryServices/get-same-service.html +++ b/tests/wpt/mozilla/tests/mozilla/bluetooth/getPrimaryServices/get-same-service.html @@ -11,8 +11,8 @@ promise_test(() => { }) .then(device => device.gatt.connect()) .then(gattServer => Promise.all([ - gattServer.getPrimaryServices(heart_rate.name), - gattServer.getPrimaryServices(heart_rate.name)])) + gattServer.getPrimaryServices(), + gattServer.getPrimaryServices()])) .then(services => assert_array_equals(services[0], services[1])); }, 'Calls to get the same service should return the same object.'); </script> diff --git a/tests/wpt/mozilla/tests/mozilla/bluetooth/readValue/characteristic/disconnect-called-during.html b/tests/wpt/mozilla/tests/mozilla/bluetooth/readValue/characteristic/disconnect-called-during.html new file mode 100644 index 00000000000..d38645a5b3a --- /dev/null +++ b/tests/wpt/mozilla/tests/mozilla/bluetooth/readValue/characteristic/disconnect-called-during.html @@ -0,0 +1,25 @@ +<!doctype html> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/_mozilla/mozilla/bluetooth/bluetooth-helpers.js"></script> +<script> +'use strict'; +promise_test(t => { + window.testRunner.setBluetoothMockDataSet(adapter_type.heart_rate); + return window.navigator.bluetooth.requestDevice({ + filters: [{services: [heart_rate.name]}], + optionalServices: [generic_access.name] + }) + .then(device => device.gatt.connect()) + .then(gattServer => { + return gattServer.getPrimaryService(heart_rate.name) + .then(service => service.getCharacteristic(heart_rate_measurement.name)) + .then(characteristic => characteristic.startNotifications()) + .then(characteristic => { + let promise = promise_rejects(t, 'NetworkError', characteristic.readValue()); + gattServer.disconnect(); + return promise; + }); + }); +}, 'disconnect() called during readValue. Reject with NetworkError.'); +</script> diff --git a/tests/wpt/mozilla/tests/mozilla/bluetooth/requestDevice/accept-all-devices-with-filter.html b/tests/wpt/mozilla/tests/mozilla/bluetooth/requestDevice/acceptAllDevices/accept-all-devices-with-filter.html index f47cc3beaa9..f47cc3beaa9 100644 --- a/tests/wpt/mozilla/tests/mozilla/bluetooth/requestDevice/accept-all-devices-with-filter.html +++ b/tests/wpt/mozilla/tests/mozilla/bluetooth/requestDevice/acceptAllDevices/accept-all-devices-with-filter.html diff --git a/tests/wpt/mozilla/tests/mozilla/bluetooth/requestDevice/accept-all-devices.html b/tests/wpt/mozilla/tests/mozilla/bluetooth/requestDevice/acceptAllDevices/accept-all-devices.html index 66d23a43469..66d23a43469 100644 --- a/tests/wpt/mozilla/tests/mozilla/bluetooth/requestDevice/accept-all-devices.html +++ b/tests/wpt/mozilla/tests/mozilla/bluetooth/requestDevice/acceptAllDevices/accept-all-devices.html diff --git a/tests/wpt/mozilla/tests/mozilla/bluetooth/requestDevice/acceptAllDevices/device-with-empty-name.html b/tests/wpt/mozilla/tests/mozilla/bluetooth/requestDevice/acceptAllDevices/device-with-empty-name.html new file mode 100644 index 00000000000..d9c97b17542 --- /dev/null +++ b/tests/wpt/mozilla/tests/mozilla/bluetooth/requestDevice/acceptAllDevices/device-with-empty-name.html @@ -0,0 +1,12 @@ +<!doctype html> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/_mozilla/mozilla/bluetooth/bluetooth-helpers.js"></script> +<script> +'use strict'; +promise_test(() => { + window.testRunner.setBluetoothMockDataSet(adapter_type.empty_name_heart_rate); + return window.navigator.bluetooth.requestDevice({acceptAllDevices: true}) + .then(device => assert_equals(device.name, '')); +}, 'Device with empty name and no UUIDs nearby. Should be found if acceptAllDevices is true.'); +</script> diff --git a/tests/wpt/mozilla/tests/mozilla/bluetooth/requestDevice/acceptAllDevices/device-with-name.html b/tests/wpt/mozilla/tests/mozilla/bluetooth/requestDevice/acceptAllDevices/device-with-name.html new file mode 100644 index 00000000000..f3136c5c554 --- /dev/null +++ b/tests/wpt/mozilla/tests/mozilla/bluetooth/requestDevice/acceptAllDevices/device-with-name.html @@ -0,0 +1,13 @@ +<!doctype html> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/_mozilla/mozilla/bluetooth/bluetooth-helpers.js"></script> +<script> +'use strict'; +promise_test(() => { + let device_name = '\u2764'.repeat(9); + window.testRunner.setBluetoothMockDataSet(adapter_type.unicode_device); + return window.navigator.bluetooth.requestDevice({acceptAllDevices: true}) + .then(device => assert_equals(device.name, device_name)); +}, 'Device with name and no UUIDs nearby. Should be found if acceptAllDevices is true.'); +</script> diff --git a/tests/wpt/mozilla/tests/mozilla/bluetooth/requestDevice/acceptAllDevices/device-with-no-name.html b/tests/wpt/mozilla/tests/mozilla/bluetooth/requestDevice/acceptAllDevices/device-with-no-name.html new file mode 100644 index 00000000000..6e14d220842 --- /dev/null +++ b/tests/wpt/mozilla/tests/mozilla/bluetooth/requestDevice/acceptAllDevices/device-with-no-name.html @@ -0,0 +1,12 @@ +<!doctype html> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/_mozilla/mozilla/bluetooth/bluetooth-helpers.js"></script> +<script> +'use strict'; +promise_test(() => { + window.testRunner.setBluetoothMockDataSet(adapter_type.no_name_heart_rate); + return window.navigator.bluetooth.requestDevice({acceptAllDevices: true}) + .then(device => assert_equals(device.name, null)); +}, 'Device with no name or UUIDs nearby. Should be found if acceptAllDevices is true.'); +</script> diff --git a/tests/wpt/mozilla/tests/mozilla/bluetooth/requestDevice/acceptAllDevices/optional-services-missing.html b/tests/wpt/mozilla/tests/mozilla/bluetooth/requestDevice/acceptAllDevices/optional-services-missing.html new file mode 100644 index 00000000000..6332504612a --- /dev/null +++ b/tests/wpt/mozilla/tests/mozilla/bluetooth/requestDevice/acceptAllDevices/optional-services-missing.html @@ -0,0 +1,13 @@ +<!doctype html> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/_mozilla/mozilla/bluetooth/bluetooth-helpers.js"></script> +<script> +'use strict'; +promise_test(t => { + window.testRunner.setBluetoothMockDataSet(adapter_type.two_heart_rate); + return window.navigator.bluetooth.requestDevice({acceptAllDevices: true}) + .then(device => device.gatt.connect()) + .then(gattServer => promise_rejects(t, 'NotFoundError', gattServer.getPrimaryServices())); +}, 'requestDevice called with acceptAllDevices: true and with no optionalServices. Should not get access to any services.'); +</script> diff --git a/tests/wpt/mozilla/tests/mozilla/bluetooth/requestDevice/acceptAllDevices/optional-services-present.html b/tests/wpt/mozilla/tests/mozilla/bluetooth/requestDevice/acceptAllDevices/optional-services-present.html new file mode 100644 index 00000000000..959144623f0 --- /dev/null +++ b/tests/wpt/mozilla/tests/mozilla/bluetooth/requestDevice/acceptAllDevices/optional-services-present.html @@ -0,0 +1,22 @@ +<!doctype html> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/_mozilla/mozilla/bluetooth/bluetooth-helpers.js"></script> +<script> +'use strict'; +promise_test(() => { + window.testRunner.setBluetoothMockDataSet(adapter_type.two_heart_rate); + return window.navigator.bluetooth.requestDevice({ + acceptAllDevices: true, + optionalServices: ['heart_rate'] + }) + .then(device => device.gatt.connect()) + .then(gattServer => gattServer.getPrimaryServices()) + .then(services => { + assert_equals(services.length, 2); + services.forEach(service => { + assert_equals(service.uuid, BluetoothUUID.getService('heart_rate')); + }); + }) +}, 'requestDevice called with acceptAllDevices: true and with optionalServices. Should get access to services.'); +</script> diff --git a/tests/wpt/mozilla/tests/mozilla/bluetooth/requestDevice/canonicalizeFilter/filters-xor-acceptAllDevices.html b/tests/wpt/mozilla/tests/mozilla/bluetooth/requestDevice/canonicalizeFilter/filters-xor-acceptAllDevices.html new file mode 100644 index 00000000000..537048d338b --- /dev/null +++ b/tests/wpt/mozilla/tests/mozilla/bluetooth/requestDevice/canonicalizeFilter/filters-xor-acceptAllDevices.html @@ -0,0 +1,16 @@ +<!doctype html> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/_mozilla/mozilla/bluetooth/bluetooth-helpers.js"></script> +<script> +'use strict'; +promise_test(t => { + window.testRunner.setBluetoothMockDataSet(adapter_type.glucose_heart_rate); + return promise_rejects(t, new TypeError(), window.navigator.bluetooth.requestDevice({ + filters: [{services: [battery_service.name]}, + {services: [heart_rate.name]}, + {acceptAllDevices: true}, + {acceptAllDevices: true, optionalServices: ['heart_rate']}] + })); +}, 'RequestDeviceOptions should have exactly one of \'filters\' or \'acceptAllDevices:true\'. Reject with TypeError if not.'); +</script> diff --git a/tests/wpt/mozilla/tests/mozilla/bluetooth/startNotifications/characteristic-does-not-support-notifications.html b/tests/wpt/mozilla/tests/mozilla/bluetooth/startNotifications/characteristic-does-not-support-notifications.html new file mode 100644 index 00000000000..b47023a39e4 --- /dev/null +++ b/tests/wpt/mozilla/tests/mozilla/bluetooth/startNotifications/characteristic-does-not-support-notifications.html @@ -0,0 +1,20 @@ +<!doctype html> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/_mozilla/mozilla/bluetooth/bluetooth-helpers.js"></script> +<script> +'use strict'; +promise_test(t => { + window.testRunner.setBluetoothMockDataSet(adapter_type.heart_rate); + return window.navigator.bluetooth.requestDevice({ + filters: [{services: [heart_rate.name]}], + optionalServices: [generic_access.name] + }) + .then(device => device.gatt.connect()) + .then(gattServer => gattServer.getPrimaryService(heart_rate.name)) + .then(service => service.getCharacteristic(body_sensor_location.name)) + .then(characteristic => { + return promise_rejects(t, 'NotSupportedError', characteristic.startNotifications()); + }); +}, 'Characteristic doesn\'t support Notifications. Reject with NotSupportedError.'); +</script> diff --git a/tests/wpt/mozilla/tests/mozilla/bluetooth/startNotifications/device-goes-out-of-range.html b/tests/wpt/mozilla/tests/mozilla/bluetooth/startNotifications/device-goes-out-of-range.html new file mode 100644 index 00000000000..dd561a84dbd --- /dev/null +++ b/tests/wpt/mozilla/tests/mozilla/bluetooth/startNotifications/device-goes-out-of-range.html @@ -0,0 +1,20 @@ +<!doctype html> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/_mozilla/mozilla/bluetooth/bluetooth-helpers.js"></script> +<script> +'use strict'; +promise_test(t => { + window.testRunner.setBluetoothMockDataSet(adapter_type.heart_rate); + return window.navigator.bluetooth.requestDevice({ + filters: [{services: [heart_rate.name]}] + }) + .then(device => device.gatt.connect()) + .then(gattServer => gattServer.getPrimaryService(heart_rate.name)) + .then(service => service.getCharacteristic(heart_rate_measurement.name)) + .then(characteristic => { + window.testRunner.setBluetoothMockDataSet(adapter_type.empty); + return promise_rejects(t, 'InvalidStateError', characteristic.startNotifications()); + }); +}, 'Device goes out of range. Reject with InvalidStateError.'); +</script> diff --git a/tests/wpt/mozilla/tests/mozilla/bluetooth/startNotifications/service-is-removed.html b/tests/wpt/mozilla/tests/mozilla/bluetooth/startNotifications/service-is-removed.html new file mode 100644 index 00000000000..2976971d30e --- /dev/null +++ b/tests/wpt/mozilla/tests/mozilla/bluetooth/startNotifications/service-is-removed.html @@ -0,0 +1,21 @@ +<!doctype html> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/_mozilla/mozilla/bluetooth/bluetooth-helpers.js"></script> +<script> +'use strict'; +promise_test(t => { + window.testRunner.setBluetoothMockDataSet(adapter_type.heart_rate); + return window.navigator.bluetooth.requestDevice({ + filters: [{services: [heart_rate.name]}], + optionalServices: [generic_access.name] + }) + .then(device => device.gatt.connect()) + .then(gattServer => gattServer.getPrimaryService(heart_rate.name)) + .then(service => service.getCharacteristic(heart_rate_measurement.name)) + .then(characteristic => { + window.testRunner.setBluetoothMockDataSet(adapter_type.missing_service_heart_rate); + return promise_rejects(t, 'InvalidStateError', characteristic.startNotifications()); + }); +}, 'Service gets removed. Reject with InvalidStateError.'); +</script> diff --git a/tests/wpt/mozilla/tests/mozilla/bluetooth/stopNotifications/disconnect-called-before.html b/tests/wpt/mozilla/tests/mozilla/bluetooth/stopNotifications/disconnect-called-before.html index edcf89c2cc6..d94d19e6b8e 100644 --- a/tests/wpt/mozilla/tests/mozilla/bluetooth/stopNotifications/disconnect-called-before.html +++ b/tests/wpt/mozilla/tests/mozilla/bluetooth/stopNotifications/disconnect-called-before.html @@ -17,8 +17,8 @@ promise_test(t => { .then(characteristic => characteristic.startNotifications()) .then(characteristic => { gattServer.disconnect(); - return promise_rejects(t, 'NetworkError', characteristic.startNotifications()); + return promise_rejects(t, 'InvalidStateError', characteristic.stopNotifications()); }); }); -}, 'disconnect() called before stopNotifications. Reject with NetworkError.'); +}, 'disconnect() called before stopNotifications. Reject with InvalidStateError.'); </script> diff --git a/tests/wpt/mozilla/tests/mozilla/bluetooth/stopNotifications/disconnect-called-during.html b/tests/wpt/mozilla/tests/mozilla/bluetooth/stopNotifications/disconnect-called-during.html index a10f9c1f116..34f15f3db37 100644 --- a/tests/wpt/mozilla/tests/mozilla/bluetooth/stopNotifications/disconnect-called-during.html +++ b/tests/wpt/mozilla/tests/mozilla/bluetooth/stopNotifications/disconnect-called-during.html @@ -16,10 +16,10 @@ promise_test(t => { .then(service => service.getCharacteristic(heart_rate_measurement.name)) .then(characteristic => characteristic.startNotifications()) .then(characteristic => { - let promise = promise_rejects(t, 'NetworkError', characteristic.startNotifications()); + let promise = promise_rejects(t, 'InvalidStateError', characteristic.stopNotifications()); gattServer.disconnect(); return promise; }); }); -}, 'disconnect() called during stopNotifications. Reject with NetworkError.'); +}, 'disconnect() called during stopNotifications. Reject with InvalidStateError.'); </script> diff --git a/tests/wpt/mozilla/tests/mozilla/bluetooth/stopNotifications/stop-after-start-succeeds.html b/tests/wpt/mozilla/tests/mozilla/bluetooth/stopNotifications/stop-after-start-succeeds.html new file mode 100644 index 00000000000..355688bd492 --- /dev/null +++ b/tests/wpt/mozilla/tests/mozilla/bluetooth/stopNotifications/stop-after-start-succeeds.html @@ -0,0 +1,25 @@ +<!doctype html> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/_mozilla/mozilla/bluetooth/bluetooth-helpers.js"></script> +<script> +'use strict'; +promise_test(() => { + window.testRunner.setBluetoothMockDataSet(adapter_type.heart_rate); + return window.navigator.bluetooth.requestDevice({ + filters: [{services: [heart_rate.name]}], + optionalServices: [generic_access.name] + }) + .then(device => device.gatt.connect()) + .then(gattServer => gattServer.getPrimaryService(heart_rate.name)) + .then(service => service.getCharacteristic(heart_rate_measurement.name)) + .then(characteristic => { + return characteristic.startNotifications() + .then(start_characteristic => { + assert_equals(start_characteristic, characteristic); + return characteristic.stopNotifications() + .then(stop_characteristic => assert_equals(stop_characteristic, start_characteristic)); + }); + }); +}, 'Single stop after start notifications succeeds.'); +</script> diff --git a/tests/wpt/mozilla/tests/mozilla/bluetooth/stopNotifications/stop-twice.html b/tests/wpt/mozilla/tests/mozilla/bluetooth/stopNotifications/stop-twice.html new file mode 100644 index 00000000000..92ebd704d08 --- /dev/null +++ b/tests/wpt/mozilla/tests/mozilla/bluetooth/stopNotifications/stop-twice.html @@ -0,0 +1,22 @@ +<!doctype html> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/_mozilla/mozilla/bluetooth/bluetooth-helpers.js"></script> +<script> +'use strict'; +promise_test(() => { + window.testRunner.setBluetoothMockDataSet(adapter_type.heart_rate); + return window.navigator.bluetooth.requestDevice({ + filters: [{services: [heart_rate.name]}], + optionalServices: [generic_access.name] + }) + .then(device => device.gatt.connect()) + .then(gattServer => gattServer.getPrimaryService(heart_rate.name)) + .then(service => service.getCharacteristic(heart_rate_measurement.name)) + .then(characteristic => { + return characteristic.startNotifications() + .then(() => characteristic.stopNotifications()) + .then(() => characteristic.stopNotifications()); + }); +}, 'Stopping twice.'); +</script> diff --git a/tests/wpt/mozilla/tests/mozilla/bluetooth/stopNotifications/stop-without-starting.html b/tests/wpt/mozilla/tests/mozilla/bluetooth/stopNotifications/stop-without-starting.html new file mode 100644 index 00000000000..2ff505377e5 --- /dev/null +++ b/tests/wpt/mozilla/tests/mozilla/bluetooth/stopNotifications/stop-without-starting.html @@ -0,0 +1,18 @@ +<!doctype html> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/_mozilla/mozilla/bluetooth/bluetooth-helpers.js"></script> +<script> +'use strict'; +promise_test(() => { + window.testRunner.setBluetoothMockDataSet(adapter_type.heart_rate); + return window.navigator.bluetooth.requestDevice({ + filters: [{services: [heart_rate.name]}], + optionalServices: [generic_access.name] + }) + .then(device => device.gatt.connect()) + .then(gattServer => gattServer.getPrimaryService(heart_rate.name)) + .then(service => service.getCharacteristic(heart_rate_measurement.name)) + .then(characteristic => characteristic.stopNotifications()); +}, 'Stop without starting.'); +</script> diff --git a/tests/wpt/mozilla/tests/mozilla/bluetooth/writeValue/characteristic/value-too-long.html b/tests/wpt/mozilla/tests/mozilla/bluetooth/writeValue/characteristic/value-too-long.html new file mode 100644 index 00000000000..cb17b549e36 --- /dev/null +++ b/tests/wpt/mozilla/tests/mozilla/bluetooth/writeValue/characteristic/value-too-long.html @@ -0,0 +1,19 @@ +<!doctype html> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/_mozilla/mozilla/bluetooth/bluetooth-helpers.js"></script> +<script> +'use strict'; +promise_test(t => { + window.testRunner.setBluetoothMockDataSet(adapter_type.heart_rate); + return window.navigator.bluetooth.requestDevice({ + filters: [{services: [heart_rate.name]}], + optionalServices: [generic_access.name] + }) + .then(device => device.gatt.connect()) + .then(gattServer => gattServer.getPrimaryService(generic_access.name)) + .then(service => service.getCharacteristic(device_name.name)) + .then(characteristic => + promise_rejects(t, 'InvalidModificationError', characteristic.writeValue(new Uint8Array(513)))); +}, 'Trying to write more than 512 bytes should return an InvalidModificationError.'); +</script> diff --git a/tests/wpt/mozilla/tests/mozilla/interfaces.html b/tests/wpt/mozilla/tests/mozilla/interfaces.html index a658a8eb346..6f774fec8da 100644 --- a/tests/wpt/mozilla/tests/mozilla/interfaces.html +++ b/tests/wpt/mozilla/tests/mozilla/interfaces.html @@ -22,6 +22,7 @@ test_interfaces([ "CSS", "CSSFontFaceRule", "CSSGroupingRule", + "CSSImportRule", "CSSKeyframeRule", "CSSKeyframesRule", "CSSMediaRule", @@ -142,6 +143,7 @@ test_interfaces([ "MediaError", "MediaList", "MediaQueryList", + "MediaQueryListEvent", "MessageEvent", "MimeType", "MimeTypeArray", diff --git a/tests/wpt/mozilla/tests/mozilla/keyframe-infinite-percentage.html b/tests/wpt/mozilla/tests/mozilla/keyframe-infinite-percentage.html new file mode 100644 index 00000000000..36ba83eeac4 --- /dev/null +++ b/tests/wpt/mozilla/tests/mozilla/keyframe-infinite-percentage.html @@ -0,0 +1,15 @@ +<!doctype html> +<meta charset="utf-8"> +<title>Shouldn't end up with an invalid keyframe when inf or nan are at play.</title> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<style> +@keyframes anim { + 0e309% {} +} +</style> +<script> +test(function() { + assert_true(true, "Doesn't crash"); +}, "Doesn't crash"); +</script> diff --git a/tests/wpt/mozilla/tests/mozilla/textarea_placeholder.html b/tests/wpt/mozilla/tests/mozilla/textarea_placeholder.html new file mode 100644 index 00000000000..6dd1f1e1e0c --- /dev/null +++ b/tests/wpt/mozilla/tests/mozilla/textarea_placeholder.html @@ -0,0 +1,11 @@ +<!doctype html> +<meta charset="utf-8"> +<link rel="match" href="textarea_placeholder_ref.html"> + +<textarea placeholder=""></textarea> +<textarea placeholder=" "></textarea> +<textarea placeholder="foobar"></textarea> +<textarea placeholder=" foo bar "></textarea> +<textarea rows=5 placeholder="
foo + bar
"></textarea> +<textarea placeholder="foo bar">lorem ipsum</textarea> diff --git a/tests/wpt/mozilla/tests/mozilla/textarea_placeholder_ref.html b/tests/wpt/mozilla/tests/mozilla/textarea_placeholder_ref.html new file mode 100644 index 00000000000..46d2686144f --- /dev/null +++ b/tests/wpt/mozilla/tests/mozilla/textarea_placeholder_ref.html @@ -0,0 +1,13 @@ +<!doctype html> +<meta charset="utf-8"> + +<textarea></textarea> +<textarea></textarea> +<textarea>foobar</textarea> +<textarea> foo bar </textarea> +<textarea rows=5> + + foo + bar +</textarea> +<textarea>lorem ipsum</textarea> diff --git a/tests/wpt/mozilla/tests/mozilla/timeout-in-discarded-document.html b/tests/wpt/mozilla/tests/mozilla/timeout-in-discarded-document.html new file mode 100644 index 00000000000..60d35230d09 --- /dev/null +++ b/tests/wpt/mozilla/tests/mozilla/timeout-in-discarded-document.html @@ -0,0 +1,14 @@ +<!doctype html> +<meta charset="utf-8"> +<title>Timeout in a discarded document doesn't break the browser.</title> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<iframe></iframe> +<script> + async_test(function(t) { + var i = document.querySelector('iframe'); + i.contentWindow.setTimeout(function() {}, 10); + i.remove(); + t.step_timeout(function() { t.done() }, 100); + }); +</script> diff --git a/tests/wpt/web-platform-tests/css-values/unset-value-storage.html b/tests/wpt/web-platform-tests/css-values/unset-value-storage.html new file mode 100644 index 00000000000..9cf13b250d8 --- /dev/null +++ b/tests/wpt/web-platform-tests/css-values/unset-value-storage.html @@ -0,0 +1,23 @@ +<!DOCTYPE html> +<meta charset="utf-8"> +<title>Storage of "unset" value</title> +<meta name="author" title="Xidorn Quan" href="https://www.upsuper.org"> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<style> + div { + color: unset; + border: unset; + } +</style> +<body> + <div id="log"></div> + <script> + test(function() { + let properties = ["color", "border", "border-left", "border-color", "border-right-style"]; + let style = document.styleSheets[0].cssRules[0].style; + for (let prop of properties) { + assert_equals(style.getPropertyValue(prop), "unset", `${prop} is expected to be "unset"`); + } + }); + </script> diff --git a/tests/wpt/web-platform-tests/cssom/CSSKeyframesRule.html b/tests/wpt/web-platform-tests/cssom/CSSKeyframesRule.html index b97d988c9ac..9cf387def86 100644 --- a/tests/wpt/web-platform-tests/cssom/CSSKeyframesRule.html +++ b/tests/wpt/web-platform-tests/cssom/CSSKeyframesRule.html @@ -15,18 +15,19 @@ <script> test(function () { var keyframe = document.styleSheets[0].cssRules[0]; + assert_equals(keyframe.name, "foo", "CSSKeyframesRule name attribute"); assert_equals(keyframe.cssRules.length, 2, "CSSKeyframesRule cssRule length attribute"); assert_equals(keyframe.cssRules[0].cssText, "0% { top: 0px; }", "CSSKeyframesRule cssRule cssText attribute"); assert_equals(keyframe.cssRules[1].cssText, "100% { top: 200px; }", "CSSKeyframesRule cssRule cssText attribute"); keyframe.appendRule("50% { top: 100px; }"); - assert_equals(keyframe.cssRules.length, 3, "CSSKeyframesRule prefix attribute after appendRule function"); + assert_equals(keyframe.cssRules.length, 3, "CSSKeyframesRule cssRule length attribute after appendRule function"); assert_equals(keyframe.cssRules[0].cssText, "0% { top: 0px; }", "CSSKeyframesRule cssRule cssText attribute after appendRule function"); assert_equals(keyframe.cssRules[1].cssText, "100% { top: 200px; }", "CSSKeyframesRule cssRule cssText attribute after appendRule function"); assert_equals(keyframe.cssRules[2].cssText, "50% { top: 100px; }", "CSSKeyframesRule cssRule cssText attribute after appendRule function"); keyframe.appendRule("0% { top: 50px; }"); - assert_equals(keyframe.cssRules.length, 4, "CSSKeyframesRule prefix attribute after appendRule function"); + assert_equals(keyframe.cssRules.length, 4, "CSSKeyframesRule cssRule length attribute after appendRule function"); assert_equals(keyframe.cssRules[0].cssText, "0% { top: 0px; }", "CSSKeyframesRule cssRule cssText attribute after appendRule function"); assert_equals(keyframe.cssRules[1].cssText, "100% { top: 200px; }", "CSSKeyframesRule cssRule cssText attribute after appendRule function"); assert_equals(keyframe.cssRules[2].cssText, "50% { top: 100px; }", "CSSKeyframesRule cssRule cssText attribute after appendRule function"); @@ -40,18 +41,29 @@ assert_equals(find3, null, "CSSKeyframesRule findRule function"); keyframe.deleteRule("100%"); - assert_equals(keyframe.cssRules.length, 3, "CSSKeyframesRule prefix attribute after deleteRule function"); + assert_equals(keyframe.cssRules.length, 3, "CSSKeyframesRule cssRule length attribute after deleteRule function"); assert_equals(keyframe.cssRules[0].cssText, "0% { top: 0px; }", "CSSKeyframesRule cssRule cssText attribute after deleteRule function"); assert_equals(keyframe.cssRules[1].cssText, "50% { top: 100px; }", "CSSKeyframesRule cssRule cssText attribute after deleteRule function"); assert_equals(keyframe.cssRules[2].cssText, "0% { top: 50px; }", "CSSKeyframesRule cssRule cssText attribute after deleteRule function"); assert_equals(keyframe.cssRules[3], undefined, "CSSKeyframesRule cssRule cssText attribute after deleteRule function"); keyframe.deleteRule("80%"); - assert_equals(keyframe.cssRules.length, 3, "CSSKeyframesRule prefix attribute after deleteRule function"); + assert_equals(keyframe.cssRules.length, 3, "CSSKeyframesRule cssRule length attribute after deleteRule function"); assert_equals(keyframe.cssRules[0].cssText, "0% { top: 0px; }", "CSSKeyframesRule cssRule cssText attribute after deleteRule function"); assert_equals(keyframe.cssRules[1].cssText, "50% { top: 100px; }", "CSSKeyframesRule cssRule cssText attribute after deleteRule function"); assert_equals(keyframe.cssRules[2].cssText, "0% { top: 50px; }", "CSSKeyframesRule cssRule cssText attribute after deleteRule function"); assert_equals(keyframe.cssRules[3], undefined, "CSSKeyframesRule cssRule cssText attribute after deleteRule function"); + + keyframe.name = "bar"; + assert_equals(keyframe.name, "bar", "CSSKeyframesRule name setter"); + + assert_throws("SyntaxError", + function () { keyframe.name = "initial"; }, + "CSSKeyframesRule name setter on invalid keyword."); + + assert_throws("SyntaxError", + function () { keyframe.name = "none"; }, + "CSSKeyframesRule name setter on invalid keyword."); }); </script> </head> diff --git a/tests/wpt/web-platform-tests/cssom/CSSStyleRule.html b/tests/wpt/web-platform-tests/cssom/CSSStyleRule.html new file mode 100644 index 00000000000..e6b68d7503d --- /dev/null +++ b/tests/wpt/web-platform-tests/cssom/CSSStyleRule.html @@ -0,0 +1,24 @@ +<!doctype html> +<meta charset="utf-8"> +<title></title> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<style type="text/css" id="styleElement"> + div { margin: 10px; padding: 0px; } +</style> +<script> + var styleSheet = document.getElementById("styleElement").sheet; + var rule = styleSheet.cssRules[0]; + + test(function() { + assert_equals(typeof rule.style, "object"); + assert_equals(rule.style.margin, "10px"); + assert_equals(rule.style.padding, "0px"); + + rule.style.padding = "5px"; + rule.style.border = "1px solid"; + + assert_equals(rule.style.padding, "5px"); + assert_equals(rule.style.border, "1px solid"); + }, "CSSStyleRule: style property"); +</script> diff --git a/tests/wpt/web-platform-tests/fetch/api/request/multi-globals/current/current.html b/tests/wpt/web-platform-tests/fetch/api/request/multi-globals/current/current.html index 82a48d40990..9bb6e0bbf3f 100644 --- a/tests/wpt/web-platform-tests/fetch/api/request/multi-globals/current/current.html +++ b/tests/wpt/web-platform-tests/fetch/api/request/multi-globals/current/current.html @@ -1,2 +1,3 @@ <!DOCTYPE html> <title>Current page used as a test helper</title> +<base href="success/"> diff --git a/tests/wpt/web-platform-tests/fetch/api/request/multi-globals/incumbent/incumbent.html b/tests/wpt/web-platform-tests/fetch/api/request/multi-globals/incumbent/incumbent.html index 8edc71cfb12..a885b8a0a73 100644 --- a/tests/wpt/web-platform-tests/fetch/api/request/multi-globals/incumbent/incumbent.html +++ b/tests/wpt/web-platform-tests/fetch/api/request/multi-globals/incumbent/incumbent.html @@ -6,9 +6,8 @@ <script> 'use strict'; -const current = document.querySelector('#c').contentWindow; - window.createRequest = (...args) => { + const current = document.querySelector('#c').contentWindow; return new current.Request(...args); }; diff --git a/tests/wpt/web-platform-tests/fetch/api/request/multi-globals/url-parsing.html b/tests/wpt/web-platform-tests/fetch/api/request/multi-globals/url-parsing.html index f20298ad628..df60e72507f 100644 --- a/tests/wpt/web-platform-tests/fetch/api/request/multi-globals/url-parsing.html +++ b/tests/wpt/web-platform-tests/fetch/api/request/multi-globals/url-parsing.html @@ -18,9 +18,9 @@ const loadPromise = new Promise(resolve => { promise_test(() => { return loadPromise.then(() => { - const req = frames[0].createRequest("url"); + const req = document.querySelector('iframe').contentWindow.createRequest("url"); - assert_equals(req.url, new URL("current/url", location.href).href); + assert_equals(req.url, new URL("current/success/url", location.href).href); }); }, "should parse the URL relative to the current settings object"); diff --git a/tests/wpt/web-platform-tests/fetch/api/request/request-bad-port.html b/tests/wpt/web-platform-tests/fetch/api/request/request-bad-port.html new file mode 100644 index 00000000000..e7535cf50a5 --- /dev/null +++ b/tests/wpt/web-platform-tests/fetch/api/request/request-bad-port.html @@ -0,0 +1,82 @@ +<!doctype html> +<meta charset="utf-8"> +<title></title> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script> + + // list of bad ports according to + // https://fetch.spec.whatwg.org/#port-blocking + var BLOCKED_PORTS_LIST = [ + 1, // tcpmux + 7, // echo + 9, // discard + 11, // systat + 13, // daytime + 15, // netstat + 17, // qotd + 19, // chargen + 20, // ftp-data + 21, // ftp + 22, // ssh + 23, // telnet + 25, // smtp + 37, // time + 42, // name + 43, // nicname + 53, // domain + 77, // priv-rjs + 79, // finger + 87, // ttylink + 95, // supdup + 101, // hostriame + 102, // iso-tsap + 103, // gppitnp + 104, // acr-nema + 109, // pop2 + 110, // pop3 + 111, // sunrpc + 113, // auth + 115, // sftp + 117, // uucp-path + 119, // nntp + 123, // ntp + 135, // loc-srv / epmap + 139, // netbios + 143, // imap2 + 179, // bgp + 389, // ldap + 465, // smtp+ssl + 512, // print / exec + 513, // login + 514, // shell + 515, // printer + 526, // tempo + 530, // courier + 531, // chat + 532, // netnews + 540, // uucp + 556, // remotefs + 563, // nntp+ssl + 587, // smtp + 601, // syslog-conn + 636, // ldap+ssl + 993, // imap+ssl + 995, // pop3+ssl + 2049, // nfs + 3659, // apple-sasl + 4045, // lockd + 6000, // x11 + 6665, // irc (alternate) + 6666, // irc (alternate) + 6667, // irc (default) + 6668, // irc (alternate) + 6669, // irc (alternate) + ]; + + BLOCKED_PORTS_LIST.map(function(a){ + promise_test(function(t){ + return promise_rejects(t, new TypeError(), fetch("http://example.com:" + a)) + }, 'Request on bad port ' + a + ' should throw TypeError.'); + }); +</script> diff --git a/tests/wpt/web-platform-tests/fetch/api/response/multi-globals/current/current.html b/tests/wpt/web-platform-tests/fetch/api/response/multi-globals/current/current.html index 82a48d40990..9bb6e0bbf3f 100644 --- a/tests/wpt/web-platform-tests/fetch/api/response/multi-globals/current/current.html +++ b/tests/wpt/web-platform-tests/fetch/api/response/multi-globals/current/current.html @@ -1,2 +1,3 @@ <!DOCTYPE html> <title>Current page used as a test helper</title> +<base href="success/"> diff --git a/tests/wpt/web-platform-tests/fetch/api/response/multi-globals/incumbent/incumbent.html b/tests/wpt/web-platform-tests/fetch/api/response/multi-globals/incumbent/incumbent.html index 4d1ee085440..f63372e64c2 100644 --- a/tests/wpt/web-platform-tests/fetch/api/response/multi-globals/incumbent/incumbent.html +++ b/tests/wpt/web-platform-tests/fetch/api/response/multi-globals/incumbent/incumbent.html @@ -7,10 +7,9 @@ <script> 'use strict'; -const current = document.querySelector('#c').contentWindow; -const relevant = document.querySelector('#r').contentWindow; - window.createRedirectResponse = (...args) => { + const current = document.querySelector('#c').contentWindow; + const relevant = document.querySelector('#r').contentWindow; return current.Response.redirect.call(relevant.Response, ...args); }; diff --git a/tests/wpt/web-platform-tests/fetch/api/response/multi-globals/url-parsing.html b/tests/wpt/web-platform-tests/fetch/api/response/multi-globals/url-parsing.html index 73bf9cfd0ad..5f2f42a1cea 100644 --- a/tests/wpt/web-platform-tests/fetch/api/response/multi-globals/url-parsing.html +++ b/tests/wpt/web-platform-tests/fetch/api/response/multi-globals/url-parsing.html @@ -18,9 +18,9 @@ const loadPromise = new Promise(resolve => { promise_test(() => { return loadPromise.then(() => { - const res = frames[0].createRedirectResponse("url"); + const res = document.querySelector('iframe').contentWindow.createRedirectResponse("url"); - assert_equals(res.headers.get("Location"), new URL("current/url", location.href).href); + assert_equals(res.headers.get("Location"), new URL("current/success/url", location.href).href); }); }, "should parse the redirect Location URL relative to the current settings object"); diff --git a/tests/wpt/web-platform-tests/html/semantics/forms/the-select-element/select-value.html b/tests/wpt/web-platform-tests/html/semantics/forms/the-select-element/select-value.html new file mode 100644 index 00000000000..d8d5263e3e7 --- /dev/null +++ b/tests/wpt/web-platform-tests/html/semantics/forms/the-select-element/select-value.html @@ -0,0 +1,56 @@ +<!doctype html> +<meta charset="utf-8"> +<title>HTMLSelectElement.value</title> +<link rel="help" href="https://html.spec.whatwg.org/multipage/forms.html#dom-select-value"> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<div id=log></div> + +<select id=sel1> + <option value=0></option> + <option selected value=1></option> +</select> + +<select id=sel2> + <optgroup> + <option value=0></option> + </optgroup> + <optgroup></optgroup> + <optgroup> + <option></option> + <option value=1></option> + <option selected value=2></option> + </optgroup> +</select> + +<select id=sel3> + <option selected value=1></option> +</select> + +<select id=sel4></select> + +<script> +test(function() { + var select = document.getElementById('sel1'); + assert_equals(select.value, '1'); +}, 'options'); + +test(function() { + var select = document.getElementById('sel2'); + assert_equals(select.value, '2'); +}, 'optgroups'); + +test(function() { + var select = document.getElementById('sel3'); + var option = select.options[0]; + var div = document.createElement('div'); + select.appendChild(div); + div.appendChild(option); + assert_equals(select.value, ''); +}, 'option is child of div'); + +test(function() { + var select = document.getElementById('sel4'); + assert_equals(select.value, ''); +}, 'no options'); +</script> diff --git a/tests/wpt/web-platform-tests/html/semantics/text-level-semantics/the-time-element/001.html b/tests/wpt/web-platform-tests/html/semantics/text-level-semantics/the-time-element/001.html index e732e84e41f..1caceb5b3a7 100644 --- a/tests/wpt/web-platform-tests/html/semantics/text-level-semantics/the-time-element/001.html +++ b/tests/wpt/web-platform-tests/html/semantics/text-level-semantics/the-time-element/001.html @@ -58,12 +58,9 @@ test(function () { test(function () { assert_equals( makeTime('go fish').dateTime, 'go fish' ); }, 'the datetime attribute should be reflected by the .dateTime property even if it is invalid'); -test(function () { - assert_equals( makeTime(false,'2000-02-01T03:04:05Z', '2000-02-01').dateTime, '2000-02-01' ); -}, 'the datetime content attribute should not reflect the textContent when datetime attribute is present.'); -test(function () { - assert_equals( makeTime(false,'2000-02-01T03:04:05Z').dateTime, '2000-02-01T03:04:05Z' ); -}, 'the datetime content attribute should reflect the textContent when datetime attribute is absent.'); +test(function() { + assert_equals( makeTime(false,'2000-02-01T03:04:05Z').dateTime, '' ); +}, 'the datetime attribute should not reflect the textContent'); </script> </body> |