aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.travis.yml3
-rw-r--r--README.md16
-rw-r--r--appveyor.yml6
-rw-r--r--cargo-nightly-build2
-rw-r--r--components/canvas/Cargo.toml2
-rw-r--r--components/canvas_traits/Cargo.toml6
-rw-r--r--components/canvas_traits/lib.rs1
-rw-r--r--components/compositing/Cargo.toml6
-rw-r--r--components/compositing/compositor.rs2
-rw-r--r--components/constellation/Cargo.toml6
-rw-r--r--components/constellation/constellation.rs80
-rw-r--r--components/constellation/pipeline.rs65
-rw-r--r--components/devtools/Cargo.toml6
-rw-r--r--components/devtools/actors/inspector.rs8
-rw-r--r--components/devtools/actors/network_event.rs7
-rw-r--r--components/devtools_traits/Cargo.toml6
-rw-r--r--components/devtools_traits/lib.rs9
-rw-r--r--components/gfx/Cargo.toml6
-rw-r--r--components/gfx/display_list/mod.rs57
-rw-r--r--components/gfx/paint_context.rs21
-rw-r--r--components/gfx/paint_thread.rs10
-rw-r--r--components/gfx_traits/Cargo.toml4
-rw-r--r--components/layout/Cargo.toml4
-rw-r--r--components/layout/block.rs10
-rw-r--r--components/layout/display_list_builder.rs6
-rw-r--r--components/layout/fragment.rs22
-rw-r--r--components/layout/table_cell.rs10
-rw-r--r--components/layout/table_row.rs3
-rw-r--r--components/layout/traversal.rs6
-rw-r--r--components/layout_thread/Cargo.toml4
-rw-r--r--components/layout_thread/lib.rs75
-rw-r--r--components/layout_traits/Cargo.toml2
-rw-r--r--components/layout_traits/lib.rs3
-rw-r--r--components/msg/Cargo.toml6
-rw-r--r--components/net/Cargo.toml4
-rw-r--r--components/net/blob_loader.rs54
-rw-r--r--components/net/bluetooth_thread.rs72
-rw-r--r--components/net/fetch/methods.rs53
-rw-r--r--components/net/filemanager_thread.rs328
-rw-r--r--components/net/http_loader.rs56
-rw-r--r--components/net/lib.rs2
-rw-r--r--components/net/resource_thread.rs70
-rw-r--r--components/net/storage_thread.rs18
-rw-r--r--components/net_traits/Cargo.toml6
-rw-r--r--components/net_traits/bluetooth_thread.rs12
-rw-r--r--components/net_traits/filemanager_thread.rs22
-rw-r--r--components/net_traits/lib.rs17
-rw-r--r--components/net_traits/request.rs15
-rw-r--r--components/plugins/jstraceable.rs2
-rw-r--r--components/profile/Cargo.toml6
-rw-r--r--components/profile_traits/Cargo.toml6
-rw-r--r--components/range/Cargo.toml4
-rw-r--r--components/script/Cargo.toml13
-rw-r--r--components/script/build.rs7
-rw-r--r--components/script/devtools.rs85
-rw-r--r--components/script/dom/abstractworker.rs2
-rw-r--r--components/script/dom/bindings/codegen/CodegenRust.py84
-rw-r--r--components/script/dom/bindings/error.rs109
-rw-r--r--components/script/dom/bindings/global.rs6
-rw-r--r--components/script/dom/bindings/interface.rs92
-rw-r--r--components/script/dom/bindings/proxyhandler.rs21
-rw-r--r--components/script/dom/bindings/trace.rs3
-rw-r--r--components/script/dom/blob.rs184
-rw-r--r--components/script/dom/bluetooth.rs18
-rw-r--r--components/script/dom/bluetoothremotegattcharacteristic.rs16
-rw-r--r--components/script/dom/bluetoothremotegattdescriptor.rs6
-rw-r--r--components/script/dom/bluetoothremotegattserver.rs10
-rw-r--r--components/script/dom/bluetoothremotegattservice.rs10
-rw-r--r--components/script/dom/browsingcontext.rs25
-rw-r--r--components/script/dom/dedicatedworkerglobalscope.rs10
-rw-r--r--components/script/dom/document.rs21
-rw-r--r--components/script/dom/element.rs3
-rw-r--r--components/script/dom/file.rs5
-rw-r--r--components/script/dom/filelist.rs5
-rw-r--r--components/script/dom/filereadersync.rs34
-rw-r--r--components/script/dom/headers.rs148
-rw-r--r--components/script/dom/history.rs70
-rw-r--r--components/script/dom/htmlcollection.rs2
-rw-r--r--components/script/dom/htmlformelement.rs190
-rw-r--r--components/script/dom/htmlinputelement.rs51
-rw-r--r--components/script/dom/htmllielement.rs25
-rw-r--r--components/script/dom/htmlmediaelement.rs53
-rw-r--r--components/script/dom/htmltableelement.rs60
-rw-r--r--components/script/dom/macros.rs16
-rw-r--r--components/script/dom/mod.rs2
-rw-r--r--components/script/dom/node.rs50
-rw-r--r--components/script/dom/serviceworkerglobalscope.rs60
-rw-r--r--components/script/dom/servohtmlparser.rs16
-rw-r--r--components/script/dom/url.rs6
-rw-r--r--components/script/dom/virtualmethods.rs4
-rw-r--r--components/script/dom/webidls/DedicatedWorkerGlobalScope.webidl2
-rw-r--r--components/script/dom/webidls/FileReaderSync.webidl15
-rw-r--r--components/script/dom/webidls/HTMLAnchorElement.webidl1
-rw-r--r--components/script/dom/webidls/HTMLAppletElement.webidl1
-rw-r--r--components/script/dom/webidls/HTMLAreaElement.webidl1
-rw-r--r--components/script/dom/webidls/HTMLAudioElement.webidl1
-rw-r--r--components/script/dom/webidls/HTMLBRElement.webidl1
-rw-r--r--components/script/dom/webidls/HTMLBaseElement.webidl1
-rw-r--r--components/script/dom/webidls/HTMLBodyElement.webidl1
-rw-r--r--components/script/dom/webidls/HTMLButtonElement.webidl1
-rw-r--r--components/script/dom/webidls/HTMLDListElement.webidl1
-rw-r--r--components/script/dom/webidls/HTMLDataElement.webidl1
-rw-r--r--components/script/dom/webidls/HTMLDataListElement.webidl1
-rw-r--r--components/script/dom/webidls/HTMLDetailsElement.webidl1
-rw-r--r--components/script/dom/webidls/HTMLDialogElement.webidl1
-rw-r--r--components/script/dom/webidls/HTMLDirectoryElement.webidl1
-rw-r--r--components/script/dom/webidls/HTMLDivElement.webidl1
-rw-r--r--components/script/dom/webidls/HTMLEmbedElement.webidl1
-rw-r--r--components/script/dom/webidls/HTMLFieldSetElement.webidl1
-rw-r--r--components/script/dom/webidls/HTMLFontElement.webidl1
-rw-r--r--components/script/dom/webidls/HTMLFrameElement.webidl1
-rw-r--r--components/script/dom/webidls/HTMLFrameSetElement.webidl1
-rw-r--r--components/script/dom/webidls/HTMLHRElement.webidl1
-rw-r--r--components/script/dom/webidls/HTMLHeadingElement.webidl1
-rw-r--r--components/script/dom/webidls/HTMLHtmlElement.webidl1
-rw-r--r--components/script/dom/webidls/HTMLHyperlinkElementUtils.webidl2
-rw-r--r--components/script/dom/webidls/HTMLIFrameElement.webidl1
-rw-r--r--components/script/dom/webidls/HTMLImageElement.webidl2
-rw-r--r--components/script/dom/webidls/HTMLInputElement.webidl1
-rw-r--r--components/script/dom/webidls/HTMLLIElement.webidl3
-rw-r--r--components/script/dom/webidls/HTMLLabelElement.webidl1
-rw-r--r--components/script/dom/webidls/HTMLLegendElement.webidl1
-rw-r--r--components/script/dom/webidls/HTMLParagraphElement.webidl1
-rw-r--r--components/script/dom/webidls/HTMLParamElement.webidl1
-rw-r--r--components/script/dom/webidls/HTMLPreElement.webidl1
-rw-r--r--components/script/dom/webidls/HTMLProgressElement.webidl1
-rw-r--r--components/script/dom/webidls/HTMLQuoteElement.webidl1
-rw-r--r--components/script/dom/webidls/HTMLSelectElement.webidl1
-rw-r--r--components/script/dom/webidls/HTMLSourceElement.webidl1
-rw-r--r--components/script/dom/webidls/HTMLSpanElement.webidl1
-rw-r--r--components/script/dom/webidls/HTMLStyleElement.webidl1
-rw-r--r--components/script/dom/webidls/HTMLTableCaptionElement.webidl1
-rw-r--r--components/script/dom/webidls/HTMLTableCellElement.webidl2
-rw-r--r--components/script/dom/webidls/HTMLTableColElement.webidl1
-rw-r--r--components/script/dom/webidls/HTMLTableDataCellElement.webidl1
-rw-r--r--components/script/dom/webidls/HTMLTableElement.webidl3
-rw-r--r--components/script/dom/webidls/HTMLTableHeaderCellElement.webidl1
-rw-r--r--components/script/dom/webidls/HTMLTableRowElement.webidl1
-rw-r--r--components/script/dom/webidls/HTMLTableSectionElement.webidl1
-rw-r--r--components/script/dom/webidls/HTMLTemplateElement.webidl1
-rw-r--r--components/script/dom/webidls/HTMLTextAreaElement.webidl1
-rw-r--r--components/script/dom/webidls/HTMLTimeElement.webidl1
-rw-r--r--components/script/dom/webidls/HTMLTitleElement.webidl1
-rw-r--r--components/script/dom/webidls/HTMLTrackElement.webidl1
-rw-r--r--components/script/dom/webidls/HTMLUListElement.webidl1
-rw-r--r--components/script/dom/webidls/HTMLUnknownElement.webidl1
-rw-r--r--components/script/dom/webidls/HTMLVideoElement.webidl1
-rw-r--r--components/script/dom/webidls/Headers.webidl24
-rw-r--r--components/script/dom/webidls/History.webidl18
-rw-r--r--components/script/dom/webidls/Window.webidl2
-rw-r--r--components/script/dom/websocket.rs8
-rw-r--r--components/script/dom/window.rs32
-rw-r--r--components/script/dom/worker.rs20
-rw-r--r--components/script/dom/workerglobalscope.rs6
-rw-r--r--components/script/dom/xmlhttprequest.rs1
-rw-r--r--components/script/layout_wrapper.rs9
-rw-r--r--components/script/lib.rs6
-rw-r--r--components/script/script_runtime.rs8
-rw-r--r--components/script/script_thread.rs18
-rw-r--r--components/script/serviceworker_manager.rs30
-rw-r--r--components/script/webdriver_handlers.rs19
-rw-r--r--components/script_layout_interface/Cargo.toml2
-rw-r--r--components/script_layout_interface/message.rs1
-rw-r--r--components/script_traits/Cargo.toml6
-rw-r--r--components/script_traits/lib.rs2
-rw-r--r--components/script_traits/script_msg.rs8
-rw-r--r--components/script_traits/webdriver_msg.rs5
-rw-r--r--components/servo/.cargo/config3
-rw-r--r--components/servo/Cargo.lock264
-rw-r--r--components/servo/Cargo.toml2
-rw-r--r--components/servo/fake-ld.cmd2
-rw-r--r--components/servo/lib.rs4
-rw-r--r--components/servo/main.rs5
-rw-r--r--components/servo/servo.exe.manifest2
-rw-r--r--components/style/Cargo.toml4
-rw-r--r--components/style/animation.rs26
-rw-r--r--components/style/attr.rs12
-rw-r--r--components/style/data.rs4
-rw-r--r--components/style/dom.rs53
-rw-r--r--components/style/gecko_conversions.rs34
-rw-r--r--components/style/gecko_selector_impl.rs15
-rw-r--r--components/style/matching.rs21
-rw-r--r--components/style/parallel.rs38
-rw-r--r--components/style/properties/data.py17
-rw-r--r--components/style/properties/gecko.mako.rs41
-rw-r--r--components/style/properties/helpers.mako.rs6
-rw-r--r--components/style/properties/longhand/background.mako.rs2
-rw-r--r--components/style/properties/longhand/border.mako.rs2
-rw-r--r--components/style/properties/longhand/box.mako.rs9
-rw-r--r--components/style/properties/longhand/pointing.mako.rs2
-rw-r--r--components/style/properties/properties.mako.rs4
-rw-r--r--components/style/sequential.rs19
-rw-r--r--components/style/traversal.rs58
-rw-r--r--components/style/values.rs2286
-rw-r--r--components/style/values/computed/mod.rs634
-rw-r--r--components/style/values/mod.rs98
-rw-r--r--components/style/values/specified/mod.rs1609
-rw-r--r--components/util/Cargo.toml5
-rw-r--r--components/util/lib.rs3
-rw-r--r--components/util/opts.rs11
-rw-r--r--components/util/remutex.rs217
-rw-r--r--components/webdriver_server/Cargo.toml2
-rw-r--r--components/webdriver_server/lib.rs4
-rwxr-xr-xetc/ci/upload_nightly.sh4
-rw-r--r--ports/cef/Cargo.lock258
-rw-r--r--ports/geckolib/Cargo.lock8
-rw-r--r--ports/geckolib/data.rs11
-rw-r--r--ports/geckolib/gecko_bindings/bindings.rs8
-rw-r--r--ports/geckolib/gecko_bindings/structs_debug.rs823
-rw-r--r--ports/geckolib/gecko_bindings/structs_release.rs823
-rw-r--r--ports/geckolib/gecko_bindings/sugar/ns_style_coord.rs64
-rwxr-xr-xports/geckolib/gecko_bindings/tools/regen.py13
-rw-r--r--ports/geckolib/glue.rs33
-rw-r--r--ports/geckolib/string_cache/Cargo.toml2
-rw-r--r--python/mach_bootstrap.py1
-rw-r--r--python/servo/build_commands.py3
-rw-r--r--python/servo/package_commands.py59
-rw-r--r--python/servo/testing_commands.py3
-rw-r--r--python/tidy/servo_tidy/licenseck.py8
-rw-r--r--python/tidy/servo_tidy_tests/test_tidy.py9
-rw-r--r--resources/Servo.icobin0 -> 32988 bytes
-rw-r--r--resources/servo.css4
-rw-r--r--resources/shaders/blur.fs.glsl2
-rw-r--r--resources/shaders/box_shadow.fs.glsl4
-rw-r--r--resources/shaders/debug_color.fs.glsl2
-rw-r--r--resources/shaders/debug_font.fs.glsl6
-rw-r--r--resources/shaders/es2_common.vs.glsl2
-rw-r--r--resources/shaders/gl3_common.vs.glsl5
-rw-r--r--resources/shaders/prim_shared.glsl180
-rw-r--r--resources/shaders/ps_angle_gradient.fs.glsl39
-rw-r--r--resources/shaders/ps_angle_gradient.glsl13
-rw-r--r--resources/shaders/ps_angle_gradient.vs.glsl38
-rw-r--r--resources/shaders/ps_blend.fs.glsl10
-rw-r--r--resources/shaders/ps_blend.glsl6
-rw-r--r--resources/shaders/ps_blend.vs.glsl29
-rw-r--r--resources/shaders/ps_border.fs.glsl184
-rw-r--r--resources/shaders/ps_border.glsl24
-rw-r--r--resources/shaders/ps_border.vs.glsl113
-rw-r--r--resources/shaders/ps_box_shadow.fs.glsl151
-rw-r--r--resources/shaders/ps_box_shadow.glsl11
-rw-r--r--resources/shaders/ps_box_shadow.vs.glsl29
-rw-r--r--resources/shaders/ps_clear.fs.glsl7
-rw-r--r--resources/shaders/ps_clear.glsl3
-rw-r--r--resources/shaders/ps_clear.vs.glsl23
-rw-r--r--resources/shaders/ps_composite.fs.glsl320
-rw-r--r--resources/shaders/ps_composite.glsl8
-rw-r--r--resources/shaders/ps_composite.vs.glsl37
-rw-r--r--resources/shaders/ps_gradient.fs.glsl8
-rw-r--r--resources/shaders/ps_gradient.glsl10
-rw-r--r--resources/shaders/ps_gradient.vs.glsl45
-rw-r--r--resources/shaders/ps_image.fs.glsl8
-rw-r--r--resources/shaders/ps_image.glsl7
-rw-r--r--resources/shaders/ps_image.vs.glsl24
-rw-r--r--resources/shaders/ps_image_clip.fs.glsl9
-rw-r--r--resources/shaders/ps_image_clip.glsl10
-rw-r--r--resources/shaders/ps_image_clip.vs.glsl32
-rw-r--r--resources/shaders/ps_image_transform.fs.glsl13
-rw-r--r--resources/shaders/ps_image_transform.glsl8
-rw-r--r--resources/shaders/ps_image_transform.vs.glsl65
-rw-r--r--resources/shaders/ps_rectangle.fs.glsl7
-rw-r--r--resources/shaders/ps_rectangle.glsl5
-rw-r--r--resources/shaders/ps_rectangle.vs.glsl19
-rw-r--r--resources/shaders/ps_rectangle_clip.fs.glsl9
-rw-r--r--resources/shaders/ps_rectangle_clip.glsl10
-rw-r--r--resources/shaders/ps_rectangle_clip.vs.glsl28
-rw-r--r--resources/shaders/ps_rectangle_transform.fs.glsl13
-rw-r--r--resources/shaders/ps_rectangle_transform.glsl8
-rw-r--r--resources/shaders/ps_rectangle_transform.vs.glsl59
-rw-r--r--resources/shaders/ps_text.fs.glsl8
-rw-r--r--resources/shaders/ps_text.glsl6
-rw-r--r--resources/shaders/ps_text.vs.glsl26
-rw-r--r--resources/shaders/shared.glsl45
-rw-r--r--resources/shaders/shared_other.glsl64
-rw-r--r--rust-nightly-date2
-rw-r--r--support/windows/Servo.wxs.mako215
-rw-r--r--support/windows/fonts.conf777
-rw-r--r--tests/html/bluetooth/bluetooth_battery_level.html36
-rw-r--r--tests/html/bluetooth/bluetooth_battery_level_with_filter.html (renamed from tests/html/bluetooth_battery_level.html)27
-rw-r--r--tests/html/bluetooth/bluetooth_characteristic_info.html (renamed from tests/html/bluetooth_characteristic_info.html)25
-rw-r--r--tests/html/bluetooth/bluetooth_characteristic_read_value_test_cases.html66
-rw-r--r--tests/html/bluetooth/bluetooth_characteristic_write_value_test_cases.html80
-rw-r--r--tests/html/bluetooth/bluetooth_descriptor_info.html (renamed from tests/html/bluetooth_descriptor_info.html)27
-rw-r--r--tests/html/bluetooth/bluetooth_descriptor_read_value_test_cases.html57
-rw-r--r--tests/html/bluetooth/bluetooth_descriptor_write_value_test_cases.html71
-rw-r--r--tests/html/bluetooth/bluetooth_device_disconnect.html (renamed from tests/html/bluetooth_device_disconnect.html)37
-rw-r--r--tests/html/bluetooth/bluetooth_device_info.html (renamed from tests/html/bluetooth_device_info.html)19
-rw-r--r--tests/html/bluetooth/bluetooth_functions.js32
-rw-r--r--tests/html/bluetooth/bluetooth_get_characteristic_test_cases.html82
-rw-r--r--tests/html/bluetooth/bluetooth_get_characteristics_test_cases.html87
-rw-r--r--tests/html/bluetooth/bluetooth_get_descriptor_test_cases.html66
-rw-r--r--tests/html/bluetooth/bluetooth_get_descriptors_test_cases.html68
-rw-r--r--tests/html/bluetooth/bluetooth_get_included_service_test_cases.html66
-rw-r--r--tests/html/bluetooth/bluetooth_get_included_services_test_cases.html68
-rw-r--r--tests/html/bluetooth/bluetooth_get_primary_service_test_cases.html74
-rw-r--r--tests/html/bluetooth/bluetooth_get_primary_services_test_cases.html75
-rw-r--r--tests/html/bluetooth/bluetooth_included_service_info.html (renamed from tests/html/bluetooth_included_service_info.html)19
-rw-r--r--tests/html/bluetooth/bluetooth_primary_service_info.html (renamed from tests/html/bluetooth_primary_service_info.html)19
-rw-r--r--tests/html/bluetooth/bluetooth_primary_services_info.html57
-rw-r--r--tests/html/bluetooth/bluetooth_request_device_test_cases.html73
-rw-r--r--tests/unit/gfx/Cargo.toml2
-rw-r--r--tests/unit/net/Cargo.toml2
-rw-r--r--tests/unit/net/fetch.rs182
-rw-r--r--tests/unit/net/filemanager_thread.rs66
-rw-r--r--tests/unit/net/http_loader.rs51
-rw-r--r--tests/unit/net/resource_thread.rs15
-rw-r--r--tests/unit/net/test.jpegbin4962 -> 62218 bytes
-rw-r--r--tests/unit/net/test.txt1
-rw-r--r--tests/unit/profile/Cargo.toml2
-rw-r--r--tests/unit/style/attr.rs18
-rw-r--r--tests/unit/util/lib.rs1
-rw-r--r--tests/unit/util/remutex.rs89
-rw-r--r--tests/wpt/README.md15
-rw-r--r--tests/wpt/config.ini1
-rw-r--r--tests/wpt/include.ini6
-rw-r--r--tests/wpt/metadata-css/css-transforms-1_dev/html/css-transforms-3d-on-anonymous-block-001.htm.ini2
-rw-r--r--tests/wpt/metadata-css/css-transforms-1_dev/html/transform-input-019.htm.ini3
-rw-r--r--tests/wpt/metadata-css/css21_dev/html4/margin-collapse-clear-002.htm.ini3
-rw-r--r--tests/wpt/metadata-css/css21_dev/html4/margin-collapse-clear-003.htm.ini3
-rw-r--r--tests/wpt/metadata-css/css21_dev/html4/margin-collapse-clear-008.htm.ini3
-rw-r--r--tests/wpt/metadata-css/css21_dev/html4/margin-collapse-clear-009.htm.ini3
-rw-r--r--tests/wpt/metadata/FileAPI/FileReaderSync.worker.js.ini4
-rw-r--r--tests/wpt/metadata/FileAPI/blob/Blob-XHR-revoke.html.ini1
-rw-r--r--tests/wpt/metadata/FileAPI/file/File-constructor.html.ini4
-rw-r--r--tests/wpt/metadata/FileAPI/idlharness.html.ini9
-rw-r--r--tests/wpt/metadata/FileAPI/idlharness.worker.js.ini41
-rw-r--r--tests/wpt/metadata/MANIFEST.json20
-rw-r--r--tests/wpt/metadata/dom/nodes/getElementsByClassName-21.htm.ini5
-rw-r--r--tests/wpt/metadata/fetch/api/headers/headers-basic.html.ini44
-rw-r--r--tests/wpt/metadata/fetch/api/headers/headers-casing.html.ini14
-rw-r--r--tests/wpt/metadata/fetch/api/headers/headers-combine.html.ini14
-rw-r--r--tests/wpt/metadata/fetch/api/headers/headers-errors.html.ini8
-rw-r--r--tests/wpt/metadata/fetch/api/headers/headers-idl.html.ini3
-rw-r--r--tests/wpt/metadata/fetch/api/headers/headers-normalize.html.ini11
-rw-r--r--tests/wpt/metadata/fetch/api/headers/headers-structure.html.ini12
-rw-r--r--tests/wpt/metadata/html/browsers/browsing-the-web/history-traversal/PopStateEvent.html.ini5
-rw-r--r--tests/wpt/metadata/html/browsers/browsing-the-web/history-traversal/browsing_context_name_cross_origin.html.ini4
-rw-r--r--tests/wpt/metadata/html/browsers/browsing-the-web/history-traversal/persisted-user-state-restoration/scroll-restoration-basic.html.ini3
-rw-r--r--tests/wpt/metadata/html/browsers/history/the-history-interface/001.html.ini100
-rw-r--r--tests/wpt/metadata/html/browsers/history/the-history-interface/002.html.ini97
-rw-r--r--tests/wpt/metadata/html/browsers/history/the-history-interface/004.html.ini10
-rw-r--r--tests/wpt/metadata/html/browsers/history/the-history-interface/005.html.ini7
-rw-r--r--tests/wpt/metadata/html/browsers/history/the-history-interface/007.html.ini13
-rw-r--r--tests/wpt/metadata/html/browsers/history/the-location-interface/location_assign_about_blank.html.ini5
-rw-r--r--tests/wpt/metadata/html/dom/interfaces.html.ini57
-rw-r--r--tests/wpt/metadata/html/dom/reflection-grouping.html.ini180
-rw-r--r--tests/wpt/metadata/html/semantics/embedded-content/media-elements/error-codes/error.html.ini (renamed from tests/wpt/metadata/workers/interfaces/WorkerGlobalScope/close/sending-messages.html.ini)4
-rw-r--r--tests/wpt/metadata/html/semantics/embedded-content/media-elements/event_loadeddata.html.ini3
-rw-r--r--tests/wpt/metadata/html/semantics/embedded-content/media-elements/event_loadeddata_noautoplay.html.ini6
-rw-r--r--tests/wpt/metadata/html/semantics/embedded-content/media-elements/event_loadedmetadata.html.ini6
-rw-r--r--tests/wpt/metadata/html/semantics/embedded-content/media-elements/event_loadedmetadata_noautoplay.html.ini6
-rw-r--r--tests/wpt/metadata/html/semantics/embedded-content/media-elements/event_order_loadedmetadata_loadeddata.html.ini6
-rw-r--r--tests/wpt/metadata/html/semantics/embedded-content/media-elements/readyState_during_loadeddata.html.ini6
-rw-r--r--tests/wpt/metadata/html/semantics/embedded-content/media-elements/readyState_during_loadedmetadata.html.ini6
-rw-r--r--tests/wpt/metadata/html/semantics/grouping-content/the-li-element/grouping-li.html.ini30
-rw-r--r--tests/wpt/metadata/webgl/conformance-1.0.3/conformance/more/functions/readPixelsBadArgs.html.ini2
-rw-r--r--tests/wpt/metadata/webgl/conformance-1.0.3/conformance/reading/read-pixels-pack-alignment.html.ini2
-rw-r--r--tests/wpt/metadata/webgl/conformance-1.0.3/conformance/rendering/draw-arrays-out-of-bounds.html.ini2
-rw-r--r--tests/wpt/metadata/webgl/conformance-1.0.3/conformance/rendering/draw-elements-out-of-bounds.html.ini2
-rw-r--r--tests/wpt/metadata/workers/WorkerGlobalScope_close.htm.ini5
-rw-r--r--tests/wpt/metadata/workers/constructors/Worker/unexpected-self-properties.html.ini5
-rw-r--r--tests/wpt/metadata/workers/interfaces.worker.js.ini3
-rw-r--r--tests/wpt/mozilla/meta/MANIFEST.json124
-rw-r--r--tests/wpt/mozilla/meta/mozilla/FileAPI/blob_url_upload.html.ini (renamed from tests/wpt/mozilla/meta/mozilla/blob_url_upload.html.ini)0
-rw-r--r--tests/wpt/mozilla/meta/mozilla/FileAPI/file-select.html.ini (renamed from tests/wpt/mozilla/meta/mozilla/file_upload.html.ini)2
-rw-r--r--tests/wpt/mozilla/meta/mozilla/FileAPI/file-upload.html.ini3
-rw-r--r--tests/wpt/mozilla/tests/css/animations/basic-transition.html34
-rw-r--r--tests/wpt/mozilla/tests/css/box_shadow_blur_fixed.html24
-rw-r--r--tests/wpt/mozilla/tests/css/box_shadow_blur_fixed_ref.html23
-rw-r--r--tests/wpt/mozilla/tests/css/textarea_space_calculation-ref.html19
-rw-r--r--tests/wpt/mozilla/tests/css/textarea_space_calculation.html21
-rw-r--r--tests/wpt/mozilla/tests/mozilla/FileAPI/blob.html (renamed from tests/wpt/mozilla/tests/mozilla/blob.html)0
-rw-r--r--tests/wpt/mozilla/tests/mozilla/FileAPI/blob_url_upload.html (renamed from tests/wpt/mozilla/tests/mozilla/blob_url_upload.html)0
-rw-r--r--tests/wpt/mozilla/tests/mozilla/FileAPI/blob_url_upload_ref.html (renamed from tests/wpt/mozilla/tests/mozilla/blob_url_upload_ref.html)2
-rw-r--r--tests/wpt/mozilla/tests/mozilla/FileAPI/file-select.html (renamed from tests/wpt/mozilla/tests/mozilla/file_upload.html)2
-rw-r--r--tests/wpt/mozilla/tests/mozilla/FileAPI/file-upload-frame.html8
-rw-r--r--tests/wpt/mozilla/tests/mozilla/FileAPI/file-upload.html23
-rw-r--r--tests/wpt/mozilla/tests/mozilla/FileAPI/resource/file-submission.py29
-rw-r--r--tests/wpt/mozilla/tests/mozilla/FileAPI/resource/upload.txt1
-rw-r--r--tests/wpt/mozilla/tests/mozilla/interfaces.html1
-rw-r--r--tests/wpt/mozilla/tests/mozilla/interfaces.worker.js59
-rw-r--r--tests/wpt/mozilla/tests/mozilla/table_valign_uneven_height.html34
-rw-r--r--tests/wpt/mozilla/tests/mozilla/table_valign_uneven_height_ref.html34
-rw-r--r--tests/wpt/web-platform-tests/FileAPI/idlharness.idl51
-rw-r--r--tests/wpt/web-platform-tests/fetch/api/headers/headers-basic.html2
-rw-r--r--tests/wpt/web-platform-tests/html/semantics/interactive-elements/the-dialog-element/dialog-open.html30
-rw-r--r--tests/wpt/web-platform-tests/html/semantics/tabular-data/the-table-element/remove-row.html50
386 files changed, 11236 insertions, 5295 deletions
diff --git a/.travis.yml b/.travis.yml
index 44bb3c52ccb..7796d98cd23 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -36,6 +36,9 @@ matrix:
- xorg-dev
- ccache
- libdbus-glib-1-dev
+ - libavformat-dev
+ - libavcodec-dev
+ - libavutil-dev
branches:
only:
diff --git a/README.md b/README.md
index 00d8a650d71..5164f01c958 100644
--- a/README.md
+++ b/README.md
@@ -43,7 +43,8 @@ sudo apt-get install git curl freeglut3-dev autoconf \
libfreetype6-dev libgl1-mesa-dri libglib2.0-dev xorg-dev \
gperf g++ build-essential cmake virtualenv python-pip \
libssl-dev libbz2-dev libosmesa6-dev libxmu6 libxmu-dev \
- libglu1-mesa-dev libgles2-mesa-dev libegl1-mesa-dev libdbus-1-dev
+ libglu1-mesa-dev libgles2-mesa-dev libegl1-mesa-dev libdbus-1-dev \
+ libavformat-dev
```
If you are on **Ubuntu 14.04** and encountered errors on installing these dependencies involving `libcheese`, see [#6158](https://github.com/servo/servo/issues/6158) for a workaround.
@@ -56,7 +57,7 @@ sudo dnf install curl freeglut-devel libtool gcc-c++ libXi-devel \
freetype-devel mesa-libGL-devel mesa-libEGL-devel glib2-devel libX11-devel libXrandr-devel gperf \
fontconfig-devel cabextract ttmkfdir python python-virtualenv python-pip expat-devel \
rpm-build openssl-devel cmake bzip2-devel libXcursor-devel libXmu-devel mesa-libOSMesa-devel \
- dbus-devel
+ dbus-devel ffmpeg-devel
```
On Arch Linux:
@@ -80,14 +81,21 @@ Download Python for Windows [here](https://www.python.org/downloads/release/pyth
required for the SpiderMonkey build on Windows.
Install MSYS2 from [here](https://msys2.github.io/). After you have done so, open an MSYS shell
-window and update the core libraries and install new packages:
+window and update the core libraries and install new packages. The extra step at the end is to
+downgrate GCC to 5.4, as the GCC6 versions in mingw currently fail to compile some of our
+dependencies. We are upgrading to a gcc-free build on Windows as soon as possible:
```sh
pacman -Su
pacman -Sy git mingw-w64-x86_64-toolchain mingw-w64-x86_64-freetype \
mingw-w64-x86_64-icu mingw-w64-x86_64-nspr mingw-w64-x86_64-ca-certificates \
mingw-w64-x86_64-expat mingw-w64-x86_64-cmake tar diffutils patch \
- patchutils make python2-setuptools
+ patchutils make python2-setuptools mingw-w64-x86_64-ffmpeg
+export GCC_URL=http://repo.msys2.org/mingw/x86_64/mingw-w64-x86_64-gcc
+export GCC_EXT=5.4.0-1-any.pkg.tar.xz
+pacman -U --noconfirm $GCC_URL-$GCC_EXT $GCC_URL-ada-$GCC_EXT \
+ $GCC_URL-fortran-$GCC_EXT $GCC_URL-libgfortran-$GCC_EXT $GCC_URL-libs-$GCC_EXT \
+ $GCC_URL-objc-$GCC_EXT
easy_install-2.7 pip virtualenv
```
diff --git a/appveyor.yml b/appveyor.yml
index 3fd7b59c4e5..148ee4fb5bf 100644
--- a/appveyor.yml
+++ b/appveyor.yml
@@ -19,10 +19,14 @@ cache:
install:
- bash -lc "echo $MSYSTEM; pacman --needed --noconfirm -Sy pacman-mirrors"
- bash -lc "pacman --noconfirm -Sy"
- - bash -lc "pacman -Sy --needed --noconfirm git mingw-w64-x86_64-toolchain mingw-w64-x86_64-freetype mingw-w64-x86_64-icu mingw-w64-x86_64-nspr mingw-w64-x86_64-ca-certificates mingw-w64-x86_64-expat mingw-w64-x86_64-cmake tar diffutils patch patchutils make python2-setuptools"
+ - bash -lc "pacman -Sy --needed --noconfirm git mingw-w64-x86_64-toolchain mingw-w64-x86_64-freetype mingw-w64-x86_64-icu mingw-w64-x86_64-nspr mingw-w64-x86_64-ca-certificates mingw-w64-x86_64-expat mingw-w64-x86_64-cmake tar diffutils patch patchutils make python2-setuptools mingw-w64-x86_64-ffmpeg"
- bash -lc "easy_install-2.7 pip virtualenv"
- bash -lc "mv /mingw64/bin/python2.exe /mingw64/bin/python2-mingw64.exe"
- bash -lc "mv /mingw64/bin/python2.7.exe /mingw64/bin/python2.7-mingw64.exe"
+ # Downgrade GCC to 5.4.0-1 - https://github.com/servo/servo/issues/12512
+ - set GCC_URL=http://repo.msys2.org/mingw/x86_64/mingw-w64-x86_64-gcc
+ - set GCC_EXT=5.4.0-1-any.pkg.tar.xz
+ - bash -lc "pacman -U --noconfirm $GCC_URL-$GCC_EXT $GCC_URL-ada-$GCC_EXT $GCC_URL-fortran-$GCC_EXT $GCC_URL-libgfortran-$GCC_EXT $GCC_URL-libs-$GCC_EXT $GCC_URL-objc-$GCC_EXT"
# Uncomment these lines to expose RDP access information to the build machine in the build log.
#init:
diff --git a/cargo-nightly-build b/cargo-nightly-build
index d6dd780ab85..d5817d0f464 100644
--- a/cargo-nightly-build
+++ b/cargo-nightly-build
@@ -1 +1 @@
-2016-06-20
+2016-07-30
diff --git a/components/canvas/Cargo.toml b/components/canvas/Cargo.toml
index e9803a764d5..d51f75fc12b 100644
--- a/components/canvas/Cargo.toml
+++ b/components/canvas/Cargo.toml
@@ -15,7 +15,7 @@ canvas_traits = {path = "../canvas_traits"}
euclid = "0.7.1"
gfx_traits = {path = "../gfx_traits"}
gleam = "0.2.8"
-ipc-channel = {git = "https://github.com/servo/ipc-channel"}
+ipc-channel = "0.4.0"
log = "0.3.5"
num-traits = "0.1.32"
offscreen_gl_context = "0.1.2"
diff --git a/components/canvas_traits/Cargo.toml b/components/canvas_traits/Cargo.toml
index 899e0eaf397..7016dc297a3 100644
--- a/components/canvas_traits/Cargo.toml
+++ b/components/canvas_traits/Cargo.toml
@@ -16,10 +16,10 @@ euclid = "0.7.1"
gfx_traits = {path = "../gfx_traits"}
heapsize = "0.3.0"
heapsize_plugin = "0.1.2"
-ipc-channel = {git = "https://github.com/servo/ipc-channel"}
+ipc-channel = "0.4.0"
plugins = {path = "../plugins"}
-serde = {version = "0.7.11", features = ["nightly"]}
-serde_macros = "0.7.11"
+serde = {version = "0.7.15", features = ["nightly"]}
+serde_macros = "0.7.15"
[dependencies.webrender_traits]
git = "https://github.com/servo/webrender_traits"
diff --git a/components/canvas_traits/lib.rs b/components/canvas_traits/lib.rs
index db945750a0c..3682d252338 100644
--- a/components/canvas_traits/lib.rs
+++ b/components/canvas_traits/lib.rs
@@ -74,6 +74,7 @@ pub enum FromLayoutMsg {
}
#[derive(Clone, Deserialize, Serialize)]
+#[serde(bound = "")] // Prevent serde from generating cyclic bounds.
pub enum Canvas2dMsg {
Arc(Point2D<f32>, f32, f32, f32, bool),
ArcTo(Point2D<f32>, Point2D<f32>, f32),
diff --git a/components/compositing/Cargo.toml b/components/compositing/Cargo.toml
index 6ffc18fa6bf..ff5440b54d5 100644
--- a/components/compositing/Cargo.toml
+++ b/components/compositing/Cargo.toml
@@ -16,7 +16,7 @@ euclid = "0.7.1"
gfx_traits = {path = "../gfx_traits"}
gleam = "0.2.8"
image = "0.10"
-ipc-channel = {git = "https://github.com/servo/ipc-channel"}
+ipc-channel = "0.4.0"
layers = {git = "https://github.com/servo/rust-layers", features = ["plugins"]}
log = "0.3.5"
msg = {path = "../msg"}
@@ -24,8 +24,8 @@ net_traits = {path = "../net_traits"}
plugins = {path = "../plugins"}
profile_traits = {path = "../profile_traits"}
script_traits = {path = "../script_traits"}
-serde = "0.7.11"
-serde_macros = "0.7.11"
+serde = "0.7.15"
+serde_macros = "0.7.15"
style_traits = {path = "../style_traits"}
time = "0.1.17"
url = {version = "1.0.0", features = ["heap_size"]}
diff --git a/components/compositing/compositor.rs b/components/compositing/compositor.rs
index da9272d08b9..60b64a03047 100644
--- a/components/compositing/compositor.rs
+++ b/components/compositing/compositor.rs
@@ -2114,7 +2114,7 @@ impl<Window: WindowMethods> IOCompositor<Window> {
}
// Check if there are any pending frames. If so, the image is not stable yet.
- if self.pending_subpages.len() > 0 {
+ if !self.pending_subpages.is_empty() {
return Err(NotReadyToPaint::PendingSubpages(self.pending_subpages.len()));
}
diff --git a/components/constellation/Cargo.toml b/components/constellation/Cargo.toml
index 83d8aac997a..d3688a51e91 100644
--- a/components/constellation/Cargo.toml
+++ b/components/constellation/Cargo.toml
@@ -18,7 +18,7 @@ devtools_traits = {path = "../devtools_traits"}
euclid = "0.7.1"
gfx = {path = "../gfx"}
gfx_traits = {path = "../gfx_traits"}
-ipc-channel = {git = "https://github.com/servo/ipc-channel"}
+ipc-channel = "0.4.0"
layers = {git = "https://github.com/servo/rust-layers", features = ["plugins"]}
layout_traits = {path = "../layout_traits"}
log = "0.3.5"
@@ -29,8 +29,8 @@ plugins = {path = "../plugins"}
profile_traits = {path = "../profile_traits"}
rand = "0.3"
script_traits = {path = "../script_traits"}
-serde = "0.7.11"
-serde_macros = "0.7.11"
+serde = "0.7.15"
+serde_macros = "0.7.15"
style_traits = {path = "../style_traits"}
url = {version = "1.0.0", features = ["heap_size"]}
util = {path = "../util"}
diff --git a/components/constellation/constellation.rs b/components/constellation/constellation.rs
index 7b1ae044921..dc28056e81b 100644
--- a/components/constellation/constellation.rs
+++ b/components/constellation/constellation.rs
@@ -30,7 +30,6 @@ use msg::constellation_msg::{Key, KeyModifiers, KeyState, LoadData};
use msg::constellation_msg::{PipelineNamespace, PipelineNamespaceId, TraversalDirection};
use msg::constellation_msg::{SubpageId, WindowSizeType};
use net_traits::bluetooth_thread::BluetoothMethodMsg;
-use net_traits::filemanager_thread::FileManagerThreadMsg;
use net_traits::image_cache_thread::ImageCacheThread;
use net_traits::storage_thread::StorageThreadMsg;
use net_traits::{self, ResourceThreads, IpcSend};
@@ -54,8 +53,8 @@ use std::iter::once;
use std::marker::PhantomData;
use std::mem::replace;
use std::process;
+use std::sync::Arc;
use std::sync::mpsc::{Sender, channel, Receiver};
-use std::sync::{Arc, Mutex};
use std::thread;
use std::time::Instant;
use style_traits::PagePx;
@@ -65,6 +64,7 @@ use timer_scheduler::TimerScheduler;
use url::Url;
use util::opts;
use util::prefs::PREFS;
+use util::remutex::ReentrantMutex;
use util::thread::spawn_named;
use webrender_traits;
@@ -314,14 +314,14 @@ enum ExitPipelineMode {
#[derive(Clone)]
pub struct FromScriptLogger {
/// A channel to the constellation
- pub constellation_chan: Arc<Mutex<IpcSender<FromScriptMsg>>>,
+ pub constellation_chan: Arc<ReentrantMutex<IpcSender<FromScriptMsg>>>,
}
impl FromScriptLogger {
/// Create a new constellation logger.
pub fn new(constellation_chan: IpcSender<FromScriptMsg>) -> FromScriptLogger {
FromScriptLogger {
- constellation_chan: Arc::new(Mutex::new(constellation_chan))
+ constellation_chan: Arc::new(ReentrantMutex::new(constellation_chan))
}
}
@@ -342,9 +342,8 @@ impl Log for FromScriptLogger {
let pipeline_id = PipelineId::installed();
let thread_name = thread::current().name().map(ToOwned::to_owned);
let msg = FromScriptMsg::LogEntry(pipeline_id, thread_name, entry);
- if let Ok(chan) = self.constellation_chan.lock() {
- let _ = chan.send(msg);
- }
+ let chan = self.constellation_chan.lock().unwrap_or_else(|err| err.into_inner());
+ let _ = chan.send(msg);
}
}
}
@@ -353,14 +352,14 @@ impl Log for FromScriptLogger {
#[derive(Clone)]
pub struct FromCompositorLogger {
/// A channel to the constellation
- pub constellation_chan: Arc<Mutex<Sender<FromCompositorMsg>>>,
+ pub constellation_chan: Arc<ReentrantMutex<Sender<FromCompositorMsg>>>,
}
impl FromCompositorLogger {
/// Create a new constellation logger.
pub fn new(constellation_chan: Sender<FromCompositorMsg>) -> FromCompositorLogger {
FromCompositorLogger {
- constellation_chan: Arc::new(Mutex::new(constellation_chan))
+ constellation_chan: Arc::new(ReentrantMutex::new(constellation_chan))
}
}
@@ -381,9 +380,8 @@ impl Log for FromCompositorLogger {
let pipeline_id = PipelineId::installed();
let thread_name = thread::current().name().map(ToOwned::to_owned);
let msg = FromCompositorMsg::LogEntry(pipeline_id, thread_name, entry);
- if let Ok(chan) = self.constellation_chan.lock() {
- let _ = chan.send(msg);
- }
+ let chan = self.constellation_chan.lock().unwrap_or_else(|err| err.into_inner());
+ let _ = chan.send(msg);
}
}
}
@@ -828,11 +826,6 @@ impl<Message, LTF, STF> Constellation<Message, LTF, STF>
debug!("constellation got load complete message");
self.handle_load_complete_msg(pipeline_id)
}
- // The DOM load event fired on a document
- FromScriptMsg::DOMLoad(pipeline_id) => {
- debug!("constellation got dom load message");
- self.handle_dom_load(pipeline_id)
- }
// Handle a forward or back request
FromScriptMsg::TraverseHistory(pipeline_id, direction) => {
debug!("constellation got traverse history message from script");
@@ -1048,11 +1041,6 @@ impl<Message, LTF, STF> Constellation<Message, LTF, STF>
warn!("Exit storage thread failed ({})", e);
}
- debug!("Exiting file manager resource threads.");
- if let Err(e) = self.public_resource_threads.send(FileManagerThreadMsg::Exit) {
- warn!("Exit storage thread failed ({})", e);
- }
-
debug!("Exiting bluetooth thread.");
if let Err(e) = self.bluetooth_thread.send(BluetoothMethodMsg::Exit) {
warn!("Exit bluetooth thread failed ({})", e);
@@ -1323,10 +1311,13 @@ impl<Message, LTF, STF> Constellation<Message, LTF, STF>
}
}
- fn handle_alert(&mut self, pipeline_id: PipelineId, message: String, sender: IpcSender<bool>) {
+ fn handle_alert(&mut self,
+ pipeline_id: PipelineId,
+ message: String,
+ sender: IpcSender<bool>) {
let display_alert_dialog = if PREFS.is_mozbrowser_enabled() {
let parent_pipeline_info = self.pipelines.get(&pipeline_id).and_then(|source| source.parent_info);
- if let Some(_) = parent_pipeline_info {
+ if parent_pipeline_info.is_some() {
let root_pipeline_id = self.root_frame_id
.and_then(|root_frame_id| self.frames.get(&root_frame_id))
.map(|root_frame| root_frame.current.0);
@@ -1435,15 +1426,6 @@ impl<Message, LTF, STF> Constellation<Message, LTF, STF>
}
fn handle_load_complete_msg(&mut self, pipeline_id: PipelineId) {
- if let Some(frame_id) = self.get_top_level_frame_for_pipeline(Some(pipeline_id)) {
- let forward = !self.joint_session_future(frame_id).is_empty();
- let back = !self.joint_session_past(frame_id).is_empty();
- let root = self.root_frame_id.is_none() || self.root_frame_id == Some(frame_id);
- self.compositor_proxy.send(ToCompositorMsg::LoadComplete(back, forward, root));
- }
- }
-
- fn handle_dom_load(&mut self, pipeline_id: PipelineId) {
let mut webdriver_reset = false;
if let Some((expected_pipeline_id, ref reply_chan)) = self.webdriver.load_channel {
debug!("Sending load to WebDriver");
@@ -1455,7 +1437,12 @@ impl<Message, LTF, STF> Constellation<Message, LTF, STF>
if webdriver_reset {
self.webdriver.load_channel = None;
}
-
+ if let Some(frame_id) = self.get_top_level_frame_for_pipeline(Some(pipeline_id)) {
+ let forward = !self.joint_session_future(frame_id).is_empty();
+ let back = !self.joint_session_past(frame_id).is_empty();
+ let root = self.root_frame_id.is_none() || self.root_frame_id == Some(frame_id);
+ self.compositor_proxy.send(ToCompositorMsg::LoadComplete(back, forward, root));
+ }
self.handle_subframe_loaded(pipeline_id);
}
@@ -1893,18 +1880,16 @@ impl<Message, LTF, STF> Constellation<Message, LTF, STF>
// Remove paint permissions for the pipeline being replaced.
self.revoke_paint_permission(old_pipeline_id);
- // Add new pipeline to navigation frame, and return frames evicted from history.
- self.pipelines
- .get(&old_pipeline_id)
- .and_then(|pipeline| pipeline.frame)
- .map(|frame_id| {
- self.pipelines.get_mut(&frame_change.new_pipeline_id)
- .map(|pipeline| pipeline.frame = Some(frame_id));
- self.frames.get_mut(&frame_id).map(|frame| frame.load(frame_change.new_pipeline_id));
- frame_id
- })
+ self.pipelines.get(&old_pipeline_id).and_then(|pipeline| pipeline.frame)
});
+ if let Some(frame_id) = frame_id {
+ // Add new pipeline to navigation frame, and return frames evicted from history.
+ self.pipelines.get_mut(&frame_change.new_pipeline_id)
+ .map(|pipeline| pipeline.frame = Some(frame_id));
+ self.frames.get_mut(&frame_id).map(|frame| frame.load(frame_change.new_pipeline_id));
+ }
+
if let None = frame_id {
// The new pipeline is in a new frame with no history
let frame_id = self.new_frame(frame_change.new_pipeline_id);
@@ -2073,7 +2058,7 @@ impl<Message, LTF, STF> Constellation<Message, LTF, STF>
}
// If there are pending loads, wait for those to complete.
- if self.pending_frames.len() > 0 {
+ if !self.pending_frames.is_empty() {
return ReadyToSave::PendingFrames;
}
@@ -2089,7 +2074,10 @@ impl<Message, LTF, STF> Constellation<Message, LTF, STF>
let pipeline_id = frame.current.0;
let pipeline = match self.pipelines.get(&pipeline_id) {
- None => { warn!("Pipeline {:?} screenshot while closing.", pipeline_id); continue; },
+ None => {
+ warn!("Pipeline {:?} screenshot while closing.", pipeline_id);
+ continue;
+ },
Some(pipeline) => pipeline,
};
diff --git a/components/constellation/pipeline.rs b/components/constellation/pipeline.rs
index dd2a665f6ac..a75d083db64 100644
--- a/components/constellation/pipeline.rs
+++ b/components/constellation/pipeline.rs
@@ -28,6 +28,8 @@ use script_traits::{ConstellationControlMsg, InitialScriptState, MozBrowserEvent
use script_traits::{LayoutControlMsg, LayoutMsg, NewLayoutInfo, ScriptMsg, SWManagerMsg, SWManagerSenders};
use script_traits::{ScriptThreadFactory, TimerEventRequest, WindowSizeData};
use std::collections::HashMap;
+use std::env;
+use std::ffi::OsStr;
use std::io::Error as IOError;
use std::process;
use std::sync::mpsc::{Sender, channel};
@@ -160,6 +162,7 @@ impl Pipeline {
pipeline_port: pipeline_port,
layout_to_constellation_chan: state.layout_to_constellation_chan.clone(),
content_process_shutdown_chan: layout_content_process_shutdown_chan.clone(),
+ layout_threads: opts::get().layout_threads,
};
if let Err(e) = script_chan.send(ConstellationControlMsg::AttachLayout(new_layout_info)) {
@@ -470,7 +473,8 @@ impl UnprivilegedPipelineContent {
self.time_profiler_chan,
self.mem_profiler_chan,
self.layout_content_process_shutdown_chan,
- self.webrender_api_sender);
+ self.webrender_api_sender,
+ opts::get().layout_threads);
if wait_for_completion {
let _ = self.script_content_process_shutdown_port.recv();
@@ -483,7 +487,18 @@ impl UnprivilegedPipelineContent {
use gaol::sandbox::{self, Sandbox, SandboxMethods};
use ipc_channel::ipc::IpcOneShotServer;
use sandboxing::content_process_sandbox_profile;
- use std::env;
+
+ impl CommandMethods for sandbox::Command {
+ fn arg<T>(&mut self, arg: T)
+ where T: AsRef<OsStr> {
+ self.arg(arg);
+ }
+
+ fn env<T, U>(&mut self, key: T, val: U)
+ where T: AsRef<OsStr>, U: AsRef<OsStr> {
+ self.env(key, val);
+ }
+ }
// Note that this function can panic, due to process creation,
// avoiding this panic would require a mechanism for dealing
@@ -495,11 +510,7 @@ impl UnprivilegedPipelineContent {
// If there is a sandbox, use the `gaol` API to create the child process.
let child_process = if opts::get().sandbox {
let mut command = sandbox::Command::me().expect("Failed to get current sandbox.");
- command.arg("--content-process").arg(token);
-
- if let Ok(value) = env::var("RUST_BACKTRACE") {
- command.env("RUST_BACKTRACE", value);
- }
+ self.setup_common(&mut command, token);
let profile = content_process_sandbox_profile();
ChildProcess::Sandboxed(Sandbox::new(profile).start(&mut command)
@@ -508,12 +519,7 @@ impl UnprivilegedPipelineContent {
let path_to_self = env::current_exe()
.expect("Failed to get current executor.");
let mut child_process = process::Command::new(path_to_self);
- child_process.arg("--content-process");
- child_process.arg(token);
-
- if let Ok(value) = env::var("RUST_BACKTRACE") {
- child_process.env("RUST_BACKTRACE", value);
- }
+ self.setup_common(&mut child_process, token);
ChildProcess::Unsandboxed(child_process.spawn()
.expect("Failed to start unsandboxed child process!"))
@@ -531,6 +537,19 @@ impl UnprivilegedPipelineContent {
process::exit(1);
}
+ fn setup_common<C: CommandMethods>(&self, command: &mut C, token: String) {
+ C::arg(command, "--content-process");
+ C::arg(command, token);
+
+ if let Ok(value) = env::var("RUST_BACKTRACE") {
+ C::env(command, "RUST_BACKTRACE", value);
+ }
+
+ if let Ok(value) = env::var("RUST_LOG") {
+ C::env(command, "RUST_LOG", value);
+ }
+ }
+
pub fn constellation_chan(&self) -> IpcSender<ScriptMsg> {
self.constellation_chan.clone()
}
@@ -550,3 +569,23 @@ impl UnprivilegedPipelineContent {
}
}
}
+
+trait CommandMethods {
+ fn arg<T>(&mut self, arg: T)
+ where T: AsRef<OsStr>;
+
+ fn env<T, U>(&mut self, key: T, val: U)
+ where T: AsRef<OsStr>, U: AsRef<OsStr>;
+}
+
+impl CommandMethods for process::Command {
+ fn arg<T>(&mut self, arg: T)
+ where T: AsRef<OsStr> {
+ self.arg(arg);
+ }
+
+ fn env<T, U>(&mut self, key: T, val: U)
+ where T: AsRef<OsStr>, U: AsRef<OsStr> {
+ self.env(key, val);
+ }
+}
diff --git a/components/devtools/Cargo.toml b/components/devtools/Cargo.toml
index 1a9b821d8ae..9bcf7f54a00 100644
--- a/components/devtools/Cargo.toml
+++ b/components/devtools/Cargo.toml
@@ -12,12 +12,12 @@ path = "lib.rs"
[dependencies]
devtools_traits = {path = "../devtools_traits"}
hyper = { version = "0.9.9", features = [ "serde-serialization" ] }
-ipc-channel = {git = "https://github.com/servo/ipc-channel"}
+ipc-channel = "0.4.0"
log = "0.3.5"
msg = {path = "../msg"}
plugins = {path = "../plugins"}
-serde = "0.7.11"
+serde = "0.7.15"
serde_json = "0.7"
-serde_macros = "0.7.11"
+serde_macros = "0.7.15"
time = "0.1"
util = {path = "../util"}
diff --git a/components/devtools/actors/inspector.rs b/components/devtools/actors/inspector.rs
index a41c98c7bfc..0328c538e84 100644
--- a/components/devtools/actors/inspector.rs
+++ b/components/devtools/actors/inspector.rs
@@ -290,7 +290,7 @@ impl Actor for WalkerActor {
"documentElement" => {
let (tx, rx) = ipc::channel().unwrap();
self.script_chan.send(GetDocumentElement(self.pipeline, tx)).unwrap();
- let doc_elem_info = rx.recv().unwrap();
+ let doc_elem_info = try!(rx.recv().unwrap().ok_or(()));
let node = doc_elem_info.encode(registry, true, self.script_chan.clone(), self.pipeline);
let msg = DocumentElementReply {
@@ -316,7 +316,7 @@ impl Actor for WalkerActor {
registry.actor_to_script(target.to_owned()),
tx))
.unwrap();
- let children = rx.recv().unwrap();
+ let children = try!(rx.recv().unwrap().ok_or(()));
let msg = ChildrenReply {
hasFirst: true,
@@ -490,7 +490,7 @@ impl Actor for PageStyleActor {
borderTopWidth, borderRightWidth, borderBottomWidth, borderLeftWidth,
paddingTop, paddingRight, paddingBottom, paddingLeft,
width, height,
- } = rx.recv().unwrap();
+ } = try!(rx.recv().unwrap().ok_or(()));
let auto_margins = msg.get("autoMargins")
.and_then(&Value::as_boolean).unwrap_or(false);
@@ -564,7 +564,7 @@ impl Actor for InspectorActor {
let (tx, rx) = ipc::channel().unwrap();
self.script_chan.send(GetRootNode(self.pipeline, tx)).unwrap();
- let root_info = rx.recv().unwrap();
+ let root_info = try!(rx.recv().unwrap().ok_or(()));
let node = root_info.encode(registry, false, self.script_chan.clone(), self.pipeline);
diff --git a/components/devtools/actors/network_event.rs b/components/devtools/actors/network_event.rs
index 38f7d5767df..ba2793af8b7 100644
--- a/components/devtools/actors/network_event.rs
+++ b/components/devtools/actors/network_event.rs
@@ -43,6 +43,7 @@ pub struct NetworkEventActor {
pub name: String,
request: HttpRequest,
response: HttpResponse,
+ is_xhr: bool,
}
#[derive(Serialize)]
@@ -340,7 +341,8 @@ impl NetworkEventActor {
headers: None,
status: None,
body: None,
- }
+ },
+ is_xhr: false,
}
}
@@ -353,6 +355,7 @@ impl NetworkEventActor {
self.request.timeStamp = request.timeStamp;
self.request.connect_time = request.connect_time;
self.request.send_time = request.send_time;
+ self.is_xhr = request.is_xhr;
}
pub fn add_response(&mut self, response: DevtoolsHttpResponse) {
@@ -369,7 +372,7 @@ impl NetworkEventActor {
method: format!("{}", self.request.method),
startedDateTime: format!("{}", self.request.startedDateTime.rfc3339()),
timeStamp: self.request.timeStamp,
- isXHR: false,
+ isXHR: self.is_xhr,
private: false,
}
}
diff --git a/components/devtools_traits/Cargo.toml b/components/devtools_traits/Cargo.toml
index 20626fcab5c..22ba037a7b0 100644
--- a/components/devtools_traits/Cargo.toml
+++ b/components/devtools_traits/Cargo.toml
@@ -14,9 +14,9 @@ bitflags = "0.7"
heapsize = "0.3.0"
heapsize_plugin = "0.1.2"
hyper = {version = "0.9.9", features = ["serde-serialization"]}
-ipc-channel = {git = "https://github.com/servo/ipc-channel"}
+ipc-channel = "0.4.0"
msg = {path = "../msg"}
-serde = "0.7.11"
-serde_macros = "0.7.11"
+serde = "0.7.15"
+serde_macros = "0.7.15"
time = "0.1"
url = {version = "1.0.0", features = ["heap_size"]}
diff --git a/components/devtools_traits/lib.rs b/components/devtools_traits/lib.rs
index d64ac04b16f..2d8f5f0c197 100644
--- a/components/devtools_traits/lib.rs
+++ b/components/devtools_traits/lib.rs
@@ -194,13 +194,13 @@ pub enum DevtoolScriptControlMsg {
/// Evaluate a JS snippet in the context of the global for the given pipeline.
EvaluateJS(PipelineId, String, IpcSender<EvaluateJSReply>),
/// Retrieve the details of the root node (ie. the document) for the given pipeline.
- GetRootNode(PipelineId, IpcSender<NodeInfo>),
+ GetRootNode(PipelineId, IpcSender<Option<NodeInfo>>),
/// Retrieve the details of the document element for the given pipeline.
- GetDocumentElement(PipelineId, IpcSender<NodeInfo>),
+ GetDocumentElement(PipelineId, IpcSender<Option<NodeInfo>>),
/// Retrieve the details of the child nodes of the given node in the given pipeline.
- GetChildren(PipelineId, String, IpcSender<Vec<NodeInfo>>),
+ GetChildren(PipelineId, String, IpcSender<Option<Vec<NodeInfo>>>),
/// Retrieve the computed layout properties of the given node in the given pipeline.
- GetLayout(PipelineId, String, IpcSender<ComputedNodeLayout>),
+ GetLayout(PipelineId, String, IpcSender<Option<ComputedNodeLayout>>),
/// Retrieve all stored console messages for the given pipeline.
GetCachedMessages(PipelineId, CachedConsoleMessageTypes, IpcSender<Vec<CachedConsoleMessage>>),
/// Update a given node's attributes with a list of modifications.
@@ -298,6 +298,7 @@ pub struct HttpRequest {
pub timeStamp: i64,
pub connect_time: u64,
pub send_time: u64,
+ pub is_xhr: bool,
}
#[derive(Debug, PartialEq)]
diff --git a/components/gfx/Cargo.toml b/components/gfx/Cargo.toml
index ab66071626d..450c957886d 100644
--- a/components/gfx/Cargo.toml
+++ b/components/gfx/Cargo.toml
@@ -20,7 +20,7 @@ gfx_traits = {path = "../gfx_traits"}
harfbuzz-sys = "0.1"
heapsize = "0.3.0"
heapsize_plugin = "0.1.2"
-ipc-channel = {git = "https://github.com/servo/ipc-channel"}
+ipc-channel = "0.4.0"
layers = {git = "https://github.com/servo/rust-layers", features = ["plugins"]}
lazy_static = "0.2"
libc = "0.2"
@@ -33,8 +33,8 @@ profile_traits = {path = "../profile_traits"}
rand = "0.3"
range = {path = "../range"}
rustc-serialize = "0.3"
-serde = "0.7.11"
-serde_macros = "0.7.11"
+serde = "0.7.15"
+serde_macros = "0.7.15"
smallvec = "0.1"
string_cache = {version = "0.2.20", features = ["heap_size"]}
style = {path = "../style"}
diff --git a/components/gfx/display_list/mod.rs b/components/gfx/display_list/mod.rs
index 3eed504303b..0073b1b0a69 100644
--- a/components/gfx/display_list/mod.rs
+++ b/components/gfx/display_list/mod.rs
@@ -382,7 +382,11 @@ impl DisplayList {
current_item_index: start,
last_item_index: end,
};
- self.draw_stacking_context(stacking_context, &mut traversal, paint_context, transform);
+ self.draw_stacking_context(stacking_context,
+ &mut traversal,
+ paint_context,
+ transform,
+ &Point2D::zero());
}
fn draw_stacking_context_contents<'a>(&'a self,
@@ -390,6 +394,7 @@ impl DisplayList {
traversal: &mut DisplayListTraversal<'a>,
paint_context: &mut PaintContext,
transform: &Matrix4D<f32>,
+ subpixel_offset: &Point2D<Au>,
tile_rect: Option<Rect<Au>>) {
for child in stacking_context.children.iter() {
while let Some(item) = traversal.advance(stacking_context) {
@@ -399,7 +404,11 @@ impl DisplayList {
}
if child.intersects_rect_in_parent_context(tile_rect) {
- self.draw_stacking_context(child, traversal, paint_context, &transform);
+ self.draw_stacking_context(child,
+ traversal,
+ paint_context,
+ &transform,
+ subpixel_offset);
} else {
traversal.skip_past_stacking_context(child);
}
@@ -417,12 +426,14 @@ impl DisplayList {
stacking_context: &StackingContext,
traversal: &mut DisplayListTraversal<'a>,
paint_context: &mut PaintContext,
- transform: &Matrix4D<f32>) {
+ transform: &Matrix4D<f32>,
+ subpixel_offset: &Point2D<Au>) {
if stacking_context.context_type != StackingContextType::Real {
self.draw_stacking_context_contents(stacking_context,
traversal,
paint_context,
transform,
+ subpixel_offset,
None);
return;
}
@@ -431,18 +442,35 @@ impl DisplayList {
&stacking_context.filters,
stacking_context.blend_mode);
- // If a layer is being used, the transform for this layer
- // will be handled by the compositor.
let old_transform = paint_context.draw_target.get_transform();
- let transform = match stacking_context.layer_info {
- Some(..) => *transform,
+ let pixels_per_px = paint_context.screen_pixels_per_px();
+ let (transform, subpixel_offset) = match stacking_context.layer_info {
+ // If this stacking context starts a layer, the offset and transformation are handled
+ // by layer position within the compositor.
+ Some(..) => (*transform, *subpixel_offset),
None => {
- let pixels_per_px = paint_context.screen_pixels_per_px();
- let origin = &stacking_context.bounds.origin;
- transform.translate(
- origin.x.to_nearest_pixel(pixels_per_px.get()) as AzFloat,
- origin.y.to_nearest_pixel(pixels_per_px.get()) as AzFloat,
- 0.0).mul(&stacking_context.transform)
+ let origin = stacking_context.bounds.origin + *subpixel_offset;
+ let pixel_snapped_origin =
+ Point2D::new(origin.x.to_nearest_pixel(pixels_per_px.get()),
+ origin.y.to_nearest_pixel(pixels_per_px.get()));
+
+ let transform = transform.translate(pixel_snapped_origin.x as AzFloat,
+ pixel_snapped_origin.y as AzFloat,
+ 0.0).mul(&stacking_context.transform);
+ let inverse_transform = transform.invert();
+
+ // Here we are trying to accumulate any subpixel distances across transformed
+ // stacking contexts. This allows us transform stacking context with a
+ // pixel-snapped transform, but continue to propagate any subpixels from stacking
+ // context origins to children.
+ let subpixel_offset = Point2D::new(origin.x.to_f32_px() - pixel_snapped_origin.x,
+ origin.y.to_f32_px() - pixel_snapped_origin.y);
+ let subpixel_offset = inverse_transform.transform_point(&subpixel_offset) -
+ inverse_transform.transform_point(&Point2D::zero());;
+ let subpixel_offset = Point2D::new(Au::from_f32_px(subpixel_offset.x),
+ Au::from_f32_px(subpixel_offset.y));
+
+ (transform, subpixel_offset)
}
};
@@ -455,6 +483,7 @@ impl DisplayList {
clip_rect: Some(stacking_context.overflow),
transient_clip: None,
layer_kind: paint_context.layer_kind,
+ subpixel_offset: subpixel_offset,
};
// Set up our clip rect and transform.
@@ -469,6 +498,7 @@ impl DisplayList {
traversal,
&mut paint_subcontext,
&transform,
+ &subpixel_offset,
Some(transformed_tile_rect(paint_context.screen_rect, &transform)));
paint_subcontext.remove_transient_clip_if_applicable();
@@ -744,6 +774,7 @@ impl fmt::Debug for StackingContext {
/// One drawing command in the list.
#[derive(Clone, Deserialize, HeapSizeOf, Serialize)]
+#[serde(bound = "")] // Prevent serde from generating cyclic bounds.
pub enum DisplayItem {
SolidColorClass(Box<SolidColorDisplayItem>),
TextClass(Box<TextDisplayItem>),
diff --git a/components/gfx/paint_context.rs b/components/gfx/paint_context.rs
index 2614e77fc82..15c4b169ba4 100644
--- a/components/gfx/paint_context.rs
+++ b/components/gfx/paint_context.rs
@@ -53,6 +53,10 @@ pub struct PaintContext<'a> {
pub transient_clip: Option<ClippingRegion>,
/// A temporary hack to disable clipping optimizations on 3d layers.
pub layer_kind: LayerKind,
+ /// The current subpixel offset, used to make pixel snapping aware of accumulated subpixels
+ /// from the StackingContext.
+ /// TODO: Eventually this should be added to all points handled by the PaintContext.
+ pub subpixel_offset: Point2D<Au>,
}
#[derive(Copy, Clone)]
@@ -1338,24 +1342,26 @@ impl<'a> PaintContext<'a> {
pub fn draw_text(&mut self, text: &TextDisplayItem) {
let draw_target_transform = self.draw_target.get_transform();
+ let origin = text.baseline_origin + self.subpixel_offset;
+
// Optimization: Don’t set a transform matrix for upright text, and pass a start point to
// `draw_text_into_context`.
//
// For sideways text, it’s easier to do the rotation such that its center (the baseline’s
// start point) is at (0, 0) coordinates.
let baseline_origin = match text.orientation {
- Upright => text.baseline_origin,
+ Upright => origin,
SidewaysLeft => {
- let x = text.baseline_origin.x.to_f32_px();
- let y = text.baseline_origin.y.to_f32_px();
+ let x = origin.x.to_f32_px();
+ let y = origin.y.to_f32_px();
self.draw_target.set_transform(&draw_target_transform.mul(&Matrix2D::new(0., -1.,
1., 0.,
x, y)));
Point2D::zero()
}
SidewaysRight => {
- let x = text.baseline_origin.x.to_f32_px();
- let y = text.baseline_origin.y.to_f32_px();
+ let x = origin.x.to_f32_px();
+ let y = origin.y.to_f32_px();
self.draw_target.set_transform(&draw_target_transform.mul(&Matrix2D::new(0., 1.,
-1., 0.,
x, y)));
@@ -1382,10 +1388,7 @@ impl<'a> PaintContext<'a> {
// Blur, if necessary.
self.blur_if_necessary(temporary_draw_target, text.blur_radius);
- // Undo the transform, only when we did one.
- if text.orientation != Upright {
- self.draw_target.set_transform(&draw_target_transform)
- }
+ self.draw_target.set_transform(&draw_target_transform)
}
/// Draws a linear gradient in the given boundaries from the given start point to the given end
diff --git a/components/gfx/paint_thread.rs b/components/gfx/paint_thread.rs
index b4ad2abd299..a06ef7ee7af 100644
--- a/components/gfx/paint_thread.rs
+++ b/components/gfx/paint_thread.rs
@@ -379,8 +379,7 @@ impl<C> PaintThread<C> where C: PaintListener + Send + 'static {
font_cache_thread: FontCacheThread,
time_profiler_chan: time::ProfilerChan,
mem_profiler_chan: mem::ProfilerChan) {
- thread::spawn_named(format!("PaintThread {:?}", id),
- move || {
+ thread::spawn_named(format!("PaintThread {:?}", id), move || {
thread_state::initialize(thread_state::PAINT);
PipelineId::install(id);
@@ -425,9 +424,9 @@ impl<C> PaintThread<C> where C: PaintListener + Send + 'static {
let chrome_to_paint = &self.chrome_to_paint_port;
select! {
msg = layout_to_paint.recv() =>
- Msg::FromLayout(msg.unwrap()),
+ Msg::FromLayout(msg.expect("expected message from layout")),
msg = chrome_to_paint.recv() =>
- Msg::FromChrome(msg.unwrap())
+ Msg::FromChrome(msg.expect("expected message from chrome"))
}
};
@@ -685,11 +684,12 @@ impl WorkerThread {
let mut paint_context = PaintContext {
draw_target: draw_target.clone(),
font_context: &mut self.font_context,
- page_rect: Rect::from_untyped(&tile.page_rect),
+ page_rect: Rect::from_untyped(&tile.page_rect.translate(&paint_layer.display_list_origin)),
screen_rect: Rect::from_untyped(&tile.screen_rect),
clip_rect: None,
transient_clip: None,
layer_kind: layer_kind,
+ subpixel_offset: Point2D::zero(),
};
// Apply the translation to paint the tile we want.
diff --git a/components/gfx_traits/Cargo.toml b/components/gfx_traits/Cargo.toml
index 37a7a592c72..1d303d85438 100644
--- a/components/gfx_traits/Cargo.toml
+++ b/components/gfx_traits/Cargo.toml
@@ -20,5 +20,5 @@ plugins = {path = "../plugins"}
profile_traits = {path = "../profile_traits"}
range = {path = "../range"}
rustc-serialize = "0.3"
-serde = "0.7.11"
-serde_macros = "0.7.11"
+serde = "0.7.15"
+serde_macros = "0.7.15"
diff --git a/components/layout/Cargo.toml b/components/layout/Cargo.toml
index 9c83648128a..7471c12a5f7 100644
--- a/components/layout/Cargo.toml
+++ b/components/layout/Cargo.toml
@@ -21,7 +21,7 @@ gfx = {path = "../gfx"}
gfx_traits = {path = "../gfx_traits"}
heapsize = "0.3.0"
heapsize_plugin = "0.1.2"
-ipc-channel = {git = "https://github.com/servo/ipc-channel"}
+ipc-channel = "0.4.0"
libc = "0.2"
log = "0.3.5"
msg = {path = "../msg"}
@@ -33,7 +33,7 @@ rustc-serialize = "0.3"
script_layout_interface = {path = "../script_layout_interface"}
script_traits = {path = "../script_traits"}
selectors = {version = "0.7", features = ["heap_size"]}
-serde_macros = "0.7.11"
+serde_macros = "0.7.15"
smallvec = "0.1"
string_cache = {version = "0.2.20", features = ["heap_size"]}
style = {path = "../style"}
diff --git a/components/layout/block.rs b/components/layout/block.rs
index 16a837d4dcc..62365478d2f 100644
--- a/components/layout/block.rs
+++ b/components/layout/block.rs
@@ -512,14 +512,6 @@ pub struct BlockFlow {
/// The associated fragment.
pub fragment: Fragment,
- /// The sum of the inline-sizes of all logically left floats that precede this block. This is
- /// used to speculatively lay out block formatting contexts.
- inline_size_of_preceding_left_floats: Au,
-
- /// The sum of the inline-sizes of all logically right floats that precede this block. This is
- /// used to speculatively lay out block formatting contexts.
- inline_size_of_preceding_right_floats: Au,
-
/// Additional floating flow members.
pub float: Option<Box<FloatedBlockInfo>>,
@@ -551,8 +543,6 @@ impl BlockFlow {
None => ForceNonfloatedFlag::ForceNonfloated,
}),
fragment: fragment,
- inline_size_of_preceding_left_floats: Au(0),
- inline_size_of_preceding_right_floats: Au(0),
float: float_kind.map(|kind| box FloatedBlockInfo::new(kind)),
flags: BlockFlowFlags::empty(),
}
diff --git a/components/layout/display_list_builder.rs b/components/layout/display_list_builder.rs
index 5eb20156295..58ff6d23e44 100644
--- a/components/layout/display_list_builder.rs
+++ b/components/layout/display_list_builder.rs
@@ -29,7 +29,6 @@ use gfx::display_list::{LayeredItem, LayerInfo, LineDisplayItem, OpaqueNode};
use gfx::display_list::{SolidColorDisplayItem, StackingContext, StackingContextType};
use gfx::display_list::{TextDisplayItem, TextOrientation, WebRenderImageInfo};
use gfx::paint_thread::THREAD_TINT_COLORS;
-use gfx::text::glyph::ByteIndex;
use gfx_traits::{color, ScrollPolicy, StackingContextId};
use inline::{FIRST_FRAGMENT_OF_ELEMENT, InlineFlow, LAST_FRAGMENT_OF_ELEMENT};
use ipc_channel::ipc;
@@ -399,7 +398,7 @@ impl FragmentDisplayListBuilding for Fragment {
gradient,
style);
}
- Some(computed::Image::Url(ref image_url)) => {
+ Some(computed::Image::Url(ref image_url, ref _extra_data)) => {
self.build_display_list_for_background_image(state,
style,
display_list_section,
@@ -970,7 +969,8 @@ impl FragmentDisplayListBuilding for Fragment {
Some(insertion_point_index) => insertion_point_index,
None => return,
};
- let range = Range::new(ByteIndex(0), insertion_point_index);
+ let range = Range::new(scanned_text_fragment_info.range.begin(),
+ insertion_point_index - scanned_text_fragment_info.range.begin());
let advance = scanned_text_fragment_info.run.advance_for_range(&range);
let insertion_point_bounds;
diff --git a/components/layout/fragment.rs b/components/layout/fragment.rs
index 6a6071aa3c7..0ddb083c1c0 100644
--- a/components/layout/fragment.rs
+++ b/components/layout/fragment.rs
@@ -882,16 +882,23 @@ impl Fragment {
let size = LogicalSize::new(self.style.writing_mode,
split.inline_size,
self.border_box.size.block);
- let flags = match self.specific {
- SpecificFragmentInfo::ScannedText(ref info) => info.flags,
- _ => ScannedTextFlags::empty()
+ // Preserve the insertion point if it is in this fragment's range or it is at line end.
+ let (flags, insertion_point) = match self.specific {
+ SpecificFragmentInfo::ScannedText(ref info) => {
+ match info.insertion_point {
+ Some(index) if split.range.contains(index) => (info.flags, info.insertion_point),
+ Some(index) if index == ByteIndex(text_run.text.chars().count() as isize - 1) &&
+ index == split.range.end() => (info.flags, info.insertion_point),
+ _ => (info.flags, None)
+ }
+ },
+ _ => (ScannedTextFlags::empty(), None)
};
- // FIXME(pcwalton): This should modify the insertion point as necessary.
let info = box ScannedTextFragmentInfo::new(
text_run,
split.range,
size,
- None,
+ insertion_point,
flags);
self.transform(size, SpecificFragmentInfo::ScannedText(info))
}
@@ -2012,9 +2019,10 @@ impl Fragment {
// See CSS 2.1 § 10.8.1.
let flow = &info.flow_ref;
let block_flow = flow.as_block();
+ let is_auto = self.style.get_position().height == LengthOrPercentageOrAuto::Auto;
let baseline_offset = match flow.baseline_offset_of_last_line_box_in_flow() {
- Some(baseline_offset) => baseline_offset,
- None => block_flow.fragment.border_box.size.block,
+ Some(baseline_offset) if is_auto => baseline_offset,
+ _ => block_flow.fragment.border_box.size.block,
};
let start_margin = block_flow.fragment.margin.block_start;
let end_margin = block_flow.fragment.margin.block_end;
diff --git a/components/layout/table_cell.rs b/components/layout/table_cell.rs
index a71b78b8ace..f012121f5ae 100644
--- a/components/layout/table_cell.rs
+++ b/components/layout/table_cell.rs
@@ -77,9 +77,10 @@ impl TableCellFlow {
None,
MarginsMayCollapseFlag::MarginsMayNotCollapse);
debug_assert!(remaining.is_none());
- if !flow::base(self).restyle_damage.contains(REFLOW) {
- return;
- }
+ }
+
+ /// Position this cell's children according to vertical-align.
+ pub fn valign_children(&mut self) {
// Note to the reader: this code has been tested with negative margins.
// We end up with a "end" that's before the "start," but the math still works out.
let first_start = flow::base(self).children.front().map(|kid| {
@@ -106,6 +107,9 @@ impl TableCellFlow {
let self_size = flow::base(self).position.size.block -
self.block_flow.fragment.border_padding.block_start_end();
let kids_self_gap = self_size - kids_size;
+
+ // This offset should also account for vertical_align::T::baseline.
+ // Need max cell ascent from the first row of this cell.
let offset = match self.block_flow.fragment.style().get_box().vertical_align {
vertical_align::T::middle => kids_self_gap / 2,
vertical_align::T::bottom => kids_self_gap,
diff --git a/components/layout/table_row.rs b/components/layout/table_row.rs
index 8fd0255f261..cb2f8f76c7c 100644
--- a/components/layout/table_row.rs
+++ b/components/layout/table_row.rs
@@ -162,6 +162,9 @@ impl TableRowFlow {
// Assign the child's block size.
child_table_cell.block_flow.base.position.size.block = block_size;
+ // Now we know the cell height, vertical align the cell's children.
+ child_table_cell.valign_children();
+
// Write in the size of the relative containing block for children. (This information
// is also needed to handle RTL.)
child_table_cell.block_flow.base.early_absolute_position_info =
diff --git a/components/layout/traversal.rs b/components/layout/traversal.rs
index 1362f1cb7b2..b1087e945d7 100644
--- a/components/layout/traversal.rs
+++ b/components/layout/traversal.rs
@@ -77,7 +77,9 @@ impl<'lc, N> DomTraversalContext<N> for RecalcStyleAndConstructFlows<'lc>
recalc_style_at(&self.context, self.root, node);
}
- fn process_postorder(&self, node: N) { construct_flows_at(&self.context, self.root, node); }
+ fn process_postorder(&self, node: N) {
+ construct_flows_at(&self.context, self.root, node);
+ }
}
/// A bottom-up, parallelizable traversal.
@@ -96,7 +98,7 @@ fn construct_flows_at<'a, N: LayoutNode>(context: &'a LayoutContext<'a>, root: O
// Always reconstruct if incremental layout is turned off.
let nonincremental_layout = opts::get().nonincremental_layout;
- if nonincremental_layout || node.has_dirty_descendants() {
+ if nonincremental_layout || node.is_dirty() || node.has_dirty_descendants() {
let mut flow_constructor = FlowConstructor::new(context);
if nonincremental_layout || !flow_constructor.repair_if_possible(&tnode) {
flow_constructor.process(&tnode);
diff --git a/components/layout_thread/Cargo.toml b/components/layout_thread/Cargo.toml
index 4c5393f0223..a06cf20e28f 100644
--- a/components/layout_thread/Cargo.toml
+++ b/components/layout_thread/Cargo.toml
@@ -18,7 +18,7 @@ gfx = {path = "../gfx"}
gfx_traits = {path = "../gfx_traits"}
heapsize = "0.3.0"
heapsize_plugin = "0.1.2"
-ipc-channel = {git = "https://github.com/servo/ipc-channel"}
+ipc-channel = "0.4.0"
layout = {path = "../layout"}
layout_traits = {path = "../layout_traits"}
log = "0.3.5"
@@ -30,7 +30,7 @@ script = {path = "../script"}
script_layout_interface = {path = "../script_layout_interface"}
script_traits = {path = "../script_traits"}
serde_json = "0.7"
-serde_macros = "0.7"
+serde_macros = "0.7.15"
style = {path = "../style"}
url = {version = "1.0.0", features = ["heap_size"]}
util = {path = "../util"}
diff --git a/components/layout_thread/lib.rs b/components/layout_thread/lib.rs
index 9d576e3bd02..403f30a96f5 100644
--- a/components/layout_thread/lib.rs
+++ b/components/layout_thread/lib.rs
@@ -232,6 +232,10 @@ pub struct LayoutThread {
/// The timer object to control the timing of the animations. This should
/// 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
+ // rather limit the dependency on that module here.
+ layout_threads: usize,
}
impl LayoutThreadFactory for LayoutThread {
@@ -251,7 +255,8 @@ impl LayoutThreadFactory for LayoutThread {
time_profiler_chan: time::ProfilerChan,
mem_profiler_chan: mem::ProfilerChan,
content_process_shutdown_chan: IpcSender<()>,
- webrender_api_sender: Option<webrender_traits::RenderApiSender>) {
+ webrender_api_sender: Option<webrender_traits::RenderApiSender>,
+ layout_threads: usize) {
thread::spawn_named(format!("LayoutThread {:?}", id),
move || {
thread_state::initialize(thread_state::LAYOUT);
@@ -270,7 +275,8 @@ impl LayoutThreadFactory for LayoutThread {
font_cache_thread,
time_profiler_chan,
mem_profiler_chan.clone(),
- webrender_api_sender);
+ webrender_api_sender,
+ layout_threads);
let reporter_name = format!("layout-reporter-{}", id);
mem_profiler_chan.run_with_memory_reporting(|| {
@@ -381,14 +387,14 @@ impl LayoutThread {
font_cache_thread: FontCacheThread,
time_profiler_chan: time::ProfilerChan,
mem_profiler_chan: mem::ProfilerChan,
- webrender_api_sender: Option<webrender_traits::RenderApiSender>)
+ webrender_api_sender: Option<webrender_traits::RenderApiSender>,
+ layout_threads: usize)
-> LayoutThread {
let device = Device::new(
MediaType::Screen,
opts::get().initial_window_size.as_f32() * ScaleFactor::new(1.0));
- let parallel_traversal = if opts::get().layout_threads != 1 {
- Some(WorkQueue::new("LayoutWorker", thread_state::LAYOUT,
- opts::get().layout_threads))
+ let parallel_traversal = if layout_threads != 1 {
+ Some(WorkQueue::new("LayoutWorker", thread_state::LAYOUT, layout_threads))
} else {
None
};
@@ -479,6 +485,7 @@ impl LayoutThread {
} else {
Timer::new()
},
+ layout_threads: layout_threads,
}
}
@@ -754,7 +761,8 @@ impl LayoutThread {
self.time_profiler_chan.clone(),
self.mem_profiler_chan.clone(),
info.content_process_shutdown_chan,
- self.webrender_api.as_ref().map(|wr| wr.clone_sender()));
+ self.webrender_api.as_ref().map(|wr| wr.clone_sender()),
+ info.layout_threads);
}
/// Enters a quiescent state in which no new messages will be processed until an `ExitNow` is
@@ -961,7 +969,7 @@ impl LayoutThread {
self.epoch.next();
- if opts::get().use_webrender {
+ if let Some(ref mut webrender_api) = self.webrender_api {
// TODO: Avoid the temporary conversion and build webrender sc/dl directly!
let Epoch(epoch_number) = self.epoch;
let epoch = webrender_traits::Epoch(epoch_number);
@@ -971,7 +979,7 @@ impl LayoutThread {
let mut frame_builder = WebRenderFrameBuilder::new(pipeline_id);
let root_scroll_layer_id = frame_builder.next_scroll_layer_id();
let sc_id = rw_data.display_list.as_ref().unwrap().convert_to_webrender(
- &mut self.webrender_api.as_mut().unwrap(),
+ webrender_api,
pipeline_id,
epoch,
Some(root_scroll_layer_id),
@@ -987,16 +995,15 @@ impl LayoutThread {
let viewport_size = Size2D::new(self.viewport_size.width.to_f32_px(),
self.viewport_size.height.to_f32_px());
- let api = self.webrender_api.as_ref().unwrap();
- api.set_root_stacking_context(sc_id,
- root_background_color,
- epoch,
- pipeline_id,
- viewport_size,
- frame_builder.stacking_contexts,
- frame_builder.display_lists,
- frame_builder.auxiliary_lists_builder
- .finalize());
+ webrender_api.set_root_stacking_context(
+ sc_id,
+ root_background_color,
+ epoch,
+ pipeline_id,
+ viewport_size,
+ frame_builder.stacking_contexts,
+ frame_builder.display_lists,
+ frame_builder.auxiliary_lists_builder.finalize());
} else {
self.paint_chan
.send(LayoutToPaintMsg::PaintInit(self.epoch, display_list))
@@ -1097,12 +1104,16 @@ impl LayoutThread {
.unwrap();
}
if data.document_stylesheets.iter().any(|sheet| sheet.dirty_on_viewport_size_change) {
- for node in node.traverse_preorder() {
+ let mut iter = node.traverse_preorder();
+
+ let mut next = iter.next();
+ while let Some(node) = next {
if node.needs_dirty_on_viewport_size_changed() {
- node.dirty_self();
- node.dirty_descendants();
- // TODO(shinglyu): We can skip the traversal if the descendants were already
- // dirtied
+ // NB: The dirty bit is propagated down the tree.
+ unsafe { node.set_dirty(true); }
+ next = iter.next_skipping_children();
+ } else {
+ next = iter.next();
}
}
}
@@ -1114,7 +1125,9 @@ impl LayoutThread {
let needs_reflow = viewport_size_changed && !needs_dirtying;
unsafe {
if needs_dirtying {
- LayoutThread::dirty_all_nodes(node);
+ // NB: The dirty flag is propagated down during the restyle
+ // process.
+ node.set_dirty(true);
}
}
if needs_reflow {
@@ -1158,7 +1171,7 @@ impl LayoutThread {
// TODO(pcwalton): Measure energy usage of text shaping, perhaps?
let text_shaping_time =
(font::get_and_reset_text_shaping_performance_counter() as u64) /
- (opts::get().layout_threads as u64);
+ (self.layout_threads as u64);
time::send_profile_data(time::ProfilerCategory::LayoutTextShaping,
self.profiler_metadata(),
self.time_profiler_chan.clone(),
@@ -1468,16 +1481,6 @@ impl LayoutThread {
}
}
- unsafe fn dirty_all_nodes<N: LayoutNode>(node: N) {
- for node in node.traverse_preorder() {
- // TODO(cgaebel): mark nodes which are sensitive to media queries as
- // "changed":
- // > node.set_changed(true);
- node.set_dirty(true);
- node.set_dirty_descendants(true);
- }
- }
-
fn reflow_all_nodes(flow: &mut Flow) {
debug!("reflowing all nodes!");
flow::mut_base(flow).restyle_damage.insert(REPAINT | STORE_OVERFLOW | REFLOW);
diff --git a/components/layout_traits/Cargo.toml b/components/layout_traits/Cargo.toml
index ff250314d49..653ae4102b7 100644
--- a/components/layout_traits/Cargo.toml
+++ b/components/layout_traits/Cargo.toml
@@ -16,7 +16,7 @@ msg = {path = "../msg"}
net_traits = {path = "../net_traits"}
profile_traits = {path = "../profile_traits"}
util = {path = "../util"}
-ipc-channel = {git = "https://github.com/servo/ipc-channel"}
+ipc-channel = "0.4.0"
url = {version = "1.0.0", features = ["heap_size"]}
[dependencies.webrender_traits]
diff --git a/components/layout_traits/lib.rs b/components/layout_traits/lib.rs
index 1b6c621d755..5f9fc0d472b 100644
--- a/components/layout_traits/lib.rs
+++ b/components/layout_traits/lib.rs
@@ -48,5 +48,6 @@ pub trait LayoutThreadFactory {
time_profiler_chan: time::ProfilerChan,
mem_profiler_chan: mem::ProfilerChan,
content_process_shutdown_chan: IpcSender<()>,
- webrender_api_sender: Option<webrender_traits::RenderApiSender>);
+ webrender_api_sender: Option<webrender_traits::RenderApiSender>,
+ layout_threads: usize);
}
diff --git a/components/msg/Cargo.toml b/components/msg/Cargo.toml
index 0b47f9a885c..06e60c24054 100644
--- a/components/msg/Cargo.toml
+++ b/components/msg/Cargo.toml
@@ -15,10 +15,10 @@ cssparser = {version = "0.5.4", features = ["heap_size", "serde-serialization"]}
heapsize = "0.3.0"
heapsize_plugin = "0.1.2"
hyper = {version = "0.9.9", features = ["serde-serialization"]}
-ipc-channel = {git = "https://github.com/servo/ipc-channel"}
+ipc-channel = "0.4.0"
plugins = {path = "../plugins"}
-serde = "0.7.11"
-serde_macros = "0.7.11"
+serde = "0.7.15"
+serde_macros = "0.7.15"
url = {version = "1.0.0", features = ["heap_size", "serde"]}
[dependencies.webrender_traits]
diff --git a/components/net/Cargo.toml b/components/net/Cargo.toml
index 9cb6ecfc5de..6ee9543b265 100644
--- a/components/net/Cargo.toml
+++ b/components/net/Cargo.toml
@@ -19,7 +19,7 @@ devtools_traits = {path = "../devtools_traits"}
flate2 = "0.2.0"
hyper = {version = "0.9.9", features = ["serde-serialization"]}
immeta = "0.3.1"
-ipc-channel = {git = "https://github.com/servo/ipc-channel"}
+ipc-channel = "0.4.0"
lazy_static = "0.2"
log = "0.3.5"
matches = "0.1"
@@ -46,5 +46,5 @@ git = "https://github.com/servo/webrender_traits"
default_features = false
features = ["serde_macros"]
-[target.'cfg(any(target_os = "macos", target_os = "linux"))'.dependencies]
+[target.'cfg(any(target_os = "macos", target_os = "linux", target_os = "windows"))'.dependencies]
tinyfiledialogs = {git = "https://github.com/jdm/tinyfiledialogs"}
diff --git a/components/net/blob_loader.rs b/components/net/blob_loader.rs
index 0ded019553f..0783afd979a 100644
--- a/components/net/blob_loader.rs
+++ b/components/net/blob_loader.rs
@@ -2,15 +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 filemanager_thread::{FileManager, UIProvider};
use hyper::header::{DispositionType, ContentDisposition, DispositionParam};
use hyper::header::{Headers, ContentType, ContentLength, Charset};
use hyper::http::RawStatus;
-use ipc_channel::ipc::{self, IpcSender};
+use ipc_channel::ipc;
use mime::{Mime, Attr};
use mime_classifier::MimeClassifier;
use net_traits::ProgressMsg::{Payload, Done};
use net_traits::blob_url_store::parse_blob_url;
-use net_traits::filemanager_thread::{FileManagerThreadMsg, SelectedFileId};
+use net_traits::filemanager_thread::{FileManagerThreadMsg, SelectedFileId, ReadFileProgress};
use net_traits::response::HttpsState;
use net_traits::{LoadConsumer, LoadData, Metadata, NetworkError};
use resource_thread::CancellationListener;
@@ -22,30 +23,30 @@ use util::thread::spawn_named;
// TODO: Check on GET
// https://w3c.github.io/FileAPI/#requestResponseModel
-pub fn factory(filemanager_chan: IpcSender<FileManagerThreadMsg>)
- -> Box<FnBox(LoadData,
- LoadConsumer,
- Arc<MimeClassifier>,
- CancellationListener) + Send> {
- box move |load_data: LoadData, start_chan, classifier, _cancel_listener| {
+pub fn factory<UI: 'static + UIProvider>(filemanager: Arc<FileManager<UI>>)
+ -> Box<FnBox(LoadData, LoadConsumer, Arc<MimeClassifier>, CancellationListener) + Send> {
+ box move |load_data: LoadData, start_chan, classifier, cancel_listener| {
spawn_named(format!("blob loader for {}", load_data.url), move || {
- load_blob(load_data, start_chan, classifier, filemanager_chan);
+ load_blob(load_data, start_chan, classifier, filemanager, cancel_listener);
})
}
}
-fn load_blob(load_data: LoadData, start_chan: LoadConsumer,
+fn load_blob<UI: 'static + UIProvider>
+ (load_data: LoadData, start_chan: LoadConsumer,
classifier: Arc<MimeClassifier>,
- filemanager_chan: IpcSender<FileManagerThreadMsg>) {
+ filemanager: Arc<FileManager<UI>>,
+ cancel_listener: CancellationListener) {
let (chan, recv) = ipc::channel().unwrap();
if let Ok((id, origin, _fragment)) = parse_blob_url(&load_data.url.clone()) {
let id = SelectedFileId(id.simple().to_string());
let check_url_validity = true;
let msg = FileManagerThreadMsg::ReadFile(chan, id, check_url_validity, origin);
- let _ = filemanager_chan.send(msg);
+ let _ = filemanager.handle(msg, Some(cancel_listener));
+ // Receive first chunk
match recv.recv().unwrap() {
- Ok(blob_buf) => {
+ Ok(ReadFileProgress::Meta(blob_buf)) => {
let content_type: Mime = blob_buf.type_string.parse().unwrap_or(mime!(Text / Plain));
let charset = content_type.get_param(Attr::Charset);
@@ -80,9 +81,34 @@ fn load_blob(load_data: LoadData, start_chan: LoadConsumer,
start_sending_sniffed_opt(start_chan, metadata, classifier,
&blob_buf.bytes, load_data.context.clone()) {
let _ = chan.send(Payload(blob_buf.bytes));
- let _ = chan.send(Done(Ok(())));
+
+ loop {
+ match recv.recv().unwrap() {
+ Ok(ReadFileProgress::Partial(bytes)) => {
+ let _ = chan.send(Payload(bytes));
+ }
+ Ok(ReadFileProgress::EOF) => {
+ let _ = chan.send(Done(Ok(())));
+ return;
+ }
+ Ok(_) => {
+ let err = NetworkError::Internal("Invalid filemanager reply".to_string());
+ let _ = chan.send(Done(Err(err)));
+ return;
+ }
+ Err(e) => {
+ let err = NetworkError::Internal(format!("{:?}", e));
+ let _ = chan.send(Done(Err(err)));
+ return;
+ }
+ }
+ }
}
}
+ Ok(_) => {
+ let err = NetworkError::Internal("Invalid filemanager reply".to_string());
+ send_error(load_data.url, err, start_chan);
+ }
Err(e) => {
let err = NetworkError::Internal(format!("{:?}", e));
send_error(load_data.url, err, start_chan);
diff --git a/components/net/bluetooth_thread.rs b/components/net/bluetooth_thread.rs
index 1b882763911..3c2538b1f88 100644
--- a/components/net/bluetooth_thread.rs
+++ b/components/net/bluetooth_thread.rs
@@ -12,7 +12,7 @@ use ipc_channel::ipc::{self, IpcReceiver, IpcSender};
use net_traits::bluetooth_scanfilter::{BluetoothScanfilter, BluetoothScanfilterSequence, RequestDeviceoptions};
use net_traits::bluetooth_thread::{BluetoothCharacteristicMsg, BluetoothCharacteristicsMsg};
use net_traits::bluetooth_thread::{BluetoothDescriptorMsg, BluetoothDescriptorsMsg};
-use net_traits::bluetooth_thread::{BluetoothDeviceMsg, BluetoothMethodMsg};
+use net_traits::bluetooth_thread::{BluetoothDeviceMsg, BluetoothError, BluetoothMethodMsg};
use net_traits::bluetooth_thread::{BluetoothResult, BluetoothServiceMsg, BluetoothServicesMsg};
use rand::{self, Rng};
use std::borrow::ToOwned;
@@ -25,15 +25,7 @@ use tinyfiledialogs;
use util::thread::spawn_named;
const ADAPTER_ERROR: &'static str = "No adapter found";
-const DEVICE_ERROR: &'static str = "No device found";
-const DEVICE_MATCH_ERROR: &'static str = "No device found, that matches the given options";
-const PRIMARY_SERVICE_ERROR: &'static str = "No primary service found";
-const INCLUDED_SERVICE_ERROR: &'static str = "No included service found";
-const CHARACTERISTIC_ERROR: &'static str = "No characteristic found";
-const DESCRIPTOR_ERROR: &'static str = "No descriptor found";
-const VALUE_ERROR: &'static str = "No characteristic or descriptor found with that id";
-const SECURITY_ERROR: &'static str = "The operation is insecure";
-const NETWORK_ERROR: &'static str = "A network error occurred";
+
// 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)
const MAXIMUM_TRANSACTION_TIME: u8 = 30;
@@ -73,7 +65,7 @@ macro_rules! get_adapter_or_return_error(
($bl_manager:expr, $sender:expr) => (
match $bl_manager.get_or_create_adapter() {
Some(adapter) => adapter,
- None => return drop($sender.send(Err(String::from(ADAPTER_ERROR)))),
+ None => return drop($sender.send(Err(BluetoothError::Type(ADAPTER_ERROR.to_string())))),
}
);
);
@@ -453,7 +445,7 @@ impl BluetoothManager {
if let Some(address) = self.select_device(matched_devices) {
let device_id = match self.address_to_id.get(&address) {
Some(id) => id.clone(),
- None => return drop(sender.send(Err(String::from(DEVICE_MATCH_ERROR)))),
+ None => return drop(sender.send(Err(BluetoothError::NotFound))),
};
let mut services = options.get_services_set();
if let Some(services_set) = self.allowed_services.get(&device_id) {
@@ -471,7 +463,7 @@ impl BluetoothManager {
return drop(sender.send(message));
}
}
- return drop(sender.send(Err(String::from(DEVICE_MATCH_ERROR))));
+ return drop(sender.send(Err(BluetoothError::NotFound)));
}
fn gatt_server_connect(&mut self, device_id: String, sender: IpcSender<BluetoothResult<bool>>) {
@@ -489,9 +481,9 @@ impl BluetoothManager {
false => thread::sleep(Duration::from_millis(CONNECTION_TIMEOUT_MS)),
}
}
- return drop(sender.send(Err(String::from(NETWORK_ERROR))));
+ return drop(sender.send(Err(BluetoothError::Network)));
},
- None => return drop(sender.send(Err(String::from(DEVICE_ERROR)))),
+ None => return drop(sender.send(Err(BluetoothError::NotFound))),
}
}
@@ -510,9 +502,9 @@ impl BluetoothManager {
false => return drop(sender.send(Ok(false))),
}
}
- return drop(sender.send(Err(String::from(NETWORK_ERROR))));
+ return drop(sender.send(Err(BluetoothError::Network)));
},
- None => return drop(sender.send(Err(String::from(DEVICE_ERROR)))),
+ None => return drop(sender.send(Err(BluetoothError::NotFound))),
}
}
@@ -522,11 +514,11 @@ impl BluetoothManager {
sender: IpcSender<BluetoothResult<BluetoothServiceMsg>>) {
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(String::from(SECURITY_ERROR))));
+ return drop(sender.send(Err(BluetoothError::Security)));
}
let services = self.get_gatt_services_by_uuid(&mut adapter, &device_id, &uuid);
if services.is_empty() {
- return drop(sender.send(Err(String::from(PRIMARY_SERVICE_ERROR))));
+ return drop(sender.send(Err(BluetoothError::NotFound)));
}
for service in services {
if service.is_primary().unwrap_or(false) {
@@ -539,7 +531,7 @@ impl BluetoothManager {
}
}
}
- return drop(sender.send(Err(String::from(PRIMARY_SERVICE_ERROR))));
+ return drop(sender.send(Err(BluetoothError::NotFound)));
}
fn get_primary_services(&mut self,
@@ -550,14 +542,14 @@ impl BluetoothManager {
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(String::from(SECURITY_ERROR))))
+ return drop(sender.send(Err(BluetoothError::Security)))
}
self.get_gatt_services_by_uuid(&mut adapter, &device_id, id)
},
None => self.get_and_cache_gatt_services(&mut adapter, &device_id),
};
if services.is_empty() {
- return drop(sender.send(Err(String::from(PRIMARY_SERVICE_ERROR))));
+ return drop(sender.send(Err(BluetoothError::NotFound)));
}
let mut services_vec = vec!();
for service in services {
@@ -572,7 +564,7 @@ impl BluetoothManager {
}
}
if services_vec.is_empty() {
- return drop(sender.send(Err(String::from(PRIMARY_SERVICE_ERROR))));
+ return drop(sender.send(Err(BluetoothError::NotFound)));
}
let _ = sender.send(Ok(services_vec));
@@ -584,11 +576,11 @@ impl BluetoothManager {
sender: IpcSender<BluetoothResult<BluetoothServiceMsg>>) {
let mut adapter = match self.get_or_create_adapter() {
Some(a) => a,
- None => return drop(sender.send(Err(String::from(ADAPTER_ERROR)))),
+ None => return drop(sender.send(Err(BluetoothError::Type(ADAPTER_ERROR.to_string())))),
};
let primary_service = match self.get_gatt_service(&mut adapter, &service_id) {
Some(s) => s,
- None => return drop(sender.send(Err(String::from(PRIMARY_SERVICE_ERROR)))),
+ None => return drop(sender.send(Err(BluetoothError::NotFound))),
};
let services = primary_service.get_includes().unwrap_or(vec!());
for service in services {
@@ -602,7 +594,7 @@ impl BluetoothManager {
}
}
}
- return drop(sender.send(Err(String::from(INCLUDED_SERVICE_ERROR))));
+ return drop(sender.send(Err(BluetoothError::NotFound)));
}
fn get_included_services(&mut self,
@@ -611,11 +603,11 @@ impl BluetoothManager {
sender: IpcSender<BluetoothResult<BluetoothServicesMsg>>) {
let mut adapter = match self.get_or_create_adapter() {
Some(a) => a,
- None => return drop(sender.send(Err(String::from(ADAPTER_ERROR)))),
+ None => return drop(sender.send(Err(BluetoothError::Type(ADAPTER_ERROR.to_string())))),
};
let primary_service = match self.get_gatt_service(&mut adapter, &service_id) {
Some(s) => s,
- None => return drop(sender.send(Err(String::from(PRIMARY_SERVICE_ERROR)))),
+ None => return drop(sender.send(Err(BluetoothError::NotFound))),
};
let services = primary_service.get_includes().unwrap_or(vec!());
let mut services_vec = vec!();
@@ -632,7 +624,7 @@ impl BluetoothManager {
services_vec.retain(|ref s| s.uuid == uuid);
}
if services_vec.is_empty() {
- return drop(sender.send(Err(String::from(INCLUDED_SERVICE_ERROR))));
+ return drop(sender.send(Err(BluetoothError::NotFound)));
}
let _ = sender.send(Ok(services_vec));
@@ -645,7 +637,7 @@ impl BluetoothManager {
let mut adapter = get_adapter_or_return_error!(self, sender);
let characteristics = self.get_gatt_characteristics_by_uuid(&mut adapter, &service_id, &uuid);
if characteristics.is_empty() {
- return drop(sender.send(Err(String::from(CHARACTERISTIC_ERROR))));
+ return drop(sender.send(Err(BluetoothError::NotFound)));
}
for characteristic in characteristics {
if let Ok(uuid) = characteristic.get_uuid() {
@@ -666,7 +658,7 @@ impl BluetoothManager {
return drop(sender.send(message));
}
}
- return drop(sender.send(Err(String::from(CHARACTERISTIC_ERROR))));
+ return drop(sender.send(Err(BluetoothError::NotFound)));
}
fn get_characteristics(&mut self,
@@ -679,7 +671,7 @@ impl BluetoothManager {
None => self.get_and_cache_gatt_characteristics(&mut adapter, &service_id),
};
if characteristics.is_empty() {
- return drop(sender.send(Err(String::from(CHARACTERISTIC_ERROR))));
+ return drop(sender.send(Err(BluetoothError::NotFound)));
}
let mut characteristics_vec = vec!();
for characteristic in characteristics {
@@ -702,7 +694,7 @@ impl BluetoothManager {
}
}
if characteristics_vec.is_empty() {
- return drop(sender.send(Err(String::from(CHARACTERISTIC_ERROR))));
+ return drop(sender.send(Err(BluetoothError::NotFound)));
}
let _ = sender.send(Ok(characteristics_vec));
@@ -715,7 +707,7 @@ impl BluetoothManager {
let mut adapter = get_adapter_or_return_error!(self, sender);
let descriptors = self.get_gatt_descriptors_by_uuid(&mut adapter, &characteristic_id, &uuid);
if descriptors.is_empty() {
- return drop(sender.send(Err(String::from(DESCRIPTOR_ERROR))));
+ return drop(sender.send(Err(BluetoothError::NotFound)));
}
for descriptor in descriptors {
if let Ok(uuid) = descriptor.get_uuid() {
@@ -725,7 +717,7 @@ impl BluetoothManager {
})));
}
}
- return drop(sender.send(Err(String::from(DESCRIPTOR_ERROR))));
+ return drop(sender.send(Err(BluetoothError::NotFound)));
}
fn get_descriptors(&mut self,
@@ -738,7 +730,7 @@ impl BluetoothManager {
None => self.get_and_cache_gatt_descriptors(&mut adapter, &characteristic_id),
};
if descriptors.is_empty() {
- return drop(sender.send(Err(String::from(DESCRIPTOR_ERROR))));
+ return drop(sender.send(Err(BluetoothError::NotFound)));
}
let mut descriptors_vec = vec!();
for descriptor in descriptors {
@@ -750,7 +742,7 @@ impl BluetoothManager {
}
}
if descriptors_vec.is_empty() {
- return drop(sender.send(Err(String::from(DESCRIPTOR_ERROR))));
+ return drop(sender.send(Err(BluetoothError::NotFound)));
}
let _ = sender.send(Ok(descriptors_vec));
}
@@ -763,7 +755,7 @@ impl BluetoothManager {
value = self.get_gatt_descriptor(&mut adapter, &id)
.map(|d| d.read_value().unwrap_or(vec![]));
}
- let _ = sender.send(value.ok_or(String::from(VALUE_ERROR)));
+ let _ = sender.send(value.ok_or(BluetoothError::NotSupported));
}
fn write_value(&mut self, id: String, value: Vec<u8>, sender: IpcSender<BluetoothResult<bool>>) {
@@ -777,9 +769,9 @@ impl BluetoothManager {
let message = match result {
Some(v) => match v {
Ok(_) => Ok(true),
- Err(e) => return drop(sender.send(Err(e.to_string()))),
+ Err(_) => return drop(sender.send(Err(BluetoothError::NotSupported))),
},
- None => return drop(sender.send(Err(String::from(VALUE_ERROR)))),
+ None => return drop(sender.send(Err(BluetoothError::NotSupported))),
};
let _ = sender.send(message);
}
diff --git a/components/net/fetch/methods.rs b/components/net/fetch/methods.rs
index bef25ef9ba0..15aa3d28c00 100644
--- a/components/net/fetch/methods.rs
+++ b/components/net/fetch/methods.rs
@@ -4,10 +4,12 @@
use connector::create_http_connector;
use data_loader::decode;
+use devtools_traits::DevtoolsControlMsg;
use fetch::cors_cache::CORSCache;
use http_loader::{HttpState, set_default_accept_encoding, set_request_cookies};
use http_loader::{NetworkHttpRequestFactory, ReadResult, StreamedResponse, obtain_response, read_block};
use http_loader::{auth_from_cache, determine_request_referrer};
+use http_loader::{send_response_to_devtools, send_request_to_devtools};
use hyper::header::{Accept, AcceptLanguage, Authorization, AccessControlAllowCredentials};
use hyper::header::{AccessControlAllowOrigin, AccessControlAllowHeaders, AccessControlAllowMethods};
use hyper::header::{AccessControlRequestHeaders, AccessControlMaxAge, AccessControlRequestMethod, Basic};
@@ -20,7 +22,7 @@ use hyper::status::StatusCode;
use mime_guess::guess_mime_type;
use msg::constellation_msg::ReferrerPolicy;
use net_traits::FetchTaskTarget;
-use net_traits::request::{CacheMode, CredentialsMode};
+use net_traits::request::{CacheMode, CredentialsMode, Destination};
use net_traits::request::{RedirectMode, Referer, Request, RequestMode, ResponseTainting};
use net_traits::request::{Type, Origin, Window};
use net_traits::response::{HttpsState, TerminationReason};
@@ -36,6 +38,7 @@ use std::sync::mpsc::{channel, Sender, Receiver};
use unicase::UniCase;
use url::{Origin as UrlOrigin, Url};
use util::thread::spawn_named;
+use uuid;
pub type Target = Option<Box<FetchTaskTarget + Send>>;
@@ -47,6 +50,7 @@ enum Data {
pub struct FetchContext {
pub state: HttpState,
pub user_agent: String,
+ pub devtools_chan: Option<Sender<DevtoolsControlMsg>>,
}
type DoneChannel = Option<(Sender<Data>, Receiver<Data>)>;
@@ -210,7 +214,8 @@ fn main_fetch(request: Rc<Request>, cache: &mut CORSCache, cors_flag: bool,
request.headers.borrow().iter().any(|h| !is_simple_header(&h)))) {
request.response_tainting.set(ResponseTainting::CORSTainting);
request.redirect_mode.set(RedirectMode::Error);
- let response = http_fetch(request.clone(), cache, true, true, false, target, done_chan, context);
+ let response = http_fetch(request.clone(), cache, true, true, false,
+ target, done_chan, context);
if response.is_network_error() {
// TODO clear cache entries using request
}
@@ -888,7 +893,8 @@ fn http_network_or_cache_fetch(request: Rc<Request>,
// Step 18
if response.is_none() {
- response = Some(http_network_fetch(http_request.clone(), credentials_flag, done_chan));
+ response = Some(http_network_fetch(http_request.clone(), credentials_flag,
+ done_chan, context.devtools_chan.clone()));
}
let response = response.unwrap();
@@ -924,7 +930,8 @@ fn http_network_or_cache_fetch(request: Rc<Request>,
/// [HTTP network fetch](https://fetch.spec.whatwg.org/#http-network-fetch)
fn http_network_fetch(request: Rc<Request>,
_credentials_flag: bool,
- done_chan: &mut DoneChannel) -> Response {
+ done_chan: &mut DoneChannel,
+ devtools_chan: Option<Sender<DevtoolsControlMsg>>) -> Response {
// TODO: Implement HTTP network fetch spec
// Step 1
@@ -944,14 +951,22 @@ fn http_network_fetch(request: Rc<Request>,
let url = request.current_url();
let cancellation_listener = CancellationListener::new(None);
+ let request_id = uuid::Uuid::new_v4().simple().to_string();
+
+ // XHR uses the default destination; other kinds of fetches (which haven't been implemented yet)
+ // do not. Once we support other kinds of fetches we'll need to be more fine grained here
+ // since things like image fetches are classified differently by devtools
+ let is_xhr = request.destination == Destination::None;
let wrapped_response = obtain_response(&factory, &url, &request.method.borrow(),
&request.headers.borrow(),
&cancellation_listener, &request.body.borrow(), &request.method.borrow(),
- &None, request.redirect_count.get() + 1, &None, "");
+ &request.pipeline_id.get(), request.redirect_count.get() + 1,
+ &devtools_chan, &request_id, is_xhr);
+ let pipeline_id = request.pipeline_id.get();
let mut response = Response::new();
match wrapped_response {
- Ok((res, _)) => {
+ Ok((res, msg)) => {
response.url = Some(url.clone());
response.status = Some(res.response.status);
response.raw_status = Some(res.response.status_raw().clone());
@@ -963,10 +978,29 @@ fn http_network_fetch(request: Rc<Request>,
*done_chan = Some(channel());
let meta = response.metadata().expect("Response metadata should exist at this stage");
let done_sender = done_chan.as_ref().map(|ch| ch.0.clone());
+ let devtools_sender = devtools_chan.clone();
+ let meta_status = meta.status.clone();
+ let meta_headers = meta.headers.clone();
spawn_named(format!("fetch worker thread"), move || {
match StreamedResponse::from_http_response(box res, meta) {
Ok(mut res) => {
*res_body.lock().unwrap() = ResponseBody::Receiving(vec![]);
+
+ if let Some(ref sender) = devtools_sender {
+ if let Some(m) = msg {
+ send_request_to_devtools(m, &sender);
+ }
+
+ // --- Tell devtools that we got a response
+ // Send an HttpResponse message to devtools with the corresponding request_id
+ if let Some(pipeline_id) = pipeline_id {
+ send_response_to_devtools(
+ &sender, request_id.into(),
+ meta_headers, meta_status,
+ pipeline_id);
+ }
+ }
+
loop {
match read_block(&mut res) {
Ok(ReadResult::Payload(chunk)) => {
@@ -994,7 +1028,6 @@ fn http_network_fetch(request: Rc<Request>,
break;
}
}
-
}
}
Err(_) => {
@@ -1064,9 +1097,11 @@ fn http_network_fetch(request: Rc<Request>,
}
/// [CORS preflight fetch](https://fetch.spec.whatwg.org#cors-preflight-fetch)
-fn cors_preflight_fetch(request: Rc<Request>, cache: &mut CORSCache, context: &FetchContext) -> Response {
+fn cors_preflight_fetch(request: Rc<Request>, cache: &mut CORSCache,
+ context: &FetchContext) -> Response {
// Step 1
- let mut preflight = Request::new(request.current_url(), Some(request.origin.borrow().clone()), false);
+ let mut preflight = Request::new(request.current_url(), Some(request.origin.borrow().clone()),
+ false, request.pipeline_id.get());
*preflight.method.borrow_mut() = Method::Options;
preflight.initiator = request.initiator.clone();
preflight.type_ = request.type_.clone();
diff --git a/components/net/filemanager_thread.rs b/components/net/filemanager_thread.rs
index 175d1ca3fe1..5f9e6654bed 100644
--- a/components/net/filemanager_thread.rs
+++ b/components/net/filemanager_thread.rs
@@ -2,11 +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 ipc_channel::ipc::{self, IpcReceiver, IpcSender};
+use ipc_channel::ipc::IpcSender;
use mime_guess::guess_mime_type_opt;
use net_traits::blob_url_store::{BlobBuf, BlobURLStoreError};
use net_traits::filemanager_thread::{FileManagerThreadMsg, FileManagerResult, FilterPattern, FileOrigin};
-use net_traits::filemanager_thread::{SelectedFile, RelativePos, FileManagerThreadError, SelectedFileId};
+use net_traits::filemanager_thread::{SelectedFile, RelativePos, FileManagerThreadError};
+use net_traits::filemanager_thread::{SelectedFileId, ReadFileProgress};
+use resource_thread::CancellationListener;
use std::collections::HashMap;
use std::fs::File;
use std::io::{Read, Seek, SeekFrom};
@@ -14,17 +16,13 @@ use std::ops::Index;
use std::path::{Path, PathBuf};
use std::sync::atomic::{self, AtomicUsize, AtomicBool, Ordering};
use std::sync::{Arc, RwLock};
-#[cfg(any(target_os = "macos", target_os = "linux"))]
+#[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;
-pub trait FileManagerThreadFactory<UI: 'static + UIProvider> {
- fn new(&'static UI) -> Self;
-}
-
/// Trait that provider of file-dialog UI should implement.
/// It will be used to initialize a generic FileManager.
/// For example, we can choose a dummy UI for testing purpose.
@@ -37,7 +35,7 @@ pub trait UIProvider where Self: Sync {
pub struct TFDProvider;
impl UIProvider for TFDProvider {
- #[cfg(any(target_os = "macos", target_os = "linux"))]
+ #[cfg(any(target_os = "macos", target_os = "linux", target_os = "windows"))]
fn open_file_dialog(&self, path: &str, patterns: Vec<FilterPattern>) -> Option<String> {
let mut filter = vec![];
for p in patterns {
@@ -52,7 +50,7 @@ impl UIProvider for TFDProvider {
tinyfiledialogs::open_file_dialog("Pick a file", path, filter_opt)
}
- #[cfg(any(target_os = "macos", target_os = "linux"))]
+ #[cfg(any(target_os = "macos", target_os = "linux", target_os = "windows"))]
fn open_file_dialog_multi(&self, path: &str, patterns: Vec<FilterPattern>) -> Option<Vec<String>> {
let mut filter = vec![];
for p in patterns {
@@ -67,30 +65,17 @@ impl UIProvider for TFDProvider {
tinyfiledialogs::open_file_dialog_multi("Pick files", path, filter_opt)
}
- #[cfg(not(any(target_os = "macos", target_os = "linux")))]
- fn open_file_dialog(&self, path: &str, patterns: Vec<FilterPattern>) -> Option<String> {
+ #[cfg(not(any(target_os = "macos", target_os = "linux", target_os = "windows")))]
+ fn open_file_dialog(&self, _path: &str, _patterns: Vec<FilterPattern>) -> Option<String> {
None
}
- #[cfg(not(any(target_os = "macos", target_os = "linux")))]
- fn open_file_dialog_multi(&self, path: &str, patterns: Vec<FilterPattern>) -> Option<Vec<String>> {
+ #[cfg(not(any(target_os = "macos", target_os = "linux", target_os = "windows")))]
+ fn open_file_dialog_multi(&self, _path: &str, _patterns: Vec<FilterPattern>) -> Option<Vec<String>> {
None
}
}
-impl<UI: 'static + UIProvider> FileManagerThreadFactory<UI> for IpcSender<FileManagerThreadMsg> {
- /// Create a FileManagerThread
- fn new(ui: &'static UI) -> IpcSender<FileManagerThreadMsg> {
- let (chan, recv) = ipc::channel().unwrap();
-
- spawn_named("FileManager".to_owned(), move || {
- FileManager::new(recv, ui).start();
- });
-
- chan
- }
-}
-
/// FileManagerStore's entry
struct FileStoreEntry {
/// Origin of the entry's "creator"
@@ -126,93 +111,79 @@ enum FileImpl {
Sliced(Uuid, RelativePos),
}
-struct FileManager<UI: 'static + UIProvider> {
- receiver: IpcReceiver<FileManagerThreadMsg>,
+pub struct FileManager<UI: 'static + UIProvider> {
store: Arc<FileManagerStore<UI>>,
}
impl<UI: 'static + UIProvider> FileManager<UI> {
- fn new(recv: IpcReceiver<FileManagerThreadMsg>, ui: &'static UI) -> FileManager<UI> {
+ pub fn new(ui: &'static UI) -> FileManager<UI> {
FileManager {
- receiver: recv,
store: Arc::new(FileManagerStore::new(ui)),
}
}
- /// Start the file manager event loop
- fn start(&mut self) {
- loop {
- let store = self.store.clone();
- match self.receiver.recv().unwrap() {
- FileManagerThreadMsg::SelectFile(filter, sender, origin, opt_test_path) => {
- spawn_named("select file".to_owned(), move || {
- store.select_file(filter, sender, origin, opt_test_path);
- });
- }
- FileManagerThreadMsg::SelectFiles(filter, sender, origin, opt_test_paths) => {
- spawn_named("select files".to_owned(), move || {
- store.select_files(filter, sender, origin, opt_test_paths);
- })
- }
- FileManagerThreadMsg::ReadFile(sender, id, check_url_validity, origin) => {
- spawn_named("read file".to_owned(), move || {
- match store.try_read_file(id, check_url_validity, origin) {
- Ok(buffer) => { let _ = sender.send(Ok(buffer)); }
- Err(e) => {
- let _ = sender.send(Err(FileManagerThreadError::BlobURLStoreError(e)));
- }
- }
- })
- }
- FileManagerThreadMsg::PromoteMemory(blob_buf, set_valid, sender, origin) => {
- spawn_named("transfer memory".to_owned(), move || {
- store.promote_memory(blob_buf, set_valid, sender, origin);
+ /// Message handler
+ pub fn handle(&self, msg: FileManagerThreadMsg, cancel_listener: Option<CancellationListener>) {
+ let store = self.store.clone();
+ match msg {
+ FileManagerThreadMsg::SelectFile(filter, sender, origin, opt_test_path) => {
+ spawn_named("select file".to_owned(), move || {
+ store.select_file(filter, sender, origin, opt_test_path);
+ });
+ }
+ FileManagerThreadMsg::SelectFiles(filter, sender, origin, opt_test_paths) => {
+ spawn_named("select files".to_owned(), move || {
+ store.select_files(filter, sender, origin, opt_test_paths);
+ })
+ }
+ FileManagerThreadMsg::ReadFile(sender, id, check_url_validity, origin) => {
+ spawn_named("read file".to_owned(), move || {
+ if let Err(e) = store.try_read_file(sender.clone(), id, check_url_validity,
+ origin, cancel_listener) {
+ let _ = sender.send(Err(FileManagerThreadError::BlobURLStoreError(e)));
+ }
+ })
+ }
+ FileManagerThreadMsg::PromoteMemory(blob_buf, set_valid, sender, origin) => {
+ spawn_named("transfer memory".to_owned(), move || {
+ store.promote_memory(blob_buf, set_valid, sender, origin);
+ })
+ }
+ FileManagerThreadMsg::AddSlicedURLEntry(id, rel_pos, sender, origin) =>{
+ spawn_named("add sliced URL entry".to_owned(), move || {
+ store.add_sliced_url_entry(id, rel_pos, sender, origin);
+ })
+ }
+ FileManagerThreadMsg::DecRef(id, origin, sender) => {
+ if let Ok(id) = Uuid::parse_str(&id.0) {
+ spawn_named("dec ref".to_owned(), move || {
+ // Since it is simple DecRef (possibly caused by close/drop),
+ // unset_url_validity is false
+ let _ = sender.send(store.dec_ref(&id, &origin));
})
+ } else {
+ let _ = sender.send(Err(BlobURLStoreError::InvalidFileID));
}
- FileManagerThreadMsg::AddSlicedURLEntry(id, rel_pos, sender, origin) =>{
- spawn_named("add sliced URL entry".to_owned(), move || {
- store.add_sliced_url_entry(id, rel_pos, sender, origin);
+ }
+ FileManagerThreadMsg::RevokeBlobURL(id, origin, sender) => {
+ if let Ok(id) = Uuid::parse_str(&id.0) {
+ spawn_named("revoke blob url".to_owned(), move || {
+ // Since it is revocation, unset_url_validity is true
+ let _ = sender.send(store.set_blob_url_validity(false, &id, &origin));
})
+ } else {
+ let _ = sender.send(Err(BlobURLStoreError::InvalidFileID));
}
- FileManagerThreadMsg::RevokeBlobURL(id, origin, sender) => {
- if let Ok(id) = Uuid::parse_str(&id.0) {
- spawn_named("revoke blob url".to_owned(), move || {
- // Since it is revocation, unset_url_validity is true
- let _ = sender.send(store.dec_ref(&id, &origin, true));
- })
- } else {
- let _ = sender.send(Err(BlobURLStoreError::InvalidFileID));
- }
- }
- FileManagerThreadMsg::DecRef(id, origin, sender) => {
- if let Ok(id) = Uuid::parse_str(&id.0) {
- spawn_named("dec ref".to_owned(), move || {
- // Since it is simple DecRef (possibly caused by close/drop),
- // unset_url_validity is false
- let _ = sender.send(store.dec_ref(&id, &origin, false));
- })
- } else {
- let _ = sender.send(Err(BlobURLStoreError::InvalidFileID));
- }
- }
- FileManagerThreadMsg::IncRef(id, origin) => {
- if let Ok(id) = Uuid::parse_str(&id.0) {
- spawn_named("inc ref".to_owned(), move || {
- let _ = store.inc_ref(&id, &origin);
- })
- }
- }
- FileManagerThreadMsg::ActivateBlobURL(id, sender, origin) => {
- if let Ok(id) = Uuid::parse_str(&id.0) {
- spawn_named("activate blob url".to_owned(), move || {
- let _ = sender.send(store.activate_blob_url(&id, &origin));
- });
- } else {
- let _ = sender.send(Err(BlobURLStoreError::InvalidFileID));
- }
+ }
+ FileManagerThreadMsg::ActivateBlobURL(id, sender, origin) => {
+ if let Ok(id) = Uuid::parse_str(&id.0) {
+ spawn_named("activate blob url".to_owned(), move || {
+ let _ = sender.send(store.set_blob_url_validity(true, &id, &origin));
+ });
+ } else {
+ let _ = sender.send(Err(BlobURLStoreError::InvalidFileID));
}
- FileManagerThreadMsg::Exit => break,
- };
+ }
}
}
}
@@ -287,9 +258,11 @@ impl <UI: 'static + UIProvider> FileManagerStore<UI> {
file_impl: FileImpl::Sliced(parent_id, rel_pos),
refs: AtomicUsize::new(1),
// Valid here since AddSlicedURLEntry implies URL creation
+ // from a BlobImpl::Sliced
is_valid_url: AtomicBool::new(true),
});
+ // We assume that the returned id will be held by BlobImpl::File
let _ = sender.send(Ok(SelectedFileId(new_id.simple().to_string())));
}
Err(e) => {
@@ -370,8 +343,8 @@ impl <UI: 'static + UIProvider> FileManagerStore<UI> {
fn create_entry(&self, file_path: &Path, origin: &str) -> Result<SelectedFile, FileManagerThreadError> {
use net_traits::filemanager_thread::FileManagerThreadError::FileSystemError;
- let handler = try!(File::open(file_path).map_err(|e| FileSystemError(e.to_string())));
- let metadata = try!(handler.metadata().map_err(|e| FileSystemError(e.to_string())));
+ let file = try!(File::open(file_path).map_err(|e| FileSystemError(e.to_string())));
+ let metadata = try!(file.metadata().map_err(|e| FileSystemError(e.to_string())));
let modified = try!(metadata.modified().map_err(|e| FileSystemError(e.to_string())));
let elapsed = try!(modified.elapsed().map_err(|e| FileSystemError(e.to_string())));
// Unix Epoch: https://doc.servo.org/std/time/constant.UNIX_EPOCH.html
@@ -410,22 +383,29 @@ impl <UI: 'static + UIProvider> FileManagerStore<UI> {
})
}
- fn get_blob_buf(&self, id: &Uuid, origin_in: &FileOrigin, rel_pos: RelativePos,
- check_url_validity: bool) -> Result<BlobBuf, BlobURLStoreError> {
+ fn get_blob_buf(&self, sender: IpcSender<FileManagerResult<ReadFileProgress>>,
+ id: &Uuid, origin_in: &FileOrigin, rel_pos: RelativePos,
+ check_url_validity: bool,
+ cancel_listener: Option<CancellationListener>) -> Result<(), BlobURLStoreError> {
let file_impl = try!(self.get_impl(id, origin_in, check_url_validity));
match file_impl {
FileImpl::Memory(buf) => {
let range = rel_pos.to_abs_range(buf.size as usize);
- Ok(BlobBuf {
+ let buf = BlobBuf {
filename: None,
type_string: buf.type_string,
size: range.len() as u64,
bytes: buf.bytes.index(range).to_vec(),
- })
+ };
+
+ let _ = sender.send(Ok(ReadFileProgress::Meta(buf)));
+ let _ = sender.send(Ok(ReadFileProgress::EOF));
+
+ Ok(())
}
FileImpl::MetaDataOnly(metadata) => {
/* XXX: Snapshot state check (optional) https://w3c.github.io/FileAPI/#snapshot-state.
- Concretely, here we create another handler, and this handler might not
+ Concretely, here we create another file, and this file might not
has the same underlying file state (meta-info plus content) as the time
create_entry is called.
*/
@@ -437,25 +417,20 @@ impl <UI: 'static + UIProvider> FileManagerStore<UI> {
let mime = guess_mime_type_opt(metadata.path.clone());
let range = rel_pos.to_abs_range(metadata.size as usize);
- let mut handler = try!(File::open(&metadata.path)
- .map_err(|e| BlobURLStoreError::External(e.to_string())));
- let seeked_start = try!(handler.seek(SeekFrom::Start(range.start as u64))
+ let mut file = try!(File::open(&metadata.path)
+ .map_err(|e| BlobURLStoreError::External(e.to_string())));
+ let seeked_start = try!(file.seek(SeekFrom::Start(range.start as u64))
.map_err(|e| BlobURLStoreError::External(e.to_string())));
if seeked_start == (range.start as u64) {
- let mut bytes = vec![0; range.len()];
- try!(handler.read_exact(&mut bytes)
- .map_err(|e| BlobURLStoreError::External(e.to_string())));
-
- Ok(BlobBuf {
- filename: opt_filename,
- type_string: match mime {
- Some(x) => format!("{}", x),
- None => "".to_string(),
- },
- size: range.len() as u64,
- bytes: bytes,
- })
+ let type_string = match mime {
+ Some(x) => format!("{}", x),
+ None => "".to_string(),
+ };
+
+ chunked_read(sender, &mut file, range.len(), opt_filename,
+ type_string, cancel_listener);
+ Ok(())
} else {
Err(BlobURLStoreError::InvalidEntry)
}
@@ -463,29 +438,28 @@ impl <UI: 'static + UIProvider> FileManagerStore<UI> {
FileImpl::Sliced(parent_id, inner_rel_pos) => {
// Next time we don't need to check validity since
// we have already done that for requesting URL if necessary
- self.get_blob_buf(&parent_id, origin_in, rel_pos.slice_inner(&inner_rel_pos), false)
+ self.get_blob_buf(sender, &parent_id, origin_in,
+ rel_pos.slice_inner(&inner_rel_pos), false,
+ cancel_listener)
}
}
}
// Convenient wrapper over get_blob_buf
- fn try_read_file(&self, id: SelectedFileId, check_url_validity: bool,
- origin_in: FileOrigin) -> Result<BlobBuf, BlobURLStoreError> {
+ fn try_read_file(&self, sender: IpcSender<FileManagerResult<ReadFileProgress>>,
+ id: SelectedFileId, check_url_validity: bool, origin_in: FileOrigin,
+ cancel_listener: Option<CancellationListener>) -> Result<(), BlobURLStoreError> {
let id = try!(Uuid::parse_str(&id.0).map_err(|_| BlobURLStoreError::InvalidFileID));
- self.get_blob_buf(&id, &origin_in, RelativePos::full_range(), check_url_validity)
+ self.get_blob_buf(sender, &id, &origin_in, RelativePos::full_range(),
+ check_url_validity, cancel_listener)
}
- fn dec_ref(&self, id: &Uuid, origin_in: &FileOrigin,
- unset_url_validity: bool) -> Result<(), BlobURLStoreError> {
+ fn dec_ref(&self, id: &Uuid, origin_in: &FileOrigin) -> Result<(), BlobURLStoreError> {
let (do_remove, opt_parent_id) = match self.entries.read().unwrap().get(id) {
Some(entry) => {
if *entry.origin == *origin_in {
let old_refs = entry.refs.fetch_sub(1, Ordering::Release);
- if unset_url_validity {
- entry.is_valid_url.store(false, Ordering::Release);
- }
-
if old_refs > 1 {
// not the last reference, no need to touch parent
(false, None)
@@ -515,7 +489,7 @@ impl <UI: 'static + UIProvider> FileManagerStore<UI> {
if let Some(parent_id) = opt_parent_id {
// unset_url_validity for parent is false since we only need
// to unset the initial requesting URL
- return self.dec_ref(&parent_id, origin_in, false);
+ return self.dec_ref(&parent_id, origin_in);
}
}
@@ -543,23 +517,97 @@ impl <UI: 'static + UIProvider> FileManagerStore<UI> {
}
}
- fn activate_blob_url(&self, id: &Uuid, origin_in: &FileOrigin) -> Result<(), BlobURLStoreError> {
- match self.entries.read().unwrap().get(id) {
+ fn set_blob_url_validity(&self, validity: bool, id: &Uuid,
+ origin_in: &FileOrigin) -> Result<(), BlobURLStoreError> {
+ let (do_remove, opt_parent_id, res) = match self.entries.read().unwrap().get(id) {
Some(entry) => {
if *entry.origin == *origin_in {
- entry.is_valid_url.store(true, Ordering::Release);
- Ok(())
+ entry.is_valid_url.store(validity, Ordering::Release);
+
+ if !validity {
+ // Check if it is the last possible reference
+ // since refs only accounts for blob id holders
+ // and store entry id holders
+ let zero_refs = entry.refs.load(Ordering::Acquire) == 0;
+
+ if let FileImpl::Sliced(ref parent_id, _) = entry.file_impl {
+ (zero_refs, Some(parent_id.clone()), Ok(()))
+ } else {
+ (zero_refs, None, Ok(()))
+ }
+ } else {
+ (false, None, Ok(()))
+ }
} else {
- Err(BlobURLStoreError::InvalidOrigin)
+ (false, None, Err(BlobURLStoreError::InvalidOrigin))
}
}
- None => Err(BlobURLStoreError::InvalidFileID)
+ None => (false, None, Err(BlobURLStoreError::InvalidFileID))
+ };
+
+ if do_remove {
+ atomic::fence(Ordering::Acquire);
+ self.remove(id);
+
+ if let Some(parent_id) = opt_parent_id {
+ return self.dec_ref(&parent_id, origin_in);
+ }
}
+ res
}
}
-
fn select_files_pref_enabled() -> bool {
PREFS.get("dom.testing.htmlinputelement.select_files.enabled")
.as_boolean().unwrap_or(false)
}
+
+const CHUNK_SIZE: usize = 8192;
+
+fn chunked_read(sender: IpcSender<FileManagerResult<ReadFileProgress>>,
+ file: &mut File, size: usize, opt_filename: Option<String>,
+ type_string: String, cancel_listener: Option<CancellationListener>) {
+ // First chunk
+ let mut buf = vec![0; CHUNK_SIZE];
+ match file.read(&mut buf) {
+ Ok(n) => {
+ buf.truncate(n);
+ let blob_buf = BlobBuf {
+ filename: opt_filename,
+ type_string: type_string,
+ size: size as u64,
+ bytes: buf,
+ };
+ let _ = sender.send(Ok(ReadFileProgress::Meta(blob_buf)));
+ }
+ Err(e) => {
+ let _ = sender.send(Err(FileManagerThreadError::FileSystemError(e.to_string())));
+ return;
+ }
+ }
+
+ // Send the remaining chunks
+ loop {
+ if let Some(ref listener) = cancel_listener.as_ref() {
+ if listener.is_cancelled() {
+ break;
+ }
+ }
+
+ let mut buf = vec![0; CHUNK_SIZE];
+ match file.read(&mut buf) {
+ Ok(0) => {
+ let _ = sender.send(Ok(ReadFileProgress::EOF));
+ return;
+ }
+ Ok(n) => {
+ buf.truncate(n);
+ let _ = sender.send(Ok(ReadFileProgress::Partial(buf)));
+ }
+ Err(e) => {
+ let _ = sender.send(Err(FileManagerThreadError::FileSystemError(e.to_string())));
+ return;
+ }
+ }
+ }
+}
diff --git a/components/net/http_loader.rs b/components/net/http_loader.rs
index a39d284a486..2f328917352 100644
--- a/components/net/http_loader.rs
+++ b/components/net/http_loader.rs
@@ -48,7 +48,7 @@ use std::sync::mpsc::Sender;
use std::sync::{Arc, RwLock};
use time;
use time::Tm;
-#[cfg(any(target_os = "macos", target_os = "linux"))]
+#[cfg(any(target_os = "macos", target_os = "linux", target_os = "windows"))]
use tinyfiledialogs;
use url::{Url, Position};
use util::prefs::PREFS;
@@ -600,7 +600,8 @@ fn prepare_devtools_request(request_id: String,
pipeline_id: PipelineId,
now: Tm,
connect_time: u64,
- send_time: u64) -> ChromeToDevtoolsControlMsg {
+ send_time: u64,
+ is_xhr: bool) -> ChromeToDevtoolsControlMsg {
let request = DevtoolsHttpRequest {
url: url,
method: method,
@@ -611,29 +612,28 @@ fn prepare_devtools_request(request_id: String,
timeStamp: now.to_timespec().sec,
connect_time: connect_time,
send_time: send_time,
+ is_xhr: is_xhr,
};
let net_event = NetworkEvent::HttpRequest(request);
ChromeToDevtoolsControlMsg::NetworkEvent(request_id, net_event)
}
-fn send_request_to_devtools(msg: ChromeToDevtoolsControlMsg,
+pub fn send_request_to_devtools(msg: ChromeToDevtoolsControlMsg,
devtools_chan: &Sender<DevtoolsControlMsg>) {
devtools_chan.send(DevtoolsControlMsg::FromChrome(msg)).unwrap();
}
-fn send_response_to_devtools(devtools_chan: Option<Sender<DevtoolsControlMsg>>,
+pub fn send_response_to_devtools(devtools_chan: &Sender<DevtoolsControlMsg>,
request_id: String,
headers: Option<Headers>,
status: Option<RawStatus>,
pipeline_id: PipelineId) {
- if let Some(ref chan) = devtools_chan {
- let response = DevtoolsHttpResponse { headers: headers, status: status, body: None, pipeline_id: pipeline_id };
- let net_event_response = NetworkEvent::HttpResponse(response);
+ let response = DevtoolsHttpResponse { headers: headers, status: status, body: None, pipeline_id: pipeline_id };
+ let net_event_response = NetworkEvent::HttpResponse(response);
- let msg = ChromeToDevtoolsControlMsg::NetworkEvent(request_id, net_event_response);
- chan.send(DevtoolsControlMsg::FromChrome(msg)).unwrap();
- }
+ let msg = ChromeToDevtoolsControlMsg::NetworkEvent(request_id, net_event_response);
+ let _ = devtools_chan.send(DevtoolsControlMsg::FromChrome(msg));
}
fn request_must_be_secured(url: &Url, hsts_list: &Arc<RwLock<HstsList>>) -> bool {
@@ -744,7 +744,8 @@ pub fn obtain_response<A>(request_factory: &HttpRequestFactory<R=A>,
pipeline_id: &Option<PipelineId>,
iters: u32,
devtools_chan: &Option<Sender<DevtoolsControlMsg>>,
- request_id: &str)
+ request_id: &str,
+ is_xhr: bool)
-> Result<(A::R, Option<ChromeToDevtoolsControlMsg>), LoadError>
where A: HttpRequest + 'static {
let null_data = None;
@@ -752,6 +753,7 @@ pub fn obtain_response<A>(request_factory: &HttpRequestFactory<R=A>,
let connection_url = replace_hosts(&url);
let mut msg;
+
// loop trying connections in connection pool
// they may have grown stale (disconnected), in which case we'll get
// a ConnectionAborted error. this loop tries again with a new
@@ -811,7 +813,7 @@ pub fn obtain_response<A>(request_factory: &HttpRequestFactory<R=A>,
request_id.clone().into(),
url.clone(), method.clone(), headers,
request_body.clone(), pipeline_id, time::now(),
- connect_end - connect_start, send_end - send_start))
+ connect_end - connect_start, send_end - send_start, is_xhr))
} else {
None
}
@@ -843,13 +845,13 @@ pub trait UIProvider {
}
impl UIProvider for TFDProvider {
- #[cfg(any(target_os = "macos", target_os = "linux"))]
+ #[cfg(any(target_os = "macos", target_os = "linux", target_os = "windows"))]
fn input_username_and_password(&self, prompt: &str) -> (Option<String>, Option<String>) {
(tinyfiledialogs::input_box(prompt, "Username:", ""),
tinyfiledialogs::input_box(prompt, "Password:", ""))
}
- #[cfg(not(any(target_os = "macos", target_os = "linux")))]
+ #[cfg(not(any(target_os = "macos", target_os = "linux", target_os = "windows")))]
fn input_username_and_password(&self, _prompt: &str) -> (Option<String>, Option<String>) {
(None, None)
}
@@ -989,7 +991,7 @@ pub fn load<A, B>(load_data: &LoadData,
let (response, msg) =
try!(obtain_response(request_factory, &doc_url, &method, &request_headers,
&cancel_listener, &load_data.data, &load_data.method,
- &load_data.pipeline_id, iters, &devtools_chan, &request_id));
+ &load_data.pipeline_id, iters, &devtools_chan, &request_id, false));
process_response_headers(&response, &doc_url, &http_state.cookie_jar, &http_state.hsts_list, &load_data);
@@ -1056,10 +1058,13 @@ pub fn load<A, B>(load_data: &LoadData,
doc_url = new_doc_url;
redirected_to.insert(doc_url.clone());
- continue;
}
}
+ // Only notify the devtools about the final request that received a response.
+ if let Some(m) = msg {
+ send_request_to_devtools(m, devtools_chan.as_ref().unwrap());
+ }
let mut adjusted_headers = response.headers().clone();
if viewing_source {
@@ -1078,23 +1083,24 @@ pub fn load<A, B>(load_data: &LoadData,
} else {
HttpsState::None
};
- metadata.referrer = referrer_url;
-
- // Only notify the devtools about the final request that received a response.
- if let Some(msg) = msg {
- send_request_to_devtools(msg, devtools_chan.as_ref().unwrap());
- }
+ metadata.referrer = referrer_url.clone();
// --- Tell devtools that we got a response
// Send an HttpResponse message to devtools with the corresponding request_id
// TODO: Send this message even when the load fails?
if let Some(pipeline_id) = load_data.pipeline_id {
+ if let Some(ref chan) = devtools_chan {
send_response_to_devtools(
- devtools_chan, request_id,
+ &chan, request_id,
metadata.headers.clone(), metadata.status.clone(),
pipeline_id);
- }
- return StreamedResponse::from_http_response(box response, metadata)
+ }
+ }
+ if response.status().class() == StatusClass::Redirection {
+ continue;
+ } else {
+ return StreamedResponse::from_http_response(box response, metadata);
+ }
}
}
diff --git a/components/net/lib.rs b/components/net/lib.rs
index 80c6294c277..53efb84f6c2 100644
--- a/components/net/lib.rs
+++ b/components/net/lib.rs
@@ -38,7 +38,7 @@ extern crate rand;
extern crate rustc_serialize;
extern crate threadpool;
extern crate time;
-#[cfg(any(target_os = "macos", target_os = "linux"))]
+#[cfg(any(target_os = "macos", target_os = "linux", target_os = "windows"))]
extern crate tinyfiledialogs;
extern crate unicase;
extern crate url;
diff --git a/components/net/resource_thread.rs b/components/net/resource_thread.rs
index 9ee16b911ad..411b0d22373 100644
--- a/components/net/resource_thread.rs
+++ b/components/net/resource_thread.rs
@@ -15,7 +15,7 @@ use data_loader;
use devtools_traits::DevtoolsControlMsg;
use fetch::methods::{fetch, FetchContext};
use file_loader;
-use filemanager_thread::{FileManagerThreadFactory, TFDProvider};
+use filemanager_thread::{FileManager, TFDProvider};
use hsts::HstsList;
use http_loader::{self, HttpState};
use hyper::client::pool::Pool;
@@ -25,7 +25,6 @@ use ipc_channel::ipc::{self, IpcReceiver, IpcSender, IpcReceiverSet};
use mime_classifier::{ApacheBugFlag, MimeClassifier, NoSniffFlag};
use net_traits::LoadContext;
use net_traits::ProgressMsg::Done;
-use net_traits::filemanager_thread::FileManagerThreadMsg;
use net_traits::request::{Request, RequestInit};
use net_traits::storage_thread::StorageThreadMsg;
use net_traits::{AsyncResponseTarget, Metadata, ProgressMsg, ResponseAction, CoreResourceThread};
@@ -42,13 +41,13 @@ use std::collections::HashMap;
use std::error::Error;
use std::fs::File;
use std::io::prelude::*;
-use std::path::Path;
+use std::ops::Deref;
+use std::path::{Path, PathBuf};
use std::rc::Rc;
use std::sync::mpsc::{Receiver, Sender, channel};
use std::sync::{Arc, RwLock};
use storage_thread::StorageThreadFactory;
use url::Url;
-use util::opts;
use util::prefs::PREFS;
use util::thread::spawn_named;
use websocket_loader;
@@ -165,13 +164,17 @@ fn start_sending_opt(start_chan: LoadConsumer, metadata: Metadata,
/// Returns a tuple of (public, private) senders to the new threads.
pub fn new_resource_threads(user_agent: String,
devtools_chan: Option<Sender<DevtoolsControlMsg>>,
- profiler_chan: ProfilerChan) -> (ResourceThreads, ResourceThreads) {
- let filemanager_chan: IpcSender<FileManagerThreadMsg> = FileManagerThreadFactory::new(TFD_PROVIDER);
- let (public_core, private_core) = new_core_resource_thread(user_agent, devtools_chan,
- profiler_chan, filemanager_chan.clone());
- let storage: IpcSender<StorageThreadMsg> = StorageThreadFactory::new();
- (ResourceThreads::new(public_core, storage.clone(), filemanager_chan.clone()),
- ResourceThreads::new(private_core, storage, filemanager_chan))
+ profiler_chan: ProfilerChan,
+ config_dir: Option<PathBuf>)
+ -> (ResourceThreads, ResourceThreads) {
+ let (public_core, private_core) = new_core_resource_thread(
+ user_agent,
+ devtools_chan,
+ profiler_chan,
+ config_dir.clone());
+ let storage: IpcSender<StorageThreadMsg> = StorageThreadFactory::new(config_dir);
+ (ResourceThreads::new(public_core, storage.clone()),
+ ResourceThreads::new(private_core, storage))
}
@@ -179,7 +182,7 @@ pub fn new_resource_threads(user_agent: String,
pub fn new_core_resource_thread(user_agent: String,
devtools_chan: Option<Sender<DevtoolsControlMsg>>,
profiler_chan: ProfilerChan,
- filemanager_chan: IpcSender<FileManagerThreadMsg>)
+ config_dir: Option<PathBuf>)
-> (CoreResourceThread, CoreResourceThread) {
let (public_setup_chan, public_setup_port) = ipc::channel().unwrap();
let (private_setup_chan, private_setup_port) = ipc::channel().unwrap();
@@ -187,11 +190,12 @@ pub fn new_core_resource_thread(user_agent: String,
let private_setup_chan_clone = private_setup_chan.clone();
spawn_named("ResourceManager".to_owned(), move || {
let resource_manager = CoreResourceManager::new(
- user_agent, devtools_chan, profiler_chan, filemanager_chan
+ user_agent, devtools_chan, profiler_chan
);
let mut channel_manager = ResourceChannelManager {
resource_manager: resource_manager,
+ config_dir: config_dir,
};
channel_manager.start(public_setup_chan_clone,
private_setup_chan_clone,
@@ -202,14 +206,16 @@ pub fn new_core_resource_thread(user_agent: String,
}
struct ResourceChannelManager {
- resource_manager: CoreResourceManager
+ resource_manager: CoreResourceManager,
+ config_dir: Option<PathBuf>,
}
-fn create_resource_groups() -> (ResourceGroup, ResourceGroup) {
+fn create_resource_groups(config_dir: Option<&Path>)
+ -> (ResourceGroup, ResourceGroup) {
let mut hsts_list = HstsList::from_servo_preload();
let mut auth_cache = AuthCache::new();
let mut cookie_jar = CookieStorage::new();
- if let Some(ref config_dir) = opts::get().config_dir {
+ if let Some(config_dir) = config_dir {
read_json_from_file(&mut auth_cache, config_dir, "auth_cache.json");
read_json_from_file(&mut hsts_list, config_dir, "hsts_list.json");
read_json_from_file(&mut cookie_jar, config_dir, "cookie_jar.json");
@@ -236,7 +242,8 @@ impl ResourceChannelManager {
private_control_sender: CoreResourceThread,
public_receiver: IpcReceiver<CoreResourceMsg>,
private_receiver: IpcReceiver<CoreResourceMsg>) {
- let (public_resource_group, private_resource_group) = create_resource_groups();
+ let (public_resource_group, private_resource_group) =
+ create_resource_groups(self.config_dir.as_ref().map(Deref::deref));
let mut rx_set = IpcReceiverSet::new().unwrap();
let private_id = rx_set.add(private_receiver).unwrap();
@@ -296,8 +303,9 @@ impl ResourceChannelManager {
CoreResourceMsg::Synchronize(sender) => {
let _ = sender.send(());
}
+ CoreResourceMsg::ToFileManager(msg) => self.resource_manager.filemanager.handle(msg, None),
CoreResourceMsg::Exit(sender) => {
- if let Some(ref config_dir) = opts::get().config_dir {
+ if let Some(ref config_dir) = self.config_dir {
match group.auth_cache.read() {
Ok(auth_cache) => write_json_to_file(&*auth_cache, config_dir, "auth_cache.json"),
Err(_) => warn!("Error writing auth cache to disk"),
@@ -319,8 +327,10 @@ impl ResourceChannelManager {
}
}
-pub fn read_json_from_file<T: Decodable>(data: &mut T, config_dir: &str, filename: &str) {
- let path = Path::new(config_dir).join(filename);
+pub fn read_json_from_file<T>(data: &mut T, config_dir: &Path, filename: &str)
+ where T: Decodable
+{
+ let path = config_dir.join(filename);
let display = path.display();
let mut file = match File::open(&path) {
@@ -346,13 +356,15 @@ pub fn read_json_from_file<T: Decodable>(data: &mut T, config_dir: &str, filenam
}
}
-pub fn write_json_to_file<T: Encodable>(data: &T, config_dir: &str, filename: &str) {
+pub fn write_json_to_file<T>(data: &T, config_dir: &Path, filename: &str)
+ where T: Encodable
+{
let json_encoded: String;
match json::encode(&data) {
Ok(d) => json_encoded = d,
Err(_) => return,
}
- let path = Path::new(config_dir).join(filename);
+ let path = config_dir.join(filename);
let display = path.display();
let mut file = match File::create(&path) {
@@ -461,7 +473,7 @@ pub struct CoreResourceManager {
devtools_chan: Option<Sender<DevtoolsControlMsg>>,
swmanager_chan: Option<IpcSender<CustomResponseMediator>>,
profiler_chan: ProfilerChan,
- filemanager_chan: IpcSender<FileManagerThreadMsg>,
+ filemanager: Arc<FileManager<TFDProvider>>,
cancel_load_map: HashMap<ResourceId, Sender<()>>,
next_resource_id: ResourceId,
}
@@ -469,15 +481,14 @@ pub struct CoreResourceManager {
impl CoreResourceManager {
pub fn new(user_agent: String,
devtools_channel: Option<Sender<DevtoolsControlMsg>>,
- profiler_chan: ProfilerChan,
- filemanager_chan: IpcSender<FileManagerThreadMsg>) -> CoreResourceManager {
+ profiler_chan: ProfilerChan) -> CoreResourceManager {
CoreResourceManager {
user_agent: user_agent,
mime_classifier: Arc::new(MimeClassifier::new()),
devtools_chan: devtools_channel,
swmanager_chan: None,
profiler_chan: profiler_chan,
- filemanager_chan: filemanager_chan,
+ filemanager: Arc::new(FileManager::new(TFD_PROVIDER)),
cancel_load_map: HashMap::new(),
next_resource_id: ResourceId(0),
}
@@ -552,14 +563,14 @@ impl CoreResourceManager {
},
"data" => from_factory(data_loader::factory),
"about" => from_factory(about_loader::factory),
- "blob" => blob_loader::factory(self.filemanager_chan.clone()),
+ "blob" => blob_loader::factory(self.filemanager.clone()),
_ => {
debug!("resource_thread: no loader for scheme {}", load_data.url.scheme());
send_error(load_data.url, NetworkError::Internal("no loader for scheme".to_owned()), consumer);
return
}
};
- debug!("resource_thread: loading url: {}", load_data.url);
+ debug!("loading url: {}", load_data.url);
loader.call_box((load_data,
consumer,
@@ -578,6 +589,7 @@ impl CoreResourceManager {
blocked_content: BLOCKED_CONTENT_RULES.clone(),
};
let ua = self.user_agent.clone();
+ let dc = self.devtools_chan.clone();
spawn_named(format!("fetch thread for {}", init.url), move || {
let request = Request::from_init(init);
// XXXManishearth: Check origin against pipeline id (also ensure that the mode is allowed)
@@ -585,7 +597,7 @@ impl CoreResourceManager {
// 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 };
+ let context = FetchContext { state: http_state, user_agent: ua, devtools_chan: dc };
fetch(Rc::new(request), &mut target, context);
})
}
diff --git a/components/net/storage_thread.rs b/components/net/storage_thread.rs
index cc329f08922..0e7c7647420 100644
--- a/components/net/storage_thread.rs
+++ b/components/net/storage_thread.rs
@@ -8,22 +8,22 @@ use resource_thread;
use std::borrow::ToOwned;
use std::collections::BTreeMap;
use std::collections::HashMap;
+use std::path::PathBuf;
use url::Url;
-use util::opts;
use util::thread::spawn_named;
const QUOTA_SIZE_LIMIT: usize = 5 * 1024 * 1024;
pub trait StorageThreadFactory {
- fn new() -> Self;
+ fn new(config_dir: Option<PathBuf>) -> Self;
}
impl StorageThreadFactory for IpcSender<StorageThreadMsg> {
/// Create a storage thread
- fn new() -> IpcSender<StorageThreadMsg> {
+ fn new(config_dir: Option<PathBuf>) -> IpcSender<StorageThreadMsg> {
let (chan, port) = ipc::channel().unwrap();
spawn_named("StorageManager".to_owned(), move || {
- StorageManager::new(port).start();
+ StorageManager::new(port, config_dir).start();
});
chan
}
@@ -33,18 +33,22 @@ struct StorageManager {
port: IpcReceiver<StorageThreadMsg>,
session_data: HashMap<String, (usize, BTreeMap<String, String>)>,
local_data: HashMap<String, (usize, BTreeMap<String, String>)>,
+ config_dir: Option<PathBuf>,
}
impl StorageManager {
- fn new(port: IpcReceiver<StorageThreadMsg>) -> StorageManager {
+ fn new(port: IpcReceiver<StorageThreadMsg>,
+ config_dir: Option<PathBuf>)
+ -> StorageManager {
let mut local_data = HashMap::new();
- if let Some(ref config_dir) = opts::get().config_dir {
+ if let Some(ref config_dir) = config_dir {
resource_thread::read_json_from_file(&mut local_data, config_dir, "local_data.json");
}
StorageManager {
port: port,
session_data: HashMap::new(),
local_data: local_data,
+ config_dir: config_dir,
}
}
}
@@ -75,7 +79,7 @@ impl StorageManager {
self.clear(sender, url, storage_type)
}
StorageThreadMsg::Exit(sender) => {
- if let Some(ref config_dir) = opts::get().config_dir {
+ if let Some(ref config_dir) = self.config_dir {
resource_thread::write_json_to_file(&self.local_data, config_dir, "local_data.json");
}
let _ = sender.send(());
diff --git a/components/net_traits/Cargo.toml b/components/net_traits/Cargo.toml
index 3ce61c9d303..52877605b15 100644
--- a/components/net_traits/Cargo.toml
+++ b/components/net_traits/Cargo.toml
@@ -12,7 +12,7 @@ path = "lib.rs"
[dependencies]
util = {path = "../util"}
msg = {path = "../msg"}
-ipc-channel = {git = "https://github.com/servo/ipc-channel"}
+ipc-channel = "0.4.0"
heapsize = "0.3.0"
heapsize_plugin = "0.1.2"
hyper = { version = "0.9.9", features = [ "serde-serialization" ] }
@@ -20,8 +20,8 @@ image = "0.10"
lazy_static = "0.2"
log = "0.3.5"
num-traits = "0.1.32"
-serde = "0.7.11"
-serde_macros = "0.7.11"
+serde = "0.7.15"
+serde_macros = "0.7.15"
url = {version = "1.0.0", features = ["heap_size"]}
websocket = "0.17"
uuid = { version = "0.2.2", features = ["v4", "serde"] }
diff --git a/components/net_traits/bluetooth_thread.rs b/components/net_traits/bluetooth_thread.rs
index caeadabd6d4..48f64ff7474 100644
--- a/components/net_traits/bluetooth_thread.rs
+++ b/components/net_traits/bluetooth_thread.rs
@@ -1,10 +1,20 @@
/* 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 bluetooth_scanfilter::RequestDeviceoptions;
use ipc_channel::ipc::IpcSender;
#[derive(Deserialize, Serialize)]
+pub enum BluetoothError {
+ Type(String),
+ Network,
+ NotFound,
+ NotSupported,
+ Security,
+}
+
+#[derive(Deserialize, Serialize)]
pub struct BluetoothDeviceMsg {
// Bluetooth Device properties
pub id: String,
@@ -51,7 +61,7 @@ pub type BluetoothCharacteristicsMsg = Vec<BluetoothCharacteristicMsg>;
pub type BluetoothDescriptorsMsg = Vec<BluetoothDescriptorMsg>;
-pub type BluetoothResult<T> = Result<T, String>;
+pub type BluetoothResult<T> = Result<T, BluetoothError>;
#[derive(Deserialize, Serialize)]
pub enum BluetoothMethodMsg {
diff --git a/components/net_traits/filemanager_thread.rs b/components/net_traits/filemanager_thread.rs
index 957205fcc11..8ea607f191f 100644
--- a/components/net_traits/filemanager_thread.rs
+++ b/components/net_traits/filemanager_thread.rs
@@ -127,9 +127,8 @@ pub enum FileManagerThreadMsg {
/// Select multiple files, return a vector of triples
SelectFiles(Vec<FilterPattern>, IpcSender<FileManagerResult<Vec<SelectedFile>>>, FileOrigin, Option<Vec<String>>),
- /// Read file by FileID, optionally check URL validity based on
- /// third flag, return the blob buffer object
- ReadFile(IpcSender<FileManagerResult<BlobBuf>>, SelectedFileId, bool, FileOrigin),
+ /// Read file in chunks by FileID, optionally check URL validity based on fourth flag
+ ReadFile(IpcSender<FileManagerResult<ReadFileProgress>>, SelectedFileId, bool, FileOrigin),
/// Add an entry as promoted memory-based blob and send back the associated FileID
/// as part of a valid/invalid Blob URL depending on the second bool flag
@@ -139,20 +138,21 @@ pub enum FileManagerThreadMsg {
/// as part of a valid Blob URL
AddSlicedURLEntry(SelectedFileId, RelativePos, IpcSender<Result<SelectedFileId, BlobURLStoreError>>, FileOrigin),
- /// Revoke Blob URL and send back the acknowledgement
- RevokeBlobURL(SelectedFileId, FileOrigin, IpcSender<Result<(), BlobURLStoreError>>),
-
/// Decrease reference count and send back the acknowledgement
DecRef(SelectedFileId, FileOrigin, IpcSender<Result<(), BlobURLStoreError>>),
- /// Increase reference count
- IncRef(SelectedFileId, FileOrigin),
-
/// Activate an internal FileID so it becomes valid as part of a Blob URL
ActivateBlobURL(SelectedFileId, IpcSender<Result<(), BlobURLStoreError>>, FileOrigin),
- /// Shut down this thread
- Exit,
+ /// Revoke Blob URL and send back the acknowledgement
+ RevokeBlobURL(SelectedFileId, FileOrigin, IpcSender<Result<(), BlobURLStoreError>>),
+}
+
+#[derive(Debug, Deserialize, Serialize)]
+pub enum ReadFileProgress {
+ Meta(BlobBuf),
+ Partial(Vec<u8>),
+ EOF
}
pub type FileManagerResult<T> = Result<T, FileManagerThreadError>;
diff --git a/components/net_traits/lib.rs b/components/net_traits/lib.rs
index 8e7bb996697..fd2973033eb 100644
--- a/components/net_traits/lib.rs
+++ b/components/net_traits/lib.rs
@@ -321,17 +321,14 @@ pub trait IpcSend<T> where T: serde::Serialize + serde::Deserialize {
pub struct ResourceThreads {
core_thread: CoreResourceThread,
storage_thread: IpcSender<StorageThreadMsg>,
- filemanager_thread: IpcSender<FileManagerThreadMsg>,
}
impl ResourceThreads {
pub fn new(c: CoreResourceThread,
- s: IpcSender<StorageThreadMsg>,
- f: IpcSender<FileManagerThreadMsg>) -> ResourceThreads {
+ s: IpcSender<StorageThreadMsg>) -> ResourceThreads {
ResourceThreads {
core_thread: c,
storage_thread: s,
- filemanager_thread: f,
}
}
}
@@ -356,16 +353,6 @@ impl IpcSend<StorageThreadMsg> for ResourceThreads {
}
}
-impl IpcSend<FileManagerThreadMsg> for ResourceThreads {
- fn send(&self, msg: FileManagerThreadMsg) -> IpcSendResult {
- self.filemanager_thread.send(msg)
- }
-
- fn sender(&self) -> IpcSender<FileManagerThreadMsg> {
- self.filemanager_thread.clone()
- }
-}
-
// Ignore the sub-fields
impl HeapSizeOf for ResourceThreads {
fn heap_size_of_children(&self) -> usize { 0 }
@@ -431,6 +418,8 @@ pub enum CoreResourceMsg {
Synchronize(IpcSender<()>),
/// Send the network sender in constellation to CoreResourceThread
NetworkMediator(IpcSender<CustomResponseMediator>),
+ /// Message forwarded to file manager's handler
+ ToFileManager(FileManagerThreadMsg),
/// Break the load handler loop, send a reply when done cleaning up local resources
// and exit
Exit(IpcSender<()>),
diff --git a/components/net_traits/request.rs b/components/net_traits/request.rs
index 1fbcdabe868..bf7e22d2d0b 100644
--- a/components/net_traits/request.rs
+++ b/components/net_traits/request.rs
@@ -4,7 +4,7 @@
use hyper::header::Headers;
use hyper::method::Method;
-use msg::constellation_msg::ReferrerPolicy;
+use msg::constellation_msg::{PipelineId, ReferrerPolicy};
use std::cell::{Cell, RefCell};
use std::mem::swap;
use url::{Origin as UrlOrigin, Url};
@@ -130,6 +130,7 @@ pub struct RequestInit {
// XXXManishearth these should be part of the client object
pub referer_url: Option<Url>,
pub referrer_policy: Option<ReferrerPolicy>,
+ pub pipeline_id: Option<PipelineId>,
}
/// A [Request](https://fetch.spec.whatwg.org/#requests) as defined by the Fetch spec
@@ -159,6 +160,7 @@ pub struct Request {
/// https://fetch.spec.whatwg.org/#concept-request-referrer
pub referer: RefCell<Referer>,
pub referrer_policy: Cell<Option<ReferrerPolicy>>,
+ pub pipeline_id: Cell<Option<PipelineId>>,
pub synchronous: bool,
pub mode: RequestMode,
pub use_cors_preflight: bool,
@@ -178,7 +180,8 @@ pub struct Request {
impl Request {
pub fn new(url: Url,
origin: Option<Origin>,
- is_service_worker_global_scope: bool) -> Request {
+ is_service_worker_global_scope: bool,
+ pipeline_id: Option<PipelineId>) -> Request {
Request {
method: RefCell::new(Method::Get),
local_urls_only: false,
@@ -198,6 +201,7 @@ impl Request {
same_origin_data: Cell::new(false),
referer: RefCell::new(Referer::Client),
referrer_policy: Cell::new(None),
+ pipeline_id: Cell::new(pipeline_id),
synchronous: false,
mode: RequestMode::NoCORS,
use_cors_preflight: false,
@@ -216,7 +220,7 @@ impl Request {
pub fn from_init(init: RequestInit) -> Request {
let mut req = Request::new(init.url,
Some(Origin::Origin(init.origin.origin())),
- false);
+ false, init.pipeline_id);
*req.method.borrow_mut() = init.method;
*req.headers.borrow_mut() = init.headers;
req.unsafe_request = init.unsafe_request;
@@ -234,6 +238,7 @@ impl Request {
Referer::NoReferer
};
req.referrer_policy.set(init.referrer_policy);
+ req.pipeline_id.set(init.pipeline_id);
req
}
@@ -241,7 +246,8 @@ impl Request {
pub fn potential_cors_request(url: Url,
cors_attribute_state: Option<CORSSettings>,
is_service_worker_global_scope: bool,
- same_origin_fallback: bool) -> Request {
+ same_origin_fallback: bool,
+ pipeline_id: Option<PipelineId>) -> Request {
Request {
method: RefCell::new(Method::Get),
local_urls_only: false,
@@ -281,6 +287,7 @@ impl Request {
url_list: RefCell::new(vec![url]),
redirect_count: Cell::new(0),
response_tainting: Cell::new(ResponseTainting::Basic),
+ pipeline_id: Cell::new(pipeline_id),
done: Cell::new(false)
}
}
diff --git a/components/plugins/jstraceable.rs b/components/plugins/jstraceable.rs
index a1a9d81e94f..8dcd93f2d4c 100644
--- a/components/plugins/jstraceable.rs
+++ b/components/plugins/jstraceable.rs
@@ -86,5 +86,5 @@ fn jstraceable_substructure(cx: &mut ExtCtxt, trait_span: Span, substr: &Substru
stmts.push(call_trace(span, self_.clone()));
}
- cx.expr_block(cx.block(trait_span, stmts, None))
+ cx.expr_block(cx.block(trait_span, stmts))
}
diff --git a/components/profile/Cargo.toml b/components/profile/Cargo.toml
index 7532de19136..e430982d57f 100644
--- a/components/profile/Cargo.toml
+++ b/components/profile/Cargo.toml
@@ -13,12 +13,12 @@ path = "lib.rs"
profile_traits = {path = "../profile_traits"}
plugins = {path = "../plugins"}
util = {path = "../util", features = ["servo"]}
-ipc-channel = {git = "https://github.com/servo/ipc-channel"}
+ipc-channel = "0.4.0"
heartbeats-simple = "0.3"
log = "0.3.5"
-serde = "0.7.11"
+serde = "0.7.15"
serde_json = "0.7"
-serde_macros = "0.7.11"
+serde_macros = "0.7.15"
time = "0.1.12"
[target.'cfg(target_os = "macos")'.dependencies]
diff --git a/components/profile_traits/Cargo.toml b/components/profile_traits/Cargo.toml
index 5e6d0890b64..0c8f966af28 100644
--- a/components/profile_traits/Cargo.toml
+++ b/components/profile_traits/Cargo.toml
@@ -13,10 +13,10 @@ path = "lib.rs"
energy-profiling = ["energymon", "energy-monitor"]
[dependencies]
-ipc-channel = {git = "https://github.com/servo/ipc-channel"}
+ipc-channel = "0.4.0"
energymon = {git = "https://github.com/energymon/energymon-rust.git", optional = true}
energy-monitor = {version = "0.2.0", optional = true}
plugins = {path = "../plugins"}
-serde = "0.7.11"
-serde_macros = "0.7.11"
+serde = "0.7.15"
+serde_macros = "0.7.15"
time = "0.1.12"
diff --git a/components/range/Cargo.toml b/components/range/Cargo.toml
index c3573de6515..c9cbf2e9b50 100644
--- a/components/range/Cargo.toml
+++ b/components/range/Cargo.toml
@@ -15,5 +15,5 @@ heapsize = "0.3.0"
heapsize_plugin = "0.1.2"
num-traits = "0.1.32"
rustc-serialize = "0.3"
-serde = "0.7.11"
-serde_macros = "0.7.11"
+serde = "0.7.15"
+serde_macros = "0.7.15"
diff --git a/components/script/Cargo.toml b/components/script/Cargo.toml
index 0640fb17f60..891b48f3dd9 100644
--- a/components/script/Cargo.toml
+++ b/components/script/Cargo.toml
@@ -14,9 +14,12 @@ path = "lib.rs"
[features]
debugmozjs = ['js/debugmozjs']
-[target.'cfg(any(target_os = "macos", target_os = "linux"))'.dependencies]
+[target.'cfg(any(target_os = "macos", target_os = "linux", target_os = "windows"))'.dependencies]
tinyfiledialogs = {git = "https://github.com/jdm/tinyfiledialogs"}
+[target.'cfg(not(any(target_os = "android", target_arch = "arm", target_arch = "aarch64")))'.dependencies]
+video-metadata = {git = "https://github.com/GuillaumeGomez/video-metadata-rs"}
+
[dependencies]
angle = {git = "https://github.com/servo/angle", branch = "servo"}
app_units = "0.2.5"
@@ -35,7 +38,7 @@ heapsize_plugin = "0.1.2"
html5ever = {version = "0.5.1", features = ["heap_size", "unstable"]}
hyper = {version = "0.9.9", features = ["serde-serialization"]}
image = "0.10"
-ipc-channel = {git = "https://github.com/servo/ipc-channel"}
+ipc-channel = "0.4.0"
js = {git = "https://github.com/servo/rust-mozjs"}
libc = "0.2"
log = "0.3.5"
@@ -46,8 +49,8 @@ net_traits = {path = "../net_traits"}
num-traits = "0.1.32"
offscreen_gl_context = "0.1.2"
open = "1.1.1"
-phf = "0.7.13"
-phf_macros = "0.7.13"
+phf = "0.7.16"
+phf_macros = "0.7.16"
plugins = {path = "../plugins"}
profile_traits = {path = "../profile_traits"}
rand = "0.3"
@@ -59,7 +62,7 @@ rustc-serialize = "0.3"
script_layout_interface = {path = "../script_layout_interface"}
script_traits = {path = "../script_traits"}
selectors = {version = "0.7", features = ["heap_size"]}
-serde = "0.7.11"
+serde = "0.7.15"
smallvec = "0.1"
string_cache = {version = "0.2.20", features = ["heap_size", "unstable"]}
style = {path = "../style"}
diff --git a/components/script/build.rs b/components/script/build.rs
index 88b1e22b953..a0d693d152f 100644
--- a/components/script/build.rs
+++ b/components/script/build.rs
@@ -2,12 +2,17 @@
* 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::env;
use std::process::Command;
+use std::time::Instant;
fn main() {
+ let start = Instant::now();
+ let num_jobs = env::var("NUM_JOBS").unwrap();
assert!(Command::new("make")
- .args(&["-f", "makefile.cargo"])
+ .args(&["-f", "makefile.cargo", "-j", &num_jobs])
.status()
.unwrap()
.success());
+ println!("Binding generation completed in {}s", start.elapsed().as_secs());
}
diff --git a/components/script/devtools.rs b/components/script/devtools.rs
index 20394bf367a..024307bc696 100644
--- a/components/script/devtools.rs
+++ b/components/script/devtools.rs
@@ -25,7 +25,6 @@ use ipc_channel::ipc::IpcSender;
use js::jsapi::{JSAutoCompartment, ObjectClassName};
use js::jsval::UndefinedValue;
use msg::constellation_msg::PipelineId;
-use script_thread::get_browsing_context;
use std::ffi::CStr;
use std::str;
use style::properties::longhands::{margin_top, margin_right, margin_bottom, margin_left};
@@ -68,58 +67,72 @@ pub fn handle_evaluate_js(global: &GlobalRef, eval: String, reply: IpcSender<Eva
reply.send(result).unwrap();
}
-pub fn handle_get_root_node(context: &BrowsingContext, pipeline: PipelineId, reply: IpcSender<NodeInfo>) {
- let context = get_browsing_context(context, pipeline);
+pub fn handle_get_root_node(context: &BrowsingContext, pipeline: PipelineId, reply: IpcSender<Option<NodeInfo>>) {
+ let context = match context.find(pipeline) {
+ Some(found_context) => found_context,
+ None => return reply.send(None).unwrap()
+ };
+
let document = context.active_document();
let node = document.upcast::<Node>();
- reply.send(node.summarize()).unwrap();
+ reply.send(Some(node.summarize())).unwrap();
}
pub fn handle_get_document_element(context: &BrowsingContext,
pipeline: PipelineId,
- reply: IpcSender<NodeInfo>) {
- let context = get_browsing_context(context, pipeline);
+ reply: IpcSender<Option<NodeInfo>>) {
+ let context = match context.find(pipeline) {
+ Some(found_context) => found_context,
+ None => return reply.send(None).unwrap()
+ };
+
let document = context.active_document();
let document_element = document.GetDocumentElement().unwrap();
let node = document_element.upcast::<Node>();
- reply.send(node.summarize()).unwrap();
+ reply.send(Some(node.summarize())).unwrap();
}
fn find_node_by_unique_id(context: &BrowsingContext,
pipeline: PipelineId,
- node_id: String)
- -> Root<Node> {
- let context = get_browsing_context(context, pipeline);
+ node_id: &str)
+ -> Option<Root<Node>> {
+ let context = match context.find(pipeline) {
+ Some(found_context) => found_context,
+ None => return None
+ };
+
let document = context.active_document();
let node = document.upcast::<Node>();
- for candidate in node.traverse_preorder() {
- if candidate.unique_id() == node_id {
- return candidate;
- }
- }
-
- panic!("couldn't find node with unique id {}", node_id)
+ node.traverse_preorder().find(|candidate| candidate.unique_id() == node_id)
}
pub fn handle_get_children(context: &BrowsingContext,
pipeline: PipelineId,
node_id: String,
- reply: IpcSender<Vec<NodeInfo>>) {
- let parent = find_node_by_unique_id(context, pipeline, node_id);
- let children = parent.children()
- .map(|child| child.summarize())
- .collect();
- reply.send(children).unwrap();
+ reply: IpcSender<Option<Vec<NodeInfo>>>) {
+ match find_node_by_unique_id(context, pipeline, &*node_id) {
+ None => return reply.send(None).unwrap(),
+ Some(parent) => {
+ let children = parent.children()
+ .map(|child| child.summarize())
+ .collect();
+
+ reply.send(Some(children)).unwrap();
+ }
+ };
}
pub fn handle_get_layout(context: &BrowsingContext,
pipeline: PipelineId,
node_id: String,
- reply: IpcSender<ComputedNodeLayout>) {
- let node = find_node_by_unique_id(context, pipeline, node_id);
+ reply: IpcSender<Option<ComputedNodeLayout>>) {
+ let node = match find_node_by_unique_id(context, pipeline, &*node_id) {
+ None => return reply.send(None).unwrap(),
+ Some(found_node) => found_node
+ };
let elem = node.downcast::<Element>().expect("should be getting layout of element");
let rect = elem.GetBoundingClientRect();
@@ -130,7 +143,7 @@ pub fn handle_get_layout(context: &BrowsingContext,
let elem = node.downcast::<Element>().expect("should be getting layout of element");
let computed_style = window.r().GetComputedStyle(elem, None);
- reply.send(ComputedNodeLayout {
+ reply.send(Some(ComputedNodeLayout {
display: String::from(computed_style.Display()),
position: String::from(computed_style.Position()),
zIndex: String::from(computed_style.ZIndex()),
@@ -150,7 +163,7 @@ pub fn handle_get_layout(context: &BrowsingContext,
paddingLeft: String::from(computed_style.PaddingLeft()),
width: width,
height: height,
- }).unwrap();
+ })).unwrap();
}
fn determine_auto_margins(window: &Window, node: &Node) -> AutoMargins {
@@ -209,7 +222,11 @@ pub fn handle_modify_attribute(context: &BrowsingContext,
pipeline: PipelineId,
node_id: String,
modifications: Vec<Modification>) {
- let node = find_node_by_unique_id(context, pipeline, node_id);
+ let node = match find_node_by_unique_id(context, pipeline, &*node_id) {
+ None => return warn!("node id {} for pipeline id {} is not found", &node_id, &pipeline),
+ Some(found_node) => found_node
+ };
+
let elem = node.downcast::<Element>().expect("should be getting layout of element");
for modification in modifications {
@@ -243,7 +260,11 @@ pub fn handle_drop_timeline_markers(context: &BrowsingContext,
pub fn handle_request_animation_frame(context: &BrowsingContext,
id: PipelineId,
actor_name: String) {
- let context = context.find(id).expect("There is no such context");
+ let context = match context.find(id) {
+ None => return warn!("context for pipeline id {} is not found", id),
+ Some(found_node) => found_node
+ };
+
let doc = context.active_document();
let devtools_sender = context.active_window().devtools_chan().unwrap();
doc.request_animation_frame(box move |time| {
@@ -254,7 +275,11 @@ pub fn handle_request_animation_frame(context: &BrowsingContext,
pub fn handle_reload(context: &BrowsingContext,
id: PipelineId) {
- let context = context.find(id).expect("There is no such context");
+ let context = match context.find(id) {
+ None => return warn!("context for pipeline id {} is not found", id),
+ Some(found_node) => found_node
+ };
+
let win = context.active_window();
let location = win.Location();
location.Reload();
diff --git a/components/script/dom/abstractworker.rs b/components/script/dom/abstractworker.rs
index 4f2f029800b..28c755d4f03 100644
--- a/components/script/dom/abstractworker.rs
+++ b/components/script/dom/abstractworker.rs
@@ -15,7 +15,7 @@ pub enum WorkerScriptMsg {
/// Common variants associated with the script messages
Common(CommonScriptMsg),
/// Message sent through Worker.postMessage
- DOMMessage(StructuredCloneData),
+ DOMMessage(StructuredCloneData)
}
pub struct SimpleWorkerErrorHandler<T: Reflectable> {
diff --git a/components/script/dom/bindings/codegen/CodegenRust.py b/components/script/dom/bindings/codegen/CodegenRust.py
index 8360dfc322a..2e0dc2415dd 100644
--- a/components/script/dom/bindings/codegen/CodegenRust.py
+++ b/components/script/dom/bindings/codegen/CodegenRust.py
@@ -1872,56 +1872,31 @@ class CGDOMJSClass(CGThing):
elif self.descriptor.weakReferenceable:
args["slots"] = "2"
return """\
+static CLASS_OPS: js::jsapi::ClassOps = js::jsapi::ClassOps {
+ addProperty: None,
+ delProperty: None,
+ getProperty: None,
+ setProperty: None,
+ enumerate: %(enumerateHook)s,
+ resolve: %(resolveHook)s,
+ mayResolve: None,
+ finalize: Some(%(finalizeHook)s),
+ call: None,
+ hasInstance: None,
+ construct: None,
+ trace: Some(%(traceHook)s),
+};
+
static Class: DOMJSClass = DOMJSClass {
base: js::jsapi::Class {
name: %(name)s as *const u8 as *const libc::c_char,
flags: JSCLASS_IS_DOMJSCLASS | %(flags)s |
(((%(slots)s) & JSCLASS_RESERVED_SLOTS_MASK) << JSCLASS_RESERVED_SLOTS_SHIFT)
/* JSCLASS_HAS_RESERVED_SLOTS(%(slots)s) */,
- addProperty: None,
- delProperty: None,
- getProperty: None,
- setProperty: None,
- enumerate: %(enumerateHook)s,
- resolve: %(resolveHook)s,
- mayResolve: None,
- finalize: Some(%(finalizeHook)s),
- call: None,
- hasInstance: None,
- construct: None,
- trace: Some(%(traceHook)s),
-
- spec: js::jsapi::ClassSpec {
- createConstructor_: None,
- createPrototype_: None,
- constructorFunctions_: 0 as *const js::jsapi::JSFunctionSpec,
- constructorProperties_: 0 as *const js::jsapi::JSPropertySpec,
- prototypeFunctions_: 0 as *const js::jsapi::JSFunctionSpec,
- prototypeProperties_: 0 as *const js::jsapi::JSPropertySpec,
- finishInit_: None,
- flags: 0,
- },
-
- ext: js::jsapi::ClassExtension {
- isWrappedNative: false,
- weakmapKeyDelegateOp: None,
- objectMovedOp: None,
- },
-
- ops: js::jsapi::ObjectOps {
- lookupProperty: None,
- defineProperty: None,
- hasProperty: None,
- getProperty: None,
- setProperty: None,
- getOwnPropertyDescriptor: None,
- deleteProperty: None,
- watch: None,
- unwatch: None,
- getElements: None,
- enumerate: None,
- funToString: None,
- },
+ cOps: &CLASS_OPS,
+ spec: ptr::null(),
+ ext: ptr::null(),
+ oOps: ptr::null(),
},
dom_class: %(domClass)s
};""" % args
@@ -1947,19 +1922,8 @@ static PrototypeClass: JSClass = JSClass {
flags:
// JSCLASS_HAS_RESERVED_SLOTS(%(slotCount)s)
(%(slotCount)s & JSCLASS_RESERVED_SLOTS_MASK) << JSCLASS_RESERVED_SLOTS_SHIFT,
- addProperty: None,
- delProperty: None,
- getProperty: None,
- setProperty: None,
- enumerate: None,
- resolve: None,
- mayResolve: None,
- finalize: None,
- call: None,
- hasInstance: None,
- construct: None,
- trace: None,
- reserved: [0 as *mut os::raw::c_void; 23]
+ cOps: 0 as *const _,
+ reserved: [0 as *mut os::raw::c_void; 3]
};
""" % {'name': name, 'slotCount': slotCount}
@@ -1983,9 +1947,12 @@ class CGInterfaceObjectJSClass(CGThing):
"depth": self.descriptor.prototypeDepth
}
return """\
+static INTERFACE_OBJECT_OPS: js::jsapi::ClassOps =
+ NonCallbackInterfaceObjectClass::ops(%(constructorBehavior)s);
+
static InterfaceObjectClass: NonCallbackInterfaceObjectClass =
NonCallbackInterfaceObjectClass::new(
- %(constructorBehavior)s,
+ &INTERFACE_OBJECT_OPS,
%(representation)s,
PrototypeList::ID::%(id)s,
%(depth)s);
@@ -2772,6 +2739,7 @@ let traps = ProxyTraps {
ownPropertyKeys: Some(own_property_keys),
delete_: Some(%(delete)s),
enumerate: None,
+ getPrototypeIfOrdinary: Some(proxyhandler::get_prototype_if_ordinary),
preventExtensions: Some(proxyhandler::prevent_extensions),
isExtensible: Some(proxyhandler::is_extensible),
has: None,
diff --git a/components/script/dom/bindings/error.rs b/components/script/dom/bindings/error.rs
index d0074335c23..c4bda97e521 100644
--- a/components/script/dom/bindings/error.rs
+++ b/components/script/dom/bindings/error.rs
@@ -4,15 +4,26 @@
//! Utilities to throw exceptions from Rust bindings.
+use dom::bindings::codegen::Bindings::DOMExceptionBinding::DOMExceptionMethods;
use dom::bindings::codegen::PrototypeList::proto_id_to_name;
-use dom::bindings::conversions::ToJSValConvertible;
+use dom::bindings::conversions::root_from_object;
+use dom::bindings::conversions::{FromJSValConvertible, ToJSValConvertible};
use dom::bindings::global::GlobalRef;
+use dom::bindings::str::USVString;
use dom::domexception::{DOMErrorName, DOMException};
use js::error::{throw_range_error, throw_type_error};
+use js::jsapi::HandleObject;
use js::jsapi::JSAutoCompartment;
-use js::jsapi::{JSContext, JSObject};
-use js::jsapi::{JS_IsExceptionPending, JS_ReportPendingException, JS_SetPendingException};
+use js::jsapi::JSContext;
+use js::jsapi::JSObject;
+use js::jsapi::JS_ClearPendingException;
+use js::jsapi::JS_ErrorFromException;
+use js::jsapi::JS_GetPendingException;
+use js::jsapi::JS_IsExceptionPending;
+use js::jsapi::JS_SetPendingException;
use js::jsval::UndefinedValue;
+use libc::c_uint;
+use std::slice::from_raw_parts;
/// DOM exceptions that can be thrown by a native DOM method.
#[derive(Debug, Clone, HeapSizeOf)]
@@ -123,11 +134,101 @@ pub unsafe fn throw_dom_exception(cx: *mut JSContext, global: GlobalRef, result:
JS_SetPendingException(cx, thrown.handle());
}
+struct ErrorInfo {
+ filename: String,
+ message: String,
+ lineno: c_uint,
+ column: c_uint,
+}
+
+impl ErrorInfo {
+ unsafe fn from_native_error(cx: *mut JSContext, object: HandleObject)
+ -> Option<ErrorInfo> {
+ let report = JS_ErrorFromException(cx, object);
+ if report.is_null() {
+ return None;
+ }
+
+ let filename = {
+ let filename = (*report).filename as *const u8;
+ if !filename.is_null() {
+ let length = (0..).find(|idx| *filename.offset(*idx) == 0).unwrap();
+ let filename = from_raw_parts(filename, length as usize);
+ String::from_utf8_lossy(filename).into_owned()
+ } else {
+ "none".to_string()
+ }
+ };
+
+ let lineno = (*report).lineno;
+ let column = (*report).column;
+
+ let message = {
+ let message = (*report).ucmessage;
+ let length = (0..).find(|idx| *message.offset(*idx) == 0).unwrap();
+ let message = from_raw_parts(message, length as usize);
+ String::from_utf16_lossy(message)
+ };
+
+ Some(ErrorInfo {
+ filename: filename,
+ message: message,
+ lineno: lineno,
+ column: column,
+ })
+ }
+
+ fn from_dom_exception(object: HandleObject) -> Option<ErrorInfo> {
+ let exception = match root_from_object::<DOMException>(object.get()) {
+ Ok(exception) => exception,
+ Err(_) => return None,
+ };
+
+ Some(ErrorInfo {
+ filename: "".to_string(),
+ message: exception.Stringifier().into(),
+ lineno: 0,
+ column: 0,
+ })
+ }
+}
+
/// Report a pending exception, thereby clearing it.
pub unsafe fn report_pending_exception(cx: *mut JSContext, obj: *mut JSObject) {
if JS_IsExceptionPending(cx) {
let _ac = JSAutoCompartment::new(cx, obj);
- JS_ReportPendingException(cx);
+ rooted!(in(cx) let mut value = UndefinedValue());
+ if !JS_GetPendingException(cx, value.handle_mut()) {
+ JS_ClearPendingException(cx);
+ error!("Uncaught exception: JS_GetPendingException failed");
+ return;
+ }
+
+ JS_ClearPendingException(cx);
+ if !value.is_object() {
+ match USVString::from_jsval(cx, value.handle(), ()) {
+ Ok(USVString(string)) => error!("Uncaught exception: {}", string),
+ Err(_) => error!("Uncaught exception: failed to stringify primitive"),
+ }
+ return;
+ }
+
+ rooted!(in(cx) let object = value.to_object());
+ let error_info = ErrorInfo::from_native_error(cx, object.handle())
+ .or_else(|| ErrorInfo::from_dom_exception(object.handle()));
+ let error_info = match error_info {
+ Some(error_info) => error_info,
+ None => {
+ error!("Uncaught exception: failed to extract information");
+ return;
+ }
+ };
+
+ error!("Error at {}:{}:{} {}",
+ error_info.filename,
+ error_info.lineno,
+ error_info.column,
+ error_info.message);
}
}
diff --git a/components/script/dom/bindings/global.rs b/components/script/dom/bindings/global.rs
index fe81b8a14de..bfc3212a9c4 100644
--- a/components/script/dom/bindings/global.rs
+++ b/components/script/dom/bindings/global.rs
@@ -19,7 +19,6 @@ use js::jsapi::{CurrentGlobalOrNull, GetGlobalForObjectCrossCompartment};
use js::jsapi::{JSContext, JSObject, JS_GetClass, MutableHandleValue};
use js::{JSCLASS_IS_DOMJSCLASS, JSCLASS_IS_GLOBAL};
use msg::constellation_msg::PipelineId;
-use net_traits::filemanager_thread::FileManagerThreadMsg;
use net_traits::{ResourceThreads, CoreResourceThread, IpcSend};
use profile_traits::{mem, time};
use script_runtime::{CommonScriptMsg, ScriptChan, ScriptPort};
@@ -133,11 +132,6 @@ impl<'a> GlobalRef<'a> {
self.resource_threads().sender()
}
- /// Get the port to file manager for this global scope
- pub fn filemanager_thread(&self) -> IpcSender<FileManagerThreadMsg> {
- self.resource_threads().sender()
- }
-
/// Get the worker's id.
pub fn get_worker_id(&self) -> Option<WorkerId> {
match *self {
diff --git a/components/script/dom/bindings/interface.rs b/components/script/dom/bindings/interface.rs
index 4e2c630a453..3b2b5dbde36 100644
--- a/components/script/dom/bindings/interface.rs
+++ b/components/script/dom/bindings/interface.rs
@@ -11,7 +11,7 @@ use dom::bindings::guard::Guard;
use dom::bindings::utils::get_proto_or_iface_array;
use js::error::throw_type_error;
use js::glue::{RUST_SYMBOL_TO_JSID, UncheckedUnwrapObject};
-use js::jsapi::{Class, ClassExtension, ClassSpec, GetGlobalForObjectCrossCompartment};
+use js::jsapi::{Class, ClassOps, GetGlobalForObjectCrossCompartment};
use js::jsapi::{GetWellKnownSymbol, HandleObject, HandleValue, JSClass, JSContext};
use js::jsapi::{JSFunctionSpec, JSNative, JSFUN_CONSTRUCTOR, JSPROP_ENUMERATE};
use js::jsapi::{JSPROP_PERMANENT, JSPROP_READONLY, JSPROP_RESOLVING, JSPropertySpec};
@@ -101,6 +101,21 @@ unsafe extern "C" fn fun_to_string_hook(cx: *mut JSContext,
ret
}
+const OBJECT_OPS: ObjectOps = ObjectOps {
+ lookupProperty: None,
+ defineProperty: None,
+ hasProperty: None,
+ getProperty: None,
+ setProperty: None,
+ getOwnPropertyDescriptor: None,
+ deleteProperty: None,
+ watch: None,
+ unwatch: None,
+ getElements: None,
+ enumerate: None,
+ funToString: Some(fun_to_string_hook),
+};
+
/// The class of a non-callback interface object.
#[derive(Copy, Clone)]
pub struct NonCallbackInterfaceObjectClass {
@@ -117,58 +132,39 @@ pub struct NonCallbackInterfaceObjectClass {
unsafe impl Sync for NonCallbackInterfaceObjectClass {}
impl NonCallbackInterfaceObjectClass {
+ /// Create `ClassOps` for a `NonCallbackInterfaceObjectClass`.
+ pub const fn ops(constructor_behavior: InterfaceConstructorBehavior)
+ -> ClassOps {
+ ClassOps {
+ addProperty: None,
+ delProperty: None,
+ getProperty: None,
+ setProperty: None,
+ enumerate: None,
+ resolve: None,
+ mayResolve: None,
+ finalize: None,
+ call: constructor_behavior.call,
+ construct: constructor_behavior.construct,
+ hasInstance: Some(has_instance_hook),
+ trace: None,
+ }
+ }
+
/// Create a new `NonCallbackInterfaceObjectClass` structure.
- pub const fn new(
- constructor_behavior: InterfaceConstructorBehavior,
- string_rep: &'static [u8],
- proto_id: PrototypeList::ID,
- proto_depth: u16)
- -> NonCallbackInterfaceObjectClass {
+ pub const fn new(ops: &'static ClassOps,
+ string_rep: &'static [u8],
+ proto_id: PrototypeList::ID,
+ proto_depth: u16)
+ -> NonCallbackInterfaceObjectClass {
NonCallbackInterfaceObjectClass {
class: Class {
name: b"Function\0" as *const _ as *const libc::c_char,
flags: 0,
- addProperty: None,
- delProperty: None,
- getProperty: None,
- setProperty: None,
- enumerate: None,
- resolve: None,
- mayResolve: None,
- finalize: None,
- call: constructor_behavior.call,
- construct: constructor_behavior.construct,
- hasInstance: Some(has_instance_hook),
- trace: None,
- spec: ClassSpec {
- createConstructor_: None,
- createPrototype_: None,
- constructorFunctions_: ptr::null(),
- constructorProperties_: ptr::null(),
- prototypeFunctions_: ptr::null(),
- prototypeProperties_: ptr::null(),
- finishInit_: None,
- flags: 0,
- },
- ext: ClassExtension {
- isWrappedNative: false,
- weakmapKeyDelegateOp: None,
- objectMovedOp: None,
- },
- ops: ObjectOps {
- lookupProperty: None,
- defineProperty: None,
- hasProperty: None,
- getProperty: None,
- setProperty: None,
- getOwnPropertyDescriptor: None,
- deleteProperty: None,
- watch: None,
- unwatch: None,
- getElements: None,
- enumerate: None,
- funToString: Some(fun_to_string_hook),
- }
+ cOps: ops,
+ spec: ptr::null(),
+ ext: ptr::null(),
+ oOps: &OBJECT_OPS,
},
proto_id: proto_id,
proto_depth: proto_depth,
diff --git a/components/script/dom/bindings/proxyhandler.rs b/components/script/dom/bindings/proxyhandler.rs
index 9db30d8835c..c863cc31994 100644
--- a/components/script/dom/bindings/proxyhandler.rs
+++ b/components/script/dom/bindings/proxyhandler.rs
@@ -12,7 +12,9 @@ use js::glue::GetProxyExtra;
use js::glue::InvokeGetOwnPropertyDescriptor;
use js::glue::{GetProxyHandler, SetProxyExtra};
use js::jsapi::GetObjectProto;
+use js::jsapi::GetStaticPrototype;
use js::jsapi::JS_GetPropertyDescriptorById;
+use js::jsapi::MutableHandleObject;
use js::jsapi::{Handle, HandleId, HandleObject, MutableHandle, ObjectOpResult};
use js::jsapi::{JSContext, JSObject, JSPROP_GETTER, PropertyDescriptor};
use js::jsapi::{JSErrNum, JS_StrictPropertyStub};
@@ -103,6 +105,25 @@ pub unsafe extern "C" fn is_extensible(_cx: *mut JSContext,
true
}
+/// If `proxy` (underneath any functionally-transparent wrapper proxies) has as
+/// its `[[GetPrototypeOf]]` trap the ordinary `[[GetPrototypeOf]]` behavior
+/// defined for ordinary objects, set `*is_ordinary` to true and store `obj`'s
+/// prototype in `proto`. Otherwise set `*isOrdinary` to false. In case of
+/// error, both outparams have unspecified value.
+///
+/// This implementation always handles the case of the ordinary
+/// `[[GetPrototypeOf]]` behavior. An alternative implementation will be
+/// necessary for the Location object.
+pub unsafe extern "C" fn get_prototype_if_ordinary(_: *mut JSContext,
+ proxy: HandleObject,
+ is_ordinary: *mut bool,
+ proto: MutableHandleObject)
+ -> bool {
+ *is_ordinary = true;
+ proto.set(GetStaticPrototype(proxy.get()));
+ true
+}
+
/// Get the expando object, or null if there is none.
pub fn get_expando_object(obj: HandleObject) -> *mut JSObject {
unsafe {
diff --git a/components/script/dom/bindings/trace.rs b/components/script/dom/bindings/trace.rs
index 3c13572bf37..618061fe769 100644
--- a/components/script/dom/bindings/trace.rs
+++ b/components/script/dom/bindings/trace.rs
@@ -91,6 +91,7 @@ use style::element_state::*;
use style::properties::PropertyDeclarationBlock;
use style::selector_impl::{PseudoElement, ElementSnapshot};
use style::values::specified::Length;
+use time::Duration;
use url::Origin as UrlOrigin;
use url::Url;
use uuid::Uuid;
@@ -109,6 +110,8 @@ no_jsmanaged_fields!(EncodingRef);
no_jsmanaged_fields!(Reflector);
+no_jsmanaged_fields!(Duration);
+
/// Trace a `JSVal`.
pub fn trace_jsval(tracer: *mut JSTracer, description: &str, val: &Heap<JSVal>) {
unsafe {
diff --git a/components/script/dom/blob.rs b/components/script/dom/blob.rs
index f63e66e3b7b..4711da80010 100644
--- a/components/script/dom/blob.rs
+++ b/components/script/dom/blob.rs
@@ -14,18 +14,20 @@ use dom::bindings::str::DOMString;
use encoding::all::UTF_8;
use encoding::types::{EncoderTrap, Encoding};
use ipc_channel::ipc;
-use net_traits::IpcSend;
use net_traits::blob_url_store::{BlobBuf, get_blob_origin};
-use net_traits::filemanager_thread::{FileManagerThreadMsg, SelectedFileId, RelativePos};
+use net_traits::filemanager_thread::{FileManagerThreadMsg, SelectedFileId, RelativePos, ReadFileProgress};
+use net_traits::{CoreResourceMsg, IpcSend};
use std::cell::Cell;
+use std::mem;
use std::ops::Index;
use std::path::PathBuf;
+use uuid::Uuid;
/// File-based blob
#[derive(JSTraceable)]
pub struct FileBlob {
id: SelectedFileId,
- name: PathBuf,
+ name: Option<PathBuf>,
cache: DOMRefCell<Option<Vec<u8>>>,
size: u64,
}
@@ -56,7 +58,7 @@ impl BlobImpl {
pub fn new_from_file(file_id: SelectedFileId, name: PathBuf, size: u64) -> BlobImpl {
BlobImpl::File(FileBlob {
id: file_id,
- name: name,
+ name: Some(name),
cache: DOMRefCell::new(None),
size: size,
})
@@ -97,9 +99,7 @@ impl Blob {
relativeContentType: DOMString) -> Root<Blob> {
let global = parent.global();
let blob_impl = match *parent.blob_impl.borrow() {
- BlobImpl::File(ref f) => {
- inc_ref_id(global.r(), f.id.clone());
-
+ BlobImpl::File(_) => {
// Create new parent node
BlobImpl::Sliced(JS::from_ref(parent), rel_pos)
}
@@ -109,13 +109,7 @@ impl Blob {
}
BlobImpl::Sliced(ref grandparent, ref old_rel_pos) => {
// Adjust the slicing position, using same parent
- let new_rel_pos = old_rel_pos.slice_inner(&rel_pos);
-
- if let BlobImpl::File(ref f) = *grandparent.blob_impl.borrow() {
- inc_ref_id(global.r(), f.id.clone());
- }
-
- BlobImpl::Sliced(grandparent.clone(), new_rel_pos)
+ BlobImpl::Sliced(grandparent.clone(), old_rel_pos.slice_inner(&rel_pos))
}
};
@@ -172,85 +166,116 @@ impl Blob {
/// Get a FileID representing the Blob content,
/// used by URL.createObjectURL
pub fn get_blob_url_id(&self) -> SelectedFileId {
- match *self.blob_impl.borrow() {
- BlobImpl::File(ref f) => {
- let global = self.global();
- let origin = get_blob_origin(&global.r().get_url());
- let filemanager = global.r().resource_threads().sender();
- let (tx, rx) = ipc::channel().unwrap();
-
- let _ = filemanager.send(FileManagerThreadMsg::ActivateBlobURL(f.id.clone(), tx, origin.clone()));
-
- match rx.recv().unwrap() {
- Ok(_) => f.id.clone(),
- Err(_) => SelectedFileId("".to_string()) // Return a dummy id on error
- }
- }
- BlobImpl::Memory(ref slice) => {
- self.promote(slice, true)
- }
+ let opt_sliced_parent = match *self.blob_impl.borrow() {
BlobImpl::Sliced(ref parent, ref rel_pos) => {
- match *parent.blob_impl.borrow() {
- BlobImpl::Sliced(_, _) => {
- debug!("Sliced can't have a sliced parent");
- // Return dummy id
- SelectedFileId("".to_string())
- }
- BlobImpl::File(ref f) =>
- self.create_sliced_url_id(&f.id, rel_pos),
- BlobImpl::Memory(ref bytes) => {
- let parent_id = parent.promote(bytes, false);
- *self.blob_impl.borrow_mut() = BlobImpl::Sliced(parent.clone(), rel_pos.clone());
- self.create_sliced_url_id(&parent_id, rel_pos)
- }
- }
+ Some((parent.promote(/* set_valid is */ false), rel_pos.clone(), parent.Size()))
}
+ _ => None
+ };
+
+ match opt_sliced_parent {
+ Some((parent_id, rel_pos, size)) => self.create_sliced_url_id(&parent_id, &rel_pos, size),
+ None => self.promote(/* set_valid is */ true),
}
}
- /// Promite memory-based Blob to file-based,
- /// The bytes in data slice will be transferred to file manager thread.
+ /// Promote non-Slice blob:
+ /// 1. Memory-based: The bytes in data slice will be transferred to file manager thread.
+ /// 2. File-based: Activation
/// Depending on set_valid, the returned FileID can be part of
/// valid or invalid Blob URL.
- fn promote(&self, bytes: &[u8], set_valid: bool) -> SelectedFileId {
+ fn promote(&self, set_valid: bool) -> SelectedFileId {
+ let mut bytes = vec![];
+
+ match *self.blob_impl.borrow_mut() {
+ BlobImpl::Sliced(_, _) => {
+ debug!("Sliced can't have a sliced parent");
+ // Return dummy id
+ return SelectedFileId(Uuid::new_v4().simple().to_string());
+ }
+ BlobImpl::File(ref f) => {
+ if set_valid {
+ let global = self.global();
+ let origin = get_blob_origin(&global.r().get_url());
+ let (tx, rx) = ipc::channel().unwrap();
+
+ let msg = FileManagerThreadMsg::ActivateBlobURL(f.id.clone(), tx, origin.clone());
+ self.send_to_file_manager(msg);
+
+ match rx.recv().unwrap() {
+ Ok(_) => return f.id.clone(),
+ // Return a dummy id on error
+ Err(_) => return SelectedFileId(Uuid::new_v4().simple().to_string())
+ }
+ } else {
+ // no need to activate
+ return f.id.clone();
+ }
+ }
+ BlobImpl::Memory(ref mut bytes_in) => mem::swap(bytes_in, &mut bytes),
+ };
+
let global = self.global();
let origin = get_blob_origin(&global.r().get_url());
- let filemanager = global.r().resource_threads().sender();
let blob_buf = BlobBuf {
filename: None,
type_string: self.typeString.clone(),
- size: self.Size(),
+ size: bytes.len() as u64,
bytes: bytes.to_vec(),
};
let (tx, rx) = ipc::channel().unwrap();
- let _ = filemanager.send(FileManagerThreadMsg::PromoteMemory(blob_buf, set_valid, tx, origin.clone()));
+ let msg = FileManagerThreadMsg::PromoteMemory(blob_buf, set_valid, tx, origin.clone());
+ self.send_to_file_manager(msg);
match rx.recv().unwrap() {
- Ok(new_id) => SelectedFileId(new_id.0),
+ Ok(id) => {
+ let id = SelectedFileId(id.0);
+ *self.blob_impl.borrow_mut() = BlobImpl::File(FileBlob {
+ id: id.clone(),
+ name: None,
+ cache: DOMRefCell::new(Some(bytes.to_vec())),
+ size: bytes.len() as u64,
+ });
+ id
+ }
// Dummy id
- Err(_) => SelectedFileId("".to_string()),
+ Err(_) => SelectedFileId(Uuid::new_v4().simple().to_string()),
}
}
/// Get a FileID representing sliced parent-blob content
fn create_sliced_url_id(&self, parent_id: &SelectedFileId,
- rel_pos: &RelativePos) -> SelectedFileId {
+ rel_pos: &RelativePos, parent_len: u64) -> SelectedFileId {
let global = self.global();
let origin = get_blob_origin(&global.r().get_url());
- let filemanager = global.r().resource_threads().sender();
let (tx, rx) = ipc::channel().unwrap();
let msg = FileManagerThreadMsg::AddSlicedURLEntry(parent_id.clone(),
rel_pos.clone(),
tx, origin.clone());
- let _ = filemanager.send(msg);
- let new_id = rx.recv().unwrap().unwrap();
-
- // Return the indirect id reference
- SelectedFileId(new_id.0)
+ self.send_to_file_manager(msg);
+ match rx.recv().expect("File manager thread is down") {
+ Ok(new_id) => {
+ let new_id = SelectedFileId(new_id.0);
+
+ *self.blob_impl.borrow_mut() = BlobImpl::File(FileBlob {
+ id: new_id.clone(),
+ name: None,
+ cache: DOMRefCell::new(None),
+ size: rel_pos.to_abs_range(parent_len as usize).len() as u64,
+ });
+
+ // Return the indirect id reference
+ new_id
+ }
+ Err(_) => {
+ // Return dummy id
+ SelectedFileId(Uuid::new_v4().simple().to_string())
+ }
+ }
}
/// Cleanups at the time of destruction/closing
@@ -259,14 +284,19 @@ impl Blob {
let global = self.global();
let origin = get_blob_origin(&global.r().get_url());
- let filemanager = global.r().resource_threads().sender();
let (tx, rx) = ipc::channel().unwrap();
let msg = FileManagerThreadMsg::DecRef(f.id.clone(), origin, tx);
- let _ = filemanager.send(msg);
+ self.send_to_file_manager(msg);
let _ = rx.recv().unwrap();
}
}
+
+ fn send_to_file_manager(&self, msg: FileManagerThreadMsg) {
+ let global = self.global();
+ let resource_threads = global.r().resource_threads();
+ let _ = resource_threads.send(CoreResourceMsg::ToFileManager(msg));
+ }
}
impl Drop for Blob {
@@ -278,16 +308,28 @@ impl Drop for Blob {
}
fn read_file(global: GlobalRef, id: SelectedFileId) -> Result<Vec<u8>, ()> {
- let file_manager = global.filemanager_thread();
+ let resource_threads = global.resource_threads();
let (chan, recv) = ipc::channel().map_err(|_|())?;
let origin = get_blob_origin(&global.get_url());
let check_url_validity = false;
let msg = FileManagerThreadMsg::ReadFile(chan, id, check_url_validity, origin);
- let _ = file_manager.send(msg);
+ let _ = resource_threads.send(CoreResourceMsg::ToFileManager(msg));
+
+ let mut bytes = vec![];
- match recv.recv().unwrap() {
- Ok(blob_buf) => Ok(blob_buf.bytes),
- Err(_) => Err(()),
+ loop {
+ match recv.recv().unwrap() {
+ Ok(ReadFileProgress::Meta(mut blob_buf)) => {
+ bytes.append(&mut blob_buf.bytes);
+ }
+ Ok(ReadFileProgress::Partial(mut bytes_in)) => {
+ bytes.append(&mut bytes_in);
+ }
+ Ok(ReadFileProgress::EOF) => {
+ return Ok(bytes);
+ }
+ Err(_) => return Err(()),
+ }
}
}
@@ -379,11 +421,3 @@ fn is_ascii_printable(string: &str) -> bool {
// https://w3c.github.io/FileAPI/#constructorBlob
string.chars().all(|c| c >= '\x20' && c <= '\x7E')
}
-
-/// Bump the reference counter in file manager thread
-fn inc_ref_id(global: GlobalRef, id: SelectedFileId) {
- let file_manager = global.filemanager_thread();
- let origin = get_blob_origin(&global.get_url());
- let msg = FileManagerThreadMsg::IncRef(id, origin);
- let _ = file_manager.send(msg);
-}
diff --git a/components/script/dom/bluetooth.rs b/components/script/dom/bluetooth.rs
index 7deca26c9d3..c86fa0150a3 100644
--- a/components/script/dom/bluetooth.rs
+++ b/components/script/dom/bluetooth.rs
@@ -7,7 +7,7 @@ use core::clone::Clone;
use dom::bindings::codegen::Bindings::BluetoothBinding;
use dom::bindings::codegen::Bindings::BluetoothBinding::RequestDeviceOptions;
use dom::bindings::codegen::Bindings::BluetoothBinding::{BluetoothScanFilter, BluetoothMethods};
-use dom::bindings::error::Error::{Security, Type};
+use dom::bindings::error::Error::{self, Security, Type};
use dom::bindings::error::Fallible;
use dom::bindings::global::GlobalRef;
use dom::bindings::js::Root;
@@ -19,7 +19,7 @@ use dom::bluetoothuuid::BluetoothUUID;
use ipc_channel::ipc::{self, IpcSender};
use net_traits::bluetooth_scanfilter::{BluetoothScanfilter, BluetoothScanfilterSequence};
use net_traits::bluetooth_scanfilter::{RequestDeviceoptions, ServiceUUIDSequence};
-use net_traits::bluetooth_thread::BluetoothMethodMsg;
+use net_traits::bluetooth_thread::{BluetoothError, BluetoothMethodMsg};
const FILTER_EMPTY_ERROR: &'static str = "'filters' member must be non - empty to find any devices.";
const FILTER_ERROR: &'static str = "A filter must restrict the devices in some way.";
@@ -135,6 +135,18 @@ fn convert_request_device_options(options: &RequestDeviceOptions,
ServiceUUIDSequence::new(optional_services)))
}
+impl From<BluetoothError> for Error {
+ fn from(error: BluetoothError) -> Self {
+ match error {
+ BluetoothError::Type(message) => Error::Type(message),
+ BluetoothError::Network => Error::Network,
+ BluetoothError::NotFound => Error::NotFound,
+ BluetoothError::NotSupported => Error::NotSupported,
+ BluetoothError::Security => Error::Security,
+ }
+ }
+}
+
impl BluetoothMethods for Bluetooth {
// https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetooth-requestdevice
fn RequestDevice(&self, option: &RequestDeviceOptions) -> Fallible<Root<BluetoothDevice>> {
@@ -154,7 +166,7 @@ impl BluetoothMethods for Bluetooth {
&ad_data))
},
Err(error) => {
- Err(Type(error))
+ Err(Error::from(error))
},
}
}
diff --git a/components/script/dom/bluetoothremotegattcharacteristic.rs b/components/script/dom/bluetoothremotegattcharacteristic.rs
index e3e17b4a0f9..0c27097625c 100644
--- a/components/script/dom/bluetoothremotegattcharacteristic.rs
+++ b/components/script/dom/bluetoothremotegattcharacteristic.rs
@@ -12,7 +12,7 @@ use dom::bindings::codegen::Bindings::BluetoothRemoteGATTCharacteristicBinding::
BluetoothRemoteGATTCharacteristicMethods;
use dom::bindings::codegen::Bindings::BluetoothRemoteGATTServerBinding::BluetoothRemoteGATTServerMethods;
use dom::bindings::codegen::Bindings::BluetoothRemoteGATTServiceBinding::BluetoothRemoteGATTServiceMethods;
-use dom::bindings::error::Error::{InvalidModification, Network, NotSupported, Security, Type};
+use dom::bindings::error::Error::{self, InvalidModification, Network, NotSupported, Security};
use dom::bindings::error::{Fallible, ErrorResult};
use dom::bindings::global::GlobalRef;
use dom::bindings::js::{JS, MutHeap, Root};
@@ -115,7 +115,7 @@ impl BluetoothRemoteGATTCharacteristicMethods for BluetoothRemoteGATTCharacteris
descriptor.instance_id))
},
Err(error) => {
- Err(Type(error))
+ Err(Error::from(error))
},
}
}
@@ -147,7 +147,7 @@ impl BluetoothRemoteGATTCharacteristicMethods for BluetoothRemoteGATTCharacteris
.collect())
},
Err(error) => {
- Err(Type(error))
+ Err(Error::from(error))
},
}
}
@@ -177,7 +177,7 @@ impl BluetoothRemoteGATTCharacteristicMethods for BluetoothRemoteGATTCharacteris
ByteString::new(val)
},
Err(error) => {
- return Err(Type(error))
+ return Err(Error::from(error))
},
};
*self.value.borrow_mut() = Some(value.clone());
@@ -195,6 +195,12 @@ impl BluetoothRemoteGATTCharacteristicMethods for BluetoothRemoteGATTCharacteris
if !self.Service().Device().Gatt().Connected() {
return Err(Network)
}
+
+ if !(self.Properties().Write() ||
+ self.Properties().WriteWithoutResponse() ||
+ self.Properties().AuthenticatedSignedWrites()) {
+ return Err(NotSupported)
+ }
let (sender, receiver) = ipc::channel().unwrap();
self.get_bluetooth_thread().send(
BluetoothMethodMsg::WriteValue(self.get_instance_id(), value, sender)).unwrap();
@@ -202,7 +208,7 @@ impl BluetoothRemoteGATTCharacteristicMethods for BluetoothRemoteGATTCharacteris
match result {
Ok(_) => Ok(()),
Err(error) => {
- Err(Type(error))
+ Err(Error::from(error))
},
}
}
diff --git a/components/script/dom/bluetoothremotegattdescriptor.rs b/components/script/dom/bluetoothremotegattdescriptor.rs
index f821d4aca2d..0ba52181b48 100644
--- a/components/script/dom/bluetoothremotegattdescriptor.rs
+++ b/components/script/dom/bluetoothremotegattdescriptor.rs
@@ -11,7 +11,7 @@ use dom::bindings::codegen::Bindings::BluetoothRemoteGATTDescriptorBinding;
use dom::bindings::codegen::Bindings::BluetoothRemoteGATTDescriptorBinding::BluetoothRemoteGATTDescriptorMethods;
use dom::bindings::codegen::Bindings::BluetoothRemoteGATTServerBinding::BluetoothRemoteGATTServerMethods;
use dom::bindings::codegen::Bindings::BluetoothRemoteGATTServiceBinding::BluetoothRemoteGATTServiceMethods;
-use dom::bindings::error::Error::{InvalidModification, Network, Security, Type};
+use dom::bindings::error::Error::{self, InvalidModification, Network, Security};
use dom::bindings::error::{Fallible, ErrorResult};
use dom::bindings::global::GlobalRef;
use dom::bindings::js::{JS, MutHeap, Root};
@@ -101,7 +101,7 @@ impl BluetoothRemoteGATTDescriptorMethods for BluetoothRemoteGATTDescriptor {
ByteString::new(val)
},
Err(error) => {
- return Err(Type(error))
+ return Err(Error::from(error))
},
};
*self.value.borrow_mut() = Some(value.clone());
@@ -126,7 +126,7 @@ impl BluetoothRemoteGATTDescriptorMethods for BluetoothRemoteGATTDescriptor {
match result {
Ok(_) => Ok(()),
Err(error) => {
- Err(Type(error))
+ Err(Error::from(error))
},
}
}
diff --git a/components/script/dom/bluetoothremotegattserver.rs b/components/script/dom/bluetoothremotegattserver.rs
index 56aad1b8bf6..f4b1e532f10 100644
--- a/components/script/dom/bluetoothremotegattserver.rs
+++ b/components/script/dom/bluetoothremotegattserver.rs
@@ -6,7 +6,7 @@ use bluetooth_blacklist::{Blacklist, uuid_is_blacklisted};
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::{Security, Type};
+use dom::bindings::error::Error::{self, Security};
use dom::bindings::error::{Fallible, ErrorResult};
use dom::bindings::global::GlobalRef;
use dom::bindings::js::{JS, MutHeap, Root};
@@ -72,7 +72,7 @@ impl BluetoothRemoteGATTServerMethods for BluetoothRemoteGATTServer {
Ok(Root::from_ref(self))
},
Err(error) => {
- Err(Type(error))
+ Err(Error::from(error))
},
}
}
@@ -89,7 +89,7 @@ impl BluetoothRemoteGATTServerMethods for BluetoothRemoteGATTServer {
Ok(())
},
Err(error) => {
- Err(Type(error))
+ Err(Error::from(error))
},
}
}
@@ -113,7 +113,7 @@ impl BluetoothRemoteGATTServerMethods for BluetoothRemoteGATTServer {
service.instance_id))
},
Err(error) => {
- Err(Type(error))
+ Err(Error::from(error))
},
}
}
@@ -146,7 +146,7 @@ impl BluetoothRemoteGATTServerMethods for BluetoothRemoteGATTServer {
.collect())
},
Err(error) => {
- Err(Type(error))
+ Err(Error::from(error))
},
}
}
diff --git a/components/script/dom/bluetoothremotegattservice.rs b/components/script/dom/bluetoothremotegattservice.rs
index f0954a1c76f..5b80bc6afc0 100644
--- a/components/script/dom/bluetoothremotegattservice.rs
+++ b/components/script/dom/bluetoothremotegattservice.rs
@@ -5,7 +5,7 @@
use bluetooth_blacklist::{Blacklist, uuid_is_blacklisted};
use dom::bindings::codegen::Bindings::BluetoothRemoteGATTServiceBinding;
use dom::bindings::codegen::Bindings::BluetoothRemoteGATTServiceBinding::BluetoothRemoteGATTServiceMethods;
-use dom::bindings::error::Error::{Security, Type};
+use dom::bindings::error::Error::{self, Security};
use dom::bindings::error::Fallible;
use dom::bindings::global::GlobalRef;
use dom::bindings::js::{JS, MutHeap, Root};
@@ -115,7 +115,7 @@ impl BluetoothRemoteGATTServiceMethods for BluetoothRemoteGATTService {
characteristic.instance_id))
},
Err(error) => {
- Err(Type(error))
+ Err(Error::from(error))
},
}
}
@@ -160,7 +160,7 @@ impl BluetoothRemoteGATTServiceMethods for BluetoothRemoteGATTService {
Ok(characteristics)
},
Err(error) => {
- Err(Type(error))
+ Err(Error::from(error))
},
}
}
@@ -188,7 +188,7 @@ impl BluetoothRemoteGATTServiceMethods for BluetoothRemoteGATTService {
service.instance_id))
},
Err(error) => {
- Err(Type(error))
+ Err(Error::from(error))
},
}
}
@@ -223,7 +223,7 @@ impl BluetoothRemoteGATTServiceMethods for BluetoothRemoteGATTService {
.collect())
},
Err(error) => {
- Err(Type(error))
+ Err(Error::from(error))
},
}
}
diff --git a/components/script/dom/browsingcontext.rs b/components/script/dom/browsingcontext.rs
index 4c0914ddf3c..878d376ca66 100644
--- a/components/script/dom/browsingcontext.rs
+++ b/components/script/dom/browsingcontext.rs
@@ -22,7 +22,7 @@ use js::jsapi::{Handle, HandleId, HandleObject, HandleValue, JSAutoCompartment};
use js::jsapi::{JSContext, JSPROP_READONLY, JSErrNum, JSObject, PropertyDescriptor, JS_DefinePropertyById};
use js::jsapi::{JS_ForwardGetPropertyTo, JS_ForwardSetPropertyTo, JS_GetClass, JSTracer, FreeOp};
use js::jsapi::{JS_GetOwnPropertyDescriptorById, JS_HasPropertyById, MutableHandle};
-use js::jsapi::{MutableHandleValue, ObjectOpResult};
+use js::jsapi::{MutableHandleObject, MutableHandleValue, ObjectOpResult};
use js::jsval::{UndefinedValue, PrivateValue};
use msg::constellation_msg::{PipelineId, SubpageId};
use std::cell::Cell;
@@ -354,6 +354,28 @@ unsafe extern "C" fn set(cx: *mut JSContext,
res)
}
+#[allow(unsafe_code)]
+unsafe extern "C" fn get_prototype_if_ordinary(_: *mut JSContext,
+ _: HandleObject,
+ is_ordinary: *mut bool,
+ _: MutableHandleObject)
+ -> bool {
+ // Window's [[GetPrototypeOf]] trap isn't the ordinary definition:
+ //
+ // https://html.spec.whatwg.org/multipage/#windowproxy-getprototypeof
+ //
+ // We nonetheless can implement it with a static [[Prototype]], because
+ // wrapper-class handlers (particularly, XOW in FilteringWrapper.cpp) supply
+ // all non-ordinary behavior.
+ //
+ // But from a spec point of view, it's the exact same object in both cases --
+ // only the observer's changed. So this getPrototypeIfOrdinary trap on the
+ // non-wrapper object *must* report non-ordinary, even if static [[Prototype]]
+ // usually means ordinary.
+ *is_ordinary = false;
+ return true;
+}
+
static PROXY_HANDLER: ProxyTraps = ProxyTraps {
enter: None,
getOwnPropertyDescriptor: Some(getOwnPropertyDescriptor),
@@ -361,6 +383,7 @@ static PROXY_HANDLER: ProxyTraps = ProxyTraps {
ownPropertyKeys: None,
delete_: None,
enumerate: None,
+ getPrototypeIfOrdinary: Some(get_prototype_if_ordinary),
preventExtensions: None,
isExtensible: None,
has: Some(has),
diff --git a/components/script/dom/dedicatedworkerglobalscope.rs b/components/script/dom/dedicatedworkerglobalscope.rs
index b65fd72ab62..dfe385f0696 100644
--- a/components/script/dom/dedicatedworkerglobalscope.rs
+++ b/components/script/dom/dedicatedworkerglobalscope.rs
@@ -218,7 +218,7 @@ impl DedicatedWorkerGlobalScope {
scope.execute_script(DOMString::from(source));
}
- let reporter_name = format!("worker-reporter-{}", random::<u64>());
+ let reporter_name = format!("dedicated-worker-reporter-{}", random::<u64>());
scope.mem_profiler_chan().run_with_memory_reporting(|| {
while let Ok(event) = global.receive_event() {
if scope.is_closing() {
@@ -307,7 +307,7 @@ impl DedicatedWorkerGlobalScope {
let path_seg = format!("url({})", scope.get_url());
let reports = get_reports(cx, path_seg);
reports_chan.send(reports);
- },
+ }
}
}
@@ -370,6 +370,12 @@ impl DedicatedWorkerGlobalScopeMethods for DedicatedWorkerGlobalScope {
Ok(())
}
+ // https://html.spec.whatwg.org/multipage/#dom-dedicatedworkerglobalscope-close
+ fn Close(&self) {
+ // Step 2
+ self.upcast::<WorkerGlobalScope>().close();
+ }
+
// https://html.spec.whatwg.org/multipage/#handler-dedicatedworkerglobalscope-onmessage
event_handler!(message, GetOnmessage, SetOnmessage);
}
diff --git a/components/script/dom/document.rs b/components/script/dom/document.rs
index 28edce553ad..78ccbbdf1f5 100644
--- a/components/script/dom/document.rs
+++ b/components/script/dom/document.rs
@@ -376,6 +376,7 @@ impl Document {
// that workable.
match self.GetDocumentElement() {
Some(root) => {
+ root.upcast::<Node>().is_dirty() ||
root.upcast::<Node>().has_dirty_descendants() ||
!self.modified_elements.borrow().is_empty()
}
@@ -1371,6 +1372,7 @@ impl Document {
}
pub fn finish_load(&self, load: LoadType) {
+ debug!("Document got finish_load: {:?}", load);
// The parser might need the loader, so restrict the lifetime of the borrow.
{
let mut loader = self.loader.borrow_mut();
@@ -1396,9 +1398,9 @@ impl Document {
// If we don't have a parser, and the reflow timer has been reset, explicitly
// trigger a reflow.
if let LoadType::Stylesheet(_) = load {
- self.window().reflow(ReflowGoal::ForDisplay,
- ReflowQueryType::NoQuery,
- ReflowReason::StylesheetLoaded);
+ self.window.reflow(ReflowGoal::ForDisplay,
+ ReflowQueryType::NoQuery,
+ ReflowReason::StylesheetLoaded);
}
}
@@ -1487,24 +1489,25 @@ impl Document {
return;
}
self.domcontentloaded_dispatched.set(true);
+ assert!(self.ReadyState() != DocumentReadyState::Complete,
+ "Complete before DOMContentLoaded?");
update_with_current_time_ms(&self.dom_content_loaded_event_start);
let window = self.window();
window.dom_manipulation_task_source().queue_event(self.upcast(), atom!("DOMContentLoaded"),
EventBubbles::Bubbles, EventCancelable::NotCancelable, window);
+
window.reflow(ReflowGoal::ForDisplay,
ReflowQueryType::NoQuery,
ReflowReason::DOMContentLoaded);
-
update_with_current_time_ms(&self.dom_content_loaded_event_end);
}
pub fn notify_constellation_load(&self) {
let pipeline_id = self.window.pipeline();
- let event = ConstellationMsg::DOMLoad(pipeline_id);
- self.window.constellation_chan().send(event).unwrap();
-
+ let load_event = ConstellationMsg::LoadComplete(pipeline_id);
+ self.window.constellation_chan().send(load_event).unwrap();
}
pub fn set_current_parser(&self, script: Option<ParserRef>) {
@@ -2908,16 +2911,18 @@ impl DocumentProgressHandler {
// http://w3c.github.io/navigation-timing/#widl-PerformanceNavigationTiming-loadEventStart
update_with_current_time_ms(&document.load_event_start);
+ debug!("About to dispatch load for {:?}", document.url());
let _ = wintarget.dispatch_event_with_target(document.upcast(), &event);
// http://w3c.github.io/navigation-timing/#widl-PerformanceNavigationTiming-loadEventEnd
update_with_current_time_ms(&document.load_event_end);
- document.notify_constellation_load();
window.reflow(ReflowGoal::ForDisplay,
ReflowQueryType::NoQuery,
ReflowReason::DocumentLoaded);
+
+ document.notify_constellation_load();
}
}
diff --git a/components/script/dom/element.rs b/components/script/dom/element.rs
index a4c1ed28583..ae3c31d151c 100644
--- a/components/script/dom/element.rs
+++ b/components/script/dom/element.rs
@@ -347,7 +347,8 @@ impl LayoutElementHelpers for LayoutJS<Element> {
if let Some(url) = background {
hints.push(from_declaration(
PropertyDeclaration::BackgroundImage(DeclaredValue::Value(
- background_image::SpecifiedValue(Some(specified::Image::Url(url)))))));
+ background_image::SpecifiedValue(Some(
+ specified::Image::Url(url, specified::UrlExtraData { })))))));
}
let color = if let Some(this) = self.downcast::<HTMLFontElement>() {
diff --git a/components/script/dom/file.rs b/components/script/dom/file.rs
index 4528a116e45..f9b181dbf1a 100644
--- a/components/script/dom/file.rs
+++ b/components/script/dom/file.rs
@@ -73,7 +73,10 @@ impl File {
let ref typeString = blobPropertyBag.type_;
let modified = filePropertyBag.lastModified;
- Ok(File::new(global, BlobImpl::new_from_bytes(bytes), filename, modified, typeString))
+ // NOTE: Following behaviour might be removed in future,
+ // see https://github.com/w3c/FileAPI/issues/41
+ let replaced_filename = DOMString::from_string(filename.replace("/", ":"));
+ Ok(File::new(global, BlobImpl::new_from_bytes(bytes), replaced_filename, modified, typeString))
}
pub fn name(&self) -> &DOMString {
diff --git a/components/script/dom/filelist.rs b/components/script/dom/filelist.rs
index 96bfc4ce0d3..4f8e976f5f7 100644
--- a/components/script/dom/filelist.rs
+++ b/components/script/dom/filelist.rs
@@ -9,6 +9,7 @@ use dom::bindings::js::{JS, Root};
use dom::bindings::reflector::{Reflector, reflect_dom_object};
use dom::file::File;
use dom::window::Window;
+use std::slice::Iter;
// https://w3c.github.io/FileAPI/#dfn-filelist
#[dom_struct]
@@ -32,6 +33,10 @@ impl FileList {
GlobalRef::Window(window),
FileListBinding::Wrap)
}
+
+ pub fn iter_files(&self) -> Iter<JS<File>> {
+ self.list.iter()
+ }
}
impl FileListMethods for FileList {
diff --git a/components/script/dom/filereadersync.rs b/components/script/dom/filereadersync.rs
new file mode 100644
index 00000000000..b248848edad
--- /dev/null
+++ b/components/script/dom/filereadersync.rs
@@ -0,0 +1,34 @@
+/* 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::FileReaderSyncBinding;
+use dom::bindings::error::Fallible;
+use dom::bindings::global::GlobalRef;
+use dom::bindings::js::Root;
+use dom::bindings::reflector::reflect_dom_object;
+use dom::eventtarget::EventTarget;
+
+
+
+#[dom_struct]
+pub struct FileReaderSync {
+ eventtarget: EventTarget
+}
+
+impl FileReaderSync {
+ pub fn new_inherited() -> FileReaderSync {
+ FileReaderSync {
+ eventtarget: EventTarget::new_inherited(),
+ }
+ }
+
+ pub fn new(global: GlobalRef) -> Root<FileReaderSync> {
+ reflect_dom_object(box FileReaderSync::new_inherited(),
+ global, FileReaderSyncBinding::Wrap)
+ }
+
+ pub fn Constructor(global: GlobalRef) -> Fallible<Root<FileReaderSync>> {
+ Ok(FileReaderSync::new(global))
+ }
+}
diff --git a/components/script/dom/headers.rs b/components/script/dom/headers.rs
index e97edc00572..4ae212aee78 100644
--- a/components/script/dom/headers.rs
+++ b/components/script/dom/headers.rs
@@ -5,12 +5,13 @@
use dom::bindings::cell::DOMRefCell;
use dom::bindings::codegen::Bindings::HeadersBinding;
use dom::bindings::codegen::Bindings::HeadersBinding::HeadersMethods;
-use dom::bindings::error::Error;
+use dom::bindings::codegen::UnionTypes::HeadersOrByteStringSequenceSequence;
+use dom::bindings::error::{Error, ErrorResult, Fallible};
use dom::bindings::global::GlobalRef;
use dom::bindings::js::Root;
use dom::bindings::reflector::{Reflector, reflect_dom_object};
use dom::bindings::str::{ByteString, is_token};
-use hyper;
+use hyper::header::Headers as HyperHeaders;
use std::result::Result;
#[dom_struct]
@@ -18,7 +19,7 @@ pub struct Headers {
reflector_: Reflector,
guard: Guard,
#[ignore_heap_size_of = "Defined in hyper"]
- header_list: DOMRefCell<hyper::header::Headers>
+ header_list: DOMRefCell<HyperHeaders>
}
// https://fetch.spec.whatwg.org/#concept-headers-guard
@@ -36,12 +37,50 @@ impl Headers {
Headers {
reflector_: Reflector::new(),
guard: Guard::None,
- header_list: DOMRefCell::new(hyper::header::Headers::new()),
+ header_list: DOMRefCell::new(HyperHeaders::new()),
}
}
- pub fn new(global: GlobalRef) -> Root<Headers> {
- reflect_dom_object(box Headers::new_inherited(), global, HeadersBinding::Wrap)
+ // https://fetch.spec.whatwg.org/#concept-headers-fill
+ pub fn new(global: GlobalRef, init: Option<HeadersBinding::HeadersInit>)
+ -> Fallible<Root<Headers>> {
+ let dom_headers_new = reflect_dom_object(box Headers::new_inherited(), global, HeadersBinding::Wrap);
+ match init {
+ // Step 1
+ Some(HeadersOrByteStringSequenceSequence::Headers(h)) => {
+ // header_list_copy has type hyper::header::Headers
+ let header_list_copy = h.header_list.clone();
+ for header in header_list_copy.borrow().iter() {
+ try!(dom_headers_new.Append(
+ ByteString::new(Vec::from(header.name())),
+ ByteString::new(Vec::from(header.value_string().into_bytes()))
+ ));
+ }
+ Ok(dom_headers_new)
+ },
+ // Step 2
+ Some(HeadersOrByteStringSequenceSequence::ByteStringSequenceSequence(v)) => {
+ for mut seq in v {
+ if seq.len() == 2 {
+ let val = seq.pop().unwrap();
+ let name = seq.pop().unwrap();
+ try!(dom_headers_new.Append(name, val));
+ } else {
+ return Err(Error::Type(
+ format!("Each header object must be a sequence of length 2 - found one with length {}",
+ seq.len())));
+ }
+ }
+ Ok(dom_headers_new)
+ },
+ // Step 3 TODO constructor for when init is an open-ended dictionary
+ None => Ok(dom_headers_new),
+ }
+ }
+
+ pub fn Constructor(global: GlobalRef, init: Option<HeadersBinding::HeadersInit>)
+ -> Fallible<Root<Headers>> {
+ Headers::new(global, init)
}
}
@@ -50,32 +89,102 @@ impl HeadersMethods for Headers {
fn Append(&self, name: ByteString, value: ByteString) -> Result<(), Error> {
// Step 1
let value = normalize_value(value);
-
// Step 2
- let (valid_name, valid_value) = try!(validate_name_and_value(name, value));
+ let (mut valid_name, valid_value) = try!(validate_name_and_value(name, value));
+ valid_name = valid_name.to_lowercase();
// Step 3
if self.guard == Guard::Immutable {
return Err(Error::Type("Guard is immutable".to_string()));
}
-
// Step 4
if self.guard == Guard::Request && is_forbidden_header_name(&valid_name) {
return Ok(());
}
-
// Step 5
if self.guard == Guard::RequestNoCors && !is_cors_safelisted_request_header(&valid_name) {
return Ok(());
}
-
// Step 6
if self.guard == Guard::Response && is_forbidden_response_header(&valid_name) {
return Ok(());
}
+ // Step 7
+ let mut combined_value = self.header_list.borrow_mut().get_raw(&valid_name).unwrap()[0].clone();
+ combined_value.push(b","[0]);
+ combined_value.extend(valid_value.iter().cloned());
+ self.header_list.borrow_mut().set_raw(valid_name, vec![combined_value]);
+ Ok(())
+ }
+
+ // https://fetch.spec.whatwg.org/#dom-headers-delete
+ fn Delete(&self, name: ByteString) -> ErrorResult {
+ // Step 1
+ let valid_name = try!(validate_name(name));
+ // Step 2
+ if self.guard == Guard::Immutable {
+ return Err(Error::Type("Guard is immutable".to_string()));
+ }
+ // Step 3
+ if self.guard == Guard::Request && is_forbidden_header_name(&valid_name) {
+ return Ok(());
+ }
+ // Step 4
+ if self.guard == Guard::RequestNoCors && !is_cors_safelisted_request_header(&valid_name) {
+ return Ok(());
+ }
+ // Step 5
+ if self.guard == Guard::Response && is_forbidden_response_header(&valid_name) {
+ return Ok(());
+ }
+ // Step 6
+ self.header_list.borrow_mut().remove_raw(&valid_name);
+ Ok(())
+ }
+
+ // https://fetch.spec.whatwg.org/#dom-headers-get
+ fn Get(&self, name: ByteString) -> Fallible<Option<ByteString>> {
+ // Step 1
+ let valid_name = &try!(validate_name(name));
+ Ok(self.header_list.borrow().get_raw(&valid_name).map(|v| {
+ ByteString::new(v[0].clone())
+ }))
+ }
+ // https://fetch.spec.whatwg.org/#dom-headers-has
+ fn Has(&self, name: ByteString) -> Fallible<bool> {
+ // Step 1
+ let valid_name = try!(validate_name(name));
+ // Step 2
+ Ok(self.header_list.borrow_mut().get_raw(&valid_name).is_some())
+ }
+
+ // https://fetch.spec.whatwg.org/#dom-headers-set
+ fn Set(&self, name: ByteString, value: ByteString) -> Fallible<()> {
+ // Step 1
+ let value = normalize_value(value);
+ // Step 2
+ let (mut valid_name, valid_value) = try!(validate_name_and_value(name, value));
+ valid_name = valid_name.to_lowercase();
+ // Step 3
+ if self.guard == Guard::Immutable {
+ return Err(Error::Type("Guard is immutable".to_string()));
+ }
+ // Step 4
+ if self.guard == Guard::Request && is_forbidden_header_name(&valid_name) {
+ return Ok(());
+ }
+ // Step 5
+ if self.guard == Guard::RequestNoCors && !is_cors_safelisted_request_header(&valid_name) {
+ return Ok(());
+ }
+ // Step 6
+ if self.guard == Guard::Response && is_forbidden_response_header(&valid_name) {
+ return Ok(());
+ }
// Step 7
+ // https://fetch.spec.whatwg.org/#concept-header-list-set
self.header_list.borrow_mut().set_raw(valid_name, vec![valid_value]);
- return Ok(());
+ Ok(())
}
}
@@ -130,7 +239,7 @@ pub fn is_forbidden_header_name(name: &str) -> bool {
// ISSUE 1:
// It defines a value as "a byte sequence that matches the field-content token production."
// To note, there is a difference between field-content and
-// field-value (which is made up of fied-content and obs-fold). The
+// field-value (which is made up of field-content and obs-fold). The
// current definition does not allow for obs-fold (which are white
// space and newlines) in values. So perhaps a value should be defined
// as "a byte sequence that matches the field-value token production."
@@ -147,14 +256,19 @@ pub fn is_forbidden_header_name(name: &str) -> bool {
// [4] https://www.rfc-editor.org/errata_search.php?rfc=7230
fn validate_name_and_value(name: ByteString, value: ByteString)
-> Result<(String, Vec<u8>), Error> {
- if !is_field_name(&name) {
- return Err(Error::Type("Name is not valid".to_string()));
- }
+ let valid_name = try!(validate_name(name));
if !is_field_content(&value) {
return Err(Error::Type("Value is not valid".to_string()));
}
+ Ok((valid_name, value.into()))
+}
+
+fn validate_name(name: ByteString) -> Result<String, Error> {
+ if !is_field_name(&name) {
+ return Err(Error::Type("Name is not valid".to_string()));
+ }
match String::from_utf8(name.into()) {
- Ok(ns) => Ok((ns, value.into())),
+ Ok(ns) => Ok(ns),
_ => Err(Error::Type("Non-UTF8 header name found".to_string())),
}
}
diff --git a/components/script/dom/history.rs b/components/script/dom/history.rs
new file mode 100644
index 00000000000..061d7616f4a
--- /dev/null
+++ b/components/script/dom/history.rs
@@ -0,0 +1,70 @@
+/* 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::HistoryBinding;
+use dom::bindings::codegen::Bindings::HistoryBinding::HistoryMethods;
+use dom::bindings::codegen::Bindings::LocationBinding::LocationMethods;
+use dom::bindings::codegen::Bindings::WindowBinding::WindowMethods;
+use dom::bindings::global::GlobalRef;
+use dom::bindings::js::{JS, Root};
+use dom::bindings::reflector::{Reflector, reflect_dom_object};
+use dom::window::Window;
+use msg::constellation_msg::TraversalDirection;
+use script_traits::ScriptMsg as ConstellationMsg;
+
+// https://html.spec.whatwg.org/multipage/#the-history-interface
+#[dom_struct]
+pub struct History {
+ reflector_: Reflector,
+ window: JS<Window>,
+}
+
+impl History {
+ pub fn new_inherited(window: &Window) -> History {
+ History {
+ reflector_: Reflector::new(),
+ window: JS::from_ref(&window),
+ }
+ }
+
+ pub fn new(window: &Window) -> Root<History> {
+ reflect_dom_object(box History::new_inherited(window),
+ GlobalRef::Window(window),
+ HistoryBinding::Wrap)
+ }
+}
+
+impl History {
+ fn traverse_history(&self, direction: TraversalDirection) {
+ let pipeline = self.window.pipeline();
+ let msg = ConstellationMsg::TraverseHistory(Some(pipeline), direction);
+ let _ = self.window.constellation_chan().send(msg);
+ }
+}
+
+impl HistoryMethods for History {
+ // https://html.spec.whatwg.org/multipage/#dom-history-go
+ fn Go(&self, delta: i32) {
+ let direction = if delta > 0 {
+ TraversalDirection::Forward(delta as usize)
+ } else if delta < 0 {
+ TraversalDirection::Back(-delta as usize)
+ } else {
+ self.window.Location().Reload();
+ return;
+ };
+
+ self.traverse_history(direction);
+ }
+
+ // https://html.spec.whatwg.org/multipage/#dom-history-back
+ fn Back(&self) {
+ self.traverse_history(TraversalDirection::Back(1));
+ }
+
+ // https://html.spec.whatwg.org/multipage/#dom-history-forward
+ fn Forward(&self) {
+ self.traverse_history(TraversalDirection::Forward(1));
+ }
+}
diff --git a/components/script/dom/htmlcollection.rs b/components/script/dom/htmlcollection.rs
index 798d0731b2c..95134556bc0 100644
--- a/components/script/dom/htmlcollection.rs
+++ b/components/script/dom/htmlcollection.rs
@@ -248,7 +248,7 @@ impl<'a> Iterator for HTMLCollectionElementsIter<'a> {
.filter_map(Root::downcast)
.filter(|element| filter.filter(&element, root))
.next()
- }
+ }
}
impl HTMLCollectionMethods for HTMLCollection {
diff --git a/components/script/dom/htmlformelement.rs b/components/script/dom/htmlformelement.rs
index 9d7ce208ee2..72b8cc19c16 100644
--- a/components/script/dom/htmlformelement.rs
+++ b/components/script/dom/htmlformelement.rs
@@ -37,11 +37,9 @@ use dom::htmlselectelement::HTMLSelectElement;
use dom::htmltextareaelement::HTMLTextAreaElement;
use dom::node::{Node, document_from_node, window_from_node};
use dom::virtualmethods::VirtualMethods;
-use dom::window::Window;
use encoding::EncodingRef;
use encoding::all::UTF_8;
use encoding::label::encoding_from_whatwg_label;
-use encoding::types::DecoderTrap;
use hyper::header::{Charset, ContentDisposition, ContentType, DispositionParam, DispositionType};
use hyper::method::Method;
use msg::constellation_msg::{LoadData, PipelineId};
@@ -54,7 +52,6 @@ use string_cache::Atom;
use style::attr::AttrValue;
use style::str::split_html_space_chars;
use task_source::TaskSource;
-use url::form_urlencoded;
#[derive(JSTraceable, PartialEq, Clone, Copy, HeapSizeOf)]
pub struct GenerationId(u32);
@@ -280,39 +277,38 @@ impl HTMLFormElement {
// https://html.spec.whatwg.org/multipage/#multipart/form-data-encoding-algorithm
fn encode_multipart_form_data(&self, form_data: &mut Vec<FormDatum>,
- encoding: Option<EncodingRef>,
- boundary: String) -> String {
+ boundary: String, encoding: EncodingRef) -> Vec<u8> {
// Step 1
- let mut result = "".to_owned();
+ let mut result = vec![];
// Step 2
- // (maybe take encoding as input)
- let encoding = encoding.unwrap_or(self.pick_encoding());
-
- // Step 3
let charset = &*encoding.whatwg_name().unwrap_or("UTF-8");
- // Step 4
+ // Step 3
for entry in form_data.iter_mut() {
- // Substep 1
+ // 3.1
if entry.name == "_charset_" && entry.ty == "hidden" {
entry.value = FormDatumValue::String(DOMString::from(charset.clone()));
}
- // TODO: Substep 2
+ // TODO: 3.2
- // Step 5
+ // Step 4
// https://tools.ietf.org/html/rfc7578#section-4
- result.push_str(&*format!("\r\n--{}\r\n", boundary));
+ // NOTE(izgzhen): The encoding here expected by most servers seems different from
+ // what spec says (that it should start with a '\r\n').
+ let mut boundary_bytes = format!("--{}\r\n", boundary).into_bytes();
+ result.append(&mut boundary_bytes);
let mut content_disposition = ContentDisposition {
disposition: DispositionType::Ext("form-data".to_owned()),
parameters: vec![DispositionParam::Ext("name".to_owned(), String::from(entry.name.clone()))]
};
match entry.value {
- FormDatumValue::String(ref s) =>
- result.push_str(&*format!("Content-Disposition: {}\r\n\r\n{}",
- content_disposition,
- s)),
+ FormDatumValue::String(ref s) => {
+ let mut bytes = format!("Content-Disposition: {}\r\n\r\n{}",
+ content_disposition, s).into_bytes();
+ result.append(&mut bytes);
+ }
FormDatumValue::File(ref f) => {
content_disposition.parameters.push(
DispositionParam::Filename(Charset::Ext(String::from(charset.clone())),
@@ -321,20 +317,20 @@ impl HTMLFormElement {
// https://tools.ietf.org/html/rfc7578#section-4.4
let content_type = ContentType(f.upcast::<Blob>().Type()
.parse().unwrap_or(mime!(Text / Plain)));
- result.push_str(&*format!("Content-Disposition: {}\r\n{}\r\n\r\n",
- content_disposition,
- content_type));
+ let mut type_bytes = format!("Content-Disposition: {}\r\n{}\r\n\r\n",
+ content_disposition,
+ content_type).into_bytes();
+ result.append(&mut type_bytes);
- let bytes = &f.upcast::<Blob>().get_bytes().unwrap_or(vec![])[..];
+ let mut bytes = f.upcast::<Blob>().get_bytes().unwrap_or(vec![]);
- let decoded = encoding.decode(bytes, DecoderTrap::Replace)
- .expect("Invalid encoding in file");
- result.push_str(&decoded);
+ result.append(&mut bytes);
}
}
}
- result.push_str(&*format!("\r\n--{}--", boundary));
+ let mut boundary_bytes = format!("\r\n--{}--", boundary).into_bytes();
+ result.append(&mut boundary_bytes);
result
}
@@ -351,18 +347,11 @@ impl HTMLFormElement {
let charset = &*encoding.whatwg_name().unwrap();
for entry in form_data.iter_mut() {
- // Step 4
- if entry.name == "_charset_" && entry.ty == "hidden" {
- entry.value = FormDatumValue::String(DOMString::from(charset.clone()));
- }
-
- // Step 5
- if entry.ty == "file" {
- entry.value = FormDatumValue::String(DOMString::from(entry.value_str()));
- }
+ // Step 4, 5
+ let value = entry.replace_value(charset);
// Step 6
- result.push_str(&*format!("{}={}\r\n", entry.name, entry.value_str()));
+ result.push_str(&*format!("{}={}\r\n", entry.name, value));
}
// Step 7
@@ -374,7 +363,7 @@ impl HTMLFormElement {
// Step 1
let doc = document_from_node(self);
let base = doc.url();
- // TODO: Handle browsing contexts
+ // TODO: Handle browsing contexts (Step 2, 3)
// Step 4
if submit_method_flag == SubmittedFrom::NotFromForm &&
!submitter.no_validate(self)
@@ -397,13 +386,18 @@ impl HTMLFormElement {
}
// Step 6
let mut form_data = self.get_form_dataset(Some(submitter));
+
// Step 7
- let mut action = submitter.action();
+ let encoding = self.pick_encoding();
+
// Step 8
+ let mut action = submitter.action();
+
+ // Step 9
if action.is_empty() {
action = DOMString::from(base.as_str());
}
- // Step 9-11
+ // Step 10-11
let action_components = match base.join(&action) {
Ok(url) => url,
Err(_) => return
@@ -417,57 +411,87 @@ impl HTMLFormElement {
let mut load_data = LoadData::new(action_components, doc.get_referrer_policy(), Some(doc.url().clone()));
- let parsed_data = match enctype {
+ // Step 18
+ match (&*scheme, method) {
+ (_, FormMethod::FormDialog) => {
+ // TODO: Submit dialog
+ // https://html.spec.whatwg.org/multipage/#submit-dialog
+ }
+ // https://html.spec.whatwg.org/multipage/#submit-mutate-action
+ ("http", FormMethod::FormGet) | ("https", FormMethod::FormGet) | ("data", FormMethod::FormGet) => {
+ load_data.headers.set(ContentType::form_url_encoded());
+ self.mutate_action_url(&mut form_data, load_data, encoding);
+ }
+ // https://html.spec.whatwg.org/multipage/#submit-body
+ ("http", FormMethod::FormPost) | ("https", FormMethod::FormPost) => {
+ load_data.method = Method::Post;
+ self.submit_entity_body(&mut form_data, load_data, enctype, encoding);
+ }
+ // https://html.spec.whatwg.org/multipage/#submit-get-action
+ ("file", _) | ("about", _) | ("data", FormMethod::FormPost) |
+ ("ftp", _) | ("javascript", _) => {
+ self.plan_to_navigate(load_data);
+ }
+ ("mailto", FormMethod::FormPost) => {
+ // TODO: Mail as body
+ // https://html.spec.whatwg.org/multipage/#submit-mailto-body
+ }
+ ("mailto", FormMethod::FormGet) => {
+ // TODO: Mail with headers
+ // https://html.spec.whatwg.org/multipage/#submit-mailto-headers
+ }
+ _ => return,
+ }
+ }
+
+ // https://html.spec.whatwg.org/multipage/#submit-mutate-action
+ fn mutate_action_url(&self, form_data: &mut Vec<FormDatum>, mut load_data: LoadData, encoding: EncodingRef) {
+ let charset = &*encoding.whatwg_name().unwrap();
+
+ load_data.url.query_pairs_mut().clear()
+ .encoding_override(Some(self.pick_encoding()))
+ .extend_pairs(form_data.into_iter()
+ .map(|field| (field.name.clone(), field.replace_value(charset))));
+
+ self.plan_to_navigate(load_data);
+ }
+
+ // https://html.spec.whatwg.org/multipage/#submit-body
+ fn submit_entity_body(&self, form_data: &mut Vec<FormDatum>, mut load_data: LoadData,
+ enctype: FormEncType, encoding: EncodingRef) {
+ let boundary = self.generate_boundary();
+ let bytes = match enctype {
FormEncType::UrlEncoded => {
+ let mut url = load_data.url.clone();
+ let charset = &*encoding.whatwg_name().unwrap();
load_data.headers.set(ContentType::form_url_encoded());
- form_urlencoded::Serializer::new(String::new())
- .encoding_override(Some(self.pick_encoding()))
- .extend_pairs(form_data.into_iter().map(|field| (field.name.clone(), field.value_str())))
- .finish()
+ url.query_pairs_mut().clear()
+ .encoding_override(Some(self.pick_encoding()))
+ .extend_pairs(form_data.into_iter()
+ .map(|field| (field.name.clone(), field.replace_value(charset))));
+
+ url.query().unwrap_or("").to_string().into_bytes()
}
FormEncType::FormDataEncoded => {
- let boundary = self.generate_boundary();
let mime = mime!(Multipart / FormData; Boundary =(&boundary));
load_data.headers.set(ContentType(mime));
-
- self.encode_multipart_form_data(&mut form_data, None, boundary)
+ self.encode_multipart_form_data(form_data, boundary, encoding)
}
FormEncType::TextPlainEncoded => {
load_data.headers.set(ContentType(mime!(Text / Plain)));
-
- self.encode_plaintext(&mut form_data)
+ self.encode_plaintext(form_data).into_bytes()
}
};
- // Step 18
- let win = window_from_node(self);
- match (&*scheme, method) {
- // https://html.spec.whatwg.org/multipage/#submit-dialog
- (_, FormMethod::FormDialog) => return, // Unimplemented
- // https://html.spec.whatwg.org/multipage/#submit-mutate-action
- ("http", FormMethod::FormGet) | ("https", FormMethod::FormGet) => {
- // FIXME(SimonSapin): use url.query_pairs_mut() here.
- load_data.url.set_query(Some(&*parsed_data));
- self.plan_to_navigate(load_data, &win);
- }
- // https://html.spec.whatwg.org/multipage/#submit-body
- ("http", FormMethod::FormPost) | ("https", FormMethod::FormPost) => {
- load_data.method = Method::Post;
- load_data.data = Some(parsed_data.into_bytes());
- self.plan_to_navigate(load_data, &win);
- }
- // https://html.spec.whatwg.org/multipage/#submit-get-action
- ("file", _) | ("about", _) | ("data", FormMethod::FormGet) |
- ("ftp", _) | ("javascript", _) => {
- self.plan_to_navigate(load_data, &win);
- }
- _ => return // Unimplemented (data and mailto)
- }
+ load_data.data = Some(bytes);
+ self.plan_to_navigate(load_data);
}
/// [Planned navigation](https://html.spec.whatwg.org/multipage/#planned-navigation)
- fn plan_to_navigate(&self, load_data: LoadData, window: &Window) {
+ fn plan_to_navigate(&self, load_data: LoadData) {
+ let window = window_from_node(self);
+
// Step 1
// Each planned navigation runnable is tagged with a generation ID, and
// before the runnable is handled, it first checks whether the HTMLFormElement's
@@ -485,7 +509,7 @@ impl HTMLFormElement {
};
// Step 3
- window.dom_manipulation_task_source().queue(nav, GlobalRef::Window(window)).unwrap();
+ window.dom_manipulation_task_source().queue(nav, GlobalRef::Window(&window)).unwrap();
}
/// Interactively validate the constraints of form elements
@@ -558,10 +582,8 @@ impl HTMLFormElement {
match element {
HTMLElementTypeId::HTMLInputElement => {
let input = child.downcast::<HTMLInputElement>().unwrap();
- // Step 3.2-3.7
- if let Some(datum) = input.form_datum(submitter) {
- data_set.push(datum);
- }
+
+ data_set.append(&mut input.form_datums(submitter));
}
HTMLElementTypeId::HTMLButtonElement => {
let button = child.downcast::<HTMLButtonElement>().unwrap();
@@ -709,10 +731,14 @@ pub struct FormDatum {
}
impl FormDatum {
- pub fn value_str(&self) -> String {
+ pub fn replace_value(&self, charset: &str) -> String {
+ if self.name == "_charset_" && self.ty == "hidden" {
+ return charset.to_string();
+ }
+
match self.value {
+ FormDatumValue::File(ref f) => String::from(f.name().clone()),
FormDatumValue::String(ref s) => String::from(s.clone()),
- FormDatumValue::File(ref f) => String::from(f.name().clone())
}
}
}
diff --git a/components/script/dom/htmlinputelement.rs b/components/script/dom/htmlinputelement.rs
index 7f524cac29d..a98fcbcfb4e 100644
--- a/components/script/dom/htmlinputelement.rs
+++ b/components/script/dom/htmlinputelement.rs
@@ -34,9 +34,9 @@ use dom::virtualmethods::VirtualMethods;
use ipc_channel::ipc::{self, IpcSender};
use mime_guess;
use msg::constellation_msg::Key;
-use net_traits::IpcSend;
use net_traits::blob_url_store::get_blob_origin;
use net_traits::filemanager_thread::{FileManagerThreadMsg, FilterPattern};
+use net_traits::{IpcSend, CoreResourceMsg};
use script_traits::ScriptMsg as ConstellationMsg;
use std::borrow::ToOwned;
use std::cell::Cell;
@@ -648,7 +648,7 @@ impl HTMLInputElement {
/// https://html.spec.whatwg.org/multipage/#constructing-the-form-data-set
/// Steps range from 3.1 to 3.7 (specific to HTMLInputElement)
- pub fn form_datum(&self, submitter: Option<FormSubmitter>) -> Option<FormDatum> {
+ pub fn form_datums(&self, submitter: Option<FormSubmitter>) -> Vec<FormDatum> {
// 3.1: disabled state check is in get_unclean_dataset
// Step 3.2
@@ -664,26 +664,55 @@ impl HTMLInputElement {
match ty {
// Step 3.1: it's a button but it is not submitter.
- atom!("submit") | atom!("button") | atom!("reset") if !is_submitter => return None,
+ atom!("submit") | atom!("button") | atom!("reset") if !is_submitter => return vec![],
// Step 3.1: it's the "Checkbox" or "Radio Button" and whose checkedness is false.
atom!("radio") | atom!("checkbox") => if !self.Checked() || name.is_empty() {
- return None;
+ return vec![];
},
+ atom!("file") => {
+ let mut datums = vec![];
+
+ // Step 3.2-3.7
+ let name = self.Name();
+ let type_ = self.Type();
+
+ match self.GetFiles() {
+ Some(fl) => {
+ for f in fl.iter_files() {
+ datums.push(FormDatum {
+ ty: type_.clone(),
+ name: name.clone(),
+ value: FormDatumValue::File(Root::from_ref(&f)),
+ });
+ }
+ }
+ None => {
+ datums.push(FormDatum {
+ // XXX(izgzhen): Spec says 'application/octet-stream' as the type,
+ // but this is _type_ of element rather than content right?
+ ty: type_.clone(),
+ name: name.clone(),
+ value: FormDatumValue::String(DOMString::from("")),
+ })
+ }
+ }
- atom!("image") | atom!("file") => return None, // Unimplemented
+ return datums;
+ }
+ atom!("image") => return vec![], // Unimplemented
// Step 3.1: it's not the "Image Button" and doesn't have a name attribute.
_ => if name.is_empty() {
- return None;
+ return vec![];
}
}
// Step 3.9
- Some(FormDatum {
+ vec![FormDatum {
ty: DOMString::from(&*ty), // FIXME(ajeffrey): Convert directly from Atoms to DOMStrings
name: name,
value: FormDatumValue::String(self.Value())
- })
+ }]
}
// https://html.spec.whatwg.org/multipage/#radio-button-group
@@ -751,7 +780,7 @@ impl HTMLInputElement {
fn select_files(&self, opt_test_paths: Option<Vec<DOMString>>) {
let window = window_from_node(self);
let origin = get_blob_origin(&window.get_url());
- let filemanager = window.resource_threads().sender();
+ let resource_threads = window.resource_threads();
let mut files: Vec<Root<File>> = vec![];
let mut error = None;
@@ -764,7 +793,7 @@ impl HTMLInputElement {
let (chan, recv) = ipc::channel().expect("Error initializing channel");
let msg = FileManagerThreadMsg::SelectFiles(filter, chan, origin, opt_test_paths);
- let _ = filemanager.send(msg).unwrap();
+ let _ = resource_threads.send(CoreResourceMsg::ToFileManager(msg)).unwrap();
match recv.recv().expect("IpcSender side error") {
Ok(selected_files) => {
@@ -788,7 +817,7 @@ impl HTMLInputElement {
let (chan, recv) = ipc::channel().expect("Error initializing channel");
let msg = FileManagerThreadMsg::SelectFile(filter, chan, origin, opt_test_path);
- let _ = filemanager.send(msg).unwrap();
+ let _ = resource_threads.send(CoreResourceMsg::ToFileManager(msg)).unwrap();
match recv.recv().expect("IpcSender side error") {
Ok(selected) => {
diff --git a/components/script/dom/htmllielement.rs b/components/script/dom/htmllielement.rs
index 444fc37827c..32915a5c351 100644
--- a/components/script/dom/htmllielement.rs
+++ b/components/script/dom/htmllielement.rs
@@ -3,12 +3,16 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
use dom::bindings::codegen::Bindings::HTMLLIElementBinding;
+use dom::bindings::codegen::Bindings::HTMLLIElementBinding::HTMLLIElementMethods;
+use dom::bindings::inheritance::Castable;
use dom::bindings::js::Root;
use dom::bindings::str::DOMString;
use dom::document::Document;
use dom::htmlelement::HTMLElement;
use dom::node::Node;
+use dom::virtualmethods::VirtualMethods;
use string_cache::Atom;
+use style::attr::AttrValue;
#[dom_struct]
pub struct HTMLLIElement {
@@ -31,3 +35,24 @@ impl HTMLLIElement {
HTMLLIElementBinding::Wrap)
}
}
+
+impl HTMLLIElementMethods for HTMLLIElement {
+ // https://html.spec.whatwg.org/multipage/#dom-li-value
+ make_int_getter!(Value, "value");
+
+ // https://html.spec.whatwg.org/multipage/#dom-li-value
+ make_int_setter!(SetValue, "value");
+}
+
+impl VirtualMethods for HTMLLIElement {
+ fn super_type(&self) -> Option<&VirtualMethods> {
+ Some(self.upcast::<HTMLElement>() as &VirtualMethods)
+ }
+
+ fn parse_plain_attribute(&self, name: &Atom, value: DOMString) -> AttrValue {
+ match name {
+ &atom!("value") => AttrValue::from_i32(value.into(), 0),
+ _ => self.super_type().unwrap().parse_plain_attribute(name, value),
+ }
+ }
+}
diff --git a/components/script/dom/htmlmediaelement.rs b/components/script/dom/htmlmediaelement.rs
index 7a94768c13a..119139ae6d8 100644
--- a/components/script/dom/htmlmediaelement.rs
+++ b/components/script/dom/htmlmediaelement.rs
@@ -35,6 +35,8 @@ use string_cache::Atom;
use task_source::TaskSource;
use time::{self, Timespec, Duration};
use url::Url;
+#[cfg(not(any(target_os = "android", target_arch = "arm", target_arch = "aarch64")))]
+use video_metadata;
struct HTMLMediaElementContext {
/// The element that initiated the request.
@@ -75,12 +77,11 @@ impl AsyncResponseListener for HTMLMediaElementContext {
}
}
- fn data_available(&mut self, payload: Vec<u8>) {
+ fn data_available(&mut self, mut payload: Vec<u8>) {
if self.ignore_response {
return;
}
- let mut payload = payload;
self.data.append(&mut payload);
let elem = self.elem.root();
@@ -88,11 +89,7 @@ impl AsyncResponseListener for HTMLMediaElementContext {
// https://html.spec.whatwg.org/multipage/#media-data-processing-steps-list
// => "Once enough of the media data has been fetched to determine the duration..."
if !self.have_metadata {
- //TODO: actually check if the payload contains the full metadata
-
- // Step 6
- elem.change_ready_state(HAVE_METADATA);
- self.have_metadata = true;
+ self.check_metadata(&elem);
} else {
elem.change_ready_state(HAVE_CURRENT_DATA);
}
@@ -162,6 +159,46 @@ impl HTMLMediaElementContext {
ignore_response: false,
}
}
+
+ #[cfg(not(any(target_os = "android", target_arch = "arm", target_arch = "aarch64")))]
+ fn check_metadata(&mut self, elem: &HTMLMediaElement) {
+ match video_metadata::get_format_from_slice(&self.data) {
+ Ok(meta) => {
+ let dur = meta.duration.unwrap_or(::std::time::Duration::new(0, 0));
+ *elem.video.borrow_mut() = Some(VideoMedia {
+ format: format!("{:?}", meta.format),
+ duration: Duration::seconds(dur.as_secs() as i64) +
+ Duration::nanoseconds(dur.subsec_nanos() as i64),
+ width: meta.size.width,
+ height: meta.size.height,
+ video: meta.video,
+ audio: meta.audio,
+ });
+ // Step 6
+ elem.change_ready_state(HAVE_METADATA);
+ self.have_metadata = true;
+ }
+ _ => {}
+ }
+ }
+
+ #[cfg(any(target_os = "android", target_arch = "arm", target_arch = "aarch64"))]
+ fn check_metadata(&mut self, elem: &HTMLMediaElement) {
+ // Step 6.
+ elem.change_ready_state(HAVE_METADATA);
+ self.have_metadata = true;
+ }
+}
+
+#[derive(JSTraceable, HeapSizeOf)]
+pub struct VideoMedia {
+ format: String,
+ #[ignore_heap_size_of = "defined in time"]
+ duration: Duration,
+ width: u32,
+ height: u32,
+ video: String,
+ audio: Option<String>,
}
#[dom_struct]
@@ -175,6 +212,7 @@ pub struct HTMLMediaElement {
error: MutNullableHeap<JS<MediaError>>,
paused: Cell<bool>,
autoplaying: Cell<bool>,
+ video: DOMRefCell<Option<VideoMedia>>,
}
impl HTMLMediaElement {
@@ -192,6 +230,7 @@ impl HTMLMediaElement {
error: Default::default(),
paused: Cell::new(true),
autoplaying: Cell::new(true),
+ video: DOMRefCell::new(None),
}
}
diff --git a/components/script/dom/htmltableelement.rs b/components/script/dom/htmltableelement.rs
index 4cff33b78a1..1d189f4a21f 100644
--- a/components/script/dom/htmltableelement.rs
+++ b/components/script/dom/htmltableelement.rs
@@ -34,6 +34,20 @@ pub struct HTMLTableElement {
tbodies: MutNullableHeap<JS<HTMLCollection>>,
}
+#[allow(unrooted_must_root)]
+#[derive(JSTraceable, HeapSizeOf)]
+struct TableRowFilter {
+ sections: Vec<JS<Node>>,
+}
+
+impl CollectionFilter for TableRowFilter {
+ fn filter(&self, elem: &Element, root: &Node) -> bool {
+ elem.is::<HTMLTableRowElement>() &&
+ (root.is_parent_of(elem.upcast())
+ || self.sections.iter().any(|ref section| section.is_parent_of(elem.upcast())))
+ }
+}
+
impl HTMLTableElement {
fn new_inherited(localName: Atom, prefix: Option<DOMString>, document: &Document)
-> HTMLTableElement {
@@ -120,32 +134,22 @@ impl HTMLTableElement {
thead.upcast::<Node>().remove_self();
}
}
-}
-
-impl HTMLTableElementMethods for HTMLTableElement {
- // https://html.spec.whatwg.org/multipage/#dom-table-rows
- fn Rows(&self) -> Root<HTMLCollection> {
- #[allow(unrooted_must_root)]
- #[derive(JSTraceable, HeapSizeOf)]
- struct TableRowFilter {
- sections: Vec<JS<Node>>
- }
-
- impl CollectionFilter for TableRowFilter {
- fn filter(&self, elem: &Element, root: &Node) -> bool {
- elem.is::<HTMLTableRowElement>() &&
- (root.is_parent_of(elem.upcast())
- || self.sections.iter().any(|ref section| section.is_parent_of(elem.upcast())))
- }
- }
- let filter = TableRowFilter {
+ fn get_rows(&self) -> TableRowFilter {
+ TableRowFilter {
sections: self.upcast::<Node>()
.children()
.filter_map(|ref node|
node.downcast::<HTMLTableSectionElement>().map(|_| JS::from_ref(&**node)))
.collect()
- };
+ }
+ }
+}
+
+impl HTMLTableElementMethods for HTMLTableElement {
+ // https://html.spec.whatwg.org/multipage/#dom-table-rows
+ fn Rows(&self) -> Root<HTMLCollection> {
+ let filter = self.get_rows();
HTMLCollection::new(window_from_node(self).r(), self.upcast(), box filter)
}
@@ -338,6 +342,22 @@ impl HTMLTableElementMethods for HTMLTableElement {
Ok(new_row)
}
+ // https://html.spec.whatwg.org/multipage/#dom-table-deleterow
+ fn DeleteRow(&self, mut index: i32) -> Fallible<()> {
+ let rows = self.Rows();
+ // Step 1.
+ if index == -1 {
+ index = rows.Length() as i32 - 1;
+ }
+ // Step 2.
+ if index < 0 || index as u32 >= rows.Length() {
+ return Err(Error::IndexSize);
+ }
+ // Step 3.
+ Root::upcast::<Node>(rows.Item(index as u32).unwrap()).remove_self();
+ Ok(())
+ }
+
// https://html.spec.whatwg.org/multipage/#dom-table-bgcolor
make_getter!(BgColor, "bgcolor");
diff --git a/components/script/dom/macros.rs b/components/script/dom/macros.rs
index 58af2b28ac6..2b29ec8014c 100644
--- a/components/script/dom/macros.rs
+++ b/components/script/dom/macros.rs
@@ -47,6 +47,22 @@ macro_rules! make_limited_int_setter(
);
#[macro_export]
+macro_rules! make_int_setter(
+ ($attr:ident, $htmlname:tt, $default:expr) => (
+ fn $attr(&self, value: i32) {
+ use dom::bindings::inheritance::Castable;
+ use dom::element::Element;
+
+ let element = self.upcast::<Element>();
+ element.set_int_attribute(&atom!($htmlname), value)
+ }
+ );
+ ($attr:ident, $htmlname:tt) => {
+ make_int_setter!($attr, $htmlname, 0);
+ };
+);
+
+#[macro_export]
macro_rules! make_int_getter(
($attr:ident, $htmlname:tt, $default:expr) => (
fn $attr(&self) -> i32 {
diff --git a/components/script/dom/mod.rs b/components/script/dom/mod.rs
index 172026c4d8e..a2112526228 100644
--- a/components/script/dom/mod.rs
+++ b/components/script/dom/mod.rs
@@ -265,11 +265,13 @@ pub mod eventtarget;
pub mod file;
pub mod filelist;
pub mod filereader;
+pub mod filereadersync;
pub mod focusevent;
pub mod forcetouchevent;
pub mod formdata;
pub mod hashchangeevent;
pub mod headers;
+pub mod history;
pub mod htmlanchorelement;
pub mod htmlappletelement;
pub mod htmlareaelement;
diff --git a/components/script/dom/node.rs b/components/script/dom/node.rs
index 37495be3ba3..2769b7503bc 100644
--- a/components/script/dom/node.rs
+++ b/components/script/dom/node.rs
@@ -479,19 +479,7 @@ impl Node {
return
}
- // 2. Dirty descendants.
- fn dirty_subtree(node: &Node) {
- // Stop if this subtree is already dirty.
- if node.is_dirty() { return }
-
- node.set_flag(IS_DIRTY | HAS_DIRTY_DESCENDANTS, true);
-
- for kid in node.children() {
- dirty_subtree(kid.r());
- }
- }
-
- dirty_subtree(self);
+ self.set_flag(IS_DIRTY, true);
// 4. Dirty ancestors.
for ancestor in self.ancestors() {
@@ -1299,22 +1287,17 @@ impl TreeIterator {
depth: 0,
}
}
-}
-impl Iterator for TreeIterator {
- type Item = Root<Node>;
-
- // https://dom.spec.whatwg.org/#concept-tree-order
- fn next(&mut self) -> Option<Root<Node>> {
+ pub fn next_skipping_children(&mut self) -> Option<Root<Node>> {
let current = match self.current.take() {
None => return None,
Some(current) => current,
};
- if let Some(first_child) = current.GetFirstChild() {
- self.current = Some(first_child);
- self.depth += 1;
- return Some(current);
- };
+
+ self.next_skipping_children_impl(current)
+ }
+
+ fn next_skipping_children_impl(&mut self, current: Root<Node>) -> Option<Root<Node>> {
for ancestor in current.inclusive_ancestors() {
if self.depth == 0 {
break;
@@ -1331,6 +1314,25 @@ impl Iterator for TreeIterator {
}
}
+impl Iterator for TreeIterator {
+ type Item = Root<Node>;
+
+ // https://dom.spec.whatwg.org/#concept-tree-order
+ fn next(&mut self) -> Option<Root<Node>> {
+ let current = match self.current.take() {
+ None => return None,
+ Some(current) => current,
+ };
+ if let Some(first_child) = current.GetFirstChild() {
+ self.current = Some(first_child);
+ self.depth += 1;
+ return Some(current);
+ };
+
+ self.next_skipping_children_impl(current)
+ }
+}
+
/// Specifies whether children must be recursively cloned or not.
#[derive(Copy, Clone, PartialEq, HeapSizeOf)]
pub enum CloneChildrenFlag {
diff --git a/components/script/dom/serviceworkerglobalscope.rs b/components/script/dom/serviceworkerglobalscope.rs
index 4841e0ff08a..c6a238ac10f 100644
--- a/components/script/dom/serviceworkerglobalscope.rs
+++ b/components/script/dom/serviceworkerglobalscope.rs
@@ -24,7 +24,8 @@ use js::jsapi::{JS_SetInterruptCallback, JSAutoCompartment, JSContext};
use js::jsval::UndefinedValue;
use js::rust::Runtime;
use msg::constellation_msg::PipelineId;
-use net_traits::{LoadContext, load_whole_resource, IpcSend};
+use net_traits::{LoadContext, load_whole_resource, IpcSend, CustomResponseMediator};
+use rand::random;
use script_runtime::{CommonScriptMsg, StackRootTLS, get_reports, new_rt_and_cx};
use script_traits::{TimerEvent, WorkerGlobalScopeInit, ScopeThings, ServiceWorkerMsg};
use std::sync::mpsc::{Receiver, RecvError, Select, Sender, channel};
@@ -36,8 +37,16 @@ use util::thread::spawn_named;
use util::thread_state;
use util::thread_state::{IN_WORKER, SCRIPT};
+/// Messages used to control service worker event loop
+pub enum ServiceWorkerScriptMsg {
+ /// Message common to all workers
+ CommonWorker(WorkerScriptMsg),
+ // Message to request a custom response by the service worker
+ Response(CustomResponseMediator)
+}
+
pub enum MixedMessage {
- FromServiceWorker((TrustedServiceWorkerAddress, WorkerScriptMsg)),
+ FromServiceWorker(ServiceWorkerScriptMsg),
FromDevtools(DevtoolScriptControlMsg),
FromTimeoutThread(()),
}
@@ -47,9 +56,9 @@ pub struct ServiceWorkerGlobalScope {
workerglobalscope: WorkerGlobalScope,
id: PipelineId,
#[ignore_heap_size_of = "Defined in std"]
- receiver: Receiver<(TrustedServiceWorkerAddress, WorkerScriptMsg)>,
+ receiver: Receiver<ServiceWorkerScriptMsg>,
#[ignore_heap_size_of = "Defined in std"]
- own_sender: Sender<(TrustedServiceWorkerAddress, WorkerScriptMsg)>,
+ own_sender: Sender<ServiceWorkerScriptMsg>,
#[ignore_heap_size_of = "Defined in std"]
timer_event_port: Receiver<()>,
#[ignore_heap_size_of = "Trusted<T> has unclear ownership like JS<T>"]
@@ -66,8 +75,8 @@ impl ServiceWorkerGlobalScope {
id: PipelineId,
from_devtools_receiver: Receiver<DevtoolScriptControlMsg>,
runtime: Runtime,
- own_sender: Sender<(TrustedServiceWorkerAddress, WorkerScriptMsg)>,
- receiver: Receiver<(TrustedServiceWorkerAddress, WorkerScriptMsg)>,
+ own_sender: Sender<ServiceWorkerScriptMsg>,
+ receiver: Receiver<ServiceWorkerScriptMsg>,
timer_event_chan: IpcSender<TimerEvent>,
timer_event_port: Receiver<()>,
swmanager_sender: IpcSender<ServiceWorkerMsg>,
@@ -95,8 +104,8 @@ impl ServiceWorkerGlobalScope {
id: PipelineId,
from_devtools_receiver: Receiver<DevtoolScriptControlMsg>,
runtime: Runtime,
- own_sender: Sender<(TrustedServiceWorkerAddress, WorkerScriptMsg)>,
- receiver: Receiver<(TrustedServiceWorkerAddress, WorkerScriptMsg)>,
+ own_sender: Sender<ServiceWorkerScriptMsg>,
+ receiver: Receiver<ServiceWorkerScriptMsg>,
timer_event_chan: IpcSender<TimerEvent>,
timer_event_port: Receiver<()>,
swmanager_sender: IpcSender<ServiceWorkerMsg>,
@@ -119,8 +128,8 @@ impl ServiceWorkerGlobalScope {
#[allow(unsafe_code)]
pub fn run_serviceworker_scope(scope_things: ScopeThings,
- own_sender: Sender<(TrustedServiceWorkerAddress, WorkerScriptMsg)>,
- receiver: Receiver<(TrustedServiceWorkerAddress, WorkerScriptMsg)>,
+ own_sender: Sender<ServiceWorkerScriptMsg>,
+ receiver: Receiver<ServiceWorkerScriptMsg>,
devtools_receiver: IpcReceiver<DevtoolScriptControlMsg>,
swmanager_sender: IpcSender<ServiceWorkerMsg>,
scope_url: Url) {
@@ -177,12 +186,14 @@ impl ServiceWorkerGlobalScope {
let _ = timer_chan.send(());
});
- // TODO XXXcreativcoder bring back run_with_memory_reporting when things are more concrete here.
- while let Ok(event) = global.receive_event() {
- if !global.handle_event(event) {
- break;
+ let reporter_name = format!("service-worker-reporter-{}", random::<u64>());
+ scope.mem_profiler_chan().run_with_memory_reporting(|| {
+ while let Ok(event) = global.receive_event() {
+ if !global.handle_event(event) {
+ break;
+ }
}
- }
+ }, reporter_name, scope.script_chan(), CommonScriptMsg::CollectReports);
});
}
@@ -201,7 +212,7 @@ impl ServiceWorkerGlobalScope {
}
true
}
- MixedMessage::FromServiceWorker((_, msg)) => {
+ MixedMessage::FromServiceWorker(msg) => {
self.handle_script_event(msg);
true
}
@@ -212,9 +223,11 @@ impl ServiceWorkerGlobalScope {
}
}
- fn handle_script_event(&self, msg: WorkerScriptMsg) {
+ fn handle_script_event(&self, msg: ServiceWorkerScriptMsg) {
+ use self::ServiceWorkerScriptMsg::*;
+
match msg {
- WorkerScriptMsg::DOMMessage(data) => {
+ CommonWorker(WorkerScriptMsg::DOMMessage(data)) => {
let scope = self.upcast::<WorkerGlobalScope>();
let target = self.upcast();
let _ac = JSAutoCompartment::new(scope.get_cx(),
@@ -223,19 +236,22 @@ impl ServiceWorkerGlobalScope {
data.read(GlobalRef::Worker(scope), message.handle_mut());
MessageEvent::dispatch_jsval(target, GlobalRef::Worker(scope), message.handle());
},
- WorkerScriptMsg::Common(CommonScriptMsg::RunnableMsg(_, runnable)) => {
+ CommonWorker(WorkerScriptMsg::Common(CommonScriptMsg::RunnableMsg(_, runnable))) => {
runnable.handler()
},
- WorkerScriptMsg::Common(CommonScriptMsg::RefcountCleanup(addr)) => {
+ CommonWorker(WorkerScriptMsg::Common(CommonScriptMsg::RefcountCleanup(addr))) => {
LiveDOMReferences::cleanup(addr);
},
- WorkerScriptMsg::Common(CommonScriptMsg::CollectReports(reports_chan)) => {
+ CommonWorker(WorkerScriptMsg::Common(CommonScriptMsg::CollectReports(reports_chan))) => {
let scope = self.upcast::<WorkerGlobalScope>();
let cx = scope.get_cx();
let path_seg = format!("url({})", scope.get_url());
let reports = get_reports(cx, path_seg);
reports_chan.send(reports);
},
+ Response(mediator) => {
+ let _ = mediator.response_chan.send(None);
+ }
}
}
@@ -275,7 +291,7 @@ impl ServiceWorkerGlobalScope {
}
pub fn process_event(&self, msg: CommonScriptMsg) {
- self.handle_script_event(WorkerScriptMsg::Common(msg));
+ self.handle_script_event(ServiceWorkerScriptMsg::CommonWorker(WorkerScriptMsg::Common(msg)));
}
}
diff --git a/components/script/dom/servohtmlparser.rs b/components/script/dom/servohtmlparser.rs
index a28612416fc..09ee38a1232 100644
--- a/components/script/dom/servohtmlparser.rs
+++ b/components/script/dom/servohtmlparser.rs
@@ -7,13 +7,18 @@
use document_loader::LoadType;
use dom::bindings::cell::DOMRefCell;
+use dom::bindings::codegen::Bindings::DocumentBinding::DocumentMethods;
+use dom::bindings::codegen::Bindings::HTMLImageElementBinding::HTMLImageElementMethods;
+use dom::bindings::codegen::Bindings::NodeBinding::NodeMethods;
use dom::bindings::codegen::Bindings::ServoHTMLParserBinding;
use dom::bindings::global::GlobalRef;
use dom::bindings::js::{JS, Root};
use dom::bindings::refcounted::Trusted;
use dom::bindings::reflector::{Reflector, reflect_dom_object};
+use dom::bindings::str::DOMString;
use dom::bindings::trace::JSTraceable;
use dom::document::Document;
+use dom::htmlimageelement::HTMLImageElement;
use dom::node::Node;
use dom::window::Window;
use encoding::all::UTF_8;
@@ -112,13 +117,20 @@ impl AsyncResponseListener for ParserContext {
match content_type {
Some(ContentType(Mime(TopLevel::Image, _, _))) => {
self.is_synthesized_document = true;
- let page = format!("<html><body><img src='{}' /></body></html>", self.url);
+ let page = "<html><body></body></html>".into();
parser.pending_input().borrow_mut().push(page);
parser.parse_sync();
+
+ let doc = parser.document();
+ let doc_body = Root::upcast::<Node>(doc.GetBody().unwrap());
+ let img = HTMLImageElement::new(atom!("img"), None, doc);
+ img.SetSrc(DOMString::from(self.url.to_string()));
+ doc_body.AppendChild(&Root::upcast::<Node>(img)).expect("Appending failed");
+
},
Some(ContentType(Mime(TopLevel::Text, SubLevel::Plain, _))) => {
// https://html.spec.whatwg.org/multipage/#read-text
- let page = format!("<pre>\n");
+ let page = "<pre>\n".into();
parser.pending_input().borrow_mut().push(page);
parser.parse_sync();
parser.set_plaintext_state();
diff --git a/components/script/dom/url.rs b/components/script/dom/url.rs
index 81c806de806..768dabf1475 100644
--- a/components/script/dom/url.rs
+++ b/components/script/dom/url.rs
@@ -14,9 +14,9 @@ use dom::blob::Blob;
use dom::urlhelper::UrlHelper;
use dom::urlsearchparams::URLSearchParams;
use ipc_channel::ipc;
-use net_traits::IpcSend;
use net_traits::blob_url_store::{get_blob_origin, parse_blob_url};
use net_traits::filemanager_thread::{SelectedFileId, FileManagerThreadMsg};
+use net_traits::{IpcSend, CoreResourceMsg};
use std::borrow::ToOwned;
use std::default::Default;
use url::quirks::domain_to_unicode;
@@ -145,11 +145,11 @@ impl URL {
if let Ok(url) = Url::parse(&url) {
if let Ok((id, _, _)) = parse_blob_url(&url) {
- let filemanager = global.resource_threads().sender();
+ let resource_threads = global.resource_threads();
let id = SelectedFileId(id.simple().to_string());
let (tx, rx) = ipc::channel().unwrap();
let msg = FileManagerThreadMsg::RevokeBlobURL(id, origin, tx);
- let _ = filemanager.send(msg);
+ let _ = resource_threads.send(CoreResourceMsg::ToFileManager(msg));
let _ = rx.recv().unwrap();
}
diff --git a/components/script/dom/virtualmethods.rs b/components/script/dom/virtualmethods.rs
index b42e8b676c3..d4cf1609568 100644
--- a/components/script/dom/virtualmethods.rs
+++ b/components/script/dom/virtualmethods.rs
@@ -29,6 +29,7 @@ use dom::htmliframeelement::HTMLIFrameElement;
use dom::htmlimageelement::HTMLImageElement;
use dom::htmlinputelement::HTMLInputElement;
use dom::htmllabelelement::HTMLLabelElement;
+use dom::htmllielement::HTMLLIElement;
use dom::htmllinkelement::HTMLLinkElement;
use dom::htmlmediaelement::HTMLMediaElement;
use dom::htmlmetaelement::HTMLMetaElement;
@@ -179,6 +180,9 @@ pub fn vtable_for(node: &Node) -> &VirtualMethods {
NodeTypeId::Element(ElementTypeId::HTMLElement(HTMLElementTypeId::HTMLLabelElement)) => {
node.downcast::<HTMLLabelElement>().unwrap() as &VirtualMethods
}
+ NodeTypeId::Element(ElementTypeId::HTMLElement(HTMLElementTypeId::HTMLLIElement)) => {
+ node.downcast::<HTMLLIElement>().unwrap() as &VirtualMethods
+ }
NodeTypeId::Element(ElementTypeId::HTMLElement(HTMLElementTypeId::HTMLLinkElement)) => {
node.downcast::<HTMLLinkElement>().unwrap() as &VirtualMethods
}
diff --git a/components/script/dom/webidls/DedicatedWorkerGlobalScope.webidl b/components/script/dom/webidls/DedicatedWorkerGlobalScope.webidl
index cd0d393e22e..53996ee3965 100644
--- a/components/script/dom/webidls/DedicatedWorkerGlobalScope.webidl
+++ b/components/script/dom/webidls/DedicatedWorkerGlobalScope.webidl
@@ -8,4 +8,6 @@
[Throws]
void postMessage(any message/*, optional sequence<Transferable> transfer*/);
attribute EventHandler onmessage;
+
+ void close();
};
diff --git a/components/script/dom/webidls/FileReaderSync.webidl b/components/script/dom/webidls/FileReaderSync.webidl
new file mode 100644
index 00000000000..cbc18a47921
--- /dev/null
+++ b/components/script/dom/webidls/FileReaderSync.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://w3c.github.io/FileAPI/#FileReaderSync
+
+[Constructor, Exposed=Worker]
+interface FileReaderSync {
+ // Synchronously return strings
+
+ // ArrayBuffer readAsArrayBuffer(Blob blob);
+ // DOMString readAsBinaryString(Blob blob);
+ // DOMString readAsText(Blob blob, optional DOMString label);
+ // DOMString readAsDataURL(Blob blob);
+};
diff --git a/components/script/dom/webidls/HTMLAnchorElement.webidl b/components/script/dom/webidls/HTMLAnchorElement.webidl
index c728744e495..f78d1dae6dd 100644
--- a/components/script/dom/webidls/HTMLAnchorElement.webidl
+++ b/components/script/dom/webidls/HTMLAnchorElement.webidl
@@ -11,7 +11,6 @@
*/
// https://html.spec.whatwg.org/multipage/#htmlanchorelement
-[Exposed=(Window,Worker)]
interface HTMLAnchorElement : HTMLElement {
attribute DOMString target;
// attribute DOMString download;
diff --git a/components/script/dom/webidls/HTMLAppletElement.webidl b/components/script/dom/webidls/HTMLAppletElement.webidl
index efb3d24b2e7..9cfeb4183df 100644
--- a/components/script/dom/webidls/HTMLAppletElement.webidl
+++ b/components/script/dom/webidls/HTMLAppletElement.webidl
@@ -3,7 +3,6 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
// https://html.spec.whatwg.org/multipage/#htmlappletelement
-[Exposed=(Window,Worker)]
interface HTMLAppletElement : HTMLElement {
// attribute DOMString align;
// attribute DOMString alt;
diff --git a/components/script/dom/webidls/HTMLAreaElement.webidl b/components/script/dom/webidls/HTMLAreaElement.webidl
index f39db4fa4d2..14883df3613 100644
--- a/components/script/dom/webidls/HTMLAreaElement.webidl
+++ b/components/script/dom/webidls/HTMLAreaElement.webidl
@@ -3,7 +3,6 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
// https://html.spec.whatwg.org/multipage/#htmlareaelement
-[Exposed=(Window,Worker)]
interface HTMLAreaElement : HTMLElement {
// attribute DOMString alt;
// attribute DOMString coords;
diff --git a/components/script/dom/webidls/HTMLAudioElement.webidl b/components/script/dom/webidls/HTMLAudioElement.webidl
index df0710b1856..09ad8a7cdb3 100644
--- a/components/script/dom/webidls/HTMLAudioElement.webidl
+++ b/components/script/dom/webidls/HTMLAudioElement.webidl
@@ -4,5 +4,4 @@
// https://html.spec.whatwg.org/multipage/#htmlaudioelement
//[NamedConstructor=Audio(optional DOMString src)]
-[Exposed=(Window,Worker)]
interface HTMLAudioElement : HTMLMediaElement {};
diff --git a/components/script/dom/webidls/HTMLBRElement.webidl b/components/script/dom/webidls/HTMLBRElement.webidl
index 4d811f3e285..ab277396bdd 100644
--- a/components/script/dom/webidls/HTMLBRElement.webidl
+++ b/components/script/dom/webidls/HTMLBRElement.webidl
@@ -3,7 +3,6 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
// https://html.spec.whatwg.org/multipage/#htmlbrelement
-[Exposed=(Window,Worker)]
interface HTMLBRElement : HTMLElement {
// also has obsolete members
};
diff --git a/components/script/dom/webidls/HTMLBaseElement.webidl b/components/script/dom/webidls/HTMLBaseElement.webidl
index dee9895c8ef..a13be544cb9 100644
--- a/components/script/dom/webidls/HTMLBaseElement.webidl
+++ b/components/script/dom/webidls/HTMLBaseElement.webidl
@@ -3,7 +3,6 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
// https://html.spec.whatwg.org/multipage/#htmlbaseelement
-[Exposed=(Window,Worker)]
interface HTMLBaseElement : HTMLElement {
attribute DOMString href;
// attribute DOMString target;
diff --git a/components/script/dom/webidls/HTMLBodyElement.webidl b/components/script/dom/webidls/HTMLBodyElement.webidl
index 31097e75614..36c6f4d64e3 100644
--- a/components/script/dom/webidls/HTMLBodyElement.webidl
+++ b/components/script/dom/webidls/HTMLBodyElement.webidl
@@ -3,7 +3,6 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
// https://html.spec.whatwg.org/multipage/#the-body-element
-[Exposed=(Window,Worker)]
interface HTMLBodyElement : HTMLElement {
// also has obsolete members
};
diff --git a/components/script/dom/webidls/HTMLButtonElement.webidl b/components/script/dom/webidls/HTMLButtonElement.webidl
index a5c689cbc46..7f663fd305f 100644
--- a/components/script/dom/webidls/HTMLButtonElement.webidl
+++ b/components/script/dom/webidls/HTMLButtonElement.webidl
@@ -3,7 +3,6 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
// https://html.spec.whatwg.org/multipage/#htmlbuttonelement
-[Exposed=(Window,Worker)]
interface HTMLButtonElement : HTMLElement {
// attribute boolean autofocus;
attribute boolean disabled;
diff --git a/components/script/dom/webidls/HTMLDListElement.webidl b/components/script/dom/webidls/HTMLDListElement.webidl
index e0420cf8418..b6275107db5 100644
--- a/components/script/dom/webidls/HTMLDListElement.webidl
+++ b/components/script/dom/webidls/HTMLDListElement.webidl
@@ -3,7 +3,6 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
// https://html.spec.whatwg.org/multipage/#htmldlistelement
-[Exposed=(Window,Worker)]
interface HTMLDListElement : HTMLElement {
// also has obsolete members
};
diff --git a/components/script/dom/webidls/HTMLDataElement.webidl b/components/script/dom/webidls/HTMLDataElement.webidl
index e0b2aa2cafa..be932250678 100644
--- a/components/script/dom/webidls/HTMLDataElement.webidl
+++ b/components/script/dom/webidls/HTMLDataElement.webidl
@@ -3,7 +3,6 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
// https://html.spec.whatwg.org/multipage/#htmldataelement
-[Exposed=(Window,Worker)]
interface HTMLDataElement : HTMLElement {
// attribute DOMString value;
};
diff --git a/components/script/dom/webidls/HTMLDataListElement.webidl b/components/script/dom/webidls/HTMLDataListElement.webidl
index c970ae495fb..b8673b21c77 100644
--- a/components/script/dom/webidls/HTMLDataListElement.webidl
+++ b/components/script/dom/webidls/HTMLDataListElement.webidl
@@ -3,7 +3,6 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
// https://html.spec.whatwg.org/multipage/#htmldatalistelement
-[Exposed=(Window,Worker)]
interface HTMLDataListElement : HTMLElement {
readonly attribute HTMLCollection options;
};
diff --git a/components/script/dom/webidls/HTMLDetailsElement.webidl b/components/script/dom/webidls/HTMLDetailsElement.webidl
index 8dbffdea064..811465c1c02 100644
--- a/components/script/dom/webidls/HTMLDetailsElement.webidl
+++ b/components/script/dom/webidls/HTMLDetailsElement.webidl
@@ -3,7 +3,6 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
// https://html.spec.whatwg.org/multipage/#htmldetailselement
-[Exposed=(Window,Worker)]
interface HTMLDetailsElement : HTMLElement {
attribute boolean open;
};
diff --git a/components/script/dom/webidls/HTMLDialogElement.webidl b/components/script/dom/webidls/HTMLDialogElement.webidl
index 82d11ea2cae..78a14e1e2a0 100644
--- a/components/script/dom/webidls/HTMLDialogElement.webidl
+++ b/components/script/dom/webidls/HTMLDialogElement.webidl
@@ -3,7 +3,6 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
// https://html.spec.whatwg.org/multipage/#htmldialogelement
-[Exposed=(Window,Worker)]
interface HTMLDialogElement : HTMLElement {
attribute boolean open;
attribute DOMString returnValue;
diff --git a/components/script/dom/webidls/HTMLDirectoryElement.webidl b/components/script/dom/webidls/HTMLDirectoryElement.webidl
index 4a1d8af74ab..5df65cd90c2 100644
--- a/components/script/dom/webidls/HTMLDirectoryElement.webidl
+++ b/components/script/dom/webidls/HTMLDirectoryElement.webidl
@@ -3,7 +3,6 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
// https://html.spec.whatwg.org/multipage/#htmldirectoryelement
-[Exposed=(Window,Worker)]
interface HTMLDirectoryElement : HTMLElement {
// attribute boolean compact;
};
diff --git a/components/script/dom/webidls/HTMLDivElement.webidl b/components/script/dom/webidls/HTMLDivElement.webidl
index 827dfe7ab49..46ee67ee0e5 100644
--- a/components/script/dom/webidls/HTMLDivElement.webidl
+++ b/components/script/dom/webidls/HTMLDivElement.webidl
@@ -3,7 +3,6 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
// https://html.spec.whatwg.org/multipage/#htmldivelement
-[Exposed=(Window,Worker)]
interface HTMLDivElement : HTMLElement {
// also has obsolete members
};
diff --git a/components/script/dom/webidls/HTMLEmbedElement.webidl b/components/script/dom/webidls/HTMLEmbedElement.webidl
index 3e4063c9377..26fa4c3ea5a 100644
--- a/components/script/dom/webidls/HTMLEmbedElement.webidl
+++ b/components/script/dom/webidls/HTMLEmbedElement.webidl
@@ -3,7 +3,6 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
// https://html.spec.whatwg.org/multipage/#htmlembedelement
-[Exposed=(Window,Worker)]
interface HTMLEmbedElement : HTMLElement {
// attribute DOMString src;
// attribute DOMString type;
diff --git a/components/script/dom/webidls/HTMLFieldSetElement.webidl b/components/script/dom/webidls/HTMLFieldSetElement.webidl
index 6c05b23f9ae..d041cdd612f 100644
--- a/components/script/dom/webidls/HTMLFieldSetElement.webidl
+++ b/components/script/dom/webidls/HTMLFieldSetElement.webidl
@@ -3,7 +3,6 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
// https://html.spec.whatwg.org/multipage/#htmlfieldsetelement
-[Exposed=(Window,Worker)]
interface HTMLFieldSetElement : HTMLElement {
attribute boolean disabled;
readonly attribute HTMLFormElement? form;
diff --git a/components/script/dom/webidls/HTMLFontElement.webidl b/components/script/dom/webidls/HTMLFontElement.webidl
index 7c524eb0a4d..74db3f45057 100644
--- a/components/script/dom/webidls/HTMLFontElement.webidl
+++ b/components/script/dom/webidls/HTMLFontElement.webidl
@@ -3,7 +3,6 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
// https://html.spec.whatwg.org/multipage/#htmlfontelement
-[Exposed=(Window,Worker)]
interface HTMLFontElement : HTMLElement {
[TreatNullAs=EmptyString] attribute DOMString color;
attribute DOMString face;
diff --git a/components/script/dom/webidls/HTMLFrameElement.webidl b/components/script/dom/webidls/HTMLFrameElement.webidl
index 0de80f7df1e..ecac61f6860 100644
--- a/components/script/dom/webidls/HTMLFrameElement.webidl
+++ b/components/script/dom/webidls/HTMLFrameElement.webidl
@@ -3,7 +3,6 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
// https://html.spec.whatwg.org/multipage/#htmlframeelement
-[Exposed=(Window,Worker)]
interface HTMLFrameElement : HTMLElement {
// attribute DOMString name;
// attribute DOMString scrolling;
diff --git a/components/script/dom/webidls/HTMLFrameSetElement.webidl b/components/script/dom/webidls/HTMLFrameSetElement.webidl
index 34ab7a42289..5addd41d253 100644
--- a/components/script/dom/webidls/HTMLFrameSetElement.webidl
+++ b/components/script/dom/webidls/HTMLFrameSetElement.webidl
@@ -3,7 +3,6 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
// https://html.spec.whatwg.org/multipage/#htmlframesetelement
-[Exposed=(Window,Worker)]
interface HTMLFrameSetElement : HTMLElement {
// attribute DOMString cols;
// attribute DOMString rows;
diff --git a/components/script/dom/webidls/HTMLHRElement.webidl b/components/script/dom/webidls/HTMLHRElement.webidl
index 84ab2a423c6..56e2f6ae19b 100644
--- a/components/script/dom/webidls/HTMLHRElement.webidl
+++ b/components/script/dom/webidls/HTMLHRElement.webidl
@@ -3,7 +3,6 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
// https://html.spec.whatwg.org/multipage/#htmlhrelement
-[Exposed=(Window,Worker)]
interface HTMLHRElement : HTMLElement {
// also has obsolete members
};
diff --git a/components/script/dom/webidls/HTMLHeadingElement.webidl b/components/script/dom/webidls/HTMLHeadingElement.webidl
index 8185fcb961e..2c47d6fa10f 100644
--- a/components/script/dom/webidls/HTMLHeadingElement.webidl
+++ b/components/script/dom/webidls/HTMLHeadingElement.webidl
@@ -3,7 +3,6 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
// https://html.spec.whatwg.org/multipage/#htmlheadingelement
-[Exposed=(Window,Worker)]
interface HTMLHeadingElement : HTMLElement {
// also has obsolete members
};
diff --git a/components/script/dom/webidls/HTMLHtmlElement.webidl b/components/script/dom/webidls/HTMLHtmlElement.webidl
index d25b22702b3..ed409b1b84c 100644
--- a/components/script/dom/webidls/HTMLHtmlElement.webidl
+++ b/components/script/dom/webidls/HTMLHtmlElement.webidl
@@ -3,7 +3,6 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
// https://html.spec.whatwg.org/multipage/#htmlhtmlelement
-[Exposed=(Window,Worker)]
interface HTMLHtmlElement : HTMLElement {
// also has obsolete members
};
diff --git a/components/script/dom/webidls/HTMLHyperlinkElementUtils.webidl b/components/script/dom/webidls/HTMLHyperlinkElementUtils.webidl
index 46336743a53..3ff0418b13f 100644
--- a/components/script/dom/webidls/HTMLHyperlinkElementUtils.webidl
+++ b/components/script/dom/webidls/HTMLHyperlinkElementUtils.webidl
@@ -3,7 +3,7 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
// https://html.spec.whatwg.org/multipage/#htmlhyperlinkelementutils
-[NoInterfaceObject, Exposed=(Window,Worker)]
+[NoInterfaceObject]
interface HTMLHyperlinkElementUtils {
// stringifier attribute USVString href;
attribute USVString href;
diff --git a/components/script/dom/webidls/HTMLIFrameElement.webidl b/components/script/dom/webidls/HTMLIFrameElement.webidl
index 58a9af38d9c..ced089391d2 100644
--- a/components/script/dom/webidls/HTMLIFrameElement.webidl
+++ b/components/script/dom/webidls/HTMLIFrameElement.webidl
@@ -3,7 +3,6 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
// https://html.spec.whatwg.org/multipage/#htmliframeelement
-[Exposed=(Window,Worker)]
interface HTMLIFrameElement : HTMLElement {
attribute DOMString src;
// attribute DOMString srcdoc;
diff --git a/components/script/dom/webidls/HTMLImageElement.webidl b/components/script/dom/webidls/HTMLImageElement.webidl
index d3e2a419132..88e0dae8d3b 100644
--- a/components/script/dom/webidls/HTMLImageElement.webidl
+++ b/components/script/dom/webidls/HTMLImageElement.webidl
@@ -3,7 +3,7 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
// https://html.spec.whatwg.org/multipage/#htmlimageelement
-[NamedConstructor=Image(optional unsigned long width, optional unsigned long height), Exposed=(Window,Worker)]
+[NamedConstructor=Image(optional unsigned long width, optional unsigned long height)]
interface HTMLImageElement : HTMLElement {
attribute DOMString alt;
attribute DOMString src;
diff --git a/components/script/dom/webidls/HTMLInputElement.webidl b/components/script/dom/webidls/HTMLInputElement.webidl
index d5b3a3985ed..1d6160b14cd 100644
--- a/components/script/dom/webidls/HTMLInputElement.webidl
+++ b/components/script/dom/webidls/HTMLInputElement.webidl
@@ -3,7 +3,6 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
// https://html.spec.whatwg.org/multipage/#htmlinputelement
-[Exposed=(Window,Worker)]
interface HTMLInputElement : HTMLElement {
attribute DOMString accept;
attribute DOMString alt;
diff --git a/components/script/dom/webidls/HTMLLIElement.webidl b/components/script/dom/webidls/HTMLLIElement.webidl
index 944029bfb04..ea7d574eba4 100644
--- a/components/script/dom/webidls/HTMLLIElement.webidl
+++ b/components/script/dom/webidls/HTMLLIElement.webidl
@@ -3,9 +3,8 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
// https://html.spec.whatwg.org/multipage/#htmllielement
-[Exposed=(Window,Worker)]
interface HTMLLIElement : HTMLElement {
- // attribute long value;
+ attribute long value;
// also has obsolete members
};
diff --git a/components/script/dom/webidls/HTMLLabelElement.webidl b/components/script/dom/webidls/HTMLLabelElement.webidl
index 5a194998747..8acb1f312c8 100644
--- a/components/script/dom/webidls/HTMLLabelElement.webidl
+++ b/components/script/dom/webidls/HTMLLabelElement.webidl
@@ -3,7 +3,6 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
// https://html.spec.whatwg.org/multipage/#htmllabelelement
-[Exposed=(Window,Worker)]
interface HTMLLabelElement : HTMLElement {
readonly attribute HTMLFormElement? form;
attribute DOMString htmlFor;
diff --git a/components/script/dom/webidls/HTMLLegendElement.webidl b/components/script/dom/webidls/HTMLLegendElement.webidl
index 4c79ce2ecc6..c137d6db66a 100644
--- a/components/script/dom/webidls/HTMLLegendElement.webidl
+++ b/components/script/dom/webidls/HTMLLegendElement.webidl
@@ -3,7 +3,6 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
// https://html.spec.whatwg.org/multipage/#htmllegendelement
-[Exposed=(Window,Worker)]
interface HTMLLegendElement : HTMLElement {
readonly attribute HTMLFormElement? form;
diff --git a/components/script/dom/webidls/HTMLParagraphElement.webidl b/components/script/dom/webidls/HTMLParagraphElement.webidl
index ff2facc455d..a96c6dc6f81 100644
--- a/components/script/dom/webidls/HTMLParagraphElement.webidl
+++ b/components/script/dom/webidls/HTMLParagraphElement.webidl
@@ -3,7 +3,6 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
// https://html.spec.whatwg.org/multipage/#htmlparagraphelement
-[Exposed=(Window,Worker)]
interface HTMLParagraphElement : HTMLElement {
// also has obsolete members
};
diff --git a/components/script/dom/webidls/HTMLParamElement.webidl b/components/script/dom/webidls/HTMLParamElement.webidl
index 1b0805480a6..9648c9f87ce 100644
--- a/components/script/dom/webidls/HTMLParamElement.webidl
+++ b/components/script/dom/webidls/HTMLParamElement.webidl
@@ -3,7 +3,6 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
// https://html.spec.whatwg.org/multipage/#htmlparamelement
-[Exposed=(Window,Worker)]
interface HTMLParamElement : HTMLElement {
// attribute DOMString name;
// attribute DOMString value;
diff --git a/components/script/dom/webidls/HTMLPreElement.webidl b/components/script/dom/webidls/HTMLPreElement.webidl
index 7d65e225d4f..ea0df151020 100644
--- a/components/script/dom/webidls/HTMLPreElement.webidl
+++ b/components/script/dom/webidls/HTMLPreElement.webidl
@@ -3,7 +3,6 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
// https://html.spec.whatwg.org/multipage/#htmlpreelement
-[Exposed=(Window,Worker)]
interface HTMLPreElement : HTMLElement {
// also has obsolete members
};
diff --git a/components/script/dom/webidls/HTMLProgressElement.webidl b/components/script/dom/webidls/HTMLProgressElement.webidl
index 852e683b1f7..cf69566ecdd 100644
--- a/components/script/dom/webidls/HTMLProgressElement.webidl
+++ b/components/script/dom/webidls/HTMLProgressElement.webidl
@@ -3,7 +3,6 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
// https://html.spec.whatwg.org/multipage/#htmlprogresselement
-[Exposed=(Window,Worker)]
interface HTMLProgressElement : HTMLElement {
// attribute double value;
// attribute double max;
diff --git a/components/script/dom/webidls/HTMLQuoteElement.webidl b/components/script/dom/webidls/HTMLQuoteElement.webidl
index 6741d7b4041..e546f151d49 100644
--- a/components/script/dom/webidls/HTMLQuoteElement.webidl
+++ b/components/script/dom/webidls/HTMLQuoteElement.webidl
@@ -3,7 +3,6 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
// https://html.spec.whatwg.org/multipage/#htmlquoteelement
-[Exposed=(Window,Worker)]
interface HTMLQuoteElement : HTMLElement {
// attribute DOMString cite;
};
diff --git a/components/script/dom/webidls/HTMLSelectElement.webidl b/components/script/dom/webidls/HTMLSelectElement.webidl
index 2bcbbf098e4..ba84d183a72 100644
--- a/components/script/dom/webidls/HTMLSelectElement.webidl
+++ b/components/script/dom/webidls/HTMLSelectElement.webidl
@@ -3,7 +3,6 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
// https://html.spec.whatwg.org/multipage/#htmlselectelement
-[Exposed=(Window,Worker)]
interface HTMLSelectElement : HTMLElement {
// attribute boolean autofocus;
attribute boolean disabled;
diff --git a/components/script/dom/webidls/HTMLSourceElement.webidl b/components/script/dom/webidls/HTMLSourceElement.webidl
index a631876b42e..738a545713a 100644
--- a/components/script/dom/webidls/HTMLSourceElement.webidl
+++ b/components/script/dom/webidls/HTMLSourceElement.webidl
@@ -3,7 +3,6 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
// https://html.spec.whatwg.org/multipage/#htmlsourceelement
-[Exposed=(Window,Worker)]
interface HTMLSourceElement : HTMLElement {
// attribute DOMString src;
// attribute DOMString type;
diff --git a/components/script/dom/webidls/HTMLSpanElement.webidl b/components/script/dom/webidls/HTMLSpanElement.webidl
index 082ba45cf8b..a74967536a1 100644
--- a/components/script/dom/webidls/HTMLSpanElement.webidl
+++ b/components/script/dom/webidls/HTMLSpanElement.webidl
@@ -3,5 +3,4 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
// https://html.spec.whatwg.org/multipage/#htmlspanelement
-[Exposed=(Window,Worker)]
interface HTMLSpanElement : HTMLElement {};
diff --git a/components/script/dom/webidls/HTMLStyleElement.webidl b/components/script/dom/webidls/HTMLStyleElement.webidl
index 4bc4430a38c..dd766f41d22 100644
--- a/components/script/dom/webidls/HTMLStyleElement.webidl
+++ b/components/script/dom/webidls/HTMLStyleElement.webidl
@@ -3,7 +3,6 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
// https://html.spec.whatwg.org/multipage/#htmlstyleelement
-[Exposed=(Window,Worker)]
interface HTMLStyleElement : HTMLElement {
// attribute DOMString media;
// attribute DOMString type;
diff --git a/components/script/dom/webidls/HTMLTableCaptionElement.webidl b/components/script/dom/webidls/HTMLTableCaptionElement.webidl
index 0860aa7e796..b405d23ed40 100644
--- a/components/script/dom/webidls/HTMLTableCaptionElement.webidl
+++ b/components/script/dom/webidls/HTMLTableCaptionElement.webidl
@@ -3,7 +3,6 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
// https://html.spec.whatwg.org/multipage/#htmltablecaptionelement
-[Exposed=(Window,Worker)]
interface HTMLTableCaptionElement : HTMLElement {
// also has obsolete members
};
diff --git a/components/script/dom/webidls/HTMLTableCellElement.webidl b/components/script/dom/webidls/HTMLTableCellElement.webidl
index 2264d56b5e2..33863b3dc20 100644
--- a/components/script/dom/webidls/HTMLTableCellElement.webidl
+++ b/components/script/dom/webidls/HTMLTableCellElement.webidl
@@ -3,7 +3,7 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
// https://html.spec.whatwg.org/multipage/#htmltablecellelement
-[Abstract, Exposed=(Window,Worker)]
+[Abstract]
interface HTMLTableCellElement : HTMLElement {
attribute unsigned long colSpan;
// attribute unsigned long rowSpan;
diff --git a/components/script/dom/webidls/HTMLTableColElement.webidl b/components/script/dom/webidls/HTMLTableColElement.webidl
index 3868de31272..69188251443 100644
--- a/components/script/dom/webidls/HTMLTableColElement.webidl
+++ b/components/script/dom/webidls/HTMLTableColElement.webidl
@@ -3,7 +3,6 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
// https://html.spec.whatwg.org/multipage/#htmltablecolelement
-[Exposed=(Window,Worker)]
interface HTMLTableColElement : HTMLElement {
// attribute unsigned long span;
diff --git a/components/script/dom/webidls/HTMLTableDataCellElement.webidl b/components/script/dom/webidls/HTMLTableDataCellElement.webidl
index 7c286df77e4..208ed76d692 100644
--- a/components/script/dom/webidls/HTMLTableDataCellElement.webidl
+++ b/components/script/dom/webidls/HTMLTableDataCellElement.webidl
@@ -3,7 +3,6 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
// https://html.spec.whatwg.org/multipage/#htmltabledatacellelement
-[Exposed=(Window,Worker)]
interface HTMLTableDataCellElement : HTMLTableCellElement {
// also has obsolete members
};
diff --git a/components/script/dom/webidls/HTMLTableElement.webidl b/components/script/dom/webidls/HTMLTableElement.webidl
index c97d24fd57b..f0d8e19d0eb 100644
--- a/components/script/dom/webidls/HTMLTableElement.webidl
+++ b/components/script/dom/webidls/HTMLTableElement.webidl
@@ -3,7 +3,6 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
// https://html.spec.whatwg.org/multipage/#htmltableelement
-[Exposed=(Window,Worker)]
interface HTMLTableElement : HTMLElement {
attribute HTMLTableCaptionElement? caption;
HTMLTableCaptionElement createCaption();
@@ -20,7 +19,7 @@ interface HTMLTableElement : HTMLElement {
HTMLTableSectionElement createTBody();
readonly attribute HTMLCollection rows;
[Throws] HTMLTableRowElement insertRow(optional long index = -1);
- //void deleteRow(long index);
+ [Throws] void deleteRow(long index);
// also has obsolete members
};
diff --git a/components/script/dom/webidls/HTMLTableHeaderCellElement.webidl b/components/script/dom/webidls/HTMLTableHeaderCellElement.webidl
index fb3e7126672..9bf8f1fc950 100644
--- a/components/script/dom/webidls/HTMLTableHeaderCellElement.webidl
+++ b/components/script/dom/webidls/HTMLTableHeaderCellElement.webidl
@@ -3,7 +3,6 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
// https://html.spec.whatwg.org/multipage/#htmltableheadercellelement
-[Exposed=(Window,Worker)]
interface HTMLTableHeaderCellElement : HTMLTableCellElement {
// attribute DOMString scope;
// attribute DOMString abbr;
diff --git a/components/script/dom/webidls/HTMLTableRowElement.webidl b/components/script/dom/webidls/HTMLTableRowElement.webidl
index 75898c577e1..9d4b0655cad 100644
--- a/components/script/dom/webidls/HTMLTableRowElement.webidl
+++ b/components/script/dom/webidls/HTMLTableRowElement.webidl
@@ -3,7 +3,6 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
// https://html.spec.whatwg.org/multipage/#htmltablerowelement
-[Exposed=(Window,Worker)]
interface HTMLTableRowElement : HTMLElement {
readonly attribute long rowIndex;
readonly attribute long sectionRowIndex;
diff --git a/components/script/dom/webidls/HTMLTableSectionElement.webidl b/components/script/dom/webidls/HTMLTableSectionElement.webidl
index dd9d1c654f1..979d8030ffd 100644
--- a/components/script/dom/webidls/HTMLTableSectionElement.webidl
+++ b/components/script/dom/webidls/HTMLTableSectionElement.webidl
@@ -3,7 +3,6 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
// https://html.spec.whatwg.org/multipage/#htmltablesectionelement
-[Exposed=(Window,Worker)]
interface HTMLTableSectionElement : HTMLElement {
readonly attribute HTMLCollection rows;
[Throws]
diff --git a/components/script/dom/webidls/HTMLTemplateElement.webidl b/components/script/dom/webidls/HTMLTemplateElement.webidl
index 7506f9a28e0..b3383de69d2 100644
--- a/components/script/dom/webidls/HTMLTemplateElement.webidl
+++ b/components/script/dom/webidls/HTMLTemplateElement.webidl
@@ -3,7 +3,6 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
// https://html.spec.whatwg.org/multipage/#htmltemplateelement
-[Exposed=(Window,Worker)]
interface HTMLTemplateElement : HTMLElement {
readonly attribute DocumentFragment content;
};
diff --git a/components/script/dom/webidls/HTMLTextAreaElement.webidl b/components/script/dom/webidls/HTMLTextAreaElement.webidl
index 32a2ba43ccf..f92e662c354 100644
--- a/components/script/dom/webidls/HTMLTextAreaElement.webidl
+++ b/components/script/dom/webidls/HTMLTextAreaElement.webidl
@@ -3,7 +3,6 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
// https://html.spec.whatwg.org/multipage/#htmltextareaelement
-[Exposed=(Window,Worker)]
interface HTMLTextAreaElement : HTMLElement {
// attribute DOMString autocomplete;
// attribute boolean autofocus;
diff --git a/components/script/dom/webidls/HTMLTimeElement.webidl b/components/script/dom/webidls/HTMLTimeElement.webidl
index dbd80686b0c..21f9dcf090e 100644
--- a/components/script/dom/webidls/HTMLTimeElement.webidl
+++ b/components/script/dom/webidls/HTMLTimeElement.webidl
@@ -3,7 +3,6 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
// https://html.spec.whatwg.org/multipage/#htmltimeelement
-[Exposed=(Window,Worker)]
interface HTMLTimeElement : HTMLElement {
// attribute DOMString dateTime;
};
diff --git a/components/script/dom/webidls/HTMLTitleElement.webidl b/components/script/dom/webidls/HTMLTitleElement.webidl
index 9332cae40a7..10373be7e4b 100644
--- a/components/script/dom/webidls/HTMLTitleElement.webidl
+++ b/components/script/dom/webidls/HTMLTitleElement.webidl
@@ -3,7 +3,6 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
// https://html.spec.whatwg.org/multipage/#htmltitleelement
-[Exposed=(Window,Worker)]
interface HTMLTitleElement : HTMLElement {
[Pure]
attribute DOMString text;
diff --git a/components/script/dom/webidls/HTMLTrackElement.webidl b/components/script/dom/webidls/HTMLTrackElement.webidl
index 9828139bee2..55733235321 100644
--- a/components/script/dom/webidls/HTMLTrackElement.webidl
+++ b/components/script/dom/webidls/HTMLTrackElement.webidl
@@ -3,7 +3,6 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
// https://html.spec.whatwg.org/multipage/#htmltrackelement
-[Exposed=(Window,Worker)]
interface HTMLTrackElement : HTMLElement {
// attribute DOMString kind;
// attribute DOMString src;
diff --git a/components/script/dom/webidls/HTMLUListElement.webidl b/components/script/dom/webidls/HTMLUListElement.webidl
index 6abaf544b7f..91a79c7f925 100644
--- a/components/script/dom/webidls/HTMLUListElement.webidl
+++ b/components/script/dom/webidls/HTMLUListElement.webidl
@@ -3,7 +3,6 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
// https://html.spec.whatwg.org/multipage/#htmlulistelement
-[Exposed=(Window,Worker)]
interface HTMLUListElement : HTMLElement {
// also has obsolete members
};
diff --git a/components/script/dom/webidls/HTMLUnknownElement.webidl b/components/script/dom/webidls/HTMLUnknownElement.webidl
index 624d7d8541d..acf5a47a996 100644
--- a/components/script/dom/webidls/HTMLUnknownElement.webidl
+++ b/components/script/dom/webidls/HTMLUnknownElement.webidl
@@ -11,6 +11,5 @@
* and create derivative works of this document.
*/
-[Exposed=(Window,Worker)]
interface HTMLUnknownElement : HTMLElement {
};
diff --git a/components/script/dom/webidls/HTMLVideoElement.webidl b/components/script/dom/webidls/HTMLVideoElement.webidl
index 3af425cc06b..5e7c9cb9fce 100644
--- a/components/script/dom/webidls/HTMLVideoElement.webidl
+++ b/components/script/dom/webidls/HTMLVideoElement.webidl
@@ -3,7 +3,6 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
// https://html.spec.whatwg.org/multipage/#htmlvideoelement
-[Exposed=(Window,Worker)]
interface HTMLVideoElement : HTMLMediaElement {
// attribute unsigned long width;
// attribute unsigned long height;
diff --git a/components/script/dom/webidls/Headers.webidl b/components/script/dom/webidls/Headers.webidl
index 038dbe46f74..6696bf64731 100644
--- a/components/script/dom/webidls/Headers.webidl
+++ b/components/script/dom/webidls/Headers.webidl
@@ -4,19 +4,21 @@
// https://fetch.spec.whatwg.org/#headers-class
-/* typedef (Headers or sequence<sequence<ByteString>>) HeadersInit; */
-
-/* [Constructor(optional HeadersInit init),*/
- [Exposed=(Window,Worker)]
+// TODO support OpenEndedDictionary<ByteString>
+typedef (Headers or sequence<sequence<ByteString>>) HeadersInit;
+[Constructor(optional HeadersInit init),
+ Exposed=(Window,Worker)]
interface Headers {
[Throws]
void append(ByteString name, ByteString value);
+ [Throws]
+ void delete(ByteString name);
+ [Throws]
+ ByteString? get(ByteString name);
+ [Throws]
+ boolean has(ByteString name);
+ [Throws]
+ void set(ByteString name, ByteString value);
+ // iterable<ByteString, ByteString>; // TODO see issue #12628
};
-
-/* void delete(ByteString name);
- * ByteString? get(ByteString name);
- * boolean has(ByteString name);
- * void set(ByteString name, ByteString value);
- * iterable<ByteString, ByteString>;
- * }; */
diff --git a/components/script/dom/webidls/History.webidl b/components/script/dom/webidls/History.webidl
new file mode 100644
index 00000000000..04742d52601
--- /dev/null
+++ b/components/script/dom/webidls/History.webidl
@@ -0,0 +1,18 @@
+/* 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/. */
+
+// enum ScrollRestoration { "auto", "manual" };
+
+// https://html.spec.whatwg.org/multipage/#the-history-interface
+[Exposed=(Window,Worker)]
+interface History {
+ // readonly attribute unsigned long length;
+ // attribute ScrollRestoration scrollRestoration;
+ // readonly attribute any state;
+ void go(optional long delta = 0);
+ void back();
+ void forward();
+ // void pushState(any data, DOMString title, optional USVString? url = null);
+ // void replaceState(any data, DOMString title, optional USVString? url = null);
+};
diff --git a/components/script/dom/webidls/Window.webidl b/components/script/dom/webidls/Window.webidl
index bda73c9479a..651c7081305 100644
--- a/components/script/dom/webidls/Window.webidl
+++ b/components/script/dom/webidls/Window.webidl
@@ -11,7 +11,7 @@
[Unforgeable] readonly attribute Document document;
// attribute DOMString name;
[/*PutForwards=href, */Unforgeable] readonly attribute Location location;
- //readonly attribute History history;
+ readonly attribute History history;
//[Replaceable] readonly attribute BarProp locationbar;
//[Replaceable] readonly attribute BarProp menubar;
//[Replaceable] readonly attribute BarProp personalbar;
diff --git a/components/script/dom/websocket.rs b/components/script/dom/websocket.rs
index 1a34096f26b..3b3652040e9 100644
--- a/components/script/dom/websocket.rs
+++ b/components/script/dom/websocket.rs
@@ -461,6 +461,8 @@ struct ConnectionEstablishedTask {
}
impl Runnable for ConnectionEstablishedTask {
+ fn name(&self) -> &'static str { "ConnectionEstablishedTask" }
+
fn handler(self: Box<Self>) {
let ws = self.address.root();
let global = ws.r().global();
@@ -510,6 +512,8 @@ impl Runnable for BufferedAmountTask {
// To be compliant with standards, we need to reset bufferedAmount only when the event loop
// reaches step 1. In our implementation, the bytes will already have been sent on a background
// thread.
+ fn name(&self) -> &'static str { "BufferedAmountTask" }
+
fn handler(self: Box<Self>) {
let ws = self.address.root();
@@ -526,6 +530,8 @@ struct CloseTask {
}
impl Runnable for CloseTask {
+ fn name(&self) -> &'static str { "CloseTask" }
+
fn handler(self: Box<Self>) {
let ws = self.address.root();
let ws = ws.r();
@@ -568,6 +574,8 @@ struct MessageReceivedTask {
}
impl Runnable for MessageReceivedTask {
+ fn name(&self) -> &'static str { "MessageReceivedTask" }
+
#[allow(unsafe_code)]
fn handler(self: Box<Self>) {
let ws = self.address.root();
diff --git a/components/script/dom/window.rs b/components/script/dom/window.rs
index b4984bb2a4a..ebd9550d117 100644
--- a/components/script/dom/window.rs
+++ b/components/script/dom/window.rs
@@ -30,6 +30,7 @@ use dom::document::Document;
use dom::element::Element;
use dom::event::Event;
use dom::eventtarget::EventTarget;
+use dom::history::History;
use dom::htmliframeelement::build_mozbrowser_custom_event;
use dom::location::Location;
use dom::navigator::Navigator;
@@ -94,7 +95,7 @@ use task_source::networking::NetworkingTaskSource;
use task_source::user_interaction::UserInteractionTaskSource;
use time;
use timers::{IsInterval, OneshotTimerCallback, OneshotTimerHandle, OneshotTimers, TimerCallback};
-#[cfg(any(target_os = "macos", target_os = "linux"))]
+#[cfg(any(target_os = "macos", target_os = "linux", target_os = "windows"))]
use tinyfiledialogs::{self, MessageBoxIcon};
use url::Url;
use util::geometry::{self, MAX_RECT};
@@ -158,6 +159,7 @@ pub struct Window {
#[ignore_heap_size_of = "channels are hard"]
image_cache_chan: ImageCacheChan,
browsing_context: MutNullableHeap<JS<BrowsingContext>>,
+ history: MutNullableHeap<JS<History>>,
performance: MutNullableHeap<JS<Performance>>,
navigation_start: u64,
navigation_start_precise: f64,
@@ -359,14 +361,14 @@ impl Window {
}
}
-#[cfg(any(target_os = "macos", target_os = "linux"))]
+#[cfg(any(target_os = "macos", target_os = "linux", target_os = "windows"))]
fn display_alert_dialog(message: &str) {
tinyfiledialogs::message_box_ok("Alert!", message, MessageBoxIcon::Warning);
}
-#[cfg(not(any(target_os = "macos", target_os = "linux")))]
+#[cfg(not(any(target_os = "macos", target_os = "linux", target_os = "windows")))]
fn display_alert_dialog(_message: &str) {
- // tinyfiledialogs not supported on Windows
+ // tinyfiledialogs not supported on Android
}
// https://html.spec.whatwg.org/multipage/#atob
@@ -448,13 +450,15 @@ impl WindowMethods for Window {
// Right now, just print to the console
// Ensure that stderr doesn't trample through the alert() we use to
// communicate test results (see executorservo.py in wptrunner).
- let stderr = stderr();
- let mut stderr = stderr.lock();
- let stdout = stdout();
- let mut stdout = stdout.lock();
- writeln!(&mut stdout, "ALERT: {}", s).unwrap();
- stdout.flush().unwrap();
- stderr.flush().unwrap();
+ {
+ let stderr = stderr();
+ let mut stderr = stderr.lock();
+ let stdout = stdout();
+ let mut stdout = stdout.lock();
+ writeln!(&mut stdout, "ALERT: {}", s).unwrap();
+ stdout.flush().unwrap();
+ stderr.flush().unwrap();
+ }
let (sender, receiver) = ipc::channel().unwrap();
self.constellation_chan().send(ConstellationMsg::Alert(self.pipeline(), s.to_string(), sender)).unwrap();
@@ -475,6 +479,11 @@ impl WindowMethods for Window {
self.browsing_context().active_document()
}
+ // https://html.spec.whatwg.org/multipage/#dom-history
+ fn History(&self) -> Root<History> {
+ self.history.or_init(|| History::new(self))
+ }
+
// https://html.spec.whatwg.org/multipage/#dom-location
fn Location(&self) -> Root<Location> {
self.Document().GetLocation().unwrap()
@@ -1648,6 +1657,7 @@ impl Window {
mem_profiler_chan: mem_profiler_chan,
time_profiler_chan: time_profiler_chan,
devtools_chan: devtools_chan,
+ history: Default::default(),
browsing_context: Default::default(),
performance: Default::default(),
navigation_start: (current_time.sec * 1000 + current_time.nsec as i64 / 1000000) as u64,
diff --git a/components/script/dom/worker.rs b/components/script/dom/worker.rs
index c318672fb7a..c1ad7cf5a96 100644
--- a/components/script/dom/worker.rs
+++ b/components/script/dom/worker.rs
@@ -27,6 +27,7 @@ use js::jsapi::{HandleValue, JSContext, JSAutoCompartment};
use js::jsval::UndefinedValue;
use script_thread::Runnable;
use script_traits::WorkerScriptLoadOrigin;
+use std::cell::Cell;
use std::sync::atomic::{AtomicBool, Ordering};
use std::sync::mpsc::{Sender, channel};
use std::sync::{Arc, Mutex};
@@ -43,7 +44,8 @@ pub struct Worker {
sender: Sender<(TrustedWorkerAddress, WorkerScriptMsg)>,
closing: Arc<AtomicBool>,
#[ignore_heap_size_of = "Defined in rust-mozjs"]
- runtime: Arc<Mutex<Option<SharedRt>>>
+ runtime: Arc<Mutex<Option<SharedRt>>>,
+ terminated: Cell<bool>,
}
impl Worker {
@@ -53,7 +55,8 @@ impl Worker {
eventtarget: EventTarget::new_inherited(),
sender: sender,
closing: closing,
- runtime: Arc::new(Mutex::new(None))
+ runtime: Arc::new(Mutex::new(None)),
+ terminated: Cell::new(false),
}
}
@@ -112,11 +115,15 @@ impl Worker {
self.closing.load(Ordering::SeqCst)
}
+ pub fn is_terminated(&self) -> bool {
+ self.terminated.get()
+ }
+
pub fn handle_message(address: TrustedWorkerAddress,
data: StructuredCloneData) {
let worker = address.root();
- if worker.is_closing() {
+ if worker.is_terminated() {
return;
}
@@ -137,7 +144,7 @@ impl Worker {
filename: DOMString, lineno: u32, colno: u32) {
let worker = address.root();
- if worker.is_closing() {
+ if worker.is_terminated() {
return;
}
@@ -169,7 +176,10 @@ impl WorkerMethods for Worker {
return;
}
- // Step 4
+ // Step 2
+ self.terminated.set(true);
+
+ // Step 3
if let Some(runtime) = *self.runtime.lock().unwrap() {
runtime.request_interrupt();
}
diff --git a/components/script/dom/workerglobalscope.rs b/components/script/dom/workerglobalscope.rs
index 154705fe145..16388d54d73 100644
--- a/components/script/dom/workerglobalscope.rs
+++ b/components/script/dom/workerglobalscope.rs
@@ -444,4 +444,10 @@ impl WorkerGlobalScope {
pub fn set_devtools_wants_updates(&self, value: bool) {
self.devtools_wants_updates.set(value);
}
+
+ pub fn close(&self) {
+ if let Some(ref closing) = self.closing {
+ closing.store(true, Ordering::SeqCst);
+ }
+ }
}
diff --git a/components/script/dom/xmlhttprequest.rs b/components/script/dom/xmlhttprequest.rs
index 5cef702c01a..b35ffef73c5 100644
--- a/components/script/dom/xmlhttprequest.rs
+++ b/components/script/dom/xmlhttprequest.rs
@@ -594,6 +594,7 @@ impl XMLHttpRequestMethods for XMLHttpRequest {
origin: self.global().r().get_url(),
referer_url: self.referrer_url.clone(),
referrer_policy: self.referrer_policy.clone(),
+ pipeline_id: self.pipeline_id(),
};
if bypass_cross_origin_check {
diff --git a/components/script/layout_wrapper.rs b/components/script/layout_wrapper.rs
index df44774dd5a..bfd7a8273d9 100644
--- a/components/script/layout_wrapper.rs
+++ b/components/script/layout_wrapper.rs
@@ -199,15 +199,6 @@ impl<'ln> TNode for ServoLayoutNode<'ln> {
self.node.set_flag(DIRTY_ON_VIEWPORT_SIZE_CHANGE, true);
}
- fn set_descendants_dirty_on_viewport_size_changed(&self) {
- for ref child in self.children() {
- unsafe {
- child.set_dirty_on_viewport_size_changed();
- }
- child.set_descendants_dirty_on_viewport_size_changed();
- }
- }
-
fn can_be_fragmented(&self) -> bool {
unsafe { self.node.get_flag(CAN_BE_FRAGMENTED) }
}
diff --git a/components/script/lib.rs b/components/script/lib.rs
index 78a84f83586..2eecac4d1b5 100644
--- a/components/script/lib.rs
+++ b/components/script/lib.rs
@@ -10,7 +10,6 @@
#![feature(custom_attribute)]
#![feature(custom_derive)]
#![feature(fnbox)]
-#![feature(iter_arith)]
#![feature(mpsc_select)]
#![feature(nonzero)]
#![feature(on_unimplemented)]
@@ -82,12 +81,14 @@ extern crate smallvec;
#[macro_use]
extern crate style;
extern crate time;
-#[cfg(any(target_os = "macos", target_os = "linux"))]
+#[cfg(any(target_os = "macos", target_os = "linux", target_os = "windows"))]
extern crate tinyfiledialogs;
extern crate url;
#[macro_use]
extern crate util;
extern crate uuid;
+#[cfg(not(any(target_os = "android", target_arch = "arm", target_arch = "aarch64")))]
+extern crate video_metadata;
extern crate webrender_traits;
extern crate websocket;
extern crate xml5ever;
@@ -186,4 +187,3 @@ pub fn init(sw_senders: SWManagerSenders) {
pub unsafe fn script_can_initiate_scroll(_: *mut JSContext, _: Handle<*mut JSObject>) -> bool {
!opts::get().use_webrender
}
-
diff --git a/components/script/script_runtime.rs b/components/script/script_runtime.rs
index d07491d8ce8..dfbb5ba5203 100644
--- a/components/script/script_runtime.rs
+++ b/components/script/script_runtime.rs
@@ -120,7 +120,7 @@ pub unsafe fn new_rt_and_cx() -> Runtime {
// Pre barriers aren't working correctly at the moment
DisableIncrementalGC(runtime.rt());
- set_gc_zeal_options(runtime.cx());
+ set_gc_zeal_options(runtime.rt());
// Enable or disable the JITs.
let rt_opts = &mut *RuntimeOptionsRef(runtime.rt());
@@ -400,7 +400,7 @@ unsafe extern fn trace_rust_roots(tr: *mut JSTracer, _data: *mut os::raw::c_void
#[allow(unsafe_code)]
#[cfg(feature = "debugmozjs")]
-unsafe fn set_gc_zeal_options(cx: *mut JSContext) {
+unsafe fn set_gc_zeal_options(rt: *mut JSRuntime) {
use js::jsapi::{JS_DEFAULT_ZEAL_FREQ, JS_SetGCZeal};
let level = match PREFS.get("js.mem.gc.zeal.level").as_i64() {
@@ -411,9 +411,9 @@ unsafe fn set_gc_zeal_options(cx: *mut JSContext) {
Some(frequency) if frequency >= 0 => frequency as u32,
_ => JS_DEFAULT_ZEAL_FREQ,
};
- JS_SetGCZeal(cx, level, frequency);
+ JS_SetGCZeal(rt, level, frequency);
}
#[allow(unsafe_code)]
#[cfg(not(feature = "debugmozjs"))]
-unsafe fn set_gc_zeal_options(_: *mut JSContext) {}
+unsafe fn set_gc_zeal_options(_: *mut JSRuntime) {}
diff --git a/components/script/script_thread.rs b/components/script/script_thread.rs
index cf0cebf5a65..e3d2766c84c 100644
--- a/components/script/script_thread.rs
+++ b/components/script/script_thread.rs
@@ -1073,7 +1073,10 @@ impl ScriptThread {
fn handle_resize(&self, id: PipelineId, size: WindowSizeData, size_type: WindowSizeType) {
if let Some(ref context) = self.find_child_context(id) {
- let window = context.active_window();
+ let window = match context.find(id) {
+ Some(browsing_context) => browsing_context.active_window(),
+ None => return warn!("Message sent to closed pipeline {}.", id),
+ };
window.set_resize_event(size, size_type);
return;
}
@@ -1142,6 +1145,7 @@ impl ScriptThread {
pipeline_port,
layout_to_constellation_chan,
content_process_shutdown_chan,
+ layout_threads,
} = new_layout_info;
let layout_pair = channel();
@@ -1158,6 +1162,7 @@ impl ScriptThread {
script_chan: self.control_chan.clone(),
image_cache_thread: self.image_cache_thread.clone(),
content_process_shutdown_chan: content_process_shutdown_chan,
+ layout_threads: layout_threads,
};
let context = self.root_browsing_context();
@@ -1193,8 +1198,6 @@ impl ScriptThread {
// https://html.spec.whatwg.org/multipage/#the-end step 7
let handler = box DocumentProgressHandler::new(Trusted::new(doc));
self.dom_manipulation_task_source.queue(handler, GlobalRef::Window(doc.window())).unwrap();
-
- self.constellation_chan.send(ConstellationMsg::LoadComplete(pipeline)).unwrap();
}
fn collect_reports(&self, reports_chan: ReportsChan) {
@@ -2209,15 +2212,6 @@ fn shut_down_layout(context_tree: &BrowsingContext) {
}
}
-// TODO: remove this function, as it's a source of panic.
-pub fn get_browsing_context(context: &BrowsingContext,
- pipeline_id: PipelineId)
- -> Root<BrowsingContext> {
- context.find(pipeline_id).expect("ScriptThread: received an event \
- message for a layout channel that is not associated with this script thread.\
- This is a bug.")
-}
-
fn dom_last_modified(tm: &Tm) -> String {
tm.to_local().strftime("%m/%d/%Y %H:%M:%S").unwrap().to_string()
}
diff --git a/components/script/serviceworker_manager.rs b/components/script/serviceworker_manager.rs
index 85f76faadd1..1c24c6fef3f 100644
--- a/components/script/serviceworker_manager.rs
+++ b/components/script/serviceworker_manager.rs
@@ -8,15 +8,16 @@
//! active_workers map
use devtools_traits::{DevtoolsPageInfo, ScriptToDevtoolsControlMsg};
-use dom::serviceworkerglobalscope::ServiceWorkerGlobalScope;
+use dom::serviceworkerglobalscope::{ServiceWorkerGlobalScope, ServiceWorkerScriptMsg};
use dom::serviceworkerregistration::longest_prefix_match;
use ipc_channel::ipc::{self, IpcSender};
use ipc_channel::router::ROUTER;
use net_traits::{CustomResponseMediator, CoreResourceMsg};
use script_traits::{ServiceWorkerMsg, ScopeThings, SWManagerMsg, SWManagerSenders};
use std::collections::HashMap;
-use std::sync::mpsc::{channel, Receiver, RecvError};
+use std::sync::mpsc::{channel, Sender, Receiver, RecvError};
use url::Url;
+use util::prefs::PREFS;
use util::thread::spawn_named;
enum Message {
@@ -62,7 +63,7 @@ impl ServiceWorkerManager {
});
}
- pub fn prepare_activation(&mut self, load_url: &Url) {
+ pub fn prepare_activation(&mut self, load_url: &Url) -> Option<Sender<ServiceWorkerScriptMsg>> {
let mut scope_url = None;
for scope in self.registered_workers.keys() {
if longest_prefix_match(&scope, load_url) {
@@ -75,7 +76,7 @@ impl ServiceWorkerManager {
if self.active_workers.contains_key(&scope_url) {
// do not run the same worker if already active.
warn!("Service worker for {:?} already active", scope_url);
- return;
+ return None;
}
let scope_things = self.registered_workers.get(&scope_url);
if let Some(scope_things) = scope_things {
@@ -93,17 +94,19 @@ impl ServiceWorkerManager {
page_info));
};
ServiceWorkerGlobalScope::run_serviceworker_scope(scope_things.clone(),
- sender,
+ sender.clone(),
receiver,
devtools_receiver,
self.own_sender.clone(),
scope_url.clone());
// We store the activated worker
self.active_workers.insert(scope_url.clone(), scope_things.clone());
+ return Some(sender);
} else {
warn!("Unable to activate service worker");
}
}
+ None
}
fn handle_message(&mut self) {
@@ -146,11 +149,14 @@ impl ServiceWorkerManager {
#[inline]
fn handle_message_from_resource(&mut self, mediator: CustomResponseMediator) -> bool {
- self.prepare_activation(&mediator.load_url);
- // TODO XXXcreativcoder This mediator will need to be send to the appropriate service worker
- // so that it may do the sending of custom responses.
- // For now we just send a None from here itself
- let _ = mediator.response_chan.send(None);
+ if serviceworker_enabled() {
+ let worker_sender = self.prepare_activation(&mediator.load_url);
+ if let Some(ref sender) = worker_sender {
+ let _ = sender.send(ServiceWorkerScriptMsg::Response(mediator));
+ }
+ } else {
+ let _ = mediator.response_chan.send(None);
+ }
true
}
@@ -164,3 +170,7 @@ impl ServiceWorkerManager {
}
}
}
+
+pub fn serviceworker_enabled() -> bool {
+ PREFS.get("dom.serviceworker.enabled").as_boolean().unwrap_or(false)
+}
diff --git a/components/script/webdriver_handlers.rs b/components/script/webdriver_handlers.rs
index 2711cfb1225..74a754c36ce 100644
--- a/components/script/webdriver_handlers.rs
+++ b/components/script/webdriver_handlers.rs
@@ -34,7 +34,6 @@ use msg::constellation_msg::PipelineId;
use net_traits::CookieSource::{HTTP, NonHTTP};
use net_traits::CoreResourceMsg::{GetCookiesDataForUrl, SetCookiesForUrlWithData};
use net_traits::IpcSend;
-use script_thread::get_browsing_context;
use script_traits::webdriver_msg::WebDriverCookieError;
use script_traits::webdriver_msg::{WebDriverFrameId, WebDriverJSError, WebDriverJSResult, WebDriverJSValue};
use url::Url;
@@ -43,7 +42,11 @@ fn find_node_by_unique_id(context: &BrowsingContext,
pipeline: PipelineId,
node_id: String)
-> Option<Root<Node>> {
- let context = get_browsing_context(&context, pipeline);
+ let context = match context.find(pipeline) {
+ Some(context) => context,
+ None => return None
+ };
+
let document = context.active_document();
document.upcast::<Node>().traverse_preorder().find(|candidate| candidate.unique_id() == node_id)
}
@@ -72,7 +75,11 @@ pub fn handle_execute_script(context: &BrowsingContext,
pipeline: PipelineId,
eval: String,
reply: IpcSender<WebDriverJSResult>) {
- let context = get_browsing_context(&context, pipeline);
+ let context = match context.find(pipeline) {
+ Some(context) => context,
+ None => return reply.send(Err(WebDriverJSError::BrowsingContextNotFound)).unwrap()
+ };
+
let window = context.active_window();
let result = unsafe {
let cx = window.get_cx();
@@ -87,7 +94,11 @@ pub fn handle_execute_async_script(context: &BrowsingContext,
pipeline: PipelineId,
eval: String,
reply: IpcSender<WebDriverJSResult>) {
- let context = get_browsing_context(&context, pipeline);
+ let context = match context.find(pipeline) {
+ Some(context) => context,
+ None => return reply.send(Err(WebDriverJSError::BrowsingContextNotFound)).unwrap()
+ };
+
let window = context.active_window();
let cx = window.get_cx();
window.set_webdriver_script_chan(Some(reply));
diff --git a/components/script_layout_interface/Cargo.toml b/components/script_layout_interface/Cargo.toml
index d4a71804900..cbd8d65b72e 100644
--- a/components/script_layout_interface/Cargo.toml
+++ b/components/script_layout_interface/Cargo.toml
@@ -18,7 +18,7 @@ euclid = "0.7.1"
gfx_traits = {path = "../gfx_traits"}
heapsize = "0.3.0"
heapsize_plugin = "0.1.2"
-ipc-channel = {git = "https://github.com/servo/ipc-channel"}
+ipc-channel = "0.4.0"
libc = "0.2"
log = "0.3.5"
msg = {path = "../msg"}
diff --git a/components/script_layout_interface/message.rs b/components/script_layout_interface/message.rs
index 4fbed81429d..b46703e778e 100644
--- a/components/script_layout_interface/message.rs
+++ b/components/script_layout_interface/message.rs
@@ -149,4 +149,5 @@ pub struct NewLayoutThreadInfo {
pub image_cache_thread: ImageCacheThread,
pub paint_chan: OptionalOpaqueIpcSender,
pub content_process_shutdown_chan: IpcSender<()>,
+ pub layout_threads: usize,
}
diff --git a/components/script_traits/Cargo.toml b/components/script_traits/Cargo.toml
index 67a229cbb80..47fc10b95c7 100644
--- a/components/script_traits/Cargo.toml
+++ b/components/script_traits/Cargo.toml
@@ -18,7 +18,7 @@ euclid = "0.7.1"
gfx_traits = {path = "../gfx_traits"}
heapsize = "0.3.0"
heapsize_plugin = "0.1.2"
-ipc-channel = {git = "https://github.com/servo/ipc-channel"}
+ipc-channel = "0.4.0"
layers = {git = "https://github.com/servo/rust-layers", features = ["plugins"]}
libc = "0.2"
msg = {path = "../msg"}
@@ -27,8 +27,8 @@ offscreen_gl_context = "0.1.2"
plugins = {path = "../plugins"}
profile_traits = {path = "../profile_traits"}
rustc-serialize = "0.3.4"
-serde = "0.7.11"
-serde_macros = "0.7.11"
+serde = "0.7.15"
+serde_macros = "0.7.15"
style_traits = {path = "../style_traits", features = ["servo"]}
time = "0.1.12"
url = {version = "1.0.0", features = ["heap_size"]}
diff --git a/components/script_traits/lib.rs b/components/script_traits/lib.rs
index 7731e16743d..8269ca318ed 100644
--- a/components/script_traits/lib.rs
+++ b/components/script_traits/lib.rs
@@ -146,6 +146,8 @@ pub struct NewLayoutInfo {
pub layout_to_constellation_chan: IpcSender<LayoutMsg>,
/// A shutdown channel so that layout can tell the content process to shut down when it's done.
pub content_process_shutdown_chan: IpcSender<()>,
+ /// Number of threads to use for layout.
+ pub layout_threads: usize,
}
/// Messages sent from the constellation or layout to the script thread.
diff --git a/components/script_traits/script_msg.rs b/components/script_traits/script_msg.rs
index 3ba4494432b..58a49165448 100644
--- a/components/script_traits/script_msg.rs
+++ b/components/script_traits/script_msg.rs
@@ -59,6 +59,7 @@ pub enum LogEntry {
/// Messages from the script to the constellation.
#[derive(Deserialize, Serialize)]
+#[serde(bound = "")] // Prevent serde from generating cyclic bounds.
pub enum ScriptMsg {
/// Indicates whether this pipeline is currently running animations.
ChangeRunningAnimationsState(PipelineId, AnimationState),
@@ -70,10 +71,6 @@ pub enum ScriptMsg {
CreateWebGLPaintThread(Size2D<i32>,
GLContextAttributes,
IpcSender<Result<(IpcSender<CanvasMsg>, GLLimits), String>>),
- /// Dispatched after the DOM load event has fired on a document
- /// Causes a `load` event to be dispatched to any enclosing frame context element
- /// for the given pipeline.
- DOMLoad(PipelineId),
/// Notifies the constellation that this frame has received focus.
Focus(PipelineId),
/// Re-send a mouse button event that was sent to the parent window.
@@ -84,7 +81,8 @@ pub enum ScriptMsg {
GetClipboardContents(IpcSender<String>),
/// <head> tag finished parsing
HeadParsed,
- /// All pending loads are complete.
+ /// All pending loads are complete, and the `load` event for this pipeline
+ /// has been dispatched.
LoadComplete(PipelineId),
/// A new load has been requested.
LoadUrl(PipelineId, LoadData),
diff --git a/components/script_traits/webdriver_msg.rs b/components/script_traits/webdriver_msg.rs
index 0694c97f29d..09d3c9e9e1c 100644
--- a/components/script_traits/webdriver_msg.rs
+++ b/components/script_traits/webdriver_msg.rs
@@ -53,7 +53,10 @@ pub enum WebDriverJSValue {
#[derive(Deserialize, Serialize)]
pub enum WebDriverJSError {
Timeout,
- UnknownType
+ UnknownType,
+ /// Occurs when handler received an event message for a layout channel that is not
+ /// associated with the current script thread
+ BrowsingContextNotFound
}
pub type WebDriverJSResult = Result<WebDriverJSValue, WebDriverJSError>;
diff --git a/components/servo/.cargo/config b/components/servo/.cargo/config
index dffe440072c..1cea095353f 100644
--- a/components/servo/.cargo/config
+++ b/components/servo/.cargo/config
@@ -9,3 +9,6 @@ ar = "arm-linux-gnueabihf-ar"
[target.aarch64-unknown-linux-gnu]
linker = "aarch64-linux-gnu-gcc"
ar = "aarch64-linux-gnu-ar"
+
+[target.'cfg(target_os=windows)']
+linker = "./fake-ld.cmd" \ No newline at end of file
diff --git a/components/servo/Cargo.lock b/components/servo/Cargo.lock
index b881a7c3ac4..55e2ebc8d87 100644
--- a/components/servo/Cargo.lock
+++ b/components/servo/Cargo.lock
@@ -19,7 +19,7 @@ dependencies = [
"gfx_tests 0.0.1",
"gleam 0.2.20 (registry+https://github.com/rust-lang/crates.io-index)",
"glutin_app 0.0.1",
- "ipc-channel 0.4.0 (git+https://github.com/servo/ipc-channel)",
+ "ipc-channel 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
"layout 0.0.1",
"layout_tests 0.0.1",
"layout_thread 0.0.1",
@@ -83,7 +83,7 @@ dependencies = [
"heapsize 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
"num-traits 0.1.32 (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.7.11 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 0.7.15 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@@ -97,7 +97,7 @@ dependencies = [
[[package]]
name = "aster"
-version = "0.19.0"
+version = "0.22.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
@@ -113,8 +113,8 @@ dependencies = [
"heapsize 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
"heapsize_plugin 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.13 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde 0.7.11 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde_macros 0.7.11 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 0.7.15 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde_macros 0.7.15 (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 2.4.11 (registry+https://github.com/rust-lang/crates.io-index)",
"servo-skia 0.20130412.10 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -152,7 +152,7 @@ dependencies = [
"byteorder 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)",
"num-traits 0.1.32 (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.7.11 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 0.7.15 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@@ -209,7 +209,7 @@ dependencies = [
"euclid 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)",
"gfx_traits 0.0.1",
"gleam 0.2.20 (registry+https://github.com/rust-lang/crates.io-index)",
- "ipc-channel 0.4.0 (git+https://github.com/servo/ipc-channel)",
+ "ipc-channel 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
"num-traits 0.1.32 (registry+https://github.com/rust-lang/crates.io-index)",
"offscreen_gl_context 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -228,10 +228,10 @@ dependencies = [
"gfx_traits 0.0.1",
"heapsize 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
"heapsize_plugin 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
- "ipc-channel 0.4.0 (git+https://github.com/servo/ipc-channel)",
+ "ipc-channel 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
"plugins 0.0.1",
- "serde 0.7.11 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde_macros 0.7.11 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 0.7.15 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde_macros 0.7.15 (registry+https://github.com/rust-lang/crates.io-index)",
"webrender_traits 0.2.0 (git+https://github.com/servo/webrender_traits)",
]
@@ -307,7 +307,7 @@ dependencies = [
"gfx_traits 0.0.1",
"gleam 0.2.20 (registry+https://github.com/rust-lang/crates.io-index)",
"image 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "ipc-channel 0.4.0 (git+https://github.com/servo/ipc-channel)",
+ "ipc-channel 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
"layers 0.2.6 (git+https://github.com/servo/rust-layers)",
"log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
"msg 0.0.1",
@@ -315,8 +315,8 @@ dependencies = [
"plugins 0.0.1",
"profile_traits 0.0.1",
"script_traits 0.0.1",
- "serde 0.7.11 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde_macros 0.7.11 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 0.7.15 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde_macros 0.7.15 (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)",
"url 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -338,7 +338,7 @@ dependencies = [
"gaol 0.0.1 (git+https://github.com/servo/gaol)",
"gfx 0.0.1",
"gfx_traits 0.0.1",
- "ipc-channel 0.4.0 (git+https://github.com/servo/ipc-channel)",
+ "ipc-channel 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
"layers 0.2.6 (git+https://github.com/servo/rust-layers)",
"layout_traits 0.0.1",
"log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -349,8 +349,8 @@ dependencies = [
"profile_traits 0.0.1",
"rand 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)",
"script_traits 0.0.1",
- "serde 0.7.11 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde_macros 0.7.11 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 0.7.15 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde_macros 0.7.15 (registry+https://github.com/rust-lang/crates.io-index)",
"style_traits 0.0.1",
"url 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
"util 0.0.1",
@@ -374,7 +374,7 @@ 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)",
- "serde 0.7.11 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 0.7.15 (registry+https://github.com/rust-lang/crates.io-index)",
"time 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)",
"url 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
@@ -403,7 +403,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)",
"libc 0.2.13 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde 0.7.11 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 0.7.15 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@@ -430,8 +430,8 @@ dependencies = [
"heapsize 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
"heapsize_plugin 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
"matches 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde 0.7.11 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde_macros 0.7.11 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 0.7.15 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde_macros 0.7.15 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@@ -482,13 +482,13 @@ version = "0.0.1"
dependencies = [
"devtools_traits 0.0.1",
"hyper 0.9.10 (registry+https://github.com/rust-lang/crates.io-index)",
- "ipc-channel 0.4.0 (git+https://github.com/servo/ipc-channel)",
+ "ipc-channel 0.4.0 (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.7.11 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 0.7.15 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_json 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde_macros 0.7.11 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde_macros 0.7.15 (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",
]
@@ -501,10 +501,10 @@ dependencies = [
"heapsize 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
"heapsize_plugin 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
"hyper 0.9.10 (registry+https://github.com/rust-lang/crates.io-index)",
- "ipc-channel 0.4.0 (git+https://github.com/servo/ipc-channel)",
+ "ipc-channel 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
"msg 0.0.1",
- "serde 0.7.11 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde_macros 0.7.11 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 0.7.15 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde_macros 0.7.15 (registry+https://github.com/rust-lang/crates.io-index)",
"time 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)",
"url 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
@@ -658,7 +658,7 @@ dependencies = [
"log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
"num-traits 0.1.32 (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.7.11 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 0.7.15 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@@ -758,7 +758,7 @@ dependencies = [
"harfbuzz-sys 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
"heapsize 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
"heapsize_plugin 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
- "ipc-channel 0.4.0 (git+https://github.com/servo/ipc-channel)",
+ "ipc-channel 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
"layers 0.2.6 (git+https://github.com/servo/rust-layers)",
"lazy_static 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.13 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -771,8 +771,8 @@ dependencies = [
"rand 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)",
"range 0.0.1",
"rustc-serialize 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde 0.7.11 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde_macros 0.7.11 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 0.7.15 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde_macros 0.7.15 (registry+https://github.com/rust-lang/crates.io-index)",
"servo-fontconfig 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
"simd 0.1.0 (git+https://github.com/huonw/simd)",
"smallvec 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -792,7 +792,7 @@ name = "gfx_tests"
version = "0.0.1"
dependencies = [
"gfx 0.0.1",
- "ipc-channel 0.4.0 (git+https://github.com/servo/ipc-channel)",
+ "ipc-channel 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
"style 0.0.1",
]
@@ -810,8 +810,8 @@ dependencies = [
"profile_traits 0.0.1",
"range 0.0.1",
"rustc-serialize 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde 0.7.11 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde_macros 0.7.11 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 0.7.15 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde_macros 0.7.15 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@@ -938,8 +938,8 @@ dependencies = [
"heapsize_plugin 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
"mac 0.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
- "phf 0.7.15 (registry+https://github.com/rust-lang/crates.io-index)",
- "phf_codegen 0.7.15 (registry+https://github.com/rust-lang/crates.io-index)",
+ "phf 0.7.16 (registry+https://github.com/rust-lang/crates.io-index)",
+ "phf_codegen 0.7.16 (registry+https://github.com/rust-lang/crates.io-index)",
"rustc-serialize 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)",
"string_cache 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)",
"tendril 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -965,7 +965,7 @@ dependencies = [
"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)",
- "serde 0.7.11 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 0.7.15 (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)",
@@ -997,7 +997,7 @@ dependencies = [
"num-iter 0.1.32 (registry+https://github.com/rust-lang/crates.io-index)",
"num-rational 0.1.32 (registry+https://github.com/rust-lang/crates.io-index)",
"num-traits 0.1.32 (registry+https://github.com/rust-lang/crates.io-index)",
- "png 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "png 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@@ -1031,13 +1031,13 @@ dependencies = [
[[package]]
name = "ipc-channel"
version = "0.4.0"
-source = "git+https://github.com/servo/ipc-channel#346456b792f0a8e86b4ed077997408a697a06a0f"
+source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"bincode 0.5.9 (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.13 (registry+https://github.com/rust-lang/crates.io-index)",
"rand 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde 0.7.11 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 0.7.15 (registry+https://github.com/rust-lang/crates.io-index)",
"uuid 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
]
@@ -1053,7 +1053,7 @@ dependencies = [
[[package]]
name = "js"
version = "0.1.3"
-source = "git+https://github.com/servo/rust-mozjs#bc9add648b3174120d70d0bef3935912bd6f1313"
+source = "git+https://github.com/servo/rust-mozjs#14e4556d7cd3dc4fd5eaf5e19e725a1325be14e6"
dependencies = [
"heapsize 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
"lazy_static 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1119,7 +1119,7 @@ dependencies = [
"gfx_traits 0.0.1",
"heapsize 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
"heapsize_plugin 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
- "ipc-channel 0.4.0 (git+https://github.com/servo/ipc-channel)",
+ "ipc-channel 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.13 (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",
@@ -1131,7 +1131,7 @@ dependencies = [
"script_layout_interface 0.0.1",
"script_traits 0.0.1",
"selectors 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde_macros 0.7.11 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde_macros 0.7.15 (registry+https://github.com/rust-lang/crates.io-index)",
"smallvec 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)",
"string_cache 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)",
"style 0.0.1",
@@ -1162,7 +1162,7 @@ dependencies = [
"gfx_traits 0.0.1",
"heapsize 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
"heapsize_plugin 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
- "ipc-channel 0.4.0 (git+https://github.com/servo/ipc-channel)",
+ "ipc-channel 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
"layout 0.0.1",
"layout_traits 0.0.1",
"log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1174,7 +1174,7 @@ dependencies = [
"script_layout_interface 0.0.1",
"script_traits 0.0.1",
"serde_json 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde_macros 0.7.11 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde_macros 0.7.15 (registry+https://github.com/rust-lang/crates.io-index)",
"style 0.0.1",
"url 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
"util 0.0.1",
@@ -1186,7 +1186,7 @@ name = "layout_traits"
version = "0.0.1"
dependencies = [
"gfx 0.0.1",
- "ipc-channel 0.4.0 (git+https://github.com/servo/ipc-channel)",
+ "ipc-channel 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
"msg 0.0.1",
"net_traits 0.0.1",
"profile_traits 0.0.1",
@@ -1310,7 +1310,7 @@ version = "0.2.1"
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.7.11 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 0.7.15 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@@ -1319,8 +1319,8 @@ version = "1.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"mime 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "phf 0.7.15 (registry+https://github.com/rust-lang/crates.io-index)",
- "phf_codegen 0.7.15 (registry+https://github.com/rust-lang/crates.io-index)",
+ "phf 0.7.16 (registry+https://github.com/rust-lang/crates.io-index)",
+ "phf_codegen 0.7.16 (registry+https://github.com/rust-lang/crates.io-index)",
"unicase 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
@@ -1336,7 +1336,7 @@ dependencies = [
[[package]]
name = "mozjs_sys"
version = "0.0.0"
-source = "git+https://github.com/servo/mozjs#2af5849a97a9f18acd482940ba3fa0c6797ed7eb"
+source = "git+https://github.com/servo/mozjs#94eabc218780b696933122184e524bd35544c378"
dependencies = [
"libc 0.2.13 (registry+https://github.com/rust-lang/crates.io-index)",
"libz-sys 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1351,10 +1351,10 @@ dependencies = [
"heapsize 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
"heapsize_plugin 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
"hyper 0.9.10 (registry+https://github.com/rust-lang/crates.io-index)",
- "ipc-channel 0.4.0 (git+https://github.com/servo/ipc-channel)",
+ "ipc-channel 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
"plugins 0.0.1",
- "serde 0.7.11 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde_macros 0.7.11 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 0.7.15 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde_macros 0.7.15 (registry+https://github.com/rust-lang/crates.io-index)",
"url 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
"webrender_traits 0.2.0 (git+https://github.com/servo/webrender_traits)",
]
@@ -1372,7 +1372,7 @@ dependencies = [
"flate2 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)",
"hyper 0.9.10 (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.4.0 (git+https://github.com/servo/ipc-channel)",
+ "ipc-channel 0.4.0 (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)",
"matches 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1418,7 +1418,7 @@ dependencies = [
"devtools_traits 0.0.1",
"flate2 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)",
"hyper 0.9.10 (registry+https://github.com/rust-lang/crates.io-index)",
- "ipc-channel 0.4.0 (git+https://github.com/servo/ipc-channel)",
+ "ipc-channel 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
"msg 0.0.1",
"net 0.0.1",
"net_traits 0.0.1",
@@ -1439,13 +1439,13 @@ dependencies = [
"heapsize_plugin 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
"hyper 0.9.10 (registry+https://github.com/rust-lang/crates.io-index)",
"image 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "ipc-channel 0.4.0 (git+https://github.com/servo/ipc-channel)",
+ "ipc-channel 0.4.0 (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)",
"msg 0.0.1",
"num-traits 0.1.32 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde 0.7.11 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde_macros 0.7.11 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 0.7.15 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde_macros 0.7.15 (registry+https://github.com/rust-lang/crates.io-index)",
"url 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
"util 0.0.1",
"uuid 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1554,7 +1554,7 @@ dependencies = [
"gleam 0.2.20 (registry+https://github.com/rust-lang/crates.io-index)",
"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)",
- "serde 0.7.11 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 0.7.15 (registry+https://github.com/rust-lang/crates.io-index)",
"x11 2.6.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
@@ -1617,42 +1617,42 @@ dependencies = [
[[package]]
name = "phf"
-version = "0.7.15"
+version = "0.7.16"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
- "phf_shared 0.7.15 (registry+https://github.com/rust-lang/crates.io-index)",
+ "phf_shared 0.7.16 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "phf_codegen"
-version = "0.7.15"
+version = "0.7.16"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
- "phf_generator 0.7.15 (registry+https://github.com/rust-lang/crates.io-index)",
- "phf_shared 0.7.15 (registry+https://github.com/rust-lang/crates.io-index)",
+ "phf_generator 0.7.16 (registry+https://github.com/rust-lang/crates.io-index)",
+ "phf_shared 0.7.16 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "phf_generator"
-version = "0.7.15"
+version = "0.7.16"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
- "phf_shared 0.7.15 (registry+https://github.com/rust-lang/crates.io-index)",
+ "phf_shared 0.7.16 (registry+https://github.com/rust-lang/crates.io-index)",
"rand 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "phf_macros"
-version = "0.7.15"
+version = "0.7.16"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
- "phf_generator 0.7.15 (registry+https://github.com/rust-lang/crates.io-index)",
- "phf_shared 0.7.15 (registry+https://github.com/rust-lang/crates.io-index)",
+ "phf_generator 0.7.16 (registry+https://github.com/rust-lang/crates.io-index)",
+ "phf_shared 0.7.16 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "phf_shared"
-version = "0.7.15"
+version = "0.7.16"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"unicase 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1689,13 +1689,12 @@ dependencies = [
[[package]]
name = "png"
-version = "0.5.1"
+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)",
"flate2 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)",
"inflate 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "libc 0.2.13 (registry+https://github.com/rust-lang/crates.io-index)",
"num-iter 0.1.32 (registry+https://github.com/rust-lang/crates.io-index)",
]
@@ -1704,15 +1703,15 @@ name = "profile"
version = "0.0.1"
dependencies = [
"heartbeats-simple 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "ipc-channel 0.4.0 (git+https://github.com/servo/ipc-channel)",
+ "ipc-channel 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.13 (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.71 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde 0.7.11 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 0.7.15 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_json 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde_macros 0.7.11 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde_macros 0.7.15 (registry+https://github.com/rust-lang/crates.io-index)",
"task_info 0.0.1",
"time 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)",
"util 0.0.1",
@@ -1722,7 +1721,7 @@ dependencies = [
name = "profile_tests"
version = "0.0.1"
dependencies = [
- "ipc-channel 0.4.0 (git+https://github.com/servo/ipc-channel)",
+ "ipc-channel 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
"profile 0.0.1",
"profile_traits 0.0.1",
]
@@ -1733,32 +1732,32 @@ 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)",
- "ipc-channel 0.4.0 (git+https://github.com/servo/ipc-channel)",
+ "ipc-channel 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
"plugins 0.0.1",
- "serde 0.7.11 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde_macros 0.7.11 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 0.7.15 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde_macros 0.7.15 (registry+https://github.com/rust-lang/crates.io-index)",
"time 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "quasi"
-version = "0.13.0"
+version = "0.16.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "quasi_codegen"
-version = "0.13.0"
+version = "0.16.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
- "aster 0.19.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "aster 0.22.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "quasi_macros"
-version = "0.13.0"
+version = "0.16.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
- "quasi_codegen 0.13.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "quasi_codegen 0.16.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@@ -1786,8 +1785,8 @@ dependencies = [
"heapsize_plugin 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
"num-traits 0.1.32 (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.7.11 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde_macros 0.7.11 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 0.7.15 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde_macros 0.7.15 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@@ -1871,7 +1870,7 @@ dependencies = [
"html5ever 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)",
"hyper 0.9.10 (registry+https://github.com/rust-lang/crates.io-index)",
"image 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "ipc-channel 0.4.0 (git+https://github.com/servo/ipc-channel)",
+ "ipc-channel 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
"js 0.1.3 (git+https://github.com/servo/rust-mozjs)",
"libc 0.2.13 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1882,8 +1881,8 @@ dependencies = [
"num-traits 0.1.32 (registry+https://github.com/rust-lang/crates.io-index)",
"offscreen_gl_context 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)",
"open 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "phf 0.7.15 (registry+https://github.com/rust-lang/crates.io-index)",
- "phf_macros 0.7.15 (registry+https://github.com/rust-lang/crates.io-index)",
+ "phf 0.7.16 (registry+https://github.com/rust-lang/crates.io-index)",
+ "phf_macros 0.7.16 (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)",
@@ -1895,7 +1894,7 @@ dependencies = [
"script_layout_interface 0.0.1",
"script_traits 0.0.1",
"selectors 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde 0.7.11 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 0.7.15 (registry+https://github.com/rust-lang/crates.io-index)",
"smallvec 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)",
"string_cache 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)",
"style 0.0.1",
@@ -1904,6 +1903,7 @@ dependencies = [
"url 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
"util 0.0.1",
"uuid 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "video-metadata 0.1.3 (git+https://github.com/GuillaumeGomez/video-metadata-rs)",
"webrender_traits 0.2.0 (git+https://github.com/servo/webrender_traits)",
"websocket 0.17.1 (registry+https://github.com/rust-lang/crates.io-index)",
"xml5ever 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1921,7 +1921,7 @@ dependencies = [
"gfx_traits 0.0.1",
"heapsize 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
"heapsize_plugin 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
- "ipc-channel 0.4.0 (git+https://github.com/servo/ipc-channel)",
+ "ipc-channel 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.13 (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",
@@ -1959,7 +1959,7 @@ dependencies = [
"gfx_traits 0.0.1",
"heapsize 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
"heapsize_plugin 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
- "ipc-channel 0.4.0 (git+https://github.com/servo/ipc-channel)",
+ "ipc-channel 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
"layers 0.2.6 (git+https://github.com/servo/rust-layers)",
"libc 0.2.13 (registry+https://github.com/rust-lang/crates.io-index)",
"msg 0.0.1",
@@ -1968,8 +1968,8 @@ dependencies = [
"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.7.11 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde_macros 0.7.11 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 0.7.15 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde_macros 0.7.15 (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)",
"url 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1999,23 +1999,23 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "serde"
-version = "0.7.11"
+version = "0.7.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "serde_codegen"
-version = "0.7.11"
+version = "0.7.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
- "aster 0.19.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "quasi 0.13.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "quasi_macros 0.13.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde_item 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "aster 0.22.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "quasi 0.16.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "quasi_macros 0.16.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde_codegen_internals 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
-name = "serde_item"
-version = "0.2.0"
+name = "serde_codegen_internals"
+version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
@@ -2024,15 +2024,15 @@ version = "0.7.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"num-traits 0.1.32 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde 0.7.11 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 0.7.15 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "serde_macros"
-version = "0.7.11"
+version = "0.7.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
- "serde_codegen 0.7.11 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde_codegen 0.7.15 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@@ -2169,9 +2169,9 @@ dependencies = [
"heapsize 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
"heapsize_plugin 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
"lazy_static 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "phf_generator 0.7.15 (registry+https://github.com/rust-lang/crates.io-index)",
- "phf_shared 0.7.15 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde 0.7.11 (registry+https://github.com/rust-lang/crates.io-index)",
+ "phf_generator 0.7.16 (registry+https://github.com/rust-lang/crates.io-index)",
+ "phf_shared 0.7.16 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 0.7.15 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@@ -2197,8 +2197,8 @@ dependencies = [
"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)",
"selectors 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde 0.7.11 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde_macros 0.7.11 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 0.7.15 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde_macros 0.7.15 (registry+https://github.com/rust-lang/crates.io-index)",
"smallvec 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)",
"string_cache 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)",
"style_traits 0.0.1",
@@ -2233,8 +2233,8 @@ dependencies = [
"heapsize 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
"heapsize_plugin 0.1.5 (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.7.11 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde_macros 0.7.11 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 0.7.15 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde_macros 0.7.15 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@@ -2316,8 +2316,9 @@ dependencies = [
[[package]]
name = "tinyfiledialogs"
version = "0.1.0"
-source = "git+https://github.com/jdm/tinyfiledialogs#3a30f8f95686195cb3bcecfc77ff77277a624a53"
+source = "git+https://github.com/jdm/tinyfiledialogs#54f6aa4f579edbc726b8a764fd759a6d6ed0dd84"
dependencies = [
+ "gcc 0.3.28 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.13 (registry+https://github.com/rust-lang/crates.io-index)",
]
@@ -2379,7 +2380,7 @@ dependencies = [
"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.7.11 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 0.7.15 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@@ -2413,14 +2414,14 @@ dependencies = [
"euclid 0.7.1 (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.6 (registry+https://github.com/rust-lang/crates.io-index)",
- "ipc-channel 0.4.0 (git+https://github.com/servo/ipc-channel)",
+ "ipc-channel 0.4.0 (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 0.2.13 (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.7.11 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde_macros 0.7.11 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 0.7.15 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde_macros 0.7.15 (registry+https://github.com/rust-lang/crates.io-index)",
"url 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
"xdg 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
@@ -2438,7 +2439,18 @@ version = "0.2.2"
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.7.11 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 0.7.15 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "video-metadata"
+version = "0.1.3"
+source = "git+https://github.com/GuillaumeGomez/video-metadata-rs#44c8d547f9212be5d368a38d9f1238d85bc6728e"
+dependencies = [
+ "gcc 0.3.28 (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.13 (registry+https://github.com/rust-lang/crates.io-index)",
+ "pkg-config 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@@ -2526,7 +2538,7 @@ dependencies = [
"euclid 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)",
"hyper 0.9.10 (registry+https://github.com/rust-lang/crates.io-index)",
"image 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "ipc-channel 0.4.0 (git+https://github.com/servo/ipc-channel)",
+ "ipc-channel 0.4.0 (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",
@@ -2542,7 +2554,7 @@ dependencies = [
[[package]]
name = "webrender"
version = "0.1.0"
-source = "git+https://github.com/servo/webrender#fd38ab8994be39ba194f56182af8c467b4f9f929"
+source = "git+https://github.com/servo/webrender#79b807160ea3c3cf558072813c51a59bbaccb8dd"
dependencies = [
"app_units 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)",
"bit-set 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -2553,7 +2565,7 @@ dependencies = [
"fnv 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
"freetype 0.1.0 (git+https://github.com/servo/rust-freetype)",
"gleam 0.2.20 (registry+https://github.com/rust-lang/crates.io-index)",
- "ipc-channel 0.4.0 (git+https://github.com/servo/ipc-channel)",
+ "ipc-channel 0.4.0 (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-traits 0.1.32 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -2566,7 +2578,7 @@ dependencies = [
[[package]]
name = "webrender_traits"
version = "0.2.0"
-source = "git+https://github.com/servo/webrender_traits#d86e51ace4fd1b43123e0490dc80f631be0726d0"
+source = "git+https://github.com/servo/webrender_traits#a26ebe4da490cc1fb60d830c73cbefb135b768b1"
dependencies = [
"app_units 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)",
"byteorder 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -2574,10 +2586,10 @@ dependencies = [
"euclid 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)",
"gleam 0.2.20 (registry+https://github.com/rust-lang/crates.io-index)",
"heapsize 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
- "ipc-channel 0.4.0 (git+https://github.com/servo/ipc-channel)",
+ "ipc-channel 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
"offscreen_gl_context 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde 0.7.11 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde_macros 0.7.11 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 0.7.15 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde_macros 0.7.15 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@@ -2658,8 +2670,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
"mac 0.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
- "phf 0.7.15 (registry+https://github.com/rust-lang/crates.io-index)",
- "phf_codegen 0.7.15 (registry+https://github.com/rust-lang/crates.io-index)",
+ "phf 0.7.16 (registry+https://github.com/rust-lang/crates.io-index)",
+ "phf_codegen 0.7.16 (registry+https://github.com/rust-lang/crates.io-index)",
"rustc-serialize 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)",
"string_cache 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)",
"tendril 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
diff --git a/components/servo/Cargo.toml b/components/servo/Cargo.toml
index ba9279d35fc..9a809f5148b 100644
--- a/components/servo/Cargo.toml
+++ b/components/servo/Cargo.toml
@@ -56,7 +56,7 @@ euclid = "0.7.1"
gfx = {path = "../gfx"}
gleam = "0.2"
glutin_app = {path = "../../ports/glutin"}
-ipc-channel = {git = "https://github.com/servo/ipc-channel"}
+ipc-channel = "0.4.0"
layout = {path = "../layout"}
layout_thread = {path = "../layout_thread"}
libc = "0.2"
diff --git a/components/servo/fake-ld.cmd b/components/servo/fake-ld.cmd
new file mode 100644
index 00000000000..b13c7e818ab
--- /dev/null
+++ b/components/servo/fake-ld.cmd
@@ -0,0 +1,2 @@
+@echo off
+gcc -mwindows %*
diff --git a/components/servo/lib.rs b/components/servo/lib.rs
index d96da810889..515f4d898a7 100644
--- a/components/servo/lib.rs
+++ b/components/servo/lib.rs
@@ -150,6 +150,7 @@ impl<Window> Browser<Window> where Window: WindowMethods + 'static {
enable_aa: opts.enable_text_antialiasing,
enable_msaa: opts.use_msaa,
enable_profiler: opts.webrender_stats,
+ debug: opts.webrender_debug,
});
(Some(webrender), Some(webrender_sender))
} else {
@@ -239,7 +240,8 @@ fn create_constellation(opts: opts::Opts,
let (public_resource_threads, private_resource_threads) =
new_resource_threads(opts.user_agent.clone(),
devtools_chan.clone(),
- time_profiler_chan.clone());
+ time_profiler_chan.clone(),
+ opts.config_dir.map(Into::into));
let image_cache_thread = new_image_cache_thread(public_resource_threads.sender(),
webrender_api_sender.as_ref().map(|wr| wr.create_api()));
let font_cache_thread = FontCacheThread::new(public_resource_threads.sender(),
diff --git a/components/servo/main.rs b/components/servo/main.rs
index a13c2ca8b5d..64112fde54b 100644
--- a/components/servo/main.rs
+++ b/components/servo/main.rs
@@ -70,7 +70,10 @@ fn install_crash_handler() {
}
}
- signal!(Sig::SEGV, handler);
+ signal!(Sig::SEGV, handler); // handle segfaults
+ signal!(Sig::ILL, handler); // handle stack overflow and unsupported CPUs
+ signal!(Sig::IOT, handler); // handle double panics
+ signal!(Sig::BUS, handler); // handle invalid memory access
}
#[cfg(target_os = "android")]
diff --git a/components/servo/servo.exe.manifest b/components/servo/servo.exe.manifest
index 3748cdaca40..198d8d51709 100644
--- a/components/servo/servo.exe.manifest
+++ b/components/servo/servo.exe.manifest
@@ -6,7 +6,7 @@
name="servo.Servo"
version="0.1.0.0"/>
- <compatibility>
+ <compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1">
<application>
<supportedOS Id="{35138b9a-5d96-4fbd-8e2d-a2440225f93a}"/> <!-- Windows 7 -->
<supportedOS Id="{4a2f28e3-53b9-4441-ba9c-d69d4a4a6e38}"/> <!-- Windows 8 -->
diff --git a/components/style/Cargo.toml b/components/style/Cargo.toml
index c9a1da6fccf..71898ea32e0 100644
--- a/components/style/Cargo.toml
+++ b/components/style/Cargo.toml
@@ -38,8 +38,8 @@ num-traits = "0.1.32"
rand = "0.3"
rustc-serialize = "0.3"
selectors = "0.7"
-serde = {version = "0.7.11", optional = true}
-serde_macros = {version = "0.7.11", optional = true}
+serde = {version = "0.7.15", optional = true}
+serde_macros = {version = "0.7.15", optional = true}
smallvec = "0.1"
string_cache = "0.2.20"
style_traits = {path = "../style_traits"}
diff --git a/components/style/animation.rs b/components/style/animation.rs
index c36cde3caea..a4600418023 100644
--- a/components/style/animation.rs
+++ b/components/style/animation.rs
@@ -668,3 +668,29 @@ where Damage: TRestyleDamage {
}
}
}
+
+/// Update the style in the node when it finishes.
+pub fn complete_expired_transitions(node: OpaqueNode, style: &mut Arc<ComputedValues>,
+ context: &SharedStyleContext) -> bool {
+ let had_animations_to_expire;
+ {
+ let all_expired_animations = context.expired_animations.read().unwrap();
+ let animations_to_expire = all_expired_animations.get(&node);
+ had_animations_to_expire = animations_to_expire.is_some();
+ if let Some(ref animations) = animations_to_expire {
+ for animation in *animations {
+ // TODO: support animation-fill-mode
+ if let Animation::Transition(_, _, ref frame, _) = *animation {
+ frame.property_animation.update(Arc::make_mut(style), 1.0);
+ }
+ }
+ }
+ }
+
+ if had_animations_to_expire {
+ context.expired_animations.write().unwrap().remove(&node);
+ }
+
+ had_animations_to_expire
+}
+
diff --git a/components/style/attr.rs b/components/style/attr.rs
index af7cfa015f6..fc741d61575 100644
--- a/components/style/attr.rs
+++ b/components/style/attr.rs
@@ -92,17 +92,17 @@ pub fn parse_double(string: &str) -> Result<f64, ()> {
let trimmed = string.trim_matches(HTML_SPACE_CHARACTERS);
let mut input = trimmed.chars().peekable();
- let (value, divisor) = match input.peek() {
+ let (value, divisor, chars_skipped) = match input.peek() {
None => return Err(()),
Some(&'-') => {
input.next();
- (-1f64, -1f64)
+ (-1f64, -1f64, 1)
}
Some(&'+') => {
input.next();
- (1f64, 1f64)
+ (1f64, 1f64, 1)
}
- _ => (1f64, 1f64)
+ _ => (1f64, 1f64, 0)
};
let (value, value_digits) = if let Some(&'.') = input.peek() {
@@ -112,11 +112,11 @@ pub fn parse_double(string: &str) -> Result<f64, ()> {
(value * read_val.and_then(|result| result.to_f64()).unwrap_or(1f64), read_digits)
};
- let input = trimmed.chars().skip(value_digits).peekable();
+ let input = trimmed.chars().skip(value_digits + chars_skipped).peekable();
let (mut value, fraction_digits) = read_fraction(input, divisor, value);
- let input = trimmed.chars().skip(value_digits + fraction_digits).peekable();
+ let input = trimmed.chars().skip(value_digits + chars_skipped + fraction_digits).peekable();
if let Some(exp) = read_exponent(input) {
value *= 10f64.powi(exp)
diff --git a/components/style/data.rs b/components/style/data.rs
index 906848998fb..44920c72c98 100644
--- a/components/style/data.rs
+++ b/components/style/data.rs
@@ -37,13 +37,13 @@ impl PrivateStyleData {
#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
pub struct DomParallelInfo {
/// The number of children that still need work done.
- pub children_count: AtomicIsize,
+ pub children_to_process: AtomicIsize,
}
impl DomParallelInfo {
pub fn new() -> DomParallelInfo {
DomParallelInfo {
- children_count: AtomicIsize::new(0),
+ children_to_process: AtomicIsize::new(0),
}
}
}
diff --git a/components/style/dom.rs b/components/style/dom.rs
index 5c5f3905d8d..c694ca75732 100644
--- a/components/style/dom.rs
+++ b/components/style/dom.rs
@@ -111,33 +111,10 @@ pub trait TNode : Sized + Copy + Clone {
unsafe fn set_dirty_descendants(&self, value: bool);
- fn dirty_self(&self) {
- unsafe {
- self.set_dirty(true);
- self.set_dirty_descendants(true);
- }
- }
-
- fn dirty_descendants(&self) {
- for ref child in self.children() {
- child.dirty_self();
- child.dirty_descendants();
- }
- }
-
fn needs_dirty_on_viewport_size_changed(&self) -> bool;
unsafe fn set_dirty_on_viewport_size_changed(&self);
- fn set_descendants_dirty_on_viewport_size_changed(&self) {
- for ref child in self.children() {
- unsafe {
- child.set_dirty_on_viewport_size_changed();
- }
- child.set_descendants_dirty_on_viewport_size_changed();
- }
- }
-
fn can_be_fragmented(&self) -> bool;
unsafe fn set_can_be_fragmented(&self, value: bool);
@@ -215,7 +192,7 @@ pub trait TElement : Sized + Copy + Clone + ElementExt + PresentationalHintsSynt
fn attr_equals(&self, namespace: &Namespace, attr: &Atom, value: &Atom) -> bool;
/// Properly marks nodes as dirty in response to restyle hints.
- fn note_restyle_hint(&self, mut hint: RestyleHint) {
+ fn note_restyle_hint(&self, hint: RestyleHint) {
// Bail early if there's no restyling to do.
if hint.is_empty() {
return;
@@ -233,23 +210,21 @@ pub trait TElement : Sized + Copy + Clone + ElementExt + PresentationalHintsSynt
// Process hints.
if hint.contains(RESTYLE_SELF) {
- node.dirty_self();
-
- // FIXME(bholley, #8438): We currently need to RESTYLE_DESCENDANTS in the
- // RESTYLE_SELF case in order to make sure "inherit" style structs propagate
- // properly. See the explanation in the github issue.
- hint.insert(RESTYLE_DESCENDANTS);
- }
- if hint.contains(RESTYLE_DESCENDANTS) {
- unsafe { node.set_dirty_descendants(true); }
- node.dirty_descendants();
+ unsafe { node.set_dirty(true); }
+ // XXX(emilio): For now, dirty implies dirty descendants if found.
+ } else if hint.contains(RESTYLE_DESCENDANTS) {
+ let mut current = node.first_child();
+ while let Some(node) = current {
+ unsafe { node.set_dirty(true); }
+ current = node.next_sibling();
+ }
}
+
if hint.contains(RESTYLE_LATER_SIBLINGS) {
let mut next = ::selectors::Element::next_sibling_element(self);
while let Some(sib) = next {
let sib_node = sib.as_node();
- sib_node.dirty_self();
- sib_node.dirty_descendants();
+ unsafe { sib_node.set_dirty(true) };
next = ::selectors::Element::next_sibling_element(&sib);
}
}
@@ -262,12 +237,16 @@ pub struct TreeIterator<ConcreteNode> where ConcreteNode: TNode {
impl<ConcreteNode> TreeIterator<ConcreteNode> where ConcreteNode: TNode {
fn new(root: ConcreteNode) -> TreeIterator<ConcreteNode> {
- let mut stack = vec!();
+ let mut stack = vec![];
stack.push(root);
TreeIterator {
stack: stack,
}
}
+
+ pub fn next_skipping_children(&mut self) -> Option<ConcreteNode> {
+ self.stack.pop()
+ }
}
impl<ConcreteNode> Iterator for TreeIterator<ConcreteNode>
diff --git a/components/style/gecko_conversions.rs b/components/style/gecko_conversions.rs
index 95ab9eb8b00..56e2e3bbc5f 100644
--- a/components/style/gecko_conversions.rs
+++ b/components/style/gecko_conversions.rs
@@ -8,7 +8,7 @@
use app_units::Au;
use gecko_bindings::structs::nsStyleCoord_CalcValue;
-use values::computed::CalcLengthOrPercentage;
+use values::computed::{CalcLengthOrPercentage, LengthOrPercentage};
impl From<CalcLengthOrPercentage> for nsStyleCoord_CalcValue {
fn from(other: CalcLengthOrPercentage) -> nsStyleCoord_CalcValue {
@@ -34,3 +34,35 @@ impl From<nsStyleCoord_CalcValue> for CalcLengthOrPercentage {
}
}
}
+
+impl From<LengthOrPercentage> for nsStyleCoord_CalcValue {
+ fn from(other: LengthOrPercentage) -> nsStyleCoord_CalcValue {
+ match other {
+ LengthOrPercentage::Length(au) => {
+ nsStyleCoord_CalcValue {
+ mLength: au.0,
+ mPercent: 0.0,
+ mHasPercent: false,
+ }
+ },
+ LengthOrPercentage::Percentage(pc) => {
+ nsStyleCoord_CalcValue {
+ mLength: 0,
+ mPercent: pc,
+ mHasPercent: true,
+ }
+ },
+ LengthOrPercentage::Calc(calc) => calc.into(),
+ }
+ }
+}
+
+impl From<nsStyleCoord_CalcValue> for LengthOrPercentage {
+ fn from(other: nsStyleCoord_CalcValue) -> LengthOrPercentage {
+ match (other.mHasPercent, other.mLength) {
+ (false, _) => LengthOrPercentage::Length(Au(other.mLength)),
+ (true, 0) => LengthOrPercentage::Percentage(other.mPercent),
+ _ => LengthOrPercentage::Calc(other.into()),
+ }
+ }
+}
diff --git a/components/style/gecko_selector_impl.rs b/components/style/gecko_selector_impl.rs
index ed99fd39758..5798222cb07 100644
--- a/components/style/gecko_selector_impl.rs
+++ b/components/style/gecko_selector_impl.rs
@@ -44,7 +44,8 @@ pub enum PseudoElement {
// https://mxr.mozilla.org/mozilla-central/source/layout/style/nsCSSAnonBoxList.h
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
pub enum AnonBoxPseudoElement {
- MozNonElement,
+ MozText,
+ MozOtherNonElement,
MozAnonymousBlock,
MozAnonymousPositionedBlock,
MozMathMLAnonymousBlock,
@@ -67,7 +68,7 @@ pub enum AnonBoxPseudoElement {
MozTableCell,
MozTableColumnGroup,
MozTableColumn,
- MozTableOuter,
+ MozTableWrapper,
MozTableRowGroup,
MozTableRow,
@@ -214,7 +215,8 @@ impl SelectorImpl for GeckoSelectorImpl {
}
Ok(AnonBox(match_ignore_ascii_case! { name,
- "-moz-non-element" => MozNonElement,
+ "-moz-text" => MozText,
+ "-moz-other-non-element" => MozOtherNonElement,
"-moz-anonymous-block" => MozAnonymousBlock,
"-moz-anonymous-positioned-block" => MozAnonymousPositionedBlock,
@@ -240,7 +242,7 @@ impl SelectorImpl for GeckoSelectorImpl {
"-moz-table-cell" => MozTableCell,
"-moz-table-column-group" => MozTableColumnGroup,
"-moz-table-column" => MozTableColumn,
- "-moz-table-outer" => MozTableOuter,
+ "-moz-table-wrapper" => MozTableWrapper,
"-moz-table-row-group" => MozTableRowGroup,
"-moz-table-row" => MozTableRow,
@@ -305,7 +307,8 @@ impl SelectorImplExt for GeckoSelectorImpl {
fun(After);
fun(FirstLine);
- fun(AnonBox(MozNonElement));
+ fun(AnonBox(MozText));
+ fun(AnonBox(MozOtherNonElement));
fun(AnonBox(MozAnonymousBlock));
fun(AnonBox(MozAnonymousPositionedBlock));
fun(AnonBox(MozMathMLAnonymousBlock));
@@ -328,7 +331,7 @@ impl SelectorImplExt for GeckoSelectorImpl {
fun(AnonBox(MozTableCell));
fun(AnonBox(MozTableColumnGroup));
fun(AnonBox(MozTableColumn));
- fun(AnonBox(MozTableOuter));
+ fun(AnonBox(MozTableWrapper));
fun(AnonBox(MozTableRowGroup));
fun(AnonBox(MozTableRow));
diff --git a/components/style/matching.rs b/components/style/matching.rs
index 2c4dfc990cd..2cd51352355 100644
--- a/components/style/matching.rs
+++ b/components/style/matching.rs
@@ -466,25 +466,8 @@ trait PrivateMatchMethods: TNode
// Finish any expired transitions.
let this_opaque = self.opaque();
- let had_animations_to_expire;
- {
- let all_expired_animations = context.expired_animations.read().unwrap();
- let animations_to_expire = all_expired_animations.get(&this_opaque);
- had_animations_to_expire = animations_to_expire.is_some();
- if let Some(ref animations) = animations_to_expire {
- for animation in *animations {
- // NB: Expiring a keyframes animation is the same as not
- // applying the keyframes style to it, so we're safe.
- if let Animation::Transition(_, _, ref frame, _) = *animation {
- frame.property_animation.update(Arc::make_mut(style), 1.0);
- }
- }
- }
- }
-
- if had_animations_to_expire {
- context.expired_animations.write().unwrap().remove(&this_opaque);
- }
+ let had_animations_to_expire =
+ animation::complete_expired_transitions(this_opaque, style, context);
// Merge any running transitions into the current style, and cancel them.
let had_running_animations = context.running_animations
diff --git a/components/style/parallel.rs b/components/style/parallel.rs
index 0bc840f7492..b82727657c3 100644
--- a/components/style/parallel.rs
+++ b/components/style/parallel.rs
@@ -63,25 +63,40 @@ fn top_down_dom<N, C>(unsafe_nodes: UnsafeNodeList,
// Get a real layout node.
let node = unsafe { N::from_unsafe(&unsafe_node) };
+ if !context.should_process(node) {
+ continue;
+ }
+
// Perform the appropriate traversal.
context.process_preorder(node);
- let child_count = node.children_count();
+ // Possibly enqueue the children.
+ let mut children_to_process = 0isize;
+ for kid in node.children() {
+ // Trigger the hook pre-adding the kid to the list. This can (and in
+ // fact uses to) change the result of the should_process operation.
+ //
+ // As of right now, this hook takes care of propagating the restyle
+ // flag down the tree. In the future, more accurate behavior is
+ // probably going to be needed.
+ context.pre_process_child_hook(node, kid);
+ if context.should_process(kid) {
+ children_to_process += 1;
+ discovered_child_nodes.push(kid.to_unsafe())
+ }
+ }
// Reset the count of children.
{
let data = node.mutate_data().unwrap();
- data.parallel.children_count.store(child_count as isize,
- Ordering::Relaxed);
+ data.parallel.children_to_process
+ .store(children_to_process,
+ Ordering::Relaxed);
}
- // Possibly enqueue the children.
- if child_count != 0 {
- for kid in node.children() {
- discovered_child_nodes.push(kid.to_unsafe())
- }
- } else {
- // If there were no more children, start walking back up.
+
+ // If there were no more children, start walking back up.
+ if children_to_process == 0 {
bottom_up_dom::<N, C>(unsafe_nodes.1, unsafe_node, proxy)
}
}
@@ -128,7 +143,7 @@ fn bottom_up_dom<N, C>(root: OpaqueNode,
if parent_data
.parallel
- .children_count
+ .children_to_process
.fetch_sub(1, Ordering::Relaxed) != 1 {
// Get out of here and find another node to work on.
break
@@ -138,4 +153,3 @@ fn bottom_up_dom<N, C>(root: OpaqueNode,
node = parent;
}
}
-
diff --git a/components/style/properties/data.py b/components/style/properties/data.py
index 1386d6486dd..7c63356ca22 100644
--- a/components/style/properties/data.py
+++ b/components/style/properties/data.py
@@ -18,11 +18,15 @@ def to_camel_case(ident):
class Keyword(object):
def __init__(self, name, values, gecko_constant_prefix=None,
+ gecko_enum_prefix=None,
extra_gecko_values=None, extra_servo_values=None):
self.name = name
self.values = values.split()
+ if gecko_constant_prefix and gecko_enum_prefix:
+ raise TypeError("Only one of gecko_constant_prefix and gecko_enum_prefix can be specified")
self.gecko_constant_prefix = gecko_constant_prefix or \
"NS_STYLE_" + self.name.upper().replace("-", "_")
+ self.gecko_enum_prefix = gecko_enum_prefix
self.extra_gecko_values = (extra_gecko_values or "").split()
self.extra_servo_values = (extra_servo_values or "").split()
@@ -41,7 +45,18 @@ class Keyword(object):
raise Exception("Bad product: " + product)
def gecko_constant(self, value):
- return self.gecko_constant_prefix + "_" + value.replace("-moz-", "").replace("-", "_").upper()
+ if self.gecko_enum_prefix:
+ if value == "none":
+ return self.gecko_enum_prefix + "::None_"
+ else:
+ parts = value.replace("-moz-", "").split("-")
+ parts = [p.title() for p in parts]
+ return self.gecko_enum_prefix + "::" + "".join(parts)
+ else:
+ return self.gecko_constant_prefix + "_" + value.replace("-moz-", "").replace("-", "_").upper()
+
+ def needs_cast(self):
+ return self.gecko_enum_prefix is None
class Longhand(object):
diff --git a/components/style/properties/gecko.mako.rs b/components/style/properties/gecko.mako.rs
index 2209651b18b..24893da9f7b 100644
--- a/components/style/properties/gecko.mako.rs
+++ b/components/style/properties/gecko.mako.rs
@@ -194,7 +194,11 @@ def set_gecko_property(ffi_name, expr):
// FIXME(bholley): Align binary representations and ditch |match| for cast + static_asserts
let result = match v {
% for value in keyword.values_for('gecko'):
- Keyword::${to_rust_ident(value)} => structs::${keyword.gecko_constant(value)} as u8,
+ % if keyword.needs_cast():
+ Keyword::${to_rust_ident(value)} => structs::${keyword.gecko_constant(value)} as u8,
+ % else:
+ Keyword::${to_rust_ident(value)} => structs::${keyword.gecko_constant(value)},
+ % endif
% endfor
};
${set_gecko_property(gecko_ffi_name, "result")}
@@ -657,9 +661,10 @@ fn static_assert() {
use gecko_bindings::structs::nsStyleUnit;
// z-index is never a calc(). If it were, we'd be leaking here, so
// assert that it isn't.
- debug_assert!(self.gecko.mZIndex.mUnit != nsStyleUnit::eStyleUnit_Calc);
- self.gecko.mZIndex.mUnit = other.gecko.mZIndex.mUnit;
- self.gecko.mZIndex.mValue = other.gecko.mZIndex.mValue;
+ debug_assert!(self.gecko.mZIndex.unit() != nsStyleUnit::eStyleUnit_Calc);
+ unsafe {
+ self.gecko.mZIndex.copy_from_unchecked(&other.gecko.mZIndex);
+ }
}
pub fn clone_z_index(&self) -> longhands::z_index::computed_value::T {
@@ -917,7 +922,8 @@ fn static_assert() {
// add support for parsing these lists in servo and pushing to nsTArray's.
<% skip_background_longhands = """background-color background-repeat
background-image background-clip
- background-origin background-attachment""" %>
+ background-origin background-attachment
+ background-position""" %>
<%self:impl_trait style_struct_name="Background"
skip_longhands="${skip_background_longhands}"
skip_additionals="*">
@@ -1005,6 +1011,29 @@ fn static_assert() {
};
}
+ pub fn copy_background_position_from(&mut self, other: &Self) {
+ self.gecko.mImage.mPositionXCount = cmp::min(1, other.gecko.mImage.mPositionXCount);
+ self.gecko.mImage.mPositionYCount = cmp::min(1, other.gecko.mImage.mPositionYCount);
+ self.gecko.mImage.mLayers.mFirstElement.mPosition =
+ other.gecko.mImage.mLayers.mFirstElement.mPosition;
+ }
+
+ pub fn clone_background_position(&self) -> longhands::background_position::computed_value::T {
+ let position = &self.gecko.mImage.mLayers.mFirstElement.mPosition;
+ longhands::background_position::computed_value::T {
+ horizontal: position.mXPosition.into(),
+ vertical: position.mYPosition.into(),
+ }
+ }
+
+ pub fn set_background_position(&mut self, v: longhands::background_position::computed_value::T) {
+ let position = &mut self.gecko.mImage.mLayers.mFirstElement.mPosition;
+ position.mXPosition = v.horizontal.into();
+ position.mYPosition = v.vertical.into();
+ self.gecko.mImage.mPositionXCount = 1;
+ self.gecko.mImage.mPositionYCount = 1;
+ }
+
pub fn copy_background_image_from(&mut self, other: &Self) {
unsafe {
Gecko_CopyImageValueFrom(&mut self.gecko.mImage.mLayers.mFirstElement.mImage,
@@ -1093,7 +1122,7 @@ fn static_assert() {
Gecko_SetGradientImageValue(&mut geckoimage.mImage, gecko_gradient);
}
},
- Image::Url(_) => {
+ Image::Url(..) => {
// let utf8_bytes = url.as_bytes();
// Gecko_SetUrlImageValue(&mut self.gecko.mImage.mLayers.mFirstElement,
// utf8_bytes.as_ptr() as *const _,
diff --git a/components/style/properties/helpers.mako.rs b/components/style/properties/helpers.mako.rs
index 40bef518de9..fc6caa1cda3 100644
--- a/components/style/properties/helpers.mako.rs
+++ b/components/style/properties/helpers.mako.rs
@@ -289,7 +289,8 @@
<%def name="single_keyword_computed(name, values, **kwargs)">
<%
keyword_kwargs = {a: kwargs.pop(a, None) for a in [
- 'gecko_constant_prefix', 'extra_gecko_values', 'extra_servo_values'
+ 'gecko_constant_prefix', 'gecko_enum_prefix',
+ 'extra_gecko_values', 'extra_servo_values',
]}
%>
<%call expr="longhand(name, keyword=Keyword(name, values, **keyword_kwargs), **kwargs)">
@@ -317,7 +318,8 @@
<%def name="keyword_list(name, values, **kwargs)">
<%
keyword_kwargs = {a: kwargs.pop(a, None) for a in [
- 'gecko_constant_prefix', 'extra_gecko_values', 'extra_servo_values'
+ 'gecko_constant_prefix', 'gecko_enum_prefix',
+ 'extra_gecko_values', 'extra_servo_values',
]}
%>
<%call expr="longhand(name, keyword=Keyword(name, values, **keyword_kwargs), **kwargs)">
diff --git a/components/style/properties/longhand/background.mako.rs b/components/style/properties/longhand/background.mako.rs
index f5708c5ede8..501a98fd7fa 100644
--- a/components/style/properties/longhand/background.mako.rs
+++ b/components/style/properties/longhand/background.mako.rs
@@ -28,7 +28,7 @@ ${helpers.predefined_type("background-color", "CSSColor",
fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
match self.0 {
None => dest.write_str("none"),
- Some(computed::Image::Url(ref url)) => url.to_css(dest),
+ Some(computed::Image::Url(ref url, ref _extra_data)) => url.to_css(dest),
Some(computed::Image::LinearGradient(ref gradient)) =>
gradient.to_css(dest)
}
diff --git a/components/style/properties/longhand/border.mako.rs b/components/style/properties/longhand/border.mako.rs
index cbf97ecc0be..da34a5f8425 100644
--- a/components/style/properties/longhand/border.mako.rs
+++ b/components/style/properties/longhand/border.mako.rs
@@ -82,6 +82,6 @@ ${helpers.single_keyword("box-decoration-break", "slice clone",
${helpers.single_keyword("-moz-float-edge", "content-box margin-box",
gecko_ffi_name="mFloatEdge",
- gecko_constant_prefix="NS_STYLE_FLOAT_EDGE",
+ gecko_enum_prefix="StyleFloatEdge",
products="gecko",
animatable=False)}
diff --git a/components/style/properties/longhand/box.mako.rs b/components/style/properties/longhand/box.mako.rs
index 87af34df33e..a00f0c01393 100644
--- a/components/style/properties/longhand/box.mako.rs
+++ b/components/style/properties/longhand/box.mako.rs
@@ -914,19 +914,12 @@ ${helpers.single_keyword("-moz-appearance",
use gecko_bindings::ptr::{GeckoArcPrincipal, GeckoArcURI};
use std::fmt::{self, Write};
use url::Url;
+ use values::specified::UrlExtraData;
use values::computed::ComputedValueAsSpecified;
use values::NoViewportPercentage;
#[derive(PartialEq, Clone, Debug)]
#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
- pub struct UrlExtraData {
- pub base: GeckoArcURI,
- pub referrer: GeckoArcURI,
- pub principal: GeckoArcPrincipal,
- }
-
- #[derive(PartialEq, Clone, Debug)]
- #[cfg_attr(feature = "servo", derive(HeapSizeOf))]
pub enum SpecifiedValue {
Url(Url, UrlExtraData),
None,
diff --git a/components/style/properties/longhand/pointing.mako.rs b/components/style/properties/longhand/pointing.mako.rs
index 3bdb71d2392..859a71527ba 100644
--- a/components/style/properties/longhand/pointing.mako.rs
+++ b/components/style/properties/longhand/pointing.mako.rs
@@ -71,5 +71,5 @@ ${helpers.single_keyword("-moz-user-modify", "read-only read-write write-only",
${helpers.single_keyword("-moz-user-focus",
"ignore normal select-after select-before select-menu select-same select-all none",
products="gecko", gecko_ffi_name="mUserFocus",
- gecko_constant_prefix="NS_STYLE_USER_FOCUS",
+ gecko_enum_prefix="StyleUserFocus",
animatable=False)}
diff --git a/components/style/properties/properties.mako.rs b/components/style/properties/properties.mako.rs
index cb9ef5152df..83ad6b73d82 100644
--- a/components/style/properties/properties.mako.rs
+++ b/components/style/properties/properties.mako.rs
@@ -2146,10 +2146,6 @@ pub fn modify_style_for_input_text(style: &mut Arc<ComputedValues>) {
margin_style.margin_right = computed::LengthOrPercentageOrAuto::Length(Au(0));
margin_style.margin_bottom = computed::LengthOrPercentageOrAuto::Length(Au(0));
margin_style.margin_left = computed::LengthOrPercentageOrAuto::Length(Au(0));
-
- // whitespace inside text input should not be collapsed
- let inherited_text = Arc::make_mut(&mut style.inheritedtext);
- inherited_text.white_space = longhands::white_space::computed_value::T::pre;
}
/// Adjusts the `clip` property so that an inline absolute hypothetical fragment doesn't clip its
diff --git a/components/style/sequential.rs b/components/style/sequential.rs
index a5a9b519e57..56b8a563d27 100644
--- a/components/style/sequential.rs
+++ b/components/style/sequential.rs
@@ -9,20 +9,29 @@ use traversal::DomTraversalContext;
pub fn traverse_dom<N, C>(root: N,
shared: &C::SharedContext)
- where N: TNode,
- C: DomTraversalContext<N> {
+ where N: TNode,
+ C: DomTraversalContext<N>
+{
fn doit<'a, N, C>(context: &'a C, node: N)
- where N: TNode, C: DomTraversalContext<N> {
+ where N: TNode,
+ C: DomTraversalContext<N>
+ {
+ debug_assert!(context.should_process(node));
context.process_preorder(node);
for kid in node.children() {
- doit::<N, C>(context, kid);
+ context.pre_process_child_hook(node, kid);
+ if context.should_process(node) {
+ doit::<N, C>(context, kid);
+ }
}
context.process_postorder(node);
}
let context = C::new(shared, root.opaque());
- doit::<N, C>(&context, root);
+ if context.should_process(root) {
+ doit::<N, C>(&context, root);
+ }
}
diff --git a/components/style/traversal.rs b/components/style/traversal.rs
index 76f8539c72f..d1cf9eb833b 100644
--- a/components/style/traversal.rs
+++ b/components/style/traversal.rs
@@ -4,6 +4,7 @@
//! Traversing the DOM tree; the bloom filter.
+use animation;
use context::{SharedStyleContext, StyleContext};
use dom::{OpaqueNode, TElement, TNode, TRestyleDamage, UnsafeNode};
use matching::{ApplicableDeclarations, ElementMatchMethods, MatchMethods, StyleSharingResult};
@@ -11,6 +12,7 @@ use selector_impl::SelectorImplExt;
use selectors::Element;
use selectors::bloom::BloomFilter;
use std::cell::RefCell;
+use std::sync::Arc;
use tid::tid;
use util::opts;
use values::HasViewportPercentage;
@@ -147,6 +149,30 @@ pub trait DomTraversalContext<N: TNode> {
fn process_preorder(&self, node: N);
/// Process `node` on the way up, after its children have been processed.
fn process_postorder(&self, node: N);
+
+ /// Returns if the node should be processed by the preorder traversal (and
+ /// then by the post-order one).
+ ///
+ /// Note that this is true unconditionally for servo, since it requires to
+ /// bubble the widths bottom-up for all the DOM.
+ fn should_process(&self, node: N) -> bool {
+ node.is_dirty() || node.has_dirty_descendants()
+ }
+
+ /// Do an action over the child before pushing him to the work queue.
+ ///
+ /// By default, propagate the IS_DIRTY flag down the tree.
+ #[allow(unsafe_code)]
+ fn pre_process_child_hook(&self, parent: N, kid: N) {
+ // NOTE: At this point is completely safe to modify either the parent or
+ // the child, since we have exclusive access to both of them.
+ if parent.is_dirty() {
+ unsafe {
+ kid.set_dirty(true);
+ parent.set_dirty_descendants(true);
+ }
+ }
+ }
}
/// Calculates the style for a single node.
@@ -232,6 +258,13 @@ pub fn recalc_style_at<'a, N, C>(context: &'a C,
node.set_restyle_damage(damage);
}
}
+ } else {
+ // Finish any expired transitions.
+ animation::complete_expired_transitions(
+ node.opaque(),
+ node.mutate_data().unwrap().style.as_mut().unwrap(),
+ context.shared_context()
+ );
}
let unsafe_layout_node = node.to_unsafe();
@@ -244,22 +277,17 @@ pub fn recalc_style_at<'a, N, C>(context: &'a C,
// NB: flow construction updates the bloom filter on the way up.
put_thread_local_bloom_filter(bf, &unsafe_layout_node, context.shared_context());
- // Mark the node as DIRTY_ON_VIEWPORT_SIZE_CHANGE is it uses viewport percentage units.
- match node.as_element() {
- Some(element) => {
- match *element.style_attribute() {
- Some(ref property_declaration_block) => {
- if property_declaration_block.declarations().any(|d| d.0.has_viewport_percentage()) {
- unsafe {
- node.set_dirty_on_viewport_size_changed();
- }
- node.set_descendants_dirty_on_viewport_size_changed();
+ // Mark the node as DIRTY_ON_VIEWPORT_SIZE_CHANGE is it uses viewport
+ // percentage units.
+ if !node.needs_dirty_on_viewport_size_changed() {
+ if let Some(element) = node.as_element() {
+ if let Some(ref property_declaration_block) = *element.style_attribute() {
+ if property_declaration_block.declarations().any(|d| d.0.has_viewport_percentage()) {
+ unsafe {
+ node.set_dirty_on_viewport_size_changed();
}
- },
- None => {}
+ }
}
- },
- None => {}
+ }
}
}
-
diff --git a/components/style/values.rs b/components/style/values.rs
deleted file mode 100644
index 35063977aa6..00000000000
--- a/components/style/values.rs
+++ /dev/null
@@ -1,2286 +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/. */
-
-//! Common [values][values] used in CSS.
-//!
-//! [values]: https://drafts.csswg.org/css-values/
-
-pub use cssparser::RGBA;
-
-use app_units::Au;
-use cssparser::CssStringWriter;
-use std::fmt::{self, Write};
-use url::Url;
-
-
-/// The real ToCss trait can't be implemented for types in crates that don't
-/// depend on each other.
-pub trait LocalToCss {
- /// Serialize `self` in CSS syntax, writing to `dest`.
- fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write;
-
- /// Serialize `self` in CSS syntax and return a string.
- ///
- /// (This is a convenience wrapper for `to_css` and probably should not be overridden.)
- #[inline]
- fn to_css_string(&self) -> String {
- let mut s = String::new();
- self.to_css(&mut s).unwrap();
- s
- }
-}
-
-impl LocalToCss for Au {
- fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
- write!(dest, "{}px", self.to_f64_px())
- }
-}
-
-impl LocalToCss for Url {
- fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
- try!(dest.write_str("url(\""));
- try!(write!(CssStringWriter::new(dest), "{}", self));
- try!(dest.write_str("\")"));
- Ok(())
- }
-}
-
-macro_rules! define_numbered_css_keyword_enum {
- ($name: ident: $( $css: expr => $variant: ident = $value: expr ),+,) => {
- define_numbered_css_keyword_enum!($name: $( $css => $variant = $value ),+);
- };
- ($name: ident: $( $css: expr => $variant: ident = $value: expr ),+) => {
- #[allow(non_camel_case_types)]
- #[derive(Clone, Eq, PartialEq, PartialOrd, Ord, Copy, RustcEncodable, Debug)]
- #[cfg_attr(feature = "servo", derive(HeapSizeOf, Deserialize, Serialize))]
- pub enum $name {
- $( $variant = $value ),+
- }
-
- impl $name {
- pub fn parse(input: &mut ::cssparser::Parser) -> Result<$name, ()> {
- match_ignore_ascii_case! { try!(input.expect_ident()),
- $( $css => Ok($name::$variant), )+
- _ => Err(())
- }
- }
- }
-
- impl ::cssparser::ToCss for $name {
- fn to_css<W>(&self, dest: &mut W) -> ::std::fmt::Result
- where W: ::std::fmt::Write {
- match *self {
- $( $name::$variant => dest.write_str($css) ),+
- }
- }
- }
- }
-}
-
-pub type CSSFloat = f32;
-
-pub const FONT_MEDIUM_PX: i32 = 16;
-
-pub trait HasViewportPercentage {
- fn has_viewport_percentage(&self) -> bool;
-}
-
-pub trait NoViewportPercentage {}
-
-impl<T> HasViewportPercentage for T where T: NoViewportPercentage {
- fn has_viewport_percentage(&self) -> bool {
- false
- }
-}
-
-pub mod specified {
- use app_units::Au;
- use cssparser::{self, Parser, ToCss, Token};
- use euclid::size::Size2D;
- use parser::ParserContext;
- use std::ascii::AsciiExt;
- use std::cmp;
- use std::f32::consts::PI;
- use std::fmt;
- use std::ops::Mul;
- use style_traits::values::specified::AllowedNumericType;
- use super::computed::{Context, ToComputedValue};
- use super::{CSSFloat, FONT_MEDIUM_PX, HasViewportPercentage, LocalToCss, NoViewportPercentage};
- use url::Url;
-
- impl NoViewportPercentage for i32 {} // For PropertyDeclaration::Order
-
- #[derive(Clone, PartialEq, Debug)]
- #[cfg_attr(feature = "servo", derive(HeapSizeOf))]
- pub struct CSSColor {
- pub parsed: cssparser::Color,
- pub authored: Option<String>,
- }
- impl CSSColor {
- pub fn parse(input: &mut Parser) -> Result<CSSColor, ()> {
- let start_position = input.position();
- let authored = match input.next() {
- Ok(Token::Ident(s)) => Some(s.into_owned()),
- _ => None,
- };
- input.reset(start_position);
- Ok(CSSColor {
- parsed: try!(cssparser::Color::parse(input)),
- authored: authored,
- })
- }
- }
-
- impl NoViewportPercentage for CSSColor {}
-
- impl ToCss for CSSColor {
- fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
- match self.authored {
- Some(ref s) => dest.write_str(s),
- None => self.parsed.to_css(dest),
- }
- }
- }
-
- #[derive(Clone, PartialEq, Debug)]
- #[cfg_attr(feature = "servo", derive(HeapSizeOf))]
- pub struct CSSRGBA {
- pub parsed: cssparser::RGBA,
- pub authored: Option<String>,
- }
-
- impl NoViewportPercentage for CSSRGBA {}
-
- impl ToCss for CSSRGBA {
- fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
- match self.authored {
- Some(ref s) => dest.write_str(s),
- None => self.parsed.to_css(dest),
- }
- }
- }
-
- #[derive(Clone, PartialEq, Copy, Debug)]
- #[cfg_attr(feature = "servo", derive(HeapSizeOf))]
- pub enum FontRelativeLength {
- Em(CSSFloat),
- Ex(CSSFloat),
- Ch(CSSFloat),
- Rem(CSSFloat)
- }
-
- impl ToCss for FontRelativeLength {
- fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
- match *self {
- FontRelativeLength::Em(length) => write!(dest, "{}em", length),
- FontRelativeLength::Ex(length) => write!(dest, "{}ex", length),
- FontRelativeLength::Ch(length) => write!(dest, "{}ch", length),
- FontRelativeLength::Rem(length) => write!(dest, "{}rem", length)
- }
- }
- }
-
- impl FontRelativeLength {
- pub fn to_computed_value(&self,
- reference_font_size: Au,
- root_font_size: Au)
- -> Au
- {
- match *self {
- FontRelativeLength::Em(length) => reference_font_size.scale_by(length),
- FontRelativeLength::Ex(length) | FontRelativeLength::Ch(length) => {
- // https://github.com/servo/servo/issues/7462
- let em_factor = 0.5;
- reference_font_size.scale_by(length * em_factor)
- },
- FontRelativeLength::Rem(length) => root_font_size.scale_by(length)
- }
- }
- }
-
- #[derive(Clone, PartialEq, Copy, Debug)]
- #[cfg_attr(feature = "servo", derive(HeapSizeOf))]
- pub enum ViewportPercentageLength {
- Vw(CSSFloat),
- Vh(CSSFloat),
- Vmin(CSSFloat),
- Vmax(CSSFloat)
- }
-
- impl HasViewportPercentage for ViewportPercentageLength {
- fn has_viewport_percentage(&self) -> bool {
- true
- }
- }
-
- impl ToCss for ViewportPercentageLength {
- fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
- match *self {
- ViewportPercentageLength::Vw(length) => write!(dest, "{}vw", length),
- ViewportPercentageLength::Vh(length) => write!(dest, "{}vh", length),
- ViewportPercentageLength::Vmin(length) => write!(dest, "{}vmin", length),
- ViewportPercentageLength::Vmax(length) => write!(dest, "{}vmax", length)
- }
- }
- }
-
- impl ViewportPercentageLength {
- pub fn to_computed_value(&self, viewport_size: Size2D<Au>) -> Au {
- macro_rules! to_unit {
- ($viewport_dimension:expr) => {
- $viewport_dimension.to_f32_px() / 100.0
- }
- }
-
- let value = match *self {
- ViewportPercentageLength::Vw(length) =>
- length * to_unit!(viewport_size.width),
- ViewportPercentageLength::Vh(length) =>
- length * to_unit!(viewport_size.height),
- ViewportPercentageLength::Vmin(length) =>
- length * to_unit!(cmp::min(viewport_size.width, viewport_size.height)),
- ViewportPercentageLength::Vmax(length) =>
- length * to_unit!(cmp::max(viewport_size.width, viewport_size.height)),
- };
- Au::from_f32_px(value)
- }
- }
-
- #[derive(Clone, PartialEq, Copy, Debug)]
- #[cfg_attr(feature = "servo", derive(HeapSizeOf))]
- pub struct CharacterWidth(pub i32);
-
- impl CharacterWidth {
- pub fn to_computed_value(&self, reference_font_size: Au) -> Au {
- // This applies the *converting a character width to pixels* algorithm as specified
- // in HTML5 § 14.5.4.
- //
- // TODO(pcwalton): Find these from the font.
- let average_advance = reference_font_size.scale_by(0.5);
- let max_advance = reference_font_size;
- average_advance.scale_by(self.0 as CSSFloat - 1.0) + max_advance
- }
- }
-
- #[derive(Clone, PartialEq, Copy, Debug)]
- #[cfg_attr(feature = "servo", derive(HeapSizeOf))]
- pub enum Length {
- Absolute(Au), // application units
- FontRelative(FontRelativeLength),
- ViewportPercentage(ViewportPercentageLength),
-
- /// HTML5 "character width", as defined in HTML5 § 14.5.4.
- ///
- /// This cannot be specified by the user directly and is only generated by
- /// `Stylist::synthesize_rules_for_legacy_attributes()`.
- ServoCharacterWidth(CharacterWidth),
-
- Calc(CalcLengthOrPercentage),
- }
-
- impl HasViewportPercentage for Length {
- fn has_viewport_percentage(&self) -> bool {
- match *self {
- Length::ViewportPercentage(_) => true,
- _ => false
- }
- }
- }
-
- impl ToCss for Length {
- fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
- match *self {
- Length::Absolute(length) => write!(dest, "{}px", length.to_f32_px()),
- Length::FontRelative(length) => length.to_css(dest),
- Length::ViewportPercentage(length) => length.to_css(dest),
- Length::Calc(calc) => calc.to_css(dest),
- Length::ServoCharacterWidth(_)
- => panic!("internal CSS values should never be serialized"),
- }
- }
- }
-
- impl Mul<CSSFloat> for Length {
- type Output = Length;
-
- #[inline]
- fn mul(self, scalar: CSSFloat) -> Length {
- match self {
- Length::Absolute(Au(v)) => Length::Absolute(Au(((v as f32) * scalar) as i32)),
- Length::FontRelative(v) => Length::FontRelative(v * scalar),
- Length::ViewportPercentage(v) => Length::ViewportPercentage(v * scalar),
- Length::Calc(_) => panic!("Can't multiply Calc!"),
- Length::ServoCharacterWidth(_) => panic!("Can't multiply ServoCharacterWidth!"),
- }
- }
- }
-
- impl Mul<CSSFloat> for FontRelativeLength {
- type Output = FontRelativeLength;
-
- #[inline]
- fn mul(self, scalar: CSSFloat) -> FontRelativeLength {
- match self {
- FontRelativeLength::Em(v) => FontRelativeLength::Em(v * scalar),
- FontRelativeLength::Ex(v) => FontRelativeLength::Ex(v * scalar),
- FontRelativeLength::Ch(v) => FontRelativeLength::Ch(v * scalar),
- FontRelativeLength::Rem(v) => FontRelativeLength::Rem(v * scalar),
- }
- }
- }
-
- impl Mul<CSSFloat> for ViewportPercentageLength {
- type Output = ViewportPercentageLength;
-
- #[inline]
- fn mul(self, scalar: CSSFloat) -> ViewportPercentageLength {
- match self {
- ViewportPercentageLength::Vw(v) => ViewportPercentageLength::Vw(v * scalar),
- ViewportPercentageLength::Vh(v) => ViewportPercentageLength::Vh(v * scalar),
- ViewportPercentageLength::Vmin(v) => ViewportPercentageLength::Vmin(v * scalar),
- ViewportPercentageLength::Vmax(v) => ViewportPercentageLength::Vmax(v * scalar),
- }
- }
- }
-
- const AU_PER_PX: CSSFloat = 60.;
- const AU_PER_IN: CSSFloat = AU_PER_PX * 96.;
- const AU_PER_CM: CSSFloat = AU_PER_IN / 2.54;
- const AU_PER_MM: CSSFloat = AU_PER_IN / 25.4;
- const AU_PER_Q: CSSFloat = AU_PER_MM / 4.;
- const AU_PER_PT: CSSFloat = AU_PER_IN / 72.;
- const AU_PER_PC: CSSFloat = AU_PER_PT * 12.;
- impl Length {
- // https://drafts.csswg.org/css-fonts-3/#font-size-prop
- pub fn from_str(s: &str) -> Option<Length> {
- Some(match_ignore_ascii_case! { s,
- "xx-small" => Length::Absolute(Au::from_px(FONT_MEDIUM_PX) * 3 / 5),
- "x-small" => Length::Absolute(Au::from_px(FONT_MEDIUM_PX) * 3 / 4),
- "small" => Length::Absolute(Au::from_px(FONT_MEDIUM_PX) * 8 / 9),
- "medium" => Length::Absolute(Au::from_px(FONT_MEDIUM_PX)),
- "large" => Length::Absolute(Au::from_px(FONT_MEDIUM_PX) * 6 / 5),
- "x-large" => Length::Absolute(Au::from_px(FONT_MEDIUM_PX) * 3 / 2),
- "xx-large" => Length::Absolute(Au::from_px(FONT_MEDIUM_PX) * 2),
-
- // https://github.com/servo/servo/issues/3423#issuecomment-56321664
- "smaller" => Length::FontRelative(FontRelativeLength::Em(0.85)),
- "larger" => Length::FontRelative(FontRelativeLength::Em(1.2)),
- _ => return None
- })
- }
-
- #[inline]
- fn parse_internal(input: &mut Parser, context: &AllowedNumericType) -> Result<Length, ()> {
- match try!(input.next()) {
- Token::Dimension(ref value, ref unit) if context.is_ok(value.value) =>
- Length::parse_dimension(value.value, unit),
- Token::Number(ref value) if value.value == 0. =>
- Ok(Length::Absolute(Au(0))),
- Token::Function(ref name) if name.eq_ignore_ascii_case("calc") =>
- input.parse_nested_block(CalcLengthOrPercentage::parse_length),
- _ => Err(())
- }
- }
- pub fn parse(input: &mut Parser) -> Result<Length, ()> {
- Length::parse_internal(input, &AllowedNumericType::All)
- }
- pub fn parse_non_negative(input: &mut Parser) -> Result<Length, ()> {
- Length::parse_internal(input, &AllowedNumericType::NonNegative)
- }
- pub fn parse_dimension(value: CSSFloat, unit: &str) -> Result<Length, ()> {
- match_ignore_ascii_case! { unit,
- "px" => Ok(Length::from_px(value)),
- "in" => Ok(Length::Absolute(Au((value * AU_PER_IN) as i32))),
- "cm" => Ok(Length::Absolute(Au((value * AU_PER_CM) as i32))),
- "mm" => Ok(Length::Absolute(Au((value * AU_PER_MM) as i32))),
- "q" => Ok(Length::Absolute(Au((value * AU_PER_Q) as i32))),
- "pt" => Ok(Length::Absolute(Au((value * AU_PER_PT) as i32))),
- "pc" => Ok(Length::Absolute(Au((value * AU_PER_PC) as i32))),
- // font-relative
- "em" => Ok(Length::FontRelative(FontRelativeLength::Em(value))),
- "ex" => Ok(Length::FontRelative(FontRelativeLength::Ex(value))),
- "ch" => Ok(Length::FontRelative(FontRelativeLength::Ch(value))),
- "rem" => Ok(Length::FontRelative(FontRelativeLength::Rem(value))),
- // viewport percentages
- "vw" => Ok(Length::ViewportPercentage(ViewportPercentageLength::Vw(value))),
- "vh" => Ok(Length::ViewportPercentage(ViewportPercentageLength::Vh(value))),
- "vmin" => Ok(Length::ViewportPercentage(ViewportPercentageLength::Vmin(value))),
- "vmax" => Ok(Length::ViewportPercentage(ViewportPercentageLength::Vmax(value))),
- _ => Err(())
- }
- }
- #[inline]
- pub fn from_px(px_value: CSSFloat) -> Length {
- Length::Absolute(Au((px_value * AU_PER_PX) as i32))
- }
- }
-
- #[derive(Clone, Debug)]
- struct CalcSumNode {
- products: Vec<CalcProductNode>,
- }
-
- #[derive(Clone, Debug)]
- struct CalcProductNode {
- values: Vec<CalcValueNode>
- }
-
- #[derive(Clone, Debug)]
- enum CalcValueNode {
- Length(Length),
- Angle(Angle),
- Time(Time),
- Percentage(CSSFloat),
- Number(CSSFloat),
- Sum(Box<CalcSumNode>),
- }
-
- #[derive(Clone, Debug)]
- struct SimplifiedSumNode {
- values: Vec<SimplifiedValueNode>,
- }
- impl<'a> Mul<CSSFloat> for &'a SimplifiedSumNode {
- type Output = SimplifiedSumNode;
-
- #[inline]
- fn mul(self, scalar: CSSFloat) -> SimplifiedSumNode {
- SimplifiedSumNode {
- values: self.values.iter().map(|p| p * scalar).collect()
- }
- }
- }
-
- #[derive(Clone, Debug)]
- enum SimplifiedValueNode {
- Length(Length),
- Angle(Angle),
- Time(Time),
- Percentage(CSSFloat),
- Number(CSSFloat),
- Sum(Box<SimplifiedSumNode>),
- }
- impl<'a> Mul<CSSFloat> for &'a SimplifiedValueNode {
- type Output = SimplifiedValueNode;
-
- #[inline]
- fn mul(self, scalar: CSSFloat) -> SimplifiedValueNode {
- match *self {
- SimplifiedValueNode::Length(l) => SimplifiedValueNode::Length(l * scalar),
- SimplifiedValueNode::Percentage(p) => SimplifiedValueNode::Percentage(p * scalar),
- SimplifiedValueNode::Angle(Angle(a)) => SimplifiedValueNode::Angle(Angle(a * scalar)),
- SimplifiedValueNode::Time(Time(t)) => SimplifiedValueNode::Time(Time(t * scalar)),
- SimplifiedValueNode::Number(n) => SimplifiedValueNode::Number(n * scalar),
- SimplifiedValueNode::Sum(ref s) => {
- let sum = &**s * scalar;
- SimplifiedValueNode::Sum(Box::new(sum))
- }
- }
- }
- }
-
- pub fn parse_integer(input: &mut Parser) -> Result<i32, ()> {
- match try!(input.next()) {
- Token::Number(ref value) => value.int_value.ok_or(()),
- Token::Function(ref name) if name.eq_ignore_ascii_case("calc") => {
- let ast = try!(input.parse_nested_block(|i| CalcLengthOrPercentage::parse_sum(i, CalcUnit::Integer)));
-
- let mut result = None;
-
- for ref node in ast.products {
- match try!(CalcLengthOrPercentage::simplify_product(node)) {
- SimplifiedValueNode::Number(val) =>
- result = Some(result.unwrap_or(0) + val as i32),
- _ => unreachable!()
- }
- }
-
- match result {
- Some(result) => Ok(result),
- _ => Err(())
- }
- }
- _ => Err(())
- }
- }
-
- pub fn parse_number(input: &mut Parser) -> Result<f32, ()> {
- match try!(input.next()) {
- Token::Number(ref value) => Ok(value.value),
- Token::Function(ref name) if name.eq_ignore_ascii_case("calc") => {
- let ast = try!(input.parse_nested_block(|i| CalcLengthOrPercentage::parse_sum(i, CalcUnit::Number)));
-
- let mut result = None;
-
- for ref node in ast.products {
- match try!(CalcLengthOrPercentage::simplify_product(node)) {
- SimplifiedValueNode::Number(val) =>
- result = Some(result.unwrap_or(0.) + val),
- _ => unreachable!()
- }
- }
-
- match result {
- Some(result) => Ok(result),
- _ => Err(())
- }
- }
- _ => Err(())
- }
- }
-
- #[derive(Clone, Copy, PartialEq)]
- enum CalcUnit {
- Number,
- Integer,
- Length,
- LengthOrPercentage,
- Angle,
- Time,
- }
-
- #[derive(Clone, PartialEq, Copy, Debug)]
- #[cfg_attr(feature = "servo", derive(HeapSizeOf))]
- pub struct CalcLengthOrPercentage {
- pub absolute: Option<Au>,
- pub vw: Option<ViewportPercentageLength>,
- pub vh: Option<ViewportPercentageLength>,
- pub vmin: Option<ViewportPercentageLength>,
- pub vmax: Option<ViewportPercentageLength>,
- pub em: Option<FontRelativeLength>,
- pub ex: Option<FontRelativeLength>,
- pub ch: Option<FontRelativeLength>,
- pub rem: Option<FontRelativeLength>,
- pub percentage: Option<Percentage>,
- }
- impl CalcLengthOrPercentage {
- fn parse_sum(input: &mut Parser, expected_unit: CalcUnit) -> Result<CalcSumNode, ()> {
- let mut products = Vec::new();
- products.push(try!(CalcLengthOrPercentage::parse_product(input, expected_unit)));
-
- while let Ok(token) = input.next() {
- match token {
- Token::Delim('+') => {
- products.push(try!(CalcLengthOrPercentage::parse_product(input, expected_unit)));
- }
- Token::Delim('-') => {
- let mut right = try!(CalcLengthOrPercentage::parse_product(input, expected_unit));
- right.values.push(CalcValueNode::Number(-1.));
- products.push(right);
- }
- _ => return Err(())
- }
- }
-
- Ok(CalcSumNode { products: products })
- }
-
- fn parse_product(input: &mut Parser, expected_unit: CalcUnit) -> Result<CalcProductNode, ()> {
- let mut values = Vec::new();
- values.push(try!(CalcLengthOrPercentage::parse_value(input, expected_unit)));
-
- loop {
- let position = input.position();
- match input.next() {
- Ok(Token::Delim('*')) => {
- values.push(try!(CalcLengthOrPercentage::parse_value(input, expected_unit)));
- }
- Ok(Token::Delim('/')) if expected_unit != CalcUnit::Integer => {
- if let Ok(Token::Number(ref value)) = input.next() {
- if value.value == 0. {
- return Err(());
- }
- values.push(CalcValueNode::Number(1. / value.value));
- } else {
- return Err(());
- }
- }
- _ => {
- input.reset(position);
- break
- }
- }
- }
-
- Ok(CalcProductNode { values: values })
- }
-
- fn parse_value(input: &mut Parser, expected_unit: CalcUnit) -> Result<CalcValueNode, ()> {
- match (try!(input.next()), expected_unit) {
- (Token::Number(ref value), _) => Ok(CalcValueNode::Number(value.value)),
- (Token::Dimension(ref value, ref unit), CalcUnit::Length) |
- (Token::Dimension(ref value, ref unit), CalcUnit::LengthOrPercentage) => {
- Length::parse_dimension(value.value, unit).map(CalcValueNode::Length)
- }
- (Token::Dimension(ref value, ref unit), CalcUnit::Angle) => {
- Angle::parse_dimension(value.value, unit).map(CalcValueNode::Angle)
- }
- (Token::Dimension(ref value, ref unit), CalcUnit::Time) => {
- Time::parse_dimension(value.value, unit).map(CalcValueNode::Time)
- }
- (Token::Percentage(ref value), CalcUnit::LengthOrPercentage) =>
- Ok(CalcValueNode::Percentage(value.unit_value)),
- (Token::ParenthesisBlock, _) => {
- input.parse_nested_block(|i| CalcLengthOrPercentage::parse_sum(i, expected_unit))
- .map(|result| CalcValueNode::Sum(Box::new(result)))
- },
- _ => Err(())
- }
- }
-
- fn simplify_value_to_number(node: &CalcValueNode) -> Option<CSSFloat> {
- match *node {
- CalcValueNode::Number(number) => Some(number),
- CalcValueNode::Sum(ref sum) => CalcLengthOrPercentage::simplify_sum_to_number(sum),
- _ => None
- }
- }
-
- fn simplify_sum_to_number(node: &CalcSumNode) -> Option<CSSFloat> {
- let mut sum = 0.;
- for ref product in &node.products {
- match CalcLengthOrPercentage::simplify_product_to_number(product) {
- Some(number) => sum += number,
- _ => return None
- }
- }
- Some(sum)
- }
-
- fn simplify_product_to_number(node: &CalcProductNode) -> Option<CSSFloat> {
- let mut product = 1.;
- for ref value in &node.values {
- match CalcLengthOrPercentage::simplify_value_to_number(value) {
- Some(number) => product *= number,
- _ => return None
- }
- }
- Some(product)
- }
-
- fn simplify_products_in_sum(node: &CalcSumNode) -> Result<SimplifiedValueNode, ()> {
- let mut simplified = Vec::new();
- for product in &node.products {
- match try!(CalcLengthOrPercentage::simplify_product(product)) {
- SimplifiedValueNode::Sum(ref sum) => simplified.extend_from_slice(&sum.values),
- val => simplified.push(val),
- }
- }
-
- if simplified.len() == 1 {
- Ok(simplified[0].clone())
- } else {
- Ok(SimplifiedValueNode::Sum(Box::new(SimplifiedSumNode { values: simplified })))
- }
- }
-
- fn simplify_product(node: &CalcProductNode) -> Result<SimplifiedValueNode, ()> {
- let mut multiplier = 1.;
- let mut node_with_unit = None;
- for node in &node.values {
- match CalcLengthOrPercentage::simplify_value_to_number(&node) {
- Some(number) => multiplier *= number,
- _ if node_with_unit.is_none() => {
- node_with_unit = Some(match *node {
- CalcValueNode::Sum(ref sum) =>
- try!(CalcLengthOrPercentage::simplify_products_in_sum(sum)),
- CalcValueNode::Length(l) => SimplifiedValueNode::Length(l),
- CalcValueNode::Angle(a) => SimplifiedValueNode::Angle(a),
- CalcValueNode::Time(t) => SimplifiedValueNode::Time(t),
- CalcValueNode::Percentage(p) => SimplifiedValueNode::Percentage(p),
- _ => unreachable!("Numbers should have been handled by simplify_value_to_nubmer")
- })
- },
- _ => return Err(()),
- }
- }
-
- match node_with_unit {
- None => Ok(SimplifiedValueNode::Number(multiplier)),
- Some(ref value) => Ok(value * multiplier)
- }
- }
-
- fn parse_length(input: &mut Parser) -> Result<Length, ()> {
- CalcLengthOrPercentage::parse(input, CalcUnit::Length).map(Length::Calc)
- }
-
- fn parse_length_or_percentage(input: &mut Parser) -> Result<CalcLengthOrPercentage, ()> {
- CalcLengthOrPercentage::parse(input, CalcUnit::LengthOrPercentage)
- }
-
- fn parse(input: &mut Parser, expected_unit: CalcUnit) -> Result<CalcLengthOrPercentage, ()> {
- let ast = try!(CalcLengthOrPercentage::parse_sum(input, expected_unit));
-
- let mut simplified = Vec::new();
- for ref node in ast.products {
- match try!(CalcLengthOrPercentage::simplify_product(node)) {
- SimplifiedValueNode::Sum(sum) => simplified.extend_from_slice(&sum.values),
- value => simplified.push(value),
- }
- }
-
- let mut absolute = None;
- let mut vw = None;
- let mut vh = None;
- let mut vmax = None;
- let mut vmin = None;
- let mut em = None;
- let mut ex = None;
- let mut ch = None;
- let mut rem = None;
- let mut percentage = None;
- let mut number = None;
-
- for value in simplified {
- match value {
- SimplifiedValueNode::Percentage(p) =>
- percentage = Some(percentage.unwrap_or(0.) + p),
- SimplifiedValueNode::Length(Length::Absolute(Au(au))) =>
- absolute = Some(absolute.unwrap_or(0) + au),
- SimplifiedValueNode::Length(Length::ViewportPercentage(v)) =>
- match v {
- ViewportPercentageLength::Vw(val) =>
- vw = Some(vw.unwrap_or(0.) + val),
- ViewportPercentageLength::Vh(val) =>
- vh = Some(vh.unwrap_or(0.) + val),
- ViewportPercentageLength::Vmin(val) =>
- vmin = Some(vmin.unwrap_or(0.) + val),
- ViewportPercentageLength::Vmax(val) =>
- vmax = Some(vmax.unwrap_or(0.) + val),
- },
- SimplifiedValueNode::Length(Length::FontRelative(f)) =>
- match f {
- FontRelativeLength::Em(val) =>
- em = Some(em.unwrap_or(0.) + val),
- FontRelativeLength::Ex(val) =>
- ex = Some(ex.unwrap_or(0.) + val),
- FontRelativeLength::Ch(val) =>
- ch = Some(ch.unwrap_or(0.) + val),
- FontRelativeLength::Rem(val) =>
- rem = Some(rem.unwrap_or(0.) + val),
- },
- SimplifiedValueNode::Number(val) => number = Some(number.unwrap_or(0.) + val),
- _ => return Err(()),
- }
- }
-
- Ok(CalcLengthOrPercentage {
- absolute: absolute.map(Au),
- vw: vw.map(ViewportPercentageLength::Vw),
- vh: vh.map(ViewportPercentageLength::Vh),
- vmax: vmax.map(ViewportPercentageLength::Vmax),
- vmin: vmin.map(ViewportPercentageLength::Vmin),
- em: em.map(FontRelativeLength::Em),
- ex: ex.map(FontRelativeLength::Ex),
- ch: ch.map(FontRelativeLength::Ch),
- rem: rem.map(FontRelativeLength::Rem),
- percentage: percentage.map(Percentage),
- })
- }
-
- pub fn parse_time(input: &mut Parser) -> Result<Time, ()> {
- let ast = try!(CalcLengthOrPercentage::parse_sum(input, CalcUnit::Time));
-
- let mut simplified = Vec::new();
- for ref node in ast.products {
- match try!(CalcLengthOrPercentage::simplify_product(node)) {
- SimplifiedValueNode::Sum(sum) => simplified.extend_from_slice(&sum.values),
- value => simplified.push(value),
- }
- }
-
- let mut time = None;
-
- for value in simplified {
- match value {
- SimplifiedValueNode::Time(Time(val)) =>
- time = Some(time.unwrap_or(0.) + val),
- _ => return Err(()),
- }
- }
-
- match time {
- Some(time) => Ok(Time(time)),
- _ => Err(())
- }
- }
-
- pub fn parse_angle(input: &mut Parser) -> Result<Angle, ()> {
- let ast = try!(CalcLengthOrPercentage::parse_sum(input, CalcUnit::Angle));
-
- let mut simplified = Vec::new();
- for ref node in ast.products {
- match try!(CalcLengthOrPercentage::simplify_product(node)) {
- SimplifiedValueNode::Sum(sum) => simplified.extend_from_slice(&sum.values),
- value => simplified.push(value),
- }
- }
-
- let mut angle = None;
- let mut number = None;
-
- for value in simplified {
- match value {
- SimplifiedValueNode::Angle(Angle(val)) =>
- angle = Some(angle.unwrap_or(0.) + val),
- SimplifiedValueNode::Number(val) => number = Some(number.unwrap_or(0.) + val),
- _ => unreachable!()
- }
- }
-
- match (angle, number) {
- (Some(angle), None) => Ok(Angle(angle)),
- (None, Some(value)) if value == 0. => Ok(Angle(0.)),
- _ => Err(())
- }
- }
- }
-
- impl ToCss for CalcLengthOrPercentage {
- #[allow(unused_assignments)]
- fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
- macro_rules! count {
- ( $( $val:ident ),* ) => {
- {
- let mut count = 0;
- $(
- if let Some(_) = self.$val {
- count += 1;
- }
- )*
- count
- }
- };
- }
-
- macro_rules! serialize {
- ( $( $val:ident ),* ) => {
- {
- let mut first_value = true;
- $(
- if let Some(val) = self.$val {
- if !first_value {
- try!(write!(dest, " + "));
- } else {
- first_value = false;
- }
- try!(val.to_css(dest));
- }
- )*
- }
- };
- }
-
- let count = count!(ch, em, ex, absolute, rem, vh, vmax, vmin, vw, percentage);
- assert!(count > 0);
-
- if count > 1 {
- try!(write!(dest, "calc("));
- }
-
- serialize!(ch, em, ex, absolute, rem, vh, vmax, vmin, vw, percentage);
-
- if count > 1 {
- try!(write!(dest, ")"));
- }
- Ok(())
- }
- }
-
- #[derive(Clone, PartialEq, Copy, Debug)]
- #[cfg_attr(feature = "servo", derive(HeapSizeOf))]
- pub struct Percentage(pub CSSFloat); // [0 .. 100%] maps to [0.0 .. 1.0]
-
- impl ToCss for Percentage {
- fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
- write!(dest, "{}%", self.0 * 100.)
- }
- }
-
- #[derive(Clone, PartialEq, Copy, Debug)]
- #[cfg_attr(feature = "servo", derive(HeapSizeOf))]
- pub enum LengthOrPercentage {
- Length(Length),
- Percentage(Percentage),
- Calc(CalcLengthOrPercentage),
- }
-
- impl HasViewportPercentage for LengthOrPercentage {
- fn has_viewport_percentage(&self) -> bool {
- match *self {
- LengthOrPercentage::Length(length) => length.has_viewport_percentage(),
- _ => false
- }
- }
- }
-
- impl ToCss for LengthOrPercentage {
- fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
- match *self {
- LengthOrPercentage::Length(length) => length.to_css(dest),
- LengthOrPercentage::Percentage(percentage) => percentage.to_css(dest),
- LengthOrPercentage::Calc(calc) => calc.to_css(dest),
- }
- }
- }
- impl LengthOrPercentage {
- pub fn zero() -> LengthOrPercentage {
- LengthOrPercentage::Length(Length::Absolute(Au(0)))
- }
-
- fn parse_internal(input: &mut Parser, context: &AllowedNumericType)
- -> Result<LengthOrPercentage, ()>
- {
- match try!(input.next()) {
- Token::Dimension(ref value, ref unit) if context.is_ok(value.value) =>
- Length::parse_dimension(value.value, unit).map(LengthOrPercentage::Length),
- Token::Percentage(ref value) if context.is_ok(value.unit_value) =>
- Ok(LengthOrPercentage::Percentage(Percentage(value.unit_value))),
- Token::Number(ref value) if value.value == 0. =>
- Ok(LengthOrPercentage::Length(Length::Absolute(Au(0)))),
- Token::Function(ref name) if name.eq_ignore_ascii_case("calc") => {
- let calc = try!(input.parse_nested_block(CalcLengthOrPercentage::parse_length_or_percentage));
- Ok(LengthOrPercentage::Calc(calc))
- },
- _ => Err(())
- }
- }
- #[inline]
- pub fn parse(input: &mut Parser) -> Result<LengthOrPercentage, ()> {
- LengthOrPercentage::parse_internal(input, &AllowedNumericType::All)
- }
- #[inline]
- pub fn parse_non_negative(input: &mut Parser) -> Result<LengthOrPercentage, ()> {
- LengthOrPercentage::parse_internal(input, &AllowedNumericType::NonNegative)
- }
- }
-
- #[derive(Clone, PartialEq, Copy, Debug)]
- #[cfg_attr(feature = "servo", derive(HeapSizeOf))]
- pub enum LengthOrPercentageOrAuto {
- Length(Length),
- Percentage(Percentage),
- Auto,
- Calc(CalcLengthOrPercentage),
- }
-
- impl HasViewportPercentage for LengthOrPercentageOrAuto {
- fn has_viewport_percentage(&self) -> bool {
- match *self {
- LengthOrPercentageOrAuto::Length(length) => length.has_viewport_percentage(),
- _ => false
- }
- }
- }
-
- impl ToCss for LengthOrPercentageOrAuto {
- fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
- match *self {
- LengthOrPercentageOrAuto::Length(length) => length.to_css(dest),
- LengthOrPercentageOrAuto::Percentage(percentage) => percentage.to_css(dest),
- LengthOrPercentageOrAuto::Auto => dest.write_str("auto"),
- LengthOrPercentageOrAuto::Calc(calc) => calc.to_css(dest),
- }
- }
- }
-
- impl LengthOrPercentageOrAuto {
- fn parse_internal(input: &mut Parser, context: &AllowedNumericType)
- -> Result<LengthOrPercentageOrAuto, ()>
- {
- match try!(input.next()) {
- Token::Dimension(ref value, ref unit) if context.is_ok(value.value) =>
- Length::parse_dimension(value.value, unit).map(LengthOrPercentageOrAuto::Length),
- Token::Percentage(ref value) if context.is_ok(value.unit_value) =>
- Ok(LengthOrPercentageOrAuto::Percentage(Percentage(value.unit_value))),
- Token::Number(ref value) if value.value == 0. =>
- Ok(LengthOrPercentageOrAuto::Length(Length::Absolute(Au(0)))),
- Token::Ident(ref value) if value.eq_ignore_ascii_case("auto") =>
- Ok(LengthOrPercentageOrAuto::Auto),
- Token::Function(ref name) if name.eq_ignore_ascii_case("calc") => {
- let calc = try!(input.parse_nested_block(CalcLengthOrPercentage::parse_length_or_percentage));
- Ok(LengthOrPercentageOrAuto::Calc(calc))
- },
- _ => Err(())
- }
- }
- #[inline]
- pub fn parse(input: &mut Parser) -> Result<LengthOrPercentageOrAuto, ()> {
- LengthOrPercentageOrAuto::parse_internal(input, &AllowedNumericType::All)
- }
- #[inline]
- pub fn parse_non_negative(input: &mut Parser) -> Result<LengthOrPercentageOrAuto, ()> {
- LengthOrPercentageOrAuto::parse_internal(input, &AllowedNumericType::NonNegative)
- }
- }
-
- #[derive(Clone, PartialEq, Copy, Debug)]
- #[cfg_attr(feature = "servo", derive(HeapSizeOf))]
- pub enum LengthOrPercentageOrNone {
- Length(Length),
- Percentage(Percentage),
- Calc(CalcLengthOrPercentage),
- None,
- }
-
- impl HasViewportPercentage for LengthOrPercentageOrNone {
- fn has_viewport_percentage(&self) -> bool {
- match *self {
- LengthOrPercentageOrNone::Length(length) => length.has_viewport_percentage(),
- _ => false
- }
- }
- }
-
- impl ToCss for LengthOrPercentageOrNone {
- fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
- match *self {
- LengthOrPercentageOrNone::Length(length) => length.to_css(dest),
- LengthOrPercentageOrNone::Percentage(percentage) => percentage.to_css(dest),
- LengthOrPercentageOrNone::Calc(calc) => calc.to_css(dest),
- LengthOrPercentageOrNone::None => dest.write_str("none"),
- }
- }
- }
- impl LengthOrPercentageOrNone {
- fn parse_internal(input: &mut Parser, context: &AllowedNumericType)
- -> Result<LengthOrPercentageOrNone, ()>
- {
- match try!(input.next()) {
- Token::Dimension(ref value, ref unit) if context.is_ok(value.value) =>
- Length::parse_dimension(value.value, unit).map(LengthOrPercentageOrNone::Length),
- Token::Percentage(ref value) if context.is_ok(value.unit_value) =>
- Ok(LengthOrPercentageOrNone::Percentage(Percentage(value.unit_value))),
- Token::Number(ref value) if value.value == 0. =>
- Ok(LengthOrPercentageOrNone::Length(Length::Absolute(Au(0)))),
- Token::Function(ref name) if name.eq_ignore_ascii_case("calc") => {
- let calc = try!(input.parse_nested_block(CalcLengthOrPercentage::parse_length_or_percentage));
- Ok(LengthOrPercentageOrNone::Calc(calc))
- },
- Token::Ident(ref value) if value.eq_ignore_ascii_case("none") =>
- Ok(LengthOrPercentageOrNone::None),
- _ => Err(())
- }
- }
- #[inline]
- pub fn parse(input: &mut Parser) -> Result<LengthOrPercentageOrNone, ()> {
- LengthOrPercentageOrNone::parse_internal(input, &AllowedNumericType::All)
- }
- #[inline]
- pub fn parse_non_negative(input: &mut Parser) -> Result<LengthOrPercentageOrNone, ()> {
- LengthOrPercentageOrNone::parse_internal(input, &AllowedNumericType::NonNegative)
- }
- }
-
- #[derive(Clone, PartialEq, Copy, Debug)]
- #[cfg_attr(feature = "servo", derive(HeapSizeOf))]
- pub enum LengthOrNone {
- Length(Length),
- None,
- }
-
- impl HasViewportPercentage for LengthOrNone {
- fn has_viewport_percentage(&self) -> bool {
- match *self {
- LengthOrNone::Length(length) => length.has_viewport_percentage(),
- _ => false
- }
- }
- }
-
- impl ToCss for LengthOrNone {
- fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
- match *self {
- LengthOrNone::Length(length) => length.to_css(dest),
- LengthOrNone::None => dest.write_str("none"),
- }
- }
- }
- impl LengthOrNone {
- fn parse_internal(input: &mut Parser, context: &AllowedNumericType)
- -> Result<LengthOrNone, ()>
- {
- match try!(input.next()) {
- Token::Dimension(ref value, ref unit) if context.is_ok(value.value) =>
- Length::parse_dimension(value.value, unit).map(LengthOrNone::Length),
- Token::Number(ref value) if value.value == 0. =>
- Ok(LengthOrNone::Length(Length::Absolute(Au(0)))),
- Token::Function(ref name) if name.eq_ignore_ascii_case("calc") =>
- input.parse_nested_block(CalcLengthOrPercentage::parse_length).map(LengthOrNone::Length),
- Token::Ident(ref value) if value.eq_ignore_ascii_case("none") =>
- Ok(LengthOrNone::None),
- _ => Err(())
- }
- }
- #[inline]
- pub fn parse(input: &mut Parser) -> Result<LengthOrNone, ()> {
- LengthOrNone::parse_internal(input, &AllowedNumericType::All)
- }
- #[inline]
- pub fn parse_non_negative(input: &mut Parser) -> Result<LengthOrNone, ()> {
- LengthOrNone::parse_internal(input, &AllowedNumericType::NonNegative)
- }
- }
-
- #[derive(Clone, PartialEq, Copy, Debug)]
- #[cfg_attr(feature = "servo", derive(HeapSizeOf))]
- pub enum LengthOrPercentageOrAutoOrContent {
- Length(Length),
- Percentage(Percentage),
- Calc(CalcLengthOrPercentage),
- Auto,
- Content
- }
-
- impl HasViewportPercentage for LengthOrPercentageOrAutoOrContent {
- fn has_viewport_percentage(&self) -> bool {
- match *self {
- LengthOrPercentageOrAutoOrContent::Length(length) => length.has_viewport_percentage(),
- _ => false
- }
- }
- }
-
- impl ToCss for LengthOrPercentageOrAutoOrContent {
- fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
- match *self {
- LengthOrPercentageOrAutoOrContent::Length(len) => len.to_css(dest),
- LengthOrPercentageOrAutoOrContent::Percentage(perc) => perc.to_css(dest),
- LengthOrPercentageOrAutoOrContent::Auto => dest.write_str("auto"),
- LengthOrPercentageOrAutoOrContent::Content => dest.write_str("content"),
- LengthOrPercentageOrAutoOrContent::Calc(calc) => calc.to_css(dest),
- }
- }
- }
-
- impl LengthOrPercentageOrAutoOrContent {
- pub fn parse(input: &mut Parser) -> Result<LengthOrPercentageOrAutoOrContent, ()> {
- let context = AllowedNumericType::NonNegative;
- match try!(input.next()) {
- Token::Dimension(ref value, ref unit) if context.is_ok(value.value) =>
- Length::parse_dimension(value.value, unit).map(LengthOrPercentageOrAutoOrContent::Length),
- Token::Percentage(ref value) if context.is_ok(value.unit_value) =>
- Ok(LengthOrPercentageOrAutoOrContent::Percentage(Percentage(value.unit_value))),
- Token::Number(ref value) if value.value == 0. =>
- Ok(LengthOrPercentageOrAutoOrContent::Length(Length::Absolute(Au(0)))),
- Token::Ident(ref value) if value.eq_ignore_ascii_case("auto") =>
- Ok(LengthOrPercentageOrAutoOrContent::Auto),
- Token::Ident(ref value) if value.eq_ignore_ascii_case("content") =>
- Ok(LengthOrPercentageOrAutoOrContent::Content),
- Token::Function(ref name) if name.eq_ignore_ascii_case("calc") => {
- let calc = try!(input.parse_nested_block(CalcLengthOrPercentage::parse_length_or_percentage));
- Ok(LengthOrPercentageOrAutoOrContent::Calc(calc))
- },
- _ => Err(())
- }
- }
- }
-
- #[derive(Clone, PartialEq, Copy, Debug)]
- #[cfg_attr(feature = "servo", derive(HeapSizeOf))]
- pub struct BorderRadiusSize(pub Size2D<LengthOrPercentage>);
-
- impl NoViewportPercentage for BorderRadiusSize {}
-
- impl BorderRadiusSize {
- pub fn zero() -> BorderRadiusSize {
- let zero = LengthOrPercentage::Length(Length::Absolute(Au(0)));
- BorderRadiusSize(Size2D::new(zero, zero))
- }
-
- pub fn new(width: LengthOrPercentage, height: LengthOrPercentage) -> BorderRadiusSize {
- BorderRadiusSize(Size2D::new(width, height))
- }
-
- pub fn circle(radius: LengthOrPercentage) -> BorderRadiusSize {
- BorderRadiusSize(Size2D::new(radius, radius))
- }
-
- #[inline]
- pub fn parse(input: &mut Parser) -> Result<BorderRadiusSize, ()> {
- let first = try!(LengthOrPercentage::parse_non_negative(input));
- let second = input.try(LengthOrPercentage::parse_non_negative).unwrap_or(first);
- Ok(BorderRadiusSize(Size2D::new(first, second)))
- }
- }
-
- impl ToCss for BorderRadiusSize {
- fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
- try!(self.0.width.to_css(dest));
- try!(dest.write_str(" "));
- self.0.height.to_css(dest)
- }
- }
-
- // http://dev.w3.org/csswg/css2/colors.html#propdef-background-position
- #[derive(Clone, PartialEq, Copy)]
- pub enum PositionComponent {
- LengthOrPercentage(LengthOrPercentage),
- Center,
- Left,
- Right,
- Top,
- Bottom,
- }
-
- impl HasViewportPercentage for PositionComponent {
- fn has_viewport_percentage(&self) -> bool {
- match *self {
- PositionComponent::LengthOrPercentage(length) => length.has_viewport_percentage(),
- _ => false
- }
- }
- }
-
- impl PositionComponent {
- pub fn parse(input: &mut Parser) -> Result<PositionComponent, ()> {
- input.try(LengthOrPercentage::parse)
- .map(PositionComponent::LengthOrPercentage)
- .or_else(|()| {
- match try!(input.next()) {
- Token::Ident(value) => {
- match_ignore_ascii_case! { value,
- "center" => Ok(PositionComponent::Center),
- "left" => Ok(PositionComponent::Left),
- "right" => Ok(PositionComponent::Right),
- "top" => Ok(PositionComponent::Top),
- "bottom" => Ok(PositionComponent::Bottom),
- _ => Err(())
- }
- },
- _ => Err(())
- }
- })
- }
- #[inline]
- pub fn to_length_or_percentage(self) -> LengthOrPercentage {
- match self {
- PositionComponent::LengthOrPercentage(value) => value,
- PositionComponent::Center => LengthOrPercentage::Percentage(Percentage(0.5)),
- PositionComponent::Left |
- PositionComponent::Top => LengthOrPercentage::Percentage(Percentage(0.0)),
- PositionComponent::Right |
- PositionComponent::Bottom => LengthOrPercentage::Percentage(Percentage(1.0)),
- }
- }
- }
-
- #[derive(Clone, PartialEq, PartialOrd, Copy, Debug)]
- #[cfg_attr(feature = "servo", derive(HeapSizeOf, Deserialize, Serialize))]
- /// An angle, normalized to radians.
- pub struct Angle(pub CSSFloat);
-
- impl ToCss for Angle {
- fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
- write!(dest, "{}rad", self.0)
- }
- }
-
- impl Angle {
- #[inline]
- pub fn radians(self) -> f32 {
- self.0
- }
-
- #[inline]
- pub fn from_radians(r: f32) -> Self {
- Angle(r)
- }
- }
-
- const RAD_PER_DEG: CSSFloat = PI / 180.0;
- const RAD_PER_GRAD: CSSFloat = PI / 200.0;
- const RAD_PER_TURN: CSSFloat = PI * 2.0;
-
- impl Angle {
- /// Parses an angle according to CSS-VALUES § 6.1.
- pub fn parse(input: &mut Parser) -> Result<Angle, ()> {
- match try!(input.next()) {
- Token::Dimension(ref value, ref unit) => Angle::parse_dimension(value.value, unit),
- Token::Number(ref value) if value.value == 0. => Ok(Angle(0.)),
- Token::Function(ref name) if name.eq_ignore_ascii_case("calc") => {
- input.parse_nested_block(CalcLengthOrPercentage::parse_angle)
- },
- _ => Err(())
- }
- }
-
- pub fn parse_dimension(value: CSSFloat, unit: &str) -> Result<Angle, ()> {
- match_ignore_ascii_case! { unit,
- "deg" => Ok(Angle(value * RAD_PER_DEG)),
- "grad" => Ok(Angle(value * RAD_PER_GRAD)),
- "turn" => Ok(Angle(value * RAD_PER_TURN)),
- "rad" => Ok(Angle(value)),
- _ => Err(())
- }
- }
- }
-
- /// Specified values for an image according to CSS-IMAGES.
- #[derive(Clone, PartialEq, Debug)]
- #[cfg_attr(feature = "servo", derive(HeapSizeOf))]
- pub enum Image {
- Url(Url),
- LinearGradient(LinearGradient),
- }
-
- impl ToCss for Image {
- fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
- use values::LocalToCss;
- match *self {
- Image::Url(ref url) => {
- url.to_css(dest)
- }
- Image::LinearGradient(ref gradient) => gradient.to_css(dest)
- }
- }
- }
-
- impl Image {
- pub fn parse(context: &ParserContext, input: &mut Parser) -> Result<Image, ()> {
- if let Ok(url) = input.try(|input| input.expect_url()) {
- Ok(Image::Url(context.parse_url(&url)))
- } else {
- match_ignore_ascii_case! { try!(input.expect_function()),
- "linear-gradient" => {
- Ok(Image::LinearGradient(try!(
- input.parse_nested_block(LinearGradient::parse_function))))
- },
- _ => Err(())
- }
- }
- }
- }
-
- /// Specified values for a CSS linear gradient.
- #[derive(Clone, PartialEq, Debug)]
- #[cfg_attr(feature = "servo", derive(HeapSizeOf))]
- pub struct LinearGradient {
- /// The angle or corner of the gradient.
- pub angle_or_corner: AngleOrCorner,
-
- /// The color stops.
- pub stops: Vec<ColorStop>,
- }
-
- impl ToCss for LinearGradient {
- fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
- try!(dest.write_str("linear-gradient("));
- try!(self.angle_or_corner.to_css(dest));
- for stop in &self.stops {
- try!(dest.write_str(", "));
- try!(stop.to_css(dest));
- }
- try!(dest.write_str(")"));
- Ok(())
- }
- }
-
- /// Specified values for an angle or a corner in a linear gradient.
- #[derive(Clone, PartialEq, Copy, Debug)]
- #[cfg_attr(feature = "servo", derive(HeapSizeOf))]
- pub enum AngleOrCorner {
- Angle(Angle),
- Corner(HorizontalDirection, VerticalDirection),
- }
-
- 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(())
- }
- }
- }
- }
-
- /// Specified values for one color stop in a linear gradient.
- #[derive(Clone, PartialEq, Debug)]
- #[cfg_attr(feature = "servo", derive(HeapSizeOf))]
- pub struct ColorStop {
- /// The color of this stop.
- pub color: CSSColor,
-
- /// The position of this stop. If not specified, this stop is placed halfway between the
- /// point that precedes it and the point that follows it.
- pub position: Option<LengthOrPercentage>,
- }
-
- impl ToCss for ColorStop {
- fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
- try!(self.color.to_css(dest));
- if let Some(position) = self.position {
- try!(dest.write_str(" "));
- try!(position.to_css(dest));
- }
- Ok(())
- }
- }
-
- define_css_keyword_enum!(HorizontalDirection: "left" => Left, "right" => Right);
- define_css_keyword_enum!(VerticalDirection: "top" => Top, "bottom" => Bottom);
-
- fn parse_one_color_stop(input: &mut Parser) -> Result<ColorStop, ()> {
- Ok(ColorStop {
- color: try!(CSSColor::parse(input)),
- position: input.try(LengthOrPercentage::parse).ok(),
- })
- }
-
- impl LinearGradient {
- /// Parses a linear gradient from the given arguments.
- pub fn parse_function(input: &mut Parser) -> Result<LinearGradient, ()> {
- let angle_or_corner = if input.try(|input| input.expect_ident_matching("to")).is_ok() {
- let (horizontal, vertical) =
- if let Ok(value) = input.try(HorizontalDirection::parse) {
- (Some(value), input.try(VerticalDirection::parse).ok())
- } else {
- let value = try!(VerticalDirection::parse(input));
- (input.try(HorizontalDirection::parse).ok(), Some(value))
- };
- try!(input.expect_comma());
- 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!(),
- }
- } else if let Ok(angle) = input.try(Angle::parse) {
- try!(input.expect_comma());
- AngleOrCorner::Angle(angle)
- } else {
- AngleOrCorner::Angle(Angle(PI))
- };
- // Parse the color stops.
- let stops = try!(input.parse_comma_separated(parse_one_color_stop));
- if stops.len() < 2 {
- return Err(())
- }
- Ok(LinearGradient {
- angle_or_corner: angle_or_corner,
- stops: stops,
- })
- }
- }
-
- pub fn parse_border_radius(input: &mut Parser) -> Result<BorderRadiusSize, ()> {
- input.try(BorderRadiusSize::parse).or_else(|()| {
- match_ignore_ascii_case! { try!(input.expect_ident()),
- "thin" => Ok(BorderRadiusSize::circle(
- LengthOrPercentage::Length(Length::from_px(1.)))),
- "medium" => Ok(BorderRadiusSize::circle(
- LengthOrPercentage::Length(Length::from_px(3.)))),
- "thick" => Ok(BorderRadiusSize::circle(
- LengthOrPercentage::Length(Length::from_px(5.)))),
- _ => Err(())
- }
- })
- }
-
- pub fn parse_border_width(input: &mut Parser) -> Result<Length, ()> {
- input.try(Length::parse_non_negative).or_else(|()| {
- match_ignore_ascii_case! { try!(input.expect_ident()),
- "thin" => Ok(Length::from_px(1.)),
- "medium" => Ok(Length::from_px(3.)),
- "thick" => Ok(Length::from_px(5.)),
- _ => Err(())
- }
- })
- }
-
- // The integer values here correspond to the border conflict resolution rules in CSS 2.1 §
- // 17.6.2.1. Higher values override lower values.
- define_numbered_css_keyword_enum! { BorderStyle:
- "none" => none = -1,
- "solid" => solid = 6,
- "double" => double = 7,
- "dotted" => dotted = 4,
- "dashed" => dashed = 5,
- "hidden" => hidden = -2,
- "groove" => groove = 1,
- "ridge" => ridge = 3,
- "inset" => inset = 0,
- "outset" => outset = 2,
- }
-
- impl NoViewportPercentage for BorderStyle {}
-
- impl BorderStyle {
- pub fn none_or_hidden(&self) -> bool {
- matches!(*self, BorderStyle::none | BorderStyle::hidden)
- }
- }
-
- /// A time in seconds according to CSS-VALUES § 6.2.
- #[derive(Clone, Copy, Debug, PartialEq, PartialOrd)]
- #[cfg_attr(feature = "servo", derive(HeapSizeOf))]
- pub struct Time(pub CSSFloat);
-
- impl Time {
- /// Returns the time in fractional seconds.
- pub fn seconds(self) -> f32 {
- let Time(seconds) = self;
- seconds
- }
-
- /// Parses a time according to CSS-VALUES § 6.2.
- fn parse_dimension(value: CSSFloat, unit: &str) -> Result<Time, ()> {
- if unit.eq_ignore_ascii_case("s") {
- Ok(Time(value))
- } else if unit.eq_ignore_ascii_case("ms") {
- Ok(Time(value / 1000.0))
- } else {
- Err(())
- }
- }
-
- pub fn parse(input: &mut Parser) -> Result<Time, ()> {
- match input.next() {
- Ok(Token::Dimension(ref value, ref unit)) => {
- Time::parse_dimension(value.value, &unit)
- }
- Ok(Token::Function(ref name)) if name.eq_ignore_ascii_case("calc") => {
- input.parse_nested_block(CalcLengthOrPercentage::parse_time)
- }
- _ => Err(())
- }
- }
- }
-
- impl ToComputedValue for Time {
- type ComputedValue = Time;
-
- #[inline]
- fn to_computed_value(&self, _: &Context) -> Time {
- *self
- }
- }
-
- impl ToCss for Time {
- fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
- write!(dest, "{}s", self.0)
- }
- }
-
- #[derive(Clone, Copy, Debug, PartialEq, PartialOrd)]
- #[cfg_attr(feature = "servo", derive(HeapSizeOf))]
- pub struct Number(pub CSSFloat);
-
- impl NoViewportPercentage for Number {}
-
- impl Number {
- pub fn parse(input: &mut Parser) -> Result<Number, ()> {
- parse_number(input).map(Number)
- }
-
- fn parse_with_minimum(input: &mut Parser, min: CSSFloat) -> Result<Number, ()> {
- match parse_number(input) {
- Ok(value) if value < min => Err(()),
- value => value.map(Number),
- }
- }
-
- pub fn parse_non_negative(input: &mut Parser) -> Result<Number, ()> {
- Number::parse_with_minimum(input, 0.0)
- }
-
- pub fn parse_at_least_one(input: &mut Parser) -> Result<Number, ()> {
- Number::parse_with_minimum(input, 1.0)
- }
- }
-
- impl ToComputedValue for Number {
- type ComputedValue = CSSFloat;
-
- #[inline]
- fn to_computed_value(&self, _: &Context) -> CSSFloat { self.0 }
- }
-
- impl ToCss for Number {
- fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
- self.0.to_css(dest)
- }
- }
-
- #[derive(Clone, Copy, Debug, PartialEq, PartialOrd)]
- #[cfg_attr(feature = "servo", derive(HeapSizeOf))]
- pub struct Opacity(pub CSSFloat);
-
- impl NoViewportPercentage for Opacity {}
-
- impl Opacity {
- pub fn parse(input: &mut Parser) -> Result<Opacity, ()> {
- parse_number(input).map(Opacity)
- }
- }
-
- impl ToComputedValue for Opacity {
- type ComputedValue = CSSFloat;
-
- #[inline]
- fn to_computed_value(&self, _: &Context) -> CSSFloat {
- if self.0 < 0.0 {
- 0.0
- } else if self.0 > 1.0 {
- 1.0
- } else {
- self.0
- }
- }
- }
-
- impl ToCss for Opacity {
- fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
- self.0.to_css(dest)
- }
- }
-}
-
-pub mod computed {
- use app_units::Au;
- use euclid::size::Size2D;
- use properties::ComputedValues;
- use std::fmt;
- use super::LocalToCss;
- use super::specified::AngleOrCorner;
- use super::{CSSFloat, specified};
- use url::Url;
- pub use cssparser::Color as CSSColor;
- pub use super::specified::{Angle, BorderStyle, Time};
-
- pub struct Context<'a> {
- pub is_root_element: bool,
- pub viewport_size: Size2D<Au>,
- pub inherited_style: &'a ComputedValues,
-
- /// Values access through this need to be in the properties "computed early":
- /// color, text-decoration, font-size, display, position, float, border-*-style, outline-style
- pub style: ComputedValues,
- }
-
- impl<'a> Context<'a> {
- pub fn is_root_element(&self) -> bool { self.is_root_element }
- pub fn viewport_size(&self) -> Size2D<Au> { self.viewport_size }
- pub fn inherited_style(&self) -> &ComputedValues { &self.inherited_style }
- pub fn style(&self) -> &ComputedValues { &self.style }
- pub fn mutate_style(&mut self) -> &mut ComputedValues { &mut self.style }
- }
-
- pub trait ToComputedValue {
- type ComputedValue;
-
- #[inline]
- fn to_computed_value(&self, _context: &Context) -> Self::ComputedValue;
- }
-
- pub trait ComputedValueAsSpecified {}
-
- impl<T> ToComputedValue for T where T: ComputedValueAsSpecified + Clone {
- type ComputedValue = T;
-
- #[inline]
- fn to_computed_value(&self, _context: &Context) -> T {
- self.clone()
- }
- }
-
- impl ToComputedValue for specified::CSSColor {
- type ComputedValue = CSSColor;
-
- #[inline]
- fn to_computed_value(&self, _context: &Context) -> CSSColor {
- self.parsed
- }
- }
-
- impl ComputedValueAsSpecified for specified::BorderStyle {}
-
- impl ToComputedValue for specified::Length {
- type ComputedValue = Au;
-
- #[inline]
- fn to_computed_value(&self, context: &Context) -> Au {
- match *self {
- specified::Length::Absolute(length) => length,
- specified::Length::Calc(calc) => calc.to_computed_value(context).length(),
- specified::Length::FontRelative(length) =>
- length.to_computed_value(context.style().get_font().clone_font_size(),
- context.style().root_font_size()),
- specified::Length::ViewportPercentage(length) =>
- length.to_computed_value(context.viewport_size()),
- specified::Length::ServoCharacterWidth(length) =>
- length.to_computed_value(context.style().get_font().clone_font_size())
- }
- }
- }
-
- #[derive(Clone, PartialEq, Copy, Debug)]
- #[cfg_attr(feature = "servo", derive(HeapSizeOf))]
- pub struct CalcLengthOrPercentage {
- pub length: Option<Au>,
- pub percentage: Option<CSSFloat>,
- }
-
- impl CalcLengthOrPercentage {
- #[inline]
- pub fn length(&self) -> Au {
- self.length.unwrap_or(Au(0))
- }
-
- #[inline]
- pub fn percentage(&self) -> CSSFloat {
- self.percentage.unwrap_or(0.)
- }
- }
-
- impl From<LengthOrPercentage> for CalcLengthOrPercentage {
- fn from(len: LengthOrPercentage) -> CalcLengthOrPercentage {
- match len {
- LengthOrPercentage::Percentage(this) => {
- CalcLengthOrPercentage {
- length: None,
- percentage: Some(this),
- }
- }
- LengthOrPercentage::Length(this) => {
- CalcLengthOrPercentage {
- length: Some(this),
- percentage: None,
- }
- }
- LengthOrPercentage::Calc(this) => {
- this
- }
- }
- }
- }
-
- impl From<LengthOrPercentageOrAuto> for Option<CalcLengthOrPercentage> {
- fn from(len: LengthOrPercentageOrAuto) -> Option<CalcLengthOrPercentage> {
- match len {
- LengthOrPercentageOrAuto::Percentage(this) => {
- Some(CalcLengthOrPercentage {
- length: None,
- percentage: Some(this),
- })
- }
- LengthOrPercentageOrAuto::Length(this) => {
- Some(CalcLengthOrPercentage {
- length: Some(this),
- percentage: None,
- })
- }
- LengthOrPercentageOrAuto::Calc(this) => {
- Some(this)
- }
- LengthOrPercentageOrAuto::Auto => {
- None
- }
- }
- }
- }
-
- impl ::cssparser::ToCss for CalcLengthOrPercentage {
- fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
- match (self.length, self.percentage) {
- (None, Some(p)) => write!(dest, "{}%", p * 100.),
- (Some(l), None) => write!(dest, "{}px", Au::to_px(l)),
- (Some(l), Some(p)) => write!(dest, "calc({}px + {}%)", Au::to_px(l), p * 100.),
- _ => unreachable!()
- }
- }
- }
-
- impl ToComputedValue for specified::CalcLengthOrPercentage {
- type ComputedValue = CalcLengthOrPercentage;
-
- fn to_computed_value(&self, context: &Context) -> CalcLengthOrPercentage {
- let mut length = None;
-
- if let Some(absolute) = self.absolute {
- length = Some(length.unwrap_or(Au(0)) + absolute);
- }
-
- for val in &[self.vw, self.vh, self.vmin, self.vmax] {
- if let Some(val) = *val {
- length = Some(length.unwrap_or(Au(0)) +
- val.to_computed_value(context.viewport_size()));
- }
- }
- for val in &[self.ch, self.em, self.ex, self.rem] {
- if let Some(val) = *val {
- length = Some(length.unwrap_or(Au(0)) + val.to_computed_value(
- context.style().get_font().clone_font_size(), context.style().root_font_size()));
- }
- }
-
- CalcLengthOrPercentage { length: length, percentage: self.percentage.map(|p| p.0) }
- }
- }
-
-
- #[derive(Debug, PartialEq, Clone, Copy)]
- #[cfg_attr(feature = "servo", derive(HeapSizeOf))]
- pub struct BorderRadiusSize(pub Size2D<LengthOrPercentage>);
-
- impl BorderRadiusSize {
- pub fn zero() -> BorderRadiusSize {
- BorderRadiusSize(Size2D::new(LengthOrPercentage::Length(Au(0)), LengthOrPercentage::Length(Au(0))))
- }
- }
-
- impl ToComputedValue for specified::BorderRadiusSize {
- type ComputedValue = BorderRadiusSize;
-
- #[inline]
- fn to_computed_value(&self, context: &Context) -> BorderRadiusSize {
- let w = self.0.width.to_computed_value(context);
- let h = self.0.height.to_computed_value(context);
- BorderRadiusSize(Size2D::new(w, h))
- }
- }
-
- impl ::cssparser::ToCss for BorderRadiusSize {
- fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
- try!(self.0.width.to_css(dest));
- try!(dest.write_str("/"));
- self.0.height.to_css(dest)
- }
- }
-
- #[derive(PartialEq, Clone, Copy)]
- #[cfg_attr(feature = "servo", derive(HeapSizeOf))]
- pub enum LengthOrPercentage {
- Length(Au),
- Percentage(CSSFloat),
- Calc(CalcLengthOrPercentage),
- }
-
- impl LengthOrPercentage {
- #[inline]
- pub fn zero() -> LengthOrPercentage {
- LengthOrPercentage::Length(Au(0))
- }
-
- /// Returns true if the computed value is absolute 0 or 0%.
- ///
- /// (Returns false for calc() values, even if ones that may resolve to zero.)
- #[inline]
- pub fn is_definitely_zero(&self) -> bool {
- use self::LengthOrPercentage::*;
- match *self {
- Length(Au(0)) | Percentage(0.0) => true,
- Length(_) | Percentage(_) | Calc(_) => false
- }
- }
- }
-
- impl fmt::Debug for LengthOrPercentage {
- fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
- match *self {
- LengthOrPercentage::Length(length) => write!(f, "{:?}", length),
- LengthOrPercentage::Percentage(percentage) => write!(f, "{}%", percentage * 100.),
- LengthOrPercentage::Calc(calc) => write!(f, "{:?}", calc),
- }
- }
- }
-
- impl ToComputedValue for specified::LengthOrPercentage {
- type ComputedValue = LengthOrPercentage;
-
- fn to_computed_value(&self, context: &Context) -> LengthOrPercentage {
- match *self {
- specified::LengthOrPercentage::Length(value) => {
- LengthOrPercentage::Length(value.to_computed_value(context))
- }
- specified::LengthOrPercentage::Percentage(value) => {
- LengthOrPercentage::Percentage(value.0)
- }
- specified::LengthOrPercentage::Calc(calc) => {
- LengthOrPercentage::Calc(calc.to_computed_value(context))
- }
- }
- }
- }
-
- impl ::cssparser::ToCss for LengthOrPercentage {
- fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
- match *self {
- LengthOrPercentage::Length(length) => length.to_css(dest),
- LengthOrPercentage::Percentage(percentage)
- => write!(dest, "{}%", percentage * 100.),
- LengthOrPercentage::Calc(calc) => calc.to_css(dest),
- }
- }
- }
-
- #[derive(PartialEq, Clone, Copy)]
- #[cfg_attr(feature = "servo", derive(HeapSizeOf))]
- pub enum LengthOrPercentageOrAuto {
- Length(Au),
- Percentage(CSSFloat),
- Auto,
- Calc(CalcLengthOrPercentage),
- }
-
- impl LengthOrPercentageOrAuto {
- /// Returns true if the computed value is absolute 0 or 0%.
- ///
- /// (Returns false for calc() values, even if ones that may resolve to zero.)
- #[inline]
- pub fn is_definitely_zero(&self) -> bool {
- use self::LengthOrPercentageOrAuto::*;
- match *self {
- Length(Au(0)) | Percentage(0.0) => true,
- Length(_) | Percentage(_) | Calc(_) | Auto => false
- }
- }
- }
-
- impl fmt::Debug for LengthOrPercentageOrAuto {
- fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
- match *self {
- LengthOrPercentageOrAuto::Length(length) => write!(f, "{:?}", length),
- LengthOrPercentageOrAuto::Percentage(percentage) => write!(f, "{}%", percentage * 100.),
- LengthOrPercentageOrAuto::Auto => write!(f, "auto"),
- LengthOrPercentageOrAuto::Calc(calc) => write!(f, "{:?}", calc),
- }
- }
- }
-
- impl ToComputedValue for specified::LengthOrPercentageOrAuto {
- type ComputedValue = LengthOrPercentageOrAuto;
-
- #[inline]
- fn to_computed_value(&self, context: &Context) -> LengthOrPercentageOrAuto {
- match *self {
- specified::LengthOrPercentageOrAuto::Length(value) => {
- LengthOrPercentageOrAuto::Length(value.to_computed_value(context))
- }
- specified::LengthOrPercentageOrAuto::Percentage(value) => {
- LengthOrPercentageOrAuto::Percentage(value.0)
- }
- specified::LengthOrPercentageOrAuto::Auto => {
- LengthOrPercentageOrAuto::Auto
- }
- specified::LengthOrPercentageOrAuto::Calc(calc) => {
- LengthOrPercentageOrAuto::Calc(calc.to_computed_value(context))
- }
- }
- }
- }
-
- impl ::cssparser::ToCss for LengthOrPercentageOrAuto {
- fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
- match *self {
- LengthOrPercentageOrAuto::Length(length) => length.to_css(dest),
- LengthOrPercentageOrAuto::Percentage(percentage)
- => write!(dest, "{}%", percentage * 100.),
- LengthOrPercentageOrAuto::Auto => dest.write_str("auto"),
- LengthOrPercentageOrAuto::Calc(calc) => calc.to_css(dest),
- }
- }
- }
-
- #[derive(PartialEq, Clone, Copy)]
- #[cfg_attr(feature = "servo", derive(HeapSizeOf))]
- pub enum LengthOrPercentageOrAutoOrContent {
- Length(Au),
- Percentage(CSSFloat),
- Calc(CalcLengthOrPercentage),
- Auto,
- Content
- }
-
- impl fmt::Debug for LengthOrPercentageOrAutoOrContent {
- fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
- match *self {
- LengthOrPercentageOrAutoOrContent::Length(length) => write!(f, "{:?}", length),
- LengthOrPercentageOrAutoOrContent::Percentage(percentage) => write!(f, "{}%", percentage * 100.),
- LengthOrPercentageOrAutoOrContent::Calc(calc) => write!(f, "{:?}", calc),
- LengthOrPercentageOrAutoOrContent::Auto => write!(f, "auto"),
- LengthOrPercentageOrAutoOrContent::Content => write!(f, "content")
- }
- }
- }
-
- impl ToComputedValue for specified::LengthOrPercentageOrAutoOrContent {
- type ComputedValue = LengthOrPercentageOrAutoOrContent;
-
- #[inline]
- fn to_computed_value(&self, context: &Context) -> LengthOrPercentageOrAutoOrContent {
- match *self {
- specified::LengthOrPercentageOrAutoOrContent::Length(value) => {
- LengthOrPercentageOrAutoOrContent::Length(value.to_computed_value(context))
- },
- specified::LengthOrPercentageOrAutoOrContent::Percentage(value) => {
- LengthOrPercentageOrAutoOrContent::Percentage(value.0)
- },
- specified::LengthOrPercentageOrAutoOrContent::Calc(calc) => {
- LengthOrPercentageOrAutoOrContent::Calc(calc.to_computed_value(context))
- },
- specified::LengthOrPercentageOrAutoOrContent::Auto => {
- LengthOrPercentageOrAutoOrContent::Auto
- },
- specified::LengthOrPercentageOrAutoOrContent::Content => {
- LengthOrPercentageOrAutoOrContent::Content
- }
- }
- }
- }
-
- impl ::cssparser::ToCss for LengthOrPercentageOrAutoOrContent {
- fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
- match *self {
- LengthOrPercentageOrAutoOrContent::Length(length) => length.to_css(dest),
- LengthOrPercentageOrAutoOrContent::Percentage(percentage)
- => write!(dest, "{}%", percentage * 100.),
- LengthOrPercentageOrAutoOrContent::Calc(calc) => calc.to_css(dest),
- LengthOrPercentageOrAutoOrContent::Auto => dest.write_str("auto"),
- LengthOrPercentageOrAutoOrContent::Content => dest.write_str("content")
- }
- }
- }
-
- #[derive(PartialEq, Clone, Copy)]
- #[cfg_attr(feature = "servo", derive(HeapSizeOf))]
- pub enum LengthOrPercentageOrNone {
- Length(Au),
- Percentage(CSSFloat),
- Calc(CalcLengthOrPercentage),
- None,
- }
-
- impl fmt::Debug for LengthOrPercentageOrNone {
- fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
- match *self {
- LengthOrPercentageOrNone::Length(length) => write!(f, "{:?}", length),
- LengthOrPercentageOrNone::Percentage(percentage) => write!(f, "{}%", percentage * 100.),
- LengthOrPercentageOrNone::Calc(calc) => write!(f, "{:?}", calc),
- LengthOrPercentageOrNone::None => write!(f, "none"),
- }
- }
- }
-
- impl ToComputedValue for specified::LengthOrPercentageOrNone {
- type ComputedValue = LengthOrPercentageOrNone;
-
- #[inline]
- fn to_computed_value(&self, context: &Context) -> LengthOrPercentageOrNone {
- match *self {
- specified::LengthOrPercentageOrNone::Length(value) => {
- LengthOrPercentageOrNone::Length(value.to_computed_value(context))
- }
- specified::LengthOrPercentageOrNone::Percentage(value) => {
- LengthOrPercentageOrNone::Percentage(value.0)
- }
- specified::LengthOrPercentageOrNone::Calc(calc) => {
- LengthOrPercentageOrNone::Calc(calc.to_computed_value(context))
- }
- specified::LengthOrPercentageOrNone::None => {
- LengthOrPercentageOrNone::None
- }
- }
- }
- }
-
- impl ::cssparser::ToCss for LengthOrPercentageOrNone {
- fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
- match *self {
- LengthOrPercentageOrNone::Length(length) => length.to_css(dest),
- LengthOrPercentageOrNone::Percentage(percentage) =>
- write!(dest, "{}%", percentage * 100.),
- LengthOrPercentageOrNone::Calc(calc) => calc.to_css(dest),
- LengthOrPercentageOrNone::None => dest.write_str("none"),
- }
- }
- }
-
- #[derive(PartialEq, Clone, Copy)]
- #[cfg_attr(feature = "servo", derive(HeapSizeOf))]
- pub enum LengthOrNone {
- Length(Au),
- None,
- }
-
- impl fmt::Debug for LengthOrNone {
- fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
- match *self {
- LengthOrNone::Length(length) => write!(f, "{:?}", length),
- LengthOrNone::None => write!(f, "none"),
- }
- }
- }
-
- impl ToComputedValue for specified::LengthOrNone {
- type ComputedValue = LengthOrNone;
-
- #[inline]
- fn to_computed_value(&self, context: &Context) -> LengthOrNone {
- match *self {
- specified::LengthOrNone::Length(specified::Length::Calc(calc)) => {
- LengthOrNone::Length(calc.to_computed_value(context).length())
- }
- specified::LengthOrNone::Length(value) => {
- LengthOrNone::Length(value.to_computed_value(context))
- }
- specified::LengthOrNone::None => {
- LengthOrNone::None
- }
- }
- }
- }
-
- impl ::cssparser::ToCss for LengthOrNone {
- fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
- match *self {
- LengthOrNone::Length(length) => length.to_css(dest),
- LengthOrNone::None => dest.write_str("none"),
- }
- }
- }
-
- impl ToComputedValue for specified::Image {
- type ComputedValue = Image;
-
- #[inline]
- fn to_computed_value(&self, context: &Context) -> Image {
- match *self {
- specified::Image::Url(ref url) => Image::Url(url.clone()),
- specified::Image::LinearGradient(ref linear_gradient) => {
- Image::LinearGradient(linear_gradient.to_computed_value(context))
- }
- }
- }
- }
-
-
- /// Computed values for an image according to CSS-IMAGES.
- #[derive(Clone, PartialEq)]
- #[cfg_attr(feature = "servo", derive(HeapSizeOf))]
- pub enum Image {
- Url(Url),
- LinearGradient(LinearGradient),
- }
-
- impl fmt::Debug for Image {
- fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
- match *self {
- Image::Url(ref url) => write!(f, "url(\"{}\")", url),
- Image::LinearGradient(ref grad) => write!(f, "linear-gradient({:?})", grad),
- }
- }
- }
-
- /// Computed values for a CSS linear gradient.
- #[derive(Clone, PartialEq)]
- #[cfg_attr(feature = "servo", derive(HeapSizeOf))]
- pub struct LinearGradient {
- /// The angle or corner of the gradient.
- pub angle_or_corner: AngleOrCorner,
-
- /// The color stops.
- pub stops: Vec<ColorStop>,
- }
-
- impl ::cssparser::ToCss for LinearGradient {
- fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
- try!(dest.write_str("linear-gradient("));
- try!(self.angle_or_corner.to_css(dest));
- for stop in &self.stops {
- try!(dest.write_str(", "));
- try!(stop.to_css(dest));
- }
- try!(dest.write_str(")"));
- Ok(())
- }
- }
-
- impl fmt::Debug for LinearGradient {
- fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
- let _ = write!(f, "{:?}", self.angle_or_corner);
- for stop in &self.stops {
- let _ = write!(f, ", {:?}", stop);
- }
- Ok(())
- }
- }
-
- /// Computed values for one color stop in a linear gradient.
- #[derive(Clone, PartialEq, Copy)]
- #[cfg_attr(feature = "servo", derive(HeapSizeOf))]
- pub struct ColorStop {
- /// The color of this stop.
- pub color: CSSColor,
-
- /// The position of this stop. If not specified, this stop is placed halfway between the
- /// point that precedes it and the point that follows it per CSS-IMAGES § 3.4.
- pub position: Option<LengthOrPercentage>,
- }
-
- impl ::cssparser::ToCss for ColorStop {
- fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
- try!(self.color.to_css(dest));
- if let Some(position) = self.position {
- try!(dest.write_str(" "));
- try!(position.to_css(dest));
- }
- Ok(())
- }
- }
-
- impl fmt::Debug for ColorStop {
- fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
- let _ = write!(f, "{:?}", self.color);
- self.position.map(|pos| {
- let _ = write!(f, " {:?}", pos);
- });
- Ok(())
- }
- }
-
- impl ToComputedValue for specified::LinearGradient {
- type ComputedValue = LinearGradient;
-
- #[inline]
- fn to_computed_value(&self, context: &Context) -> LinearGradient {
- let specified::LinearGradient {
- angle_or_corner,
- ref stops
- } = *self;
- LinearGradient {
- angle_or_corner: angle_or_corner,
- stops: stops.iter().map(|stop| {
- ColorStop {
- color: stop.color.parsed,
- position: match stop.position {
- None => None,
- Some(value) => Some(value.to_computed_value(context)),
- },
- }
- }).collect()
- }
- }
- }
- pub type Length = Au;
- pub type Number = CSSFloat;
- pub type Opacity = CSSFloat;
-}
diff --git a/components/style/values/computed/mod.rs b/components/style/values/computed/mod.rs
new file mode 100644
index 00000000000..cefe1c7d6ac
--- /dev/null
+++ b/components/style/values/computed/mod.rs
@@ -0,0 +1,634 @@
+/* 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 app_units::Au;
+use euclid::size::Size2D;
+use properties::ComputedValues;
+use std::fmt;
+use super::LocalToCss;
+use super::specified::AngleOrCorner;
+use super::{CSSFloat, specified};
+use url::Url;
+pub use cssparser::Color as CSSColor;
+pub use super::specified::{Angle, BorderStyle, Time, UrlExtraData};
+
+pub struct Context<'a> {
+ pub is_root_element: bool,
+ pub viewport_size: Size2D<Au>,
+ pub inherited_style: &'a ComputedValues,
+
+ /// Values access through this need to be in the properties "computed early":
+ /// color, text-decoration, font-size, display, position, float, border-*-style, outline-style
+ pub style: ComputedValues,
+}
+
+impl<'a> Context<'a> {
+ pub fn is_root_element(&self) -> bool { self.is_root_element }
+ pub fn viewport_size(&self) -> Size2D<Au> { self.viewport_size }
+ pub fn inherited_style(&self) -> &ComputedValues { &self.inherited_style }
+ pub fn style(&self) -> &ComputedValues { &self.style }
+ pub fn mutate_style(&mut self) -> &mut ComputedValues { &mut self.style }
+}
+
+pub trait ToComputedValue {
+ type ComputedValue;
+
+ #[inline]
+ fn to_computed_value(&self, _context: &Context) -> Self::ComputedValue;
+}
+
+pub trait ComputedValueAsSpecified {}
+
+impl<T> ToComputedValue for T where T: ComputedValueAsSpecified + Clone {
+ type ComputedValue = T;
+
+ #[inline]
+ fn to_computed_value(&self, _context: &Context) -> T {
+ self.clone()
+ }
+}
+
+impl ToComputedValue for specified::CSSColor {
+ type ComputedValue = CSSColor;
+
+ #[inline]
+ fn to_computed_value(&self, _context: &Context) -> CSSColor {
+ self.parsed
+ }
+}
+
+impl ComputedValueAsSpecified for specified::BorderStyle {}
+
+impl ToComputedValue for specified::Length {
+ type ComputedValue = Au;
+
+ #[inline]
+ fn to_computed_value(&self, context: &Context) -> Au {
+ match *self {
+ specified::Length::Absolute(length) => length,
+ specified::Length::Calc(calc) => calc.to_computed_value(context).length(),
+ specified::Length::FontRelative(length) =>
+ length.to_computed_value(context.style().get_font().clone_font_size(),
+ context.style().root_font_size()),
+ specified::Length::ViewportPercentage(length) =>
+ length.to_computed_value(context.viewport_size()),
+ specified::Length::ServoCharacterWidth(length) =>
+ length.to_computed_value(context.style().get_font().clone_font_size())
+ }
+ }
+}
+
+#[derive(Clone, PartialEq, Copy, Debug)]
+#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
+pub struct CalcLengthOrPercentage {
+ pub length: Option<Au>,
+ pub percentage: Option<CSSFloat>,
+}
+
+impl CalcLengthOrPercentage {
+ #[inline]
+ pub fn length(&self) -> Au {
+ self.length.unwrap_or(Au(0))
+ }
+
+ #[inline]
+ pub fn percentage(&self) -> CSSFloat {
+ self.percentage.unwrap_or(0.)
+ }
+}
+
+impl From<LengthOrPercentage> for CalcLengthOrPercentage {
+ fn from(len: LengthOrPercentage) -> CalcLengthOrPercentage {
+ match len {
+ LengthOrPercentage::Percentage(this) => {
+ CalcLengthOrPercentage {
+ length: None,
+ percentage: Some(this),
+ }
+ }
+ LengthOrPercentage::Length(this) => {
+ CalcLengthOrPercentage {
+ length: Some(this),
+ percentage: None,
+ }
+ }
+ LengthOrPercentage::Calc(this) => {
+ this
+ }
+ }
+ }
+}
+
+impl From<LengthOrPercentageOrAuto> for Option<CalcLengthOrPercentage> {
+ fn from(len: LengthOrPercentageOrAuto) -> Option<CalcLengthOrPercentage> {
+ match len {
+ LengthOrPercentageOrAuto::Percentage(this) => {
+ Some(CalcLengthOrPercentage {
+ length: None,
+ percentage: Some(this),
+ })
+ }
+ LengthOrPercentageOrAuto::Length(this) => {
+ Some(CalcLengthOrPercentage {
+ length: Some(this),
+ percentage: None,
+ })
+ }
+ LengthOrPercentageOrAuto::Calc(this) => {
+ Some(this)
+ }
+ LengthOrPercentageOrAuto::Auto => {
+ None
+ }
+ }
+ }
+}
+
+impl ::cssparser::ToCss for CalcLengthOrPercentage {
+ fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
+ match (self.length, self.percentage) {
+ (None, Some(p)) => write!(dest, "{}%", p * 100.),
+ (Some(l), None) => write!(dest, "{}px", Au::to_px(l)),
+ (Some(l), Some(p)) => write!(dest, "calc({}px + {}%)", Au::to_px(l), p * 100.),
+ _ => unreachable!()
+ }
+ }
+}
+
+impl ToComputedValue for specified::CalcLengthOrPercentage {
+ type ComputedValue = CalcLengthOrPercentage;
+
+ fn to_computed_value(&self, context: &Context) -> CalcLengthOrPercentage {
+ let mut length = None;
+
+ if let Some(absolute) = self.absolute {
+ length = Some(length.unwrap_or(Au(0)) + absolute);
+ }
+
+ for val in &[self.vw, self.vh, self.vmin, self.vmax] {
+ if let Some(val) = *val {
+ length = Some(length.unwrap_or(Au(0)) +
+ val.to_computed_value(context.viewport_size()));
+ }
+ }
+ for val in &[self.ch, self.em, self.ex, self.rem] {
+ if let Some(val) = *val {
+ length = Some(length.unwrap_or(Au(0)) + val.to_computed_value(
+ context.style().get_font().clone_font_size(), context.style().root_font_size()));
+ }
+ }
+
+ CalcLengthOrPercentage { length: length, percentage: self.percentage.map(|p| p.0) }
+ }
+}
+
+
+#[derive(Debug, PartialEq, Clone, Copy)]
+#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
+pub struct BorderRadiusSize(pub Size2D<LengthOrPercentage>);
+
+impl BorderRadiusSize {
+ pub fn zero() -> BorderRadiusSize {
+ BorderRadiusSize(Size2D::new(LengthOrPercentage::Length(Au(0)), LengthOrPercentage::Length(Au(0))))
+ }
+}
+
+impl ToComputedValue for specified::BorderRadiusSize {
+ type ComputedValue = BorderRadiusSize;
+
+ #[inline]
+ fn to_computed_value(&self, context: &Context) -> BorderRadiusSize {
+ let w = self.0.width.to_computed_value(context);
+ let h = self.0.height.to_computed_value(context);
+ BorderRadiusSize(Size2D::new(w, h))
+ }
+}
+
+impl ::cssparser::ToCss for BorderRadiusSize {
+ fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
+ try!(self.0.width.to_css(dest));
+ try!(dest.write_str("/"));
+ self.0.height.to_css(dest)
+ }
+}
+
+#[derive(PartialEq, Clone, Copy)]
+#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
+pub enum LengthOrPercentage {
+ Length(Au),
+ Percentage(CSSFloat),
+ Calc(CalcLengthOrPercentage),
+}
+
+impl LengthOrPercentage {
+ #[inline]
+ pub fn zero() -> LengthOrPercentage {
+ LengthOrPercentage::Length(Au(0))
+ }
+
+ /// Returns true if the computed value is absolute 0 or 0%.
+ ///
+ /// (Returns false for calc() values, even if ones that may resolve to zero.)
+ #[inline]
+ pub fn is_definitely_zero(&self) -> bool {
+ use self::LengthOrPercentage::*;
+ match *self {
+ Length(Au(0)) | Percentage(0.0) => true,
+ Length(_) | Percentage(_) | Calc(_) => false
+ }
+ }
+}
+
+impl fmt::Debug for LengthOrPercentage {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ match *self {
+ LengthOrPercentage::Length(length) => write!(f, "{:?}", length),
+ LengthOrPercentage::Percentage(percentage) => write!(f, "{}%", percentage * 100.),
+ LengthOrPercentage::Calc(calc) => write!(f, "{:?}", calc),
+ }
+ }
+}
+
+impl ToComputedValue for specified::LengthOrPercentage {
+ type ComputedValue = LengthOrPercentage;
+
+ fn to_computed_value(&self, context: &Context) -> LengthOrPercentage {
+ match *self {
+ specified::LengthOrPercentage::Length(value) => {
+ LengthOrPercentage::Length(value.to_computed_value(context))
+ }
+ specified::LengthOrPercentage::Percentage(value) => {
+ LengthOrPercentage::Percentage(value.0)
+ }
+ specified::LengthOrPercentage::Calc(calc) => {
+ LengthOrPercentage::Calc(calc.to_computed_value(context))
+ }
+ }
+ }
+}
+
+impl ::cssparser::ToCss for LengthOrPercentage {
+ fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
+ match *self {
+ LengthOrPercentage::Length(length) => length.to_css(dest),
+ LengthOrPercentage::Percentage(percentage)
+ => write!(dest, "{}%", percentage * 100.),
+ LengthOrPercentage::Calc(calc) => calc.to_css(dest),
+ }
+ }
+}
+
+#[derive(PartialEq, Clone, Copy)]
+#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
+pub enum LengthOrPercentageOrAuto {
+ Length(Au),
+ Percentage(CSSFloat),
+ Auto,
+ Calc(CalcLengthOrPercentage),
+}
+
+impl LengthOrPercentageOrAuto {
+ /// Returns true if the computed value is absolute 0 or 0%.
+ ///
+ /// (Returns false for calc() values, even if ones that may resolve to zero.)
+ #[inline]
+ pub fn is_definitely_zero(&self) -> bool {
+ use self::LengthOrPercentageOrAuto::*;
+ match *self {
+ Length(Au(0)) | Percentage(0.0) => true,
+ Length(_) | Percentage(_) | Calc(_) | Auto => false
+ }
+ }
+}
+
+impl fmt::Debug for LengthOrPercentageOrAuto {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ match *self {
+ LengthOrPercentageOrAuto::Length(length) => write!(f, "{:?}", length),
+ LengthOrPercentageOrAuto::Percentage(percentage) => write!(f, "{}%", percentage * 100.),
+ LengthOrPercentageOrAuto::Auto => write!(f, "auto"),
+ LengthOrPercentageOrAuto::Calc(calc) => write!(f, "{:?}", calc),
+ }
+ }
+}
+
+impl ToComputedValue for specified::LengthOrPercentageOrAuto {
+ type ComputedValue = LengthOrPercentageOrAuto;
+
+ #[inline]
+ fn to_computed_value(&self, context: &Context) -> LengthOrPercentageOrAuto {
+ match *self {
+ specified::LengthOrPercentageOrAuto::Length(value) => {
+ LengthOrPercentageOrAuto::Length(value.to_computed_value(context))
+ }
+ specified::LengthOrPercentageOrAuto::Percentage(value) => {
+ LengthOrPercentageOrAuto::Percentage(value.0)
+ }
+ specified::LengthOrPercentageOrAuto::Auto => {
+ LengthOrPercentageOrAuto::Auto
+ }
+ specified::LengthOrPercentageOrAuto::Calc(calc) => {
+ LengthOrPercentageOrAuto::Calc(calc.to_computed_value(context))
+ }
+ }
+ }
+}
+
+impl ::cssparser::ToCss for LengthOrPercentageOrAuto {
+ fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
+ match *self {
+ LengthOrPercentageOrAuto::Length(length) => length.to_css(dest),
+ LengthOrPercentageOrAuto::Percentage(percentage)
+ => write!(dest, "{}%", percentage * 100.),
+ LengthOrPercentageOrAuto::Auto => dest.write_str("auto"),
+ LengthOrPercentageOrAuto::Calc(calc) => calc.to_css(dest),
+ }
+ }
+}
+
+#[derive(PartialEq, Clone, Copy)]
+#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
+pub enum LengthOrPercentageOrAutoOrContent {
+ Length(Au),
+ Percentage(CSSFloat),
+ Calc(CalcLengthOrPercentage),
+ Auto,
+ Content
+}
+
+impl fmt::Debug for LengthOrPercentageOrAutoOrContent {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ match *self {
+ LengthOrPercentageOrAutoOrContent::Length(length) => write!(f, "{:?}", length),
+ LengthOrPercentageOrAutoOrContent::Percentage(percentage) => write!(f, "{}%", percentage * 100.),
+ LengthOrPercentageOrAutoOrContent::Calc(calc) => write!(f, "{:?}", calc),
+ LengthOrPercentageOrAutoOrContent::Auto => write!(f, "auto"),
+ LengthOrPercentageOrAutoOrContent::Content => write!(f, "content")
+ }
+ }
+}
+
+impl ToComputedValue for specified::LengthOrPercentageOrAutoOrContent {
+ type ComputedValue = LengthOrPercentageOrAutoOrContent;
+
+ #[inline]
+ fn to_computed_value(&self, context: &Context) -> LengthOrPercentageOrAutoOrContent {
+ match *self {
+ specified::LengthOrPercentageOrAutoOrContent::Length(value) => {
+ LengthOrPercentageOrAutoOrContent::Length(value.to_computed_value(context))
+ },
+ specified::LengthOrPercentageOrAutoOrContent::Percentage(value) => {
+ LengthOrPercentageOrAutoOrContent::Percentage(value.0)
+ },
+ specified::LengthOrPercentageOrAutoOrContent::Calc(calc) => {
+ LengthOrPercentageOrAutoOrContent::Calc(calc.to_computed_value(context))
+ },
+ specified::LengthOrPercentageOrAutoOrContent::Auto => {
+ LengthOrPercentageOrAutoOrContent::Auto
+ },
+ specified::LengthOrPercentageOrAutoOrContent::Content => {
+ LengthOrPercentageOrAutoOrContent::Content
+ }
+ }
+ }
+}
+
+impl ::cssparser::ToCss for LengthOrPercentageOrAutoOrContent {
+ fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
+ match *self {
+ LengthOrPercentageOrAutoOrContent::Length(length) => length.to_css(dest),
+ LengthOrPercentageOrAutoOrContent::Percentage(percentage)
+ => write!(dest, "{}%", percentage * 100.),
+ LengthOrPercentageOrAutoOrContent::Calc(calc) => calc.to_css(dest),
+ LengthOrPercentageOrAutoOrContent::Auto => dest.write_str("auto"),
+ LengthOrPercentageOrAutoOrContent::Content => dest.write_str("content")
+ }
+ }
+}
+
+#[derive(PartialEq, Clone, Copy)]
+#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
+pub enum LengthOrPercentageOrNone {
+ Length(Au),
+ Percentage(CSSFloat),
+ Calc(CalcLengthOrPercentage),
+ None,
+}
+
+impl fmt::Debug for LengthOrPercentageOrNone {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ match *self {
+ LengthOrPercentageOrNone::Length(length) => write!(f, "{:?}", length),
+ LengthOrPercentageOrNone::Percentage(percentage) => write!(f, "{}%", percentage * 100.),
+ LengthOrPercentageOrNone::Calc(calc) => write!(f, "{:?}", calc),
+ LengthOrPercentageOrNone::None => write!(f, "none"),
+ }
+ }
+}
+
+impl ToComputedValue for specified::LengthOrPercentageOrNone {
+ type ComputedValue = LengthOrPercentageOrNone;
+
+ #[inline]
+ fn to_computed_value(&self, context: &Context) -> LengthOrPercentageOrNone {
+ match *self {
+ specified::LengthOrPercentageOrNone::Length(value) => {
+ LengthOrPercentageOrNone::Length(value.to_computed_value(context))
+ }
+ specified::LengthOrPercentageOrNone::Percentage(value) => {
+ LengthOrPercentageOrNone::Percentage(value.0)
+ }
+ specified::LengthOrPercentageOrNone::Calc(calc) => {
+ LengthOrPercentageOrNone::Calc(calc.to_computed_value(context))
+ }
+ specified::LengthOrPercentageOrNone::None => {
+ LengthOrPercentageOrNone::None
+ }
+ }
+ }
+}
+
+impl ::cssparser::ToCss for LengthOrPercentageOrNone {
+ fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
+ match *self {
+ LengthOrPercentageOrNone::Length(length) => length.to_css(dest),
+ LengthOrPercentageOrNone::Percentage(percentage) =>
+ write!(dest, "{}%", percentage * 100.),
+ LengthOrPercentageOrNone::Calc(calc) => calc.to_css(dest),
+ LengthOrPercentageOrNone::None => dest.write_str("none"),
+ }
+ }
+}
+
+#[derive(PartialEq, Clone, Copy)]
+#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
+pub enum LengthOrNone {
+ Length(Au),
+ None,
+}
+
+impl fmt::Debug for LengthOrNone {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ match *self {
+ LengthOrNone::Length(length) => write!(f, "{:?}", length),
+ LengthOrNone::None => write!(f, "none"),
+ }
+ }
+}
+
+impl ToComputedValue for specified::LengthOrNone {
+ type ComputedValue = LengthOrNone;
+
+ #[inline]
+ fn to_computed_value(&self, context: &Context) -> LengthOrNone {
+ match *self {
+ specified::LengthOrNone::Length(specified::Length::Calc(calc)) => {
+ LengthOrNone::Length(calc.to_computed_value(context).length())
+ }
+ specified::LengthOrNone::Length(value) => {
+ LengthOrNone::Length(value.to_computed_value(context))
+ }
+ specified::LengthOrNone::None => {
+ LengthOrNone::None
+ }
+ }
+ }
+}
+
+impl ::cssparser::ToCss for LengthOrNone {
+ fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
+ match *self {
+ LengthOrNone::Length(length) => length.to_css(dest),
+ LengthOrNone::None => dest.write_str("none"),
+ }
+ }
+}
+
+impl ToComputedValue for specified::Image {
+ type ComputedValue = Image;
+
+ #[inline]
+ fn to_computed_value(&self, context: &Context) -> Image {
+ match *self {
+ specified::Image::Url(ref url, ref extra_data) => {
+ Image::Url(url.clone(), extra_data.clone())
+ },
+ specified::Image::LinearGradient(ref linear_gradient) => {
+ Image::LinearGradient(linear_gradient.to_computed_value(context))
+ }
+ }
+ }
+}
+
+
+/// Computed values for an image according to CSS-IMAGES.
+#[derive(Clone, PartialEq)]
+#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
+pub enum Image {
+ Url(Url, UrlExtraData),
+ LinearGradient(LinearGradient),
+}
+
+impl fmt::Debug for Image {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ match *self {
+ Image::Url(ref url, ref _extra_data) => write!(f, "url(\"{}\")", url),
+ Image::LinearGradient(ref grad) => write!(f, "linear-gradient({:?})", grad),
+ }
+ }
+}
+
+/// Computed values for a CSS linear gradient.
+#[derive(Clone, PartialEq)]
+#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
+pub struct LinearGradient {
+ /// The angle or corner of the gradient.
+ pub angle_or_corner: AngleOrCorner,
+
+ /// The color stops.
+ pub stops: Vec<ColorStop>,
+}
+
+impl ::cssparser::ToCss for LinearGradient {
+ fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
+ try!(dest.write_str("linear-gradient("));
+ try!(self.angle_or_corner.to_css(dest));
+ for stop in &self.stops {
+ try!(dest.write_str(", "));
+ try!(stop.to_css(dest));
+ }
+ try!(dest.write_str(")"));
+ Ok(())
+ }
+}
+
+impl fmt::Debug for LinearGradient {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ let _ = write!(f, "{:?}", self.angle_or_corner);
+ for stop in &self.stops {
+ let _ = write!(f, ", {:?}", stop);
+ }
+ Ok(())
+ }
+}
+
+/// Computed values for one color stop in a linear gradient.
+#[derive(Clone, PartialEq, Copy)]
+#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
+pub struct ColorStop {
+ /// The color of this stop.
+ pub color: CSSColor,
+
+ /// The position of this stop. If not specified, this stop is placed halfway between the
+ /// point that precedes it and the point that follows it per CSS-IMAGES § 3.4.
+ pub position: Option<LengthOrPercentage>,
+}
+
+impl ::cssparser::ToCss for ColorStop {
+ fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
+ try!(self.color.to_css(dest));
+ if let Some(position) = self.position {
+ try!(dest.write_str(" "));
+ try!(position.to_css(dest));
+ }
+ Ok(())
+ }
+}
+
+impl fmt::Debug for ColorStop {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ let _ = write!(f, "{:?}", self.color);
+ self.position.map(|pos| {
+ let _ = write!(f, " {:?}", pos);
+ });
+ Ok(())
+ }
+}
+
+impl ToComputedValue for specified::LinearGradient {
+ type ComputedValue = LinearGradient;
+
+ #[inline]
+ fn to_computed_value(&self, context: &Context) -> LinearGradient {
+ let specified::LinearGradient {
+ angle_or_corner,
+ ref stops
+ } = *self;
+ LinearGradient {
+ angle_or_corner: angle_or_corner,
+ stops: stops.iter().map(|stop| {
+ ColorStop {
+ color: stop.color.parsed,
+ position: match stop.position {
+ None => None,
+ Some(value) => Some(value.to_computed_value(context)),
+ },
+ }
+ }).collect()
+ }
+ }
+}
+pub type Length = Au;
+pub type Number = CSSFloat;
+pub type Opacity = CSSFloat;
diff --git a/components/style/values/mod.rs b/components/style/values/mod.rs
new file mode 100644
index 00000000000..e926685f11b
--- /dev/null
+++ b/components/style/values/mod.rs
@@ -0,0 +1,98 @@
+/* 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/. */
+
+//! Common [values][values] used in CSS.
+//!
+//! [values]: https://drafts.csswg.org/css-values/
+
+pub use cssparser::RGBA;
+
+use app_units::Au;
+use cssparser::CssStringWriter;
+use std::fmt::{self, Write};
+use url::Url;
+
+macro_rules! define_numbered_css_keyword_enum {
+ ($name: ident: $( $css: expr => $variant: ident = $value: expr ),+,) => {
+ define_numbered_css_keyword_enum!($name: $( $css => $variant = $value ),+);
+ };
+ ($name: ident: $( $css: expr => $variant: ident = $value: expr ),+) => {
+ #[allow(non_camel_case_types)]
+ #[derive(Clone, Eq, PartialEq, PartialOrd, Ord, Copy, RustcEncodable, Debug)]
+ #[cfg_attr(feature = "servo", derive(HeapSizeOf, Deserialize, Serialize))]
+ pub enum $name {
+ $( $variant = $value ),+
+ }
+
+ impl $name {
+ pub fn parse(input: &mut ::cssparser::Parser) -> Result<$name, ()> {
+ match_ignore_ascii_case! { try!(input.expect_ident()),
+ $( $css => Ok($name::$variant), )+
+ _ => Err(())
+ }
+ }
+ }
+
+ impl ::cssparser::ToCss for $name {
+ fn to_css<W>(&self, dest: &mut W) -> ::std::fmt::Result
+ where W: ::std::fmt::Write {
+ match *self {
+ $( $name::$variant => dest.write_str($css) ),+
+ }
+ }
+ }
+ }
+}
+
+pub mod computed;
+pub mod specified;
+
+/// The real ToCss trait can't be implemented for types in crates that don't
+/// depend on each other.
+pub trait LocalToCss {
+ /// Serialize `self` in CSS syntax, writing to `dest`.
+ fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write;
+
+ /// Serialize `self` in CSS syntax and return a string.
+ ///
+ /// (This is a convenience wrapper for `to_css` and probably should not be overridden.)
+ #[inline]
+ fn to_css_string(&self) -> String {
+ let mut s = String::new();
+ self.to_css(&mut s).unwrap();
+ s
+ }
+}
+
+impl LocalToCss for Au {
+ fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
+ write!(dest, "{}px", self.to_f64_px())
+ }
+}
+
+impl LocalToCss for Url {
+ fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
+ try!(dest.write_str("url(\""));
+ try!(write!(CssStringWriter::new(dest), "{}", self));
+ try!(dest.write_str("\")"));
+ Ok(())
+ }
+}
+
+pub type CSSFloat = f32;
+
+pub const FONT_MEDIUM_PX: i32 = 16;
+
+pub trait HasViewportPercentage {
+ fn has_viewport_percentage(&self) -> bool;
+}
+
+pub trait NoViewportPercentage {}
+
+impl<T> HasViewportPercentage for T where T: NoViewportPercentage {
+ fn has_viewport_percentage(&self) -> bool {
+ false
+ }
+}
+
diff --git a/components/style/values/specified/mod.rs b/components/style/values/specified/mod.rs
new file mode 100644
index 00000000000..93b270bc117
--- /dev/null
+++ b/components/style/values/specified/mod.rs
@@ -0,0 +1,1609 @@
+/* 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 app_units::Au;
+use cssparser::{self, Parser, ToCss, Token};
+use euclid::size::Size2D;
+#[cfg(feature = "gecko")]
+use gecko_bindings::ptr::{GeckoArcPrincipal, GeckoArcURI};
+use parser::{ParserContext, ParserContextExtraData};
+use std::ascii::AsciiExt;
+use std::cmp;
+use std::f32::consts::PI;
+use std::fmt;
+use std::ops::Mul;
+use style_traits::values::specified::AllowedNumericType;
+use super::computed::{Context, ToComputedValue};
+use super::{CSSFloat, FONT_MEDIUM_PX, HasViewportPercentage, LocalToCss, NoViewportPercentage};
+use url::Url;
+
+impl NoViewportPercentage for i32 {} // For PropertyDeclaration::Order
+
+#[derive(Clone, PartialEq, Debug)]
+#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
+pub struct CSSColor {
+ pub parsed: cssparser::Color,
+ pub authored: Option<String>,
+}
+impl CSSColor {
+ pub fn parse(input: &mut Parser) -> Result<CSSColor, ()> {
+ let start_position = input.position();
+ let authored = match input.next() {
+ Ok(Token::Ident(s)) => Some(s.into_owned()),
+ _ => None,
+ };
+ input.reset(start_position);
+ Ok(CSSColor {
+ parsed: try!(cssparser::Color::parse(input)),
+ authored: authored,
+ })
+ }
+}
+
+impl NoViewportPercentage for CSSColor {}
+
+impl ToCss for CSSColor {
+ fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
+ match self.authored {
+ Some(ref s) => dest.write_str(s),
+ None => self.parsed.to_css(dest),
+ }
+ }
+}
+
+#[derive(Clone, PartialEq, Debug)]
+#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
+pub struct CSSRGBA {
+ pub parsed: cssparser::RGBA,
+ pub authored: Option<String>,
+}
+
+impl NoViewportPercentage for CSSRGBA {}
+
+impl ToCss for CSSRGBA {
+ fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
+ match self.authored {
+ Some(ref s) => dest.write_str(s),
+ None => self.parsed.to_css(dest),
+ }
+ }
+}
+
+#[derive(Clone, PartialEq, Copy, Debug)]
+#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
+pub enum FontRelativeLength {
+ Em(CSSFloat),
+ Ex(CSSFloat),
+ Ch(CSSFloat),
+ Rem(CSSFloat)
+}
+
+impl ToCss for FontRelativeLength {
+ fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
+ match *self {
+ FontRelativeLength::Em(length) => write!(dest, "{}em", length),
+ FontRelativeLength::Ex(length) => write!(dest, "{}ex", length),
+ FontRelativeLength::Ch(length) => write!(dest, "{}ch", length),
+ FontRelativeLength::Rem(length) => write!(dest, "{}rem", length)
+ }
+ }
+}
+
+impl FontRelativeLength {
+ pub fn to_computed_value(&self,
+ reference_font_size: Au,
+ root_font_size: Au)
+ -> Au
+ {
+ match *self {
+ FontRelativeLength::Em(length) => reference_font_size.scale_by(length),
+ FontRelativeLength::Ex(length) | FontRelativeLength::Ch(length) => {
+ // https://github.com/servo/servo/issues/7462
+ let em_factor = 0.5;
+ reference_font_size.scale_by(length * em_factor)
+ },
+ FontRelativeLength::Rem(length) => root_font_size.scale_by(length)
+ }
+ }
+}
+
+#[derive(Clone, PartialEq, Copy, Debug)]
+#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
+pub enum ViewportPercentageLength {
+ Vw(CSSFloat),
+ Vh(CSSFloat),
+ Vmin(CSSFloat),
+ Vmax(CSSFloat)
+}
+
+impl HasViewportPercentage for ViewportPercentageLength {
+ fn has_viewport_percentage(&self) -> bool {
+ true
+ }
+}
+
+impl ToCss for ViewportPercentageLength {
+ fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
+ match *self {
+ ViewportPercentageLength::Vw(length) => write!(dest, "{}vw", length),
+ ViewportPercentageLength::Vh(length) => write!(dest, "{}vh", length),
+ ViewportPercentageLength::Vmin(length) => write!(dest, "{}vmin", length),
+ ViewportPercentageLength::Vmax(length) => write!(dest, "{}vmax", length)
+ }
+ }
+}
+
+impl ViewportPercentageLength {
+ pub fn to_computed_value(&self, viewport_size: Size2D<Au>) -> Au {
+ macro_rules! to_unit {
+ ($viewport_dimension:expr) => {
+ $viewport_dimension.to_f32_px() / 100.0
+ }
+ }
+
+ let value = match *self {
+ ViewportPercentageLength::Vw(length) =>
+ length * to_unit!(viewport_size.width),
+ ViewportPercentageLength::Vh(length) =>
+ length * to_unit!(viewport_size.height),
+ ViewportPercentageLength::Vmin(length) =>
+ length * to_unit!(cmp::min(viewport_size.width, viewport_size.height)),
+ ViewportPercentageLength::Vmax(length) =>
+ length * to_unit!(cmp::max(viewport_size.width, viewport_size.height)),
+ };
+ Au::from_f32_px(value)
+ }
+}
+
+#[derive(Clone, PartialEq, Copy, Debug)]
+#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
+pub struct CharacterWidth(pub i32);
+
+impl CharacterWidth {
+ pub fn to_computed_value(&self, reference_font_size: Au) -> Au {
+ // This applies the *converting a character width to pixels* algorithm as specified
+ // in HTML5 § 14.5.4.
+ //
+ // TODO(pcwalton): Find these from the font.
+ let average_advance = reference_font_size.scale_by(0.5);
+ let max_advance = reference_font_size;
+ average_advance.scale_by(self.0 as CSSFloat - 1.0) + max_advance
+ }
+}
+
+#[derive(Clone, PartialEq, Copy, Debug)]
+#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
+pub enum Length {
+ Absolute(Au), // application units
+ FontRelative(FontRelativeLength),
+ ViewportPercentage(ViewportPercentageLength),
+
+ /// HTML5 "character width", as defined in HTML5 § 14.5.4.
+ ///
+ /// This cannot be specified by the user directly and is only generated by
+ /// `Stylist::synthesize_rules_for_legacy_attributes()`.
+ ServoCharacterWidth(CharacterWidth),
+
+ Calc(CalcLengthOrPercentage),
+}
+
+impl HasViewportPercentage for Length {
+ fn has_viewport_percentage(&self) -> bool {
+ match *self {
+ Length::ViewportPercentage(_) => true,
+ _ => false
+ }
+ }
+}
+
+impl ToCss for Length {
+ fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
+ match *self {
+ Length::Absolute(length) => write!(dest, "{}px", length.to_f32_px()),
+ Length::FontRelative(length) => length.to_css(dest),
+ Length::ViewportPercentage(length) => length.to_css(dest),
+ Length::Calc(calc) => calc.to_css(dest),
+ Length::ServoCharacterWidth(_)
+ => panic!("internal CSS values should never be serialized"),
+ }
+ }
+}
+
+impl Mul<CSSFloat> for Length {
+ type Output = Length;
+
+ #[inline]
+ fn mul(self, scalar: CSSFloat) -> Length {
+ match self {
+ Length::Absolute(Au(v)) => Length::Absolute(Au(((v as f32) * scalar) as i32)),
+ Length::FontRelative(v) => Length::FontRelative(v * scalar),
+ Length::ViewportPercentage(v) => Length::ViewportPercentage(v * scalar),
+ Length::Calc(_) => panic!("Can't multiply Calc!"),
+ Length::ServoCharacterWidth(_) => panic!("Can't multiply ServoCharacterWidth!"),
+ }
+ }
+}
+
+impl Mul<CSSFloat> for FontRelativeLength {
+ type Output = FontRelativeLength;
+
+ #[inline]
+ fn mul(self, scalar: CSSFloat) -> FontRelativeLength {
+ match self {
+ FontRelativeLength::Em(v) => FontRelativeLength::Em(v * scalar),
+ FontRelativeLength::Ex(v) => FontRelativeLength::Ex(v * scalar),
+ FontRelativeLength::Ch(v) => FontRelativeLength::Ch(v * scalar),
+ FontRelativeLength::Rem(v) => FontRelativeLength::Rem(v * scalar),
+ }
+ }
+}
+
+impl Mul<CSSFloat> for ViewportPercentageLength {
+ type Output = ViewportPercentageLength;
+
+ #[inline]
+ fn mul(self, scalar: CSSFloat) -> ViewportPercentageLength {
+ match self {
+ ViewportPercentageLength::Vw(v) => ViewportPercentageLength::Vw(v * scalar),
+ ViewportPercentageLength::Vh(v) => ViewportPercentageLength::Vh(v * scalar),
+ ViewportPercentageLength::Vmin(v) => ViewportPercentageLength::Vmin(v * scalar),
+ ViewportPercentageLength::Vmax(v) => ViewportPercentageLength::Vmax(v * scalar),
+ }
+ }
+}
+
+const AU_PER_PX: CSSFloat = 60.;
+const AU_PER_IN: CSSFloat = AU_PER_PX * 96.;
+const AU_PER_CM: CSSFloat = AU_PER_IN / 2.54;
+const AU_PER_MM: CSSFloat = AU_PER_IN / 25.4;
+const AU_PER_Q: CSSFloat = AU_PER_MM / 4.;
+const AU_PER_PT: CSSFloat = AU_PER_IN / 72.;
+const AU_PER_PC: CSSFloat = AU_PER_PT * 12.;
+impl Length {
+ // https://drafts.csswg.org/css-fonts-3/#font-size-prop
+ pub fn from_str(s: &str) -> Option<Length> {
+ Some(match_ignore_ascii_case! { s,
+ "xx-small" => Length::Absolute(Au::from_px(FONT_MEDIUM_PX) * 3 / 5),
+ "x-small" => Length::Absolute(Au::from_px(FONT_MEDIUM_PX) * 3 / 4),
+ "small" => Length::Absolute(Au::from_px(FONT_MEDIUM_PX) * 8 / 9),
+ "medium" => Length::Absolute(Au::from_px(FONT_MEDIUM_PX)),
+ "large" => Length::Absolute(Au::from_px(FONT_MEDIUM_PX) * 6 / 5),
+ "x-large" => Length::Absolute(Au::from_px(FONT_MEDIUM_PX) * 3 / 2),
+ "xx-large" => Length::Absolute(Au::from_px(FONT_MEDIUM_PX) * 2),
+
+ // https://github.com/servo/servo/issues/3423#issuecomment-56321664
+ "smaller" => Length::FontRelative(FontRelativeLength::Em(0.85)),
+ "larger" => Length::FontRelative(FontRelativeLength::Em(1.2)),
+ _ => return None
+ })
+ }
+
+ #[inline]
+ fn parse_internal(input: &mut Parser, context: &AllowedNumericType) -> Result<Length, ()> {
+ match try!(input.next()) {
+ Token::Dimension(ref value, ref unit) if context.is_ok(value.value) =>
+ Length::parse_dimension(value.value, unit),
+ Token::Number(ref value) if value.value == 0. =>
+ Ok(Length::Absolute(Au(0))),
+ Token::Function(ref name) if name.eq_ignore_ascii_case("calc") =>
+ input.parse_nested_block(CalcLengthOrPercentage::parse_length),
+ _ => Err(())
+ }
+ }
+ pub fn parse(input: &mut Parser) -> Result<Length, ()> {
+ Length::parse_internal(input, &AllowedNumericType::All)
+ }
+ pub fn parse_non_negative(input: &mut Parser) -> Result<Length, ()> {
+ Length::parse_internal(input, &AllowedNumericType::NonNegative)
+ }
+ pub fn parse_dimension(value: CSSFloat, unit: &str) -> Result<Length, ()> {
+ match_ignore_ascii_case! { unit,
+ "px" => Ok(Length::from_px(value)),
+ "in" => Ok(Length::Absolute(Au((value * AU_PER_IN) as i32))),
+ "cm" => Ok(Length::Absolute(Au((value * AU_PER_CM) as i32))),
+ "mm" => Ok(Length::Absolute(Au((value * AU_PER_MM) as i32))),
+ "q" => Ok(Length::Absolute(Au((value * AU_PER_Q) as i32))),
+ "pt" => Ok(Length::Absolute(Au((value * AU_PER_PT) as i32))),
+ "pc" => Ok(Length::Absolute(Au((value * AU_PER_PC) as i32))),
+ // font-relative
+ "em" => Ok(Length::FontRelative(FontRelativeLength::Em(value))),
+ "ex" => Ok(Length::FontRelative(FontRelativeLength::Ex(value))),
+ "ch" => Ok(Length::FontRelative(FontRelativeLength::Ch(value))),
+ "rem" => Ok(Length::FontRelative(FontRelativeLength::Rem(value))),
+ // viewport percentages
+ "vw" => Ok(Length::ViewportPercentage(ViewportPercentageLength::Vw(value))),
+ "vh" => Ok(Length::ViewportPercentage(ViewportPercentageLength::Vh(value))),
+ "vmin" => Ok(Length::ViewportPercentage(ViewportPercentageLength::Vmin(value))),
+ "vmax" => Ok(Length::ViewportPercentage(ViewportPercentageLength::Vmax(value))),
+ _ => Err(())
+ }
+ }
+ #[inline]
+ pub fn from_px(px_value: CSSFloat) -> Length {
+ Length::Absolute(Au((px_value * AU_PER_PX) as i32))
+ }
+}
+
+#[derive(Clone, Debug)]
+struct CalcSumNode {
+ products: Vec<CalcProductNode>,
+}
+
+#[derive(Clone, Debug)]
+struct CalcProductNode {
+ values: Vec<CalcValueNode>
+}
+
+#[derive(Clone, Debug)]
+enum CalcValueNode {
+ Length(Length),
+ Angle(Angle),
+ Time(Time),
+ Percentage(CSSFloat),
+ Number(CSSFloat),
+ Sum(Box<CalcSumNode>),
+}
+
+#[derive(Clone, Debug)]
+struct SimplifiedSumNode {
+ values: Vec<SimplifiedValueNode>,
+}
+impl<'a> Mul<CSSFloat> for &'a SimplifiedSumNode {
+ type Output = SimplifiedSumNode;
+
+ #[inline]
+ fn mul(self, scalar: CSSFloat) -> SimplifiedSumNode {
+ SimplifiedSumNode {
+ values: self.values.iter().map(|p| p * scalar).collect()
+ }
+ }
+}
+
+#[derive(Clone, Debug)]
+enum SimplifiedValueNode {
+ Length(Length),
+ Angle(Angle),
+ Time(Time),
+ Percentage(CSSFloat),
+ Number(CSSFloat),
+ Sum(Box<SimplifiedSumNode>),
+}
+impl<'a> Mul<CSSFloat> for &'a SimplifiedValueNode {
+ type Output = SimplifiedValueNode;
+
+ #[inline]
+ fn mul(self, scalar: CSSFloat) -> SimplifiedValueNode {
+ match *self {
+ SimplifiedValueNode::Length(l) => SimplifiedValueNode::Length(l * scalar),
+ SimplifiedValueNode::Percentage(p) => SimplifiedValueNode::Percentage(p * scalar),
+ SimplifiedValueNode::Angle(Angle(a)) => SimplifiedValueNode::Angle(Angle(a * scalar)),
+ SimplifiedValueNode::Time(Time(t)) => SimplifiedValueNode::Time(Time(t * scalar)),
+ SimplifiedValueNode::Number(n) => SimplifiedValueNode::Number(n * scalar),
+ SimplifiedValueNode::Sum(ref s) => {
+ let sum = &**s * scalar;
+ SimplifiedValueNode::Sum(Box::new(sum))
+ }
+ }
+ }
+}
+
+pub fn parse_integer(input: &mut Parser) -> Result<i32, ()> {
+ match try!(input.next()) {
+ Token::Number(ref value) => value.int_value.ok_or(()),
+ Token::Function(ref name) if name.eq_ignore_ascii_case("calc") => {
+ let ast = try!(input.parse_nested_block(|i| CalcLengthOrPercentage::parse_sum(i, CalcUnit::Integer)));
+
+ let mut result = None;
+
+ for ref node in ast.products {
+ match try!(CalcLengthOrPercentage::simplify_product(node)) {
+ SimplifiedValueNode::Number(val) =>
+ result = Some(result.unwrap_or(0) + val as i32),
+ _ => unreachable!()
+ }
+ }
+
+ match result {
+ Some(result) => Ok(result),
+ _ => Err(())
+ }
+ }
+ _ => Err(())
+ }
+}
+
+pub fn parse_number(input: &mut Parser) -> Result<f32, ()> {
+ match try!(input.next()) {
+ Token::Number(ref value) => Ok(value.value),
+ Token::Function(ref name) if name.eq_ignore_ascii_case("calc") => {
+ let ast = try!(input.parse_nested_block(|i| CalcLengthOrPercentage::parse_sum(i, CalcUnit::Number)));
+
+ let mut result = None;
+
+ for ref node in ast.products {
+ match try!(CalcLengthOrPercentage::simplify_product(node)) {
+ SimplifiedValueNode::Number(val) =>
+ result = Some(result.unwrap_or(0.) + val),
+ _ => unreachable!()
+ }
+ }
+
+ match result {
+ Some(result) => Ok(result),
+ _ => Err(())
+ }
+ }
+ _ => Err(())
+ }
+}
+
+#[derive(Clone, Copy, PartialEq)]
+enum CalcUnit {
+ Number,
+ Integer,
+ Length,
+ LengthOrPercentage,
+ Angle,
+ Time,
+}
+
+#[derive(Clone, PartialEq, Copy, Debug)]
+#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
+pub struct CalcLengthOrPercentage {
+ pub absolute: Option<Au>,
+ pub vw: Option<ViewportPercentageLength>,
+ pub vh: Option<ViewportPercentageLength>,
+ pub vmin: Option<ViewportPercentageLength>,
+ pub vmax: Option<ViewportPercentageLength>,
+ pub em: Option<FontRelativeLength>,
+ pub ex: Option<FontRelativeLength>,
+ pub ch: Option<FontRelativeLength>,
+ pub rem: Option<FontRelativeLength>,
+ pub percentage: Option<Percentage>,
+}
+impl CalcLengthOrPercentage {
+ fn parse_sum(input: &mut Parser, expected_unit: CalcUnit) -> Result<CalcSumNode, ()> {
+ let mut products = Vec::new();
+ products.push(try!(CalcLengthOrPercentage::parse_product(input, expected_unit)));
+
+ while let Ok(token) = input.next() {
+ match token {
+ Token::Delim('+') => {
+ products.push(try!(CalcLengthOrPercentage::parse_product(input, expected_unit)));
+ }
+ Token::Delim('-') => {
+ let mut right = try!(CalcLengthOrPercentage::parse_product(input, expected_unit));
+ right.values.push(CalcValueNode::Number(-1.));
+ products.push(right);
+ }
+ _ => return Err(())
+ }
+ }
+
+ Ok(CalcSumNode { products: products })
+ }
+
+ fn parse_product(input: &mut Parser, expected_unit: CalcUnit) -> Result<CalcProductNode, ()> {
+ let mut values = Vec::new();
+ values.push(try!(CalcLengthOrPercentage::parse_value(input, expected_unit)));
+
+ loop {
+ let position = input.position();
+ match input.next() {
+ Ok(Token::Delim('*')) => {
+ values.push(try!(CalcLengthOrPercentage::parse_value(input, expected_unit)));
+ }
+ Ok(Token::Delim('/')) if expected_unit != CalcUnit::Integer => {
+ if let Ok(Token::Number(ref value)) = input.next() {
+ if value.value == 0. {
+ return Err(());
+ }
+ values.push(CalcValueNode::Number(1. / value.value));
+ } else {
+ return Err(());
+ }
+ }
+ _ => {
+ input.reset(position);
+ break
+ }
+ }
+ }
+
+ Ok(CalcProductNode { values: values })
+ }
+
+ fn parse_value(input: &mut Parser, expected_unit: CalcUnit) -> Result<CalcValueNode, ()> {
+ match (try!(input.next()), expected_unit) {
+ (Token::Number(ref value), _) => Ok(CalcValueNode::Number(value.value)),
+ (Token::Dimension(ref value, ref unit), CalcUnit::Length) |
+ (Token::Dimension(ref value, ref unit), CalcUnit::LengthOrPercentage) => {
+ Length::parse_dimension(value.value, unit).map(CalcValueNode::Length)
+ }
+ (Token::Dimension(ref value, ref unit), CalcUnit::Angle) => {
+ Angle::parse_dimension(value.value, unit).map(CalcValueNode::Angle)
+ }
+ (Token::Dimension(ref value, ref unit), CalcUnit::Time) => {
+ Time::parse_dimension(value.value, unit).map(CalcValueNode::Time)
+ }
+ (Token::Percentage(ref value), CalcUnit::LengthOrPercentage) =>
+ Ok(CalcValueNode::Percentage(value.unit_value)),
+ (Token::ParenthesisBlock, _) => {
+ input.parse_nested_block(|i| CalcLengthOrPercentage::parse_sum(i, expected_unit))
+ .map(|result| CalcValueNode::Sum(Box::new(result)))
+ },
+ _ => Err(())
+ }
+ }
+
+ fn simplify_value_to_number(node: &CalcValueNode) -> Option<CSSFloat> {
+ match *node {
+ CalcValueNode::Number(number) => Some(number),
+ CalcValueNode::Sum(ref sum) => CalcLengthOrPercentage::simplify_sum_to_number(sum),
+ _ => None
+ }
+ }
+
+ fn simplify_sum_to_number(node: &CalcSumNode) -> Option<CSSFloat> {
+ let mut sum = 0.;
+ for ref product in &node.products {
+ match CalcLengthOrPercentage::simplify_product_to_number(product) {
+ Some(number) => sum += number,
+ _ => return None
+ }
+ }
+ Some(sum)
+ }
+
+ fn simplify_product_to_number(node: &CalcProductNode) -> Option<CSSFloat> {
+ let mut product = 1.;
+ for ref value in &node.values {
+ match CalcLengthOrPercentage::simplify_value_to_number(value) {
+ Some(number) => product *= number,
+ _ => return None
+ }
+ }
+ Some(product)
+ }
+
+ fn simplify_products_in_sum(node: &CalcSumNode) -> Result<SimplifiedValueNode, ()> {
+ let mut simplified = Vec::new();
+ for product in &node.products {
+ match try!(CalcLengthOrPercentage::simplify_product(product)) {
+ SimplifiedValueNode::Sum(ref sum) => simplified.extend_from_slice(&sum.values),
+ val => simplified.push(val),
+ }
+ }
+
+ if simplified.len() == 1 {
+ Ok(simplified[0].clone())
+ } else {
+ Ok(SimplifiedValueNode::Sum(Box::new(SimplifiedSumNode { values: simplified })))
+ }
+ }
+
+ fn simplify_product(node: &CalcProductNode) -> Result<SimplifiedValueNode, ()> {
+ let mut multiplier = 1.;
+ let mut node_with_unit = None;
+ for node in &node.values {
+ match CalcLengthOrPercentage::simplify_value_to_number(&node) {
+ Some(number) => multiplier *= number,
+ _ if node_with_unit.is_none() => {
+ node_with_unit = Some(match *node {
+ CalcValueNode::Sum(ref sum) =>
+ try!(CalcLengthOrPercentage::simplify_products_in_sum(sum)),
+ CalcValueNode::Length(l) => SimplifiedValueNode::Length(l),
+ CalcValueNode::Angle(a) => SimplifiedValueNode::Angle(a),
+ CalcValueNode::Time(t) => SimplifiedValueNode::Time(t),
+ CalcValueNode::Percentage(p) => SimplifiedValueNode::Percentage(p),
+ _ => unreachable!("Numbers should have been handled by simplify_value_to_nubmer")
+ })
+ },
+ _ => return Err(()),
+ }
+ }
+
+ match node_with_unit {
+ None => Ok(SimplifiedValueNode::Number(multiplier)),
+ Some(ref value) => Ok(value * multiplier)
+ }
+ }
+
+ fn parse_length(input: &mut Parser) -> Result<Length, ()> {
+ CalcLengthOrPercentage::parse(input, CalcUnit::Length).map(Length::Calc)
+ }
+
+ fn parse_length_or_percentage(input: &mut Parser) -> Result<CalcLengthOrPercentage, ()> {
+ CalcLengthOrPercentage::parse(input, CalcUnit::LengthOrPercentage)
+ }
+
+ fn parse(input: &mut Parser, expected_unit: CalcUnit) -> Result<CalcLengthOrPercentage, ()> {
+ let ast = try!(CalcLengthOrPercentage::parse_sum(input, expected_unit));
+
+ let mut simplified = Vec::new();
+ for ref node in ast.products {
+ match try!(CalcLengthOrPercentage::simplify_product(node)) {
+ SimplifiedValueNode::Sum(sum) => simplified.extend_from_slice(&sum.values),
+ value => simplified.push(value),
+ }
+ }
+
+ let mut absolute = None;
+ let mut vw = None;
+ let mut vh = None;
+ let mut vmax = None;
+ let mut vmin = None;
+ let mut em = None;
+ let mut ex = None;
+ let mut ch = None;
+ let mut rem = None;
+ let mut percentage = None;
+ let mut number = None;
+
+ for value in simplified {
+ match value {
+ SimplifiedValueNode::Percentage(p) =>
+ percentage = Some(percentage.unwrap_or(0.) + p),
+ SimplifiedValueNode::Length(Length::Absolute(Au(au))) =>
+ absolute = Some(absolute.unwrap_or(0) + au),
+ SimplifiedValueNode::Length(Length::ViewportPercentage(v)) =>
+ match v {
+ ViewportPercentageLength::Vw(val) =>
+ vw = Some(vw.unwrap_or(0.) + val),
+ ViewportPercentageLength::Vh(val) =>
+ vh = Some(vh.unwrap_or(0.) + val),
+ ViewportPercentageLength::Vmin(val) =>
+ vmin = Some(vmin.unwrap_or(0.) + val),
+ ViewportPercentageLength::Vmax(val) =>
+ vmax = Some(vmax.unwrap_or(0.) + val),
+ },
+ SimplifiedValueNode::Length(Length::FontRelative(f)) =>
+ match f {
+ FontRelativeLength::Em(val) =>
+ em = Some(em.unwrap_or(0.) + val),
+ FontRelativeLength::Ex(val) =>
+ ex = Some(ex.unwrap_or(0.) + val),
+ FontRelativeLength::Ch(val) =>
+ ch = Some(ch.unwrap_or(0.) + val),
+ FontRelativeLength::Rem(val) =>
+ rem = Some(rem.unwrap_or(0.) + val),
+ },
+ SimplifiedValueNode::Number(val) => number = Some(number.unwrap_or(0.) + val),
+ _ => return Err(()),
+ }
+ }
+
+ Ok(CalcLengthOrPercentage {
+ absolute: absolute.map(Au),
+ vw: vw.map(ViewportPercentageLength::Vw),
+ vh: vh.map(ViewportPercentageLength::Vh),
+ vmax: vmax.map(ViewportPercentageLength::Vmax),
+ vmin: vmin.map(ViewportPercentageLength::Vmin),
+ em: em.map(FontRelativeLength::Em),
+ ex: ex.map(FontRelativeLength::Ex),
+ ch: ch.map(FontRelativeLength::Ch),
+ rem: rem.map(FontRelativeLength::Rem),
+ percentage: percentage.map(Percentage),
+ })
+ }
+
+ pub fn parse_time(input: &mut Parser) -> Result<Time, ()> {
+ let ast = try!(CalcLengthOrPercentage::parse_sum(input, CalcUnit::Time));
+
+ let mut simplified = Vec::new();
+ for ref node in ast.products {
+ match try!(CalcLengthOrPercentage::simplify_product(node)) {
+ SimplifiedValueNode::Sum(sum) => simplified.extend_from_slice(&sum.values),
+ value => simplified.push(value),
+ }
+ }
+
+ let mut time = None;
+
+ for value in simplified {
+ match value {
+ SimplifiedValueNode::Time(Time(val)) =>
+ time = Some(time.unwrap_or(0.) + val),
+ _ => return Err(()),
+ }
+ }
+
+ match time {
+ Some(time) => Ok(Time(time)),
+ _ => Err(())
+ }
+ }
+
+ pub fn parse_angle(input: &mut Parser) -> Result<Angle, ()> {
+ let ast = try!(CalcLengthOrPercentage::parse_sum(input, CalcUnit::Angle));
+
+ let mut simplified = Vec::new();
+ for ref node in ast.products {
+ match try!(CalcLengthOrPercentage::simplify_product(node)) {
+ SimplifiedValueNode::Sum(sum) => simplified.extend_from_slice(&sum.values),
+ value => simplified.push(value),
+ }
+ }
+
+ let mut angle = None;
+ let mut number = None;
+
+ for value in simplified {
+ match value {
+ SimplifiedValueNode::Angle(Angle(val)) =>
+ angle = Some(angle.unwrap_or(0.) + val),
+ SimplifiedValueNode::Number(val) => number = Some(number.unwrap_or(0.) + val),
+ _ => unreachable!()
+ }
+ }
+
+ match (angle, number) {
+ (Some(angle), None) => Ok(Angle(angle)),
+ (None, Some(value)) if value == 0. => Ok(Angle(0.)),
+ _ => Err(())
+ }
+ }
+}
+
+impl ToCss for CalcLengthOrPercentage {
+ #[allow(unused_assignments)]
+ fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
+ macro_rules! count {
+ ( $( $val:ident ),* ) => {
+ {
+ let mut count = 0;
+ $(
+ if let Some(_) = self.$val {
+ count += 1;
+ }
+ )*
+ count
+ }
+ };
+ }
+
+ macro_rules! serialize {
+ ( $( $val:ident ),* ) => {
+ {
+ let mut first_value = true;
+ $(
+ if let Some(val) = self.$val {
+ if !first_value {
+ try!(write!(dest, " + "));
+ } else {
+ first_value = false;
+ }
+ try!(val.to_css(dest));
+ }
+ )*
+ }
+ };
+ }
+
+ let count = count!(ch, em, ex, absolute, rem, vh, vmax, vmin, vw, percentage);
+ assert!(count > 0);
+
+ if count > 1 {
+ try!(write!(dest, "calc("));
+ }
+
+ serialize!(ch, em, ex, absolute, rem, vh, vmax, vmin, vw, percentage);
+
+ if count > 1 {
+ try!(write!(dest, ")"));
+ }
+ Ok(())
+ }
+}
+
+#[derive(Clone, PartialEq, Copy, Debug)]
+#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
+pub struct Percentage(pub CSSFloat); // [0 .. 100%] maps to [0.0 .. 1.0]
+
+impl ToCss for Percentage {
+ fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
+ write!(dest, "{}%", self.0 * 100.)
+ }
+}
+
+#[derive(Clone, PartialEq, Copy, Debug)]
+#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
+pub enum LengthOrPercentage {
+ Length(Length),
+ Percentage(Percentage),
+ Calc(CalcLengthOrPercentage),
+}
+
+impl HasViewportPercentage for LengthOrPercentage {
+ fn has_viewport_percentage(&self) -> bool {
+ match *self {
+ LengthOrPercentage::Length(length) => length.has_viewport_percentage(),
+ _ => false
+ }
+ }
+}
+
+impl ToCss for LengthOrPercentage {
+ fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
+ match *self {
+ LengthOrPercentage::Length(length) => length.to_css(dest),
+ LengthOrPercentage::Percentage(percentage) => percentage.to_css(dest),
+ LengthOrPercentage::Calc(calc) => calc.to_css(dest),
+ }
+ }
+}
+impl LengthOrPercentage {
+ pub fn zero() -> LengthOrPercentage {
+ LengthOrPercentage::Length(Length::Absolute(Au(0)))
+ }
+
+ fn parse_internal(input: &mut Parser, context: &AllowedNumericType)
+ -> Result<LengthOrPercentage, ()>
+ {
+ match try!(input.next()) {
+ Token::Dimension(ref value, ref unit) if context.is_ok(value.value) =>
+ Length::parse_dimension(value.value, unit).map(LengthOrPercentage::Length),
+ Token::Percentage(ref value) if context.is_ok(value.unit_value) =>
+ Ok(LengthOrPercentage::Percentage(Percentage(value.unit_value))),
+ Token::Number(ref value) if value.value == 0. =>
+ Ok(LengthOrPercentage::Length(Length::Absolute(Au(0)))),
+ Token::Function(ref name) if name.eq_ignore_ascii_case("calc") => {
+ let calc = try!(input.parse_nested_block(CalcLengthOrPercentage::parse_length_or_percentage));
+ Ok(LengthOrPercentage::Calc(calc))
+ },
+ _ => Err(())
+ }
+ }
+ #[inline]
+ pub fn parse(input: &mut Parser) -> Result<LengthOrPercentage, ()> {
+ LengthOrPercentage::parse_internal(input, &AllowedNumericType::All)
+ }
+ #[inline]
+ pub fn parse_non_negative(input: &mut Parser) -> Result<LengthOrPercentage, ()> {
+ LengthOrPercentage::parse_internal(input, &AllowedNumericType::NonNegative)
+ }
+}
+
+#[derive(Clone, PartialEq, Copy, Debug)]
+#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
+pub enum LengthOrPercentageOrAuto {
+ Length(Length),
+ Percentage(Percentage),
+ Auto,
+ Calc(CalcLengthOrPercentage),
+}
+
+impl HasViewportPercentage for LengthOrPercentageOrAuto {
+ fn has_viewport_percentage(&self) -> bool {
+ match *self {
+ LengthOrPercentageOrAuto::Length(length) => length.has_viewport_percentage(),
+ _ => false
+ }
+ }
+}
+
+impl ToCss for LengthOrPercentageOrAuto {
+ fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
+ match *self {
+ LengthOrPercentageOrAuto::Length(length) => length.to_css(dest),
+ LengthOrPercentageOrAuto::Percentage(percentage) => percentage.to_css(dest),
+ LengthOrPercentageOrAuto::Auto => dest.write_str("auto"),
+ LengthOrPercentageOrAuto::Calc(calc) => calc.to_css(dest),
+ }
+ }
+}
+
+impl LengthOrPercentageOrAuto {
+ fn parse_internal(input: &mut Parser, context: &AllowedNumericType)
+ -> Result<LengthOrPercentageOrAuto, ()>
+ {
+ match try!(input.next()) {
+ Token::Dimension(ref value, ref unit) if context.is_ok(value.value) =>
+ Length::parse_dimension(value.value, unit).map(LengthOrPercentageOrAuto::Length),
+ Token::Percentage(ref value) if context.is_ok(value.unit_value) =>
+ Ok(LengthOrPercentageOrAuto::Percentage(Percentage(value.unit_value))),
+ Token::Number(ref value) if value.value == 0. =>
+ Ok(LengthOrPercentageOrAuto::Length(Length::Absolute(Au(0)))),
+ Token::Ident(ref value) if value.eq_ignore_ascii_case("auto") =>
+ Ok(LengthOrPercentageOrAuto::Auto),
+ Token::Function(ref name) if name.eq_ignore_ascii_case("calc") => {
+ let calc = try!(input.parse_nested_block(CalcLengthOrPercentage::parse_length_or_percentage));
+ Ok(LengthOrPercentageOrAuto::Calc(calc))
+ },
+ _ => Err(())
+ }
+ }
+ #[inline]
+ pub fn parse(input: &mut Parser) -> Result<LengthOrPercentageOrAuto, ()> {
+ LengthOrPercentageOrAuto::parse_internal(input, &AllowedNumericType::All)
+ }
+ #[inline]
+ pub fn parse_non_negative(input: &mut Parser) -> Result<LengthOrPercentageOrAuto, ()> {
+ LengthOrPercentageOrAuto::parse_internal(input, &AllowedNumericType::NonNegative)
+ }
+}
+
+#[derive(Clone, PartialEq, Copy, Debug)]
+#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
+pub enum LengthOrPercentageOrNone {
+ Length(Length),
+ Percentage(Percentage),
+ Calc(CalcLengthOrPercentage),
+ None,
+}
+
+impl HasViewportPercentage for LengthOrPercentageOrNone {
+ fn has_viewport_percentage(&self) -> bool {
+ match *self {
+ LengthOrPercentageOrNone::Length(length) => length.has_viewport_percentage(),
+ _ => false
+ }
+ }
+}
+
+impl ToCss for LengthOrPercentageOrNone {
+ fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
+ match *self {
+ LengthOrPercentageOrNone::Length(length) => length.to_css(dest),
+ LengthOrPercentageOrNone::Percentage(percentage) => percentage.to_css(dest),
+ LengthOrPercentageOrNone::Calc(calc) => calc.to_css(dest),
+ LengthOrPercentageOrNone::None => dest.write_str("none"),
+ }
+ }
+}
+impl LengthOrPercentageOrNone {
+ fn parse_internal(input: &mut Parser, context: &AllowedNumericType)
+ -> Result<LengthOrPercentageOrNone, ()>
+ {
+ match try!(input.next()) {
+ Token::Dimension(ref value, ref unit) if context.is_ok(value.value) =>
+ Length::parse_dimension(value.value, unit).map(LengthOrPercentageOrNone::Length),
+ Token::Percentage(ref value) if context.is_ok(value.unit_value) =>
+ Ok(LengthOrPercentageOrNone::Percentage(Percentage(value.unit_value))),
+ Token::Number(ref value) if value.value == 0. =>
+ Ok(LengthOrPercentageOrNone::Length(Length::Absolute(Au(0)))),
+ Token::Function(ref name) if name.eq_ignore_ascii_case("calc") => {
+ let calc = try!(input.parse_nested_block(CalcLengthOrPercentage::parse_length_or_percentage));
+ Ok(LengthOrPercentageOrNone::Calc(calc))
+ },
+ Token::Ident(ref value) if value.eq_ignore_ascii_case("none") =>
+ Ok(LengthOrPercentageOrNone::None),
+ _ => Err(())
+ }
+ }
+ #[inline]
+ pub fn parse(input: &mut Parser) -> Result<LengthOrPercentageOrNone, ()> {
+ LengthOrPercentageOrNone::parse_internal(input, &AllowedNumericType::All)
+ }
+ #[inline]
+ pub fn parse_non_negative(input: &mut Parser) -> Result<LengthOrPercentageOrNone, ()> {
+ LengthOrPercentageOrNone::parse_internal(input, &AllowedNumericType::NonNegative)
+ }
+}
+
+#[derive(Clone, PartialEq, Copy, Debug)]
+#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
+pub enum LengthOrNone {
+ Length(Length),
+ None,
+}
+
+impl HasViewportPercentage for LengthOrNone {
+ fn has_viewport_percentage(&self) -> bool {
+ match *self {
+ LengthOrNone::Length(length) => length.has_viewport_percentage(),
+ _ => false
+ }
+ }
+}
+
+impl ToCss for LengthOrNone {
+ fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
+ match *self {
+ LengthOrNone::Length(length) => length.to_css(dest),
+ LengthOrNone::None => dest.write_str("none"),
+ }
+ }
+}
+impl LengthOrNone {
+ fn parse_internal(input: &mut Parser, context: &AllowedNumericType)
+ -> Result<LengthOrNone, ()>
+ {
+ match try!(input.next()) {
+ Token::Dimension(ref value, ref unit) if context.is_ok(value.value) =>
+ Length::parse_dimension(value.value, unit).map(LengthOrNone::Length),
+ Token::Number(ref value) if value.value == 0. =>
+ Ok(LengthOrNone::Length(Length::Absolute(Au(0)))),
+ Token::Function(ref name) if name.eq_ignore_ascii_case("calc") =>
+ input.parse_nested_block(CalcLengthOrPercentage::parse_length).map(LengthOrNone::Length),
+ Token::Ident(ref value) if value.eq_ignore_ascii_case("none") =>
+ Ok(LengthOrNone::None),
+ _ => Err(())
+ }
+ }
+ #[inline]
+ pub fn parse(input: &mut Parser) -> Result<LengthOrNone, ()> {
+ LengthOrNone::parse_internal(input, &AllowedNumericType::All)
+ }
+ #[inline]
+ pub fn parse_non_negative(input: &mut Parser) -> Result<LengthOrNone, ()> {
+ LengthOrNone::parse_internal(input, &AllowedNumericType::NonNegative)
+ }
+}
+
+#[derive(Clone, PartialEq, Copy, Debug)]
+#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
+pub enum LengthOrPercentageOrAutoOrContent {
+ Length(Length),
+ Percentage(Percentage),
+ Calc(CalcLengthOrPercentage),
+ Auto,
+ Content
+}
+
+impl HasViewportPercentage for LengthOrPercentageOrAutoOrContent {
+ fn has_viewport_percentage(&self) -> bool {
+ match *self {
+ LengthOrPercentageOrAutoOrContent::Length(length) => length.has_viewport_percentage(),
+ _ => false
+ }
+ }
+}
+
+impl ToCss for LengthOrPercentageOrAutoOrContent {
+ fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
+ match *self {
+ LengthOrPercentageOrAutoOrContent::Length(len) => len.to_css(dest),
+ LengthOrPercentageOrAutoOrContent::Percentage(perc) => perc.to_css(dest),
+ LengthOrPercentageOrAutoOrContent::Auto => dest.write_str("auto"),
+ LengthOrPercentageOrAutoOrContent::Content => dest.write_str("content"),
+ LengthOrPercentageOrAutoOrContent::Calc(calc) => calc.to_css(dest),
+ }
+ }
+}
+
+impl LengthOrPercentageOrAutoOrContent {
+ pub fn parse(input: &mut Parser) -> Result<LengthOrPercentageOrAutoOrContent, ()> {
+ let context = AllowedNumericType::NonNegative;
+ match try!(input.next()) {
+ Token::Dimension(ref value, ref unit) if context.is_ok(value.value) =>
+ Length::parse_dimension(value.value, unit).map(LengthOrPercentageOrAutoOrContent::Length),
+ Token::Percentage(ref value) if context.is_ok(value.unit_value) =>
+ Ok(LengthOrPercentageOrAutoOrContent::Percentage(Percentage(value.unit_value))),
+ Token::Number(ref value) if value.value == 0. =>
+ Ok(LengthOrPercentageOrAutoOrContent::Length(Length::Absolute(Au(0)))),
+ Token::Ident(ref value) if value.eq_ignore_ascii_case("auto") =>
+ Ok(LengthOrPercentageOrAutoOrContent::Auto),
+ Token::Ident(ref value) if value.eq_ignore_ascii_case("content") =>
+ Ok(LengthOrPercentageOrAutoOrContent::Content),
+ Token::Function(ref name) if name.eq_ignore_ascii_case("calc") => {
+ let calc = try!(input.parse_nested_block(CalcLengthOrPercentage::parse_length_or_percentage));
+ Ok(LengthOrPercentageOrAutoOrContent::Calc(calc))
+ },
+ _ => Err(())
+ }
+ }
+}
+
+#[derive(Clone, PartialEq, Copy, Debug)]
+#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
+pub struct BorderRadiusSize(pub Size2D<LengthOrPercentage>);
+
+impl NoViewportPercentage for BorderRadiusSize {}
+
+impl BorderRadiusSize {
+ pub fn zero() -> BorderRadiusSize {
+ let zero = LengthOrPercentage::Length(Length::Absolute(Au(0)));
+ BorderRadiusSize(Size2D::new(zero, zero))
+ }
+
+ pub fn new(width: LengthOrPercentage, height: LengthOrPercentage) -> BorderRadiusSize {
+ BorderRadiusSize(Size2D::new(width, height))
+ }
+
+ pub fn circle(radius: LengthOrPercentage) -> BorderRadiusSize {
+ BorderRadiusSize(Size2D::new(radius, radius))
+ }
+
+ #[inline]
+ pub fn parse(input: &mut Parser) -> Result<BorderRadiusSize, ()> {
+ let first = try!(LengthOrPercentage::parse_non_negative(input));
+ let second = input.try(LengthOrPercentage::parse_non_negative).unwrap_or(first);
+ Ok(BorderRadiusSize(Size2D::new(first, second)))
+ }
+}
+
+impl ToCss for BorderRadiusSize {
+ fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
+ try!(self.0.width.to_css(dest));
+ try!(dest.write_str(" "));
+ self.0.height.to_css(dest)
+ }
+}
+
+// http://dev.w3.org/csswg/css2/colors.html#propdef-background-position
+#[derive(Clone, PartialEq, Copy)]
+pub enum PositionComponent {
+ LengthOrPercentage(LengthOrPercentage),
+ Center,
+ Left,
+ Right,
+ Top,
+ Bottom,
+}
+
+impl HasViewportPercentage for PositionComponent {
+ fn has_viewport_percentage(&self) -> bool {
+ match *self {
+ PositionComponent::LengthOrPercentage(length) => length.has_viewport_percentage(),
+ _ => false
+ }
+ }
+}
+
+impl PositionComponent {
+ pub fn parse(input: &mut Parser) -> Result<PositionComponent, ()> {
+ input.try(LengthOrPercentage::parse)
+ .map(PositionComponent::LengthOrPercentage)
+ .or_else(|()| {
+ match try!(input.next()) {
+ Token::Ident(value) => {
+ match_ignore_ascii_case! { value,
+ "center" => Ok(PositionComponent::Center),
+ "left" => Ok(PositionComponent::Left),
+ "right" => Ok(PositionComponent::Right),
+ "top" => Ok(PositionComponent::Top),
+ "bottom" => Ok(PositionComponent::Bottom),
+ _ => Err(())
+ }
+ },
+ _ => Err(())
+ }
+ })
+ }
+ #[inline]
+ pub fn to_length_or_percentage(self) -> LengthOrPercentage {
+ match self {
+ PositionComponent::LengthOrPercentage(value) => value,
+ PositionComponent::Center => LengthOrPercentage::Percentage(Percentage(0.5)),
+ PositionComponent::Left |
+ PositionComponent::Top => LengthOrPercentage::Percentage(Percentage(0.0)),
+ PositionComponent::Right |
+ PositionComponent::Bottom => LengthOrPercentage::Percentage(Percentage(1.0)),
+ }
+ }
+}
+
+#[derive(Clone, PartialEq, PartialOrd, Copy, Debug)]
+#[cfg_attr(feature = "servo", derive(HeapSizeOf, Deserialize, Serialize))]
+/// An angle, normalized to radians.
+pub struct Angle(pub CSSFloat);
+
+impl ToCss for Angle {
+ fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
+ write!(dest, "{}rad", self.0)
+ }
+}
+
+impl Angle {
+ #[inline]
+ pub fn radians(self) -> f32 {
+ self.0
+ }
+
+ #[inline]
+ pub fn from_radians(r: f32) -> Self {
+ Angle(r)
+ }
+}
+
+const RAD_PER_DEG: CSSFloat = PI / 180.0;
+const RAD_PER_GRAD: CSSFloat = PI / 200.0;
+const RAD_PER_TURN: CSSFloat = PI * 2.0;
+
+impl Angle {
+ /// Parses an angle according to CSS-VALUES § 6.1.
+ pub fn parse(input: &mut Parser) -> Result<Angle, ()> {
+ match try!(input.next()) {
+ Token::Dimension(ref value, ref unit) => Angle::parse_dimension(value.value, unit),
+ Token::Number(ref value) if value.value == 0. => Ok(Angle(0.)),
+ Token::Function(ref name) if name.eq_ignore_ascii_case("calc") => {
+ input.parse_nested_block(CalcLengthOrPercentage::parse_angle)
+ },
+ _ => Err(())
+ }
+ }
+
+ pub fn parse_dimension(value: CSSFloat, unit: &str) -> Result<Angle, ()> {
+ match_ignore_ascii_case! { unit,
+ "deg" => Ok(Angle(value * RAD_PER_DEG)),
+ "grad" => Ok(Angle(value * RAD_PER_GRAD)),
+ "turn" => Ok(Angle(value * RAD_PER_TURN)),
+ "rad" => Ok(Angle(value)),
+ _ => Err(())
+ }
+ }
+}
+
+#[derive(PartialEq, Clone, Debug)]
+#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
+pub struct UrlExtraData {
+ #[cfg(feature = "gecko")]
+ pub base: GeckoArcURI,
+ #[cfg(feature = "gecko")]
+ pub referrer: GeckoArcURI,
+ #[cfg(feature = "gecko")]
+ pub principal: GeckoArcPrincipal,
+}
+
+impl UrlExtraData {
+ #[cfg(feature = "servo")]
+ pub fn make_from(_context: &ParserContext) -> Option<UrlExtraData> {
+ Some(UrlExtraData { })
+ }
+
+ #[cfg(feature = "gecko")]
+ pub fn make_from(context: &ParserContext) -> Option<UrlExtraData> {
+ match context.extra_data {
+ ParserContextExtraData {
+ base: Some(ref base),
+ referrer: Some(ref referrer),
+ principal: Some(ref principal),
+ } => {
+ Some(UrlExtraData {
+ base: base.clone(),
+ referrer: referrer.clone(),
+ principal: principal.clone(),
+ })
+ },
+ _ => None,
+ }
+ }
+}
+
+/// Specified values for an image according to CSS-IMAGES.
+#[derive(Clone, PartialEq, Debug)]
+#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
+pub enum Image {
+ Url(Url, UrlExtraData),
+ LinearGradient(LinearGradient),
+}
+
+impl ToCss for Image {
+ fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
+ use values::LocalToCss;
+ match *self {
+ Image::Url(ref url, ref _extra_data) => {
+ url.to_css(dest)
+ }
+ Image::LinearGradient(ref gradient) => gradient.to_css(dest)
+ }
+ }
+}
+
+impl Image {
+ pub fn parse(context: &ParserContext, input: &mut Parser) -> Result<Image, ()> {
+ if let Ok(url) = input.try(|input| input.expect_url()) {
+ match UrlExtraData::make_from(context) {
+ Some(extra_data) => {
+ Ok(Image::Url(context.parse_url(&url), extra_data))
+ },
+ None => {
+ // FIXME(heycam) should ensure we always have a principal, etc., when
+ // parsing style attributes and re-parsing due to CSS Variables.
+ println!("stylo: skipping declaration without ParserContextExtraData");
+ Err(())
+ },
+ }
+ } else {
+ match_ignore_ascii_case! { try!(input.expect_function()),
+ "linear-gradient" => {
+ Ok(Image::LinearGradient(try!(
+ input.parse_nested_block(LinearGradient::parse_function))))
+ },
+ _ => Err(())
+ }
+ }
+ }
+}
+
+/// Specified values for a CSS linear gradient.
+#[derive(Clone, PartialEq, Debug)]
+#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
+pub struct LinearGradient {
+ /// The angle or corner of the gradient.
+ pub angle_or_corner: AngleOrCorner,
+
+ /// The color stops.
+ pub stops: Vec<ColorStop>,
+}
+
+impl ToCss for LinearGradient {
+ fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
+ try!(dest.write_str("linear-gradient("));
+ try!(self.angle_or_corner.to_css(dest));
+ for stop in &self.stops {
+ try!(dest.write_str(", "));
+ try!(stop.to_css(dest));
+ }
+ try!(dest.write_str(")"));
+ Ok(())
+ }
+}
+
+/// Specified values for an angle or a corner in a linear gradient.
+#[derive(Clone, PartialEq, Copy, Debug)]
+#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
+pub enum AngleOrCorner {
+ Angle(Angle),
+ Corner(HorizontalDirection, VerticalDirection),
+}
+
+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(())
+ }
+ }
+ }
+}
+
+/// Specified values for one color stop in a linear gradient.
+#[derive(Clone, PartialEq, Debug)]
+#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
+pub struct ColorStop {
+ /// The color of this stop.
+ pub color: CSSColor,
+
+ /// The position of this stop. If not specified, this stop is placed halfway between the
+ /// point that precedes it and the point that follows it.
+ pub position: Option<LengthOrPercentage>,
+}
+
+impl ToCss for ColorStop {
+ fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
+ try!(self.color.to_css(dest));
+ if let Some(position) = self.position {
+ try!(dest.write_str(" "));
+ try!(position.to_css(dest));
+ }
+ Ok(())
+ }
+}
+
+define_css_keyword_enum!(HorizontalDirection: "left" => Left, "right" => Right);
+define_css_keyword_enum!(VerticalDirection: "top" => Top, "bottom" => Bottom);
+
+fn parse_one_color_stop(input: &mut Parser) -> Result<ColorStop, ()> {
+ Ok(ColorStop {
+ color: try!(CSSColor::parse(input)),
+ position: input.try(LengthOrPercentage::parse).ok(),
+ })
+}
+
+impl LinearGradient {
+ /// Parses a linear gradient from the given arguments.
+ pub fn parse_function(input: &mut Parser) -> Result<LinearGradient, ()> {
+ let angle_or_corner = if input.try(|input| input.expect_ident_matching("to")).is_ok() {
+ let (horizontal, vertical) =
+ if let Ok(value) = input.try(HorizontalDirection::parse) {
+ (Some(value), input.try(VerticalDirection::parse).ok())
+ } else {
+ let value = try!(VerticalDirection::parse(input));
+ (input.try(HorizontalDirection::parse).ok(), Some(value))
+ };
+ try!(input.expect_comma());
+ 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!(),
+ }
+ } else if let Ok(angle) = input.try(Angle::parse) {
+ try!(input.expect_comma());
+ AngleOrCorner::Angle(angle)
+ } else {
+ AngleOrCorner::Angle(Angle(PI))
+ };
+ // Parse the color stops.
+ let stops = try!(input.parse_comma_separated(parse_one_color_stop));
+ if stops.len() < 2 {
+ return Err(())
+ }
+ Ok(LinearGradient {
+ angle_or_corner: angle_or_corner,
+ stops: stops,
+ })
+ }
+}
+
+pub fn parse_border_radius(input: &mut Parser) -> Result<BorderRadiusSize, ()> {
+ input.try(BorderRadiusSize::parse).or_else(|()| {
+ match_ignore_ascii_case! { try!(input.expect_ident()),
+ "thin" => Ok(BorderRadiusSize::circle(
+ LengthOrPercentage::Length(Length::from_px(1.)))),
+ "medium" => Ok(BorderRadiusSize::circle(
+ LengthOrPercentage::Length(Length::from_px(3.)))),
+ "thick" => Ok(BorderRadiusSize::circle(
+ LengthOrPercentage::Length(Length::from_px(5.)))),
+ _ => Err(())
+ }
+ })
+}
+
+pub fn parse_border_width(input: &mut Parser) -> Result<Length, ()> {
+ input.try(Length::parse_non_negative).or_else(|()| {
+ match_ignore_ascii_case! { try!(input.expect_ident()),
+ "thin" => Ok(Length::from_px(1.)),
+ "medium" => Ok(Length::from_px(3.)),
+ "thick" => Ok(Length::from_px(5.)),
+ _ => Err(())
+ }
+ })
+}
+
+// The integer values here correspond to the border conflict resolution rules in CSS 2.1 §
+// 17.6.2.1. Higher values override lower values.
+define_numbered_css_keyword_enum! { BorderStyle:
+ "none" => none = -1,
+ "solid" => solid = 6,
+ "double" => double = 7,
+ "dotted" => dotted = 4,
+ "dashed" => dashed = 5,
+ "hidden" => hidden = -2,
+ "groove" => groove = 1,
+ "ridge" => ridge = 3,
+ "inset" => inset = 0,
+ "outset" => outset = 2,
+}
+
+impl NoViewportPercentage for BorderStyle {}
+
+impl BorderStyle {
+ pub fn none_or_hidden(&self) -> bool {
+ matches!(*self, BorderStyle::none | BorderStyle::hidden)
+ }
+}
+
+/// A time in seconds according to CSS-VALUES § 6.2.
+#[derive(Clone, Copy, Debug, PartialEq, PartialOrd)]
+#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
+pub struct Time(pub CSSFloat);
+
+impl Time {
+ /// Returns the time in fractional seconds.
+ pub fn seconds(self) -> f32 {
+ let Time(seconds) = self;
+ seconds
+ }
+
+ /// Parses a time according to CSS-VALUES § 6.2.
+ fn parse_dimension(value: CSSFloat, unit: &str) -> Result<Time, ()> {
+ if unit.eq_ignore_ascii_case("s") {
+ Ok(Time(value))
+ } else if unit.eq_ignore_ascii_case("ms") {
+ Ok(Time(value / 1000.0))
+ } else {
+ Err(())
+ }
+ }
+
+ pub fn parse(input: &mut Parser) -> Result<Time, ()> {
+ match input.next() {
+ Ok(Token::Dimension(ref value, ref unit)) => {
+ Time::parse_dimension(value.value, &unit)
+ }
+ Ok(Token::Function(ref name)) if name.eq_ignore_ascii_case("calc") => {
+ input.parse_nested_block(CalcLengthOrPercentage::parse_time)
+ }
+ _ => Err(())
+ }
+ }
+}
+
+impl ToComputedValue for Time {
+ type ComputedValue = Time;
+
+ #[inline]
+ fn to_computed_value(&self, _: &Context) -> Time {
+ *self
+ }
+}
+
+impl ToCss for Time {
+ fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
+ write!(dest, "{}s", self.0)
+ }
+}
+
+#[derive(Clone, Copy, Debug, PartialEq, PartialOrd)]
+#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
+pub struct Number(pub CSSFloat);
+
+impl NoViewportPercentage for Number {}
+
+impl Number {
+ pub fn parse(input: &mut Parser) -> Result<Number, ()> {
+ parse_number(input).map(Number)
+ }
+
+ fn parse_with_minimum(input: &mut Parser, min: CSSFloat) -> Result<Number, ()> {
+ match parse_number(input) {
+ Ok(value) if value < min => Err(()),
+ value => value.map(Number),
+ }
+ }
+
+ pub fn parse_non_negative(input: &mut Parser) -> Result<Number, ()> {
+ Number::parse_with_minimum(input, 0.0)
+ }
+
+ pub fn parse_at_least_one(input: &mut Parser) -> Result<Number, ()> {
+ Number::parse_with_minimum(input, 1.0)
+ }
+}
+
+impl ToComputedValue for Number {
+ type ComputedValue = CSSFloat;
+
+ #[inline]
+ fn to_computed_value(&self, _: &Context) -> CSSFloat { self.0 }
+}
+
+impl ToCss for Number {
+ fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
+ self.0.to_css(dest)
+ }
+}
+
+#[derive(Clone, Copy, Debug, PartialEq, PartialOrd)]
+#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
+pub struct Opacity(pub CSSFloat);
+
+impl NoViewportPercentage for Opacity {}
+
+impl Opacity {
+ pub fn parse(input: &mut Parser) -> Result<Opacity, ()> {
+ parse_number(input).map(Opacity)
+ }
+}
+
+impl ToComputedValue for Opacity {
+ type ComputedValue = CSSFloat;
+
+ #[inline]
+ fn to_computed_value(&self, _: &Context) -> CSSFloat {
+ if self.0 < 0.0 {
+ 0.0
+ } else if self.0 > 1.0 {
+ 1.0
+ } else {
+ self.0
+ }
+ }
+}
+
+impl ToCss for Opacity {
+ fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
+ self.0.to_css(dest)
+ }
+}
diff --git a/components/util/Cargo.toml b/components/util/Cargo.toml
index e5f0bc9b5d3..d32c015637f 100644
--- a/components/util/Cargo.toml
+++ b/components/util/Cargo.toml
@@ -20,7 +20,7 @@ bitflags = "0.7"
euclid = "0.7.1"
getopts = "0.2.11"
heapsize = "0.3.0"
-ipc-channel = {git = "https://github.com/servo/ipc-channel", optional = true}
+ipc-channel = {version = "0.4.0", optional = true}
lazy_static = "0.2"
log = "0.3.5"
num_cpus = "0.2.2"
@@ -30,5 +30,8 @@ serde_macros = {version = "0.7.11", optional = true}
url = "1.0.0"
plugins = {path = "../plugins", optional = true}
+[dev-dependencies]
+env_logger = "0.3"
+
[target.'cfg(all(unix, not(target_os = "macos"), not(target_os = "ios"), not(target_os = "android")))'.dependencies]
xdg = "2.0"
diff --git a/components/util/lib.rs b/components/util/lib.rs
index c36ec47a4cb..13e763b9cbc 100644
--- a/components/util/lib.rs
+++ b/components/util/lib.rs
@@ -4,6 +4,7 @@
#![cfg_attr(feature = "servo", feature(custom_derive))]
#![cfg_attr(feature = "servo", feature(plugin))]
+#![cfg_attr(feature = "servo", feature(nonzero))]
#![cfg_attr(feature = "servo", feature(reflect_marker))]
#![cfg_attr(feature = "servo", plugin(serde_macros))]
#![cfg_attr(feature = "servo", plugin(plugins))]
@@ -12,6 +13,7 @@
extern crate app_units;
#[allow(unused_extern_crates)] #[macro_use] extern crate bitflags;
+extern crate core;
extern crate euclid;
extern crate getopts;
#[macro_use] extern crate heapsize;
@@ -30,6 +32,7 @@ pub mod geometry;
#[cfg(feature = "servo")] #[allow(unsafe_code)] pub mod ipc;
#[allow(unsafe_code)] pub mod opts;
pub mod prefs;
+#[cfg(feature = "servo")] pub mod remutex;
pub mod resource_files;
pub mod thread;
pub mod thread_state;
diff --git a/components/util/opts.rs b/components/util/opts.rs
index 70926438540..81b83d2b273 100644
--- a/components/util/opts.rs
+++ b/components/util/opts.rs
@@ -191,6 +191,9 @@ pub struct Opts {
/// True to show webrender profiling stats on screen.
pub webrender_stats: bool,
+ /// True to show webrender debug on screen.
+ pub webrender_debug: bool,
+
/// True if WebRender should use multisample antialiasing.
pub use_msaa: bool,
@@ -289,6 +292,9 @@ pub struct DebugOptions {
/// Show webrender profiling stats on screen.
pub webrender_stats: bool,
+ /// Show webrender debug on screen.
+ pub webrender_debug: bool,
+
/// Use multisample antialiasing in WebRender.
pub use_msaa: bool,
@@ -328,6 +334,7 @@ impl DebugOptions {
"load-webfonts-synchronously" => debug_options.load_webfonts_synchronously = true,
"disable-vsync" => debug_options.disable_vsync = true,
"wr-stats" => debug_options.webrender_stats = true,
+ "wr-debug" => debug_options.webrender_debug = true,
"msaa" => debug_options.use_msaa = true,
"full-backtraces" => debug_options.full_backtraces = true,
"" => {},
@@ -377,6 +384,7 @@ pub fn print_debug_usage(app: &str) -> ! {
print_option("wr-stats", "Show WebRender profiler on screen.");
print_option("msaa", "Use multisample antialiasing in WebRender.");
print_option("full-backtraces", "Print full backtraces for all errors");
+ print_option("wr-debug", "Display webrender tile borders. Must be used with -w option.");
println!("");
@@ -511,6 +519,7 @@ pub fn default_opts() -> Opts {
config_dir: None,
full_backtraces: false,
is_printing_version: false,
+ webrender_debug: false,
}
}
@@ -570,7 +579,6 @@ pub fn from_cmdline_args(args: &[String]) -> ArgumentParsingResult {
"config directory following xdg spec on linux platform", "");
opts.optflag("v", "version", "Display servo version information");
-
let opt_match = match opts.parse(args) {
Ok(m) => m,
Err(f) => args_fail(&f.to_string()),
@@ -815,6 +823,7 @@ pub fn from_cmdline_args(args: &[String]) -> ArgumentParsingResult {
config_dir: opt_match.opt_str("config-dir"),
full_backtraces: debug_options.full_backtraces,
is_printing_version: is_printing_version,
+ webrender_debug: debug_options.webrender_debug,
};
set_defaults(opts);
diff --git a/components/util/remutex.rs b/components/util/remutex.rs
new file mode 100644
index 00000000000..ec1c27a3d1a
--- /dev/null
+++ b/components/util/remutex.rs
@@ -0,0 +1,217 @@
+/* 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/. */
+
+//! An implementation of re-entrant mutexes.
+//!
+//! Re-entrant mutexes are like mutexes, but where it is expected
+//! that a single thread may own a lock more than once.
+
+//! 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.
+
+use core::nonzero::NonZero;
+use std::cell::{Cell, UnsafeCell};
+use std::mem;
+use std::ops::Deref;
+use std::sync::atomic::{AtomicUsize, Ordering};
+use std::sync::{LockResult, Mutex, MutexGuard, PoisonError, TryLockError, TryLockResult};
+
+/// A type for thread ids.
+
+// TODO: can we use the thread-id crate for this?
+
+#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash, Debug)]
+pub struct ThreadId(NonZero<usize>);
+
+lazy_static!{ static ref THREAD_COUNT: AtomicUsize = AtomicUsize::new(1); }
+
+impl ThreadId {
+ #[allow(unsafe_code)]
+ fn new() -> ThreadId {
+ let number = THREAD_COUNT.fetch_add(1, Ordering::SeqCst);
+ ThreadId(unsafe { NonZero::new(number) })
+ }
+ pub fn current() -> ThreadId {
+ THREAD_ID.with(|tls| tls.clone())
+ }
+}
+
+thread_local!{ static THREAD_ID: ThreadId = ThreadId::new() }
+
+/// A type for atomic storage of thread ids.
+#[derive(Debug)]
+pub struct AtomicOptThreadId(AtomicUsize);
+
+impl AtomicOptThreadId {
+ pub fn new() -> AtomicOptThreadId {
+ AtomicOptThreadId(AtomicUsize::new(0))
+ }
+ pub fn store(&self, value: Option<ThreadId>, ordering: Ordering) {
+ let number = value.map(|id| *id.0).unwrap_or(0);
+ self.0.store(number, ordering);
+ }
+ #[allow(unsafe_code)]
+ pub fn load(&self, ordering: Ordering) -> Option<ThreadId> {
+ let number = self.0.load(ordering);
+ if number == 0 { None } else { Some(ThreadId(unsafe { NonZero::new(number) })) }
+ }
+ #[allow(unsafe_code)]
+ pub fn swap(&self, value: Option<ThreadId>, ordering: Ordering) -> Option<ThreadId> {
+ let number = value.map(|id| *id.0).unwrap_or(0);
+ let number = self.0.swap(number, ordering);
+ if number == 0 { None } else { Some(ThreadId(unsafe { NonZero::new(number) })) }
+ }
+}
+
+/// A type for hand-over-hand mutexes.
+///
+/// These support `lock` and `unlock` functions. `lock` blocks waiting to become the
+/// mutex owner. `unlock` can only be called by the lock owner, and panics otherwise.
+/// They have the same happens-before and poisoning semantics as `Mutex`.
+
+// TODO: Can we use `raw_lock` and `raw_unlock` from `parking_lot`'s `Mutex` for this?
+
+pub struct HandOverHandMutex {
+ mutex: Mutex<()>,
+ owner: AtomicOptThreadId,
+ guard: UnsafeCell<Option<MutexGuard<'static, ()>>>,
+}
+
+impl HandOverHandMutex {
+ pub fn new() -> HandOverHandMutex {
+ HandOverHandMutex {
+ mutex: Mutex::new(()),
+ owner: AtomicOptThreadId::new(),
+ guard: UnsafeCell::new(None),
+ }
+ }
+ #[allow(unsafe_code)]
+ pub fn lock(&self) -> LockResult<()> {
+ let (guard, result) = match self.mutex.lock() {
+ Ok(guard) => (guard, Ok(())),
+ Err(err) => (err.into_inner(), Err(PoisonError::new(()))),
+ };
+ unsafe { *self.guard.get().as_mut().unwrap() = mem::transmute(guard) };
+ self.owner.store(Some(ThreadId::current()), Ordering::Relaxed);
+ result
+ }
+ #[allow(unsafe_code)]
+ pub fn try_lock(&self) -> TryLockResult<()> {
+ let (guard, result) = match self.mutex.try_lock() {
+ Ok(guard) => (guard, Ok(())),
+ Err(TryLockError::WouldBlock) => return Err(TryLockError::WouldBlock),
+ Err(TryLockError::Poisoned(err)) => (err.into_inner(), Err(TryLockError::Poisoned(PoisonError::new(())))),
+ };
+ unsafe { *self.guard.get().as_mut().unwrap() = mem::transmute(guard) };
+ self.owner.store(Some(ThreadId::current()), Ordering::Relaxed);
+ result
+ }
+ #[allow(unsafe_code)]
+ pub fn unlock(&self) {
+ assert_eq!(Some(ThreadId::current()), self.owner.load(Ordering::Relaxed));
+ self.owner.store(None, Ordering::Relaxed);
+ unsafe { *self.guard.get().as_mut().unwrap() = None; }
+ }
+ pub fn owner(&self) -> Option<ThreadId> {
+ self.owner.load(Ordering::Relaxed)
+ }
+}
+
+#[allow(unsafe_code)]
+unsafe impl Send for HandOverHandMutex {}
+
+/// A type for re-entrant mutexes.
+///
+/// It provides the same interface as https://github.com/rust-lang/rust/blob/master/src/libstd/sys/common/remutex.rs
+
+pub struct ReentrantMutex<T> {
+ mutex: HandOverHandMutex,
+ count: Cell<usize>,
+ data: T,
+}
+
+#[allow(unsafe_code)]
+unsafe impl<T> Sync for ReentrantMutex<T> where T: Send {}
+
+impl<T> ReentrantMutex<T> {
+ pub fn new(data: T) -> ReentrantMutex<T> {
+ debug!("{:?} Creating new lock.", ThreadId::current());
+ ReentrantMutex {
+ mutex: HandOverHandMutex::new(),
+ count: Cell::new(0),
+ data: data,
+ }
+ }
+
+ pub fn lock(&self) -> LockResult<ReentrantMutexGuard<T>> {
+ debug!("{:?} Locking.", ThreadId::current());
+ if self.mutex.owner() != Some(ThreadId::current()) {
+ debug!("{:?} Becoming owner.", ThreadId::current());
+ if let Err(_) = self.mutex.lock() {
+ debug!("{:?} Poison!", ThreadId::current());
+ return Err(PoisonError::new(self.mk_guard()));
+ }
+ debug!("{:?} Became owner.", ThreadId::current());
+ }
+ Ok(self.mk_guard())
+ }
+
+ pub fn try_lock(&self) -> TryLockResult<ReentrantMutexGuard<T>> {
+ debug!("{:?} Try locking.", ThreadId::current());
+ if self.mutex.owner() != Some(ThreadId::current()) {
+ debug!("{:?} Becoming owner?", ThreadId::current());
+ if let Err(err) = self.mutex.try_lock() {
+ match err {
+ TryLockError::WouldBlock => {
+ debug!("{:?} Would block.", ThreadId::current());
+ return Err(TryLockError::WouldBlock)
+ },
+ TryLockError::Poisoned(_) => {
+ debug!("{:?} Poison!", ThreadId::current());
+ return Err(TryLockError::Poisoned(PoisonError::new(self.mk_guard())));
+ },
+ }
+ }
+ debug!("{:?} Became owner.", ThreadId::current());
+ }
+ Ok(self.mk_guard())
+ }
+
+ fn unlock(&self) {
+ debug!("{:?} Unlocking.", ThreadId::current());
+ let count = self.count.get().checked_sub(1).expect("Underflowed lock count.");
+ debug!("{:?} Decrementing count to {}.", ThreadId::current(), count);
+ self.count.set(count);
+ if count == 0 {
+ debug!("{:?} Releasing mutex.", ThreadId::current());
+ self.mutex.unlock();
+ }
+ }
+
+ fn mk_guard(&self) -> ReentrantMutexGuard<T> {
+ let count = self.count.get().checked_add(1).expect("Overflowed lock count.");
+ debug!("{:?} Incrementing count to {}.", ThreadId::current(), count);
+ self.count.set(count);
+ ReentrantMutexGuard { mutex: self }
+ }
+}
+
+#[must_use]
+pub struct ReentrantMutexGuard<'a, T> where T: 'static {
+ mutex: &'a ReentrantMutex<T>,
+}
+
+impl<'a, T> Drop for ReentrantMutexGuard<'a, T> {
+ #[allow(unsafe_code)]
+ fn drop(&mut self) {
+ self.mutex.unlock()
+ }
+}
+
+impl<'a, T> Deref for ReentrantMutexGuard<'a, T> {
+ type Target = T;
+ fn deref(&self) -> &T {
+ &self.mutex.data
+ }
+}
diff --git a/components/webdriver_server/Cargo.toml b/components/webdriver_server/Cargo.toml
index 693c7981f82..9a1b8e5c600 100644
--- a/components/webdriver_server/Cargo.toml
+++ b/components/webdriver_server/Cargo.toml
@@ -13,7 +13,7 @@ path = "lib.rs"
euclid = "0.7.1"
hyper = "0.9.9"
image = "0.10"
-ipc-channel = {git = "https://github.com/servo/ipc-channel"}
+ipc-channel = "0.4.0"
log = "0.3.5"
msg = {path = "../msg"}
plugins = {path = "../plugins"}
diff --git a/components/webdriver_server/lib.rs b/components/webdriver_server/lib.rs
index 050cb68b639..1119eace7d9 100644
--- a/components/webdriver_server/lib.rs
+++ b/components/webdriver_server/lib.rs
@@ -738,7 +738,9 @@ impl Handler {
Ok(value) => Ok(WebDriverResponse::Generic(ValueResponse::new(value.to_json()))),
Err(WebDriverJSError::Timeout) => Err(WebDriverError::new(ErrorStatus::Timeout, "")),
Err(WebDriverJSError::UnknownType) => Err(WebDriverError::new(
- ErrorStatus::UnsupportedOperation, "Unsupported return type"))
+ ErrorStatus::UnsupportedOperation, "Unsupported return type")),
+ Err(WebDriverJSError::BrowsingContextNotFound) => Err(WebDriverError::new(
+ ErrorStatus::JavascriptError, "Pipeline id not found in browsing context"))
}
}
diff --git a/etc/ci/upload_nightly.sh b/etc/ci/upload_nightly.sh
index e3033cc0902..0e5d19d8dc3 100755
--- a/etc/ci/upload_nightly.sh
+++ b/etc/ci/upload_nightly.sh
@@ -41,8 +41,8 @@ main() {
extension=dmg
package=target/*."${extension}"
elif [[ "${platform}" == "windows" ]]; then
- extension=tar.gz
- package=target/*."${extension}"
+ extension=msi
+ package=target/release/msi/*.msi
else
usage >&2
return 1
diff --git a/ports/cef/Cargo.lock b/ports/cef/Cargo.lock
index 61cbc98c96e..9b6ea69083d 100644
--- a/ports/cef/Cargo.lock
+++ b/ports/cef/Cargo.lock
@@ -57,7 +57,7 @@ dependencies = [
"heapsize 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
"num-traits 0.1.32 (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.7.11 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 0.7.15 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@@ -71,7 +71,7 @@ dependencies = [
[[package]]
name = "aster"
-version = "0.19.0"
+version = "0.22.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
@@ -87,8 +87,8 @@ dependencies = [
"heapsize 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
"heapsize_plugin 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.13 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde 0.7.11 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde_macros 0.7.11 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 0.7.15 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde_macros 0.7.15 (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 2.4.11 (registry+https://github.com/rust-lang/crates.io-index)",
"servo-skia 0.20130412.10 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -126,7 +126,7 @@ dependencies = [
"byteorder 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)",
"num-traits 0.1.32 (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.7.11 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 0.7.15 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@@ -183,7 +183,7 @@ dependencies = [
"euclid 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)",
"gfx_traits 0.0.1",
"gleam 0.2.20 (registry+https://github.com/rust-lang/crates.io-index)",
- "ipc-channel 0.4.0 (git+https://github.com/servo/ipc-channel)",
+ "ipc-channel 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
"num-traits 0.1.32 (registry+https://github.com/rust-lang/crates.io-index)",
"offscreen_gl_context 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -202,10 +202,10 @@ dependencies = [
"gfx_traits 0.0.1",
"heapsize 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
"heapsize_plugin 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
- "ipc-channel 0.4.0 (git+https://github.com/servo/ipc-channel)",
+ "ipc-channel 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
"plugins 0.0.1",
- "serde 0.7.11 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde_macros 0.7.11 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 0.7.15 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde_macros 0.7.15 (registry+https://github.com/rust-lang/crates.io-index)",
"webrender_traits 0.2.0 (git+https://github.com/servo/webrender_traits)",
]
@@ -266,7 +266,7 @@ dependencies = [
"gfx_traits 0.0.1",
"gleam 0.2.20 (registry+https://github.com/rust-lang/crates.io-index)",
"image 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "ipc-channel 0.4.0 (git+https://github.com/servo/ipc-channel)",
+ "ipc-channel 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
"layers 0.2.6 (git+https://github.com/servo/rust-layers)",
"log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
"msg 0.0.1",
@@ -274,8 +274,8 @@ dependencies = [
"plugins 0.0.1",
"profile_traits 0.0.1",
"script_traits 0.0.1",
- "serde 0.7.11 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde_macros 0.7.11 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 0.7.15 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde_macros 0.7.15 (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)",
"url 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -297,7 +297,7 @@ dependencies = [
"gaol 0.0.1 (git+https://github.com/servo/gaol)",
"gfx 0.0.1",
"gfx_traits 0.0.1",
- "ipc-channel 0.4.0 (git+https://github.com/servo/ipc-channel)",
+ "ipc-channel 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
"layers 0.2.6 (git+https://github.com/servo/rust-layers)",
"layout_traits 0.0.1",
"log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -308,8 +308,8 @@ dependencies = [
"profile_traits 0.0.1",
"rand 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)",
"script_traits 0.0.1",
- "serde 0.7.11 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde_macros 0.7.11 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 0.7.15 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde_macros 0.7.15 (registry+https://github.com/rust-lang/crates.io-index)",
"style_traits 0.0.1",
"url 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
"util 0.0.1",
@@ -333,7 +333,7 @@ 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)",
- "serde 0.7.11 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 0.7.15 (registry+https://github.com/rust-lang/crates.io-index)",
"time 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)",
"url 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
@@ -362,7 +362,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)",
"libc 0.2.13 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde 0.7.11 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 0.7.15 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@@ -389,8 +389,8 @@ dependencies = [
"heapsize 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
"heapsize_plugin 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
"matches 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde 0.7.11 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde_macros 0.7.11 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 0.7.15 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde_macros 0.7.15 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@@ -441,13 +441,13 @@ version = "0.0.1"
dependencies = [
"devtools_traits 0.0.1",
"hyper 0.9.10 (registry+https://github.com/rust-lang/crates.io-index)",
- "ipc-channel 0.4.0 (git+https://github.com/servo/ipc-channel)",
+ "ipc-channel 0.4.0 (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.7.11 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 0.7.15 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_json 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde_macros 0.7.11 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde_macros 0.7.15 (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",
]
@@ -460,10 +460,10 @@ dependencies = [
"heapsize 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
"heapsize_plugin 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
"hyper 0.9.10 (registry+https://github.com/rust-lang/crates.io-index)",
- "ipc-channel 0.4.0 (git+https://github.com/servo/ipc-channel)",
+ "ipc-channel 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
"msg 0.0.1",
- "serde 0.7.11 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde_macros 0.7.11 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 0.7.15 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde_macros 0.7.15 (registry+https://github.com/rust-lang/crates.io-index)",
"time 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)",
"url 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
@@ -576,7 +576,7 @@ dependencies = [
"log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
"num-traits 0.1.32 (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.7.11 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 0.7.15 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@@ -676,7 +676,7 @@ dependencies = [
"harfbuzz-sys 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
"heapsize 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
"heapsize_plugin 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
- "ipc-channel 0.4.0 (git+https://github.com/servo/ipc-channel)",
+ "ipc-channel 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
"layers 0.2.6 (git+https://github.com/servo/rust-layers)",
"lazy_static 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.13 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -689,8 +689,8 @@ dependencies = [
"rand 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)",
"range 0.0.1",
"rustc-serialize 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde 0.7.11 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde_macros 0.7.11 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 0.7.15 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde_macros 0.7.15 (registry+https://github.com/rust-lang/crates.io-index)",
"servo-fontconfig 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
"simd 0.1.0 (git+https://github.com/huonw/simd)",
"smallvec 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -719,8 +719,8 @@ dependencies = [
"profile_traits 0.0.1",
"range 0.0.1",
"rustc-serialize 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde 0.7.11 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde_macros 0.7.11 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 0.7.15 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde_macros 0.7.15 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@@ -847,8 +847,8 @@ dependencies = [
"heapsize_plugin 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
"mac 0.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
- "phf 0.7.15 (registry+https://github.com/rust-lang/crates.io-index)",
- "phf_codegen 0.7.15 (registry+https://github.com/rust-lang/crates.io-index)",
+ "phf 0.7.16 (registry+https://github.com/rust-lang/crates.io-index)",
+ "phf_codegen 0.7.16 (registry+https://github.com/rust-lang/crates.io-index)",
"rustc-serialize 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)",
"string_cache 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)",
"tendril 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -874,7 +874,7 @@ dependencies = [
"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)",
- "serde 0.7.11 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 0.7.15 (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)",
@@ -906,7 +906,7 @@ dependencies = [
"num-iter 0.1.32 (registry+https://github.com/rust-lang/crates.io-index)",
"num-rational 0.1.32 (registry+https://github.com/rust-lang/crates.io-index)",
"num-traits 0.1.32 (registry+https://github.com/rust-lang/crates.io-index)",
- "png 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "png 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@@ -940,13 +940,13 @@ dependencies = [
[[package]]
name = "ipc-channel"
version = "0.4.0"
-source = "git+https://github.com/servo/ipc-channel#346456b792f0a8e86b4ed077997408a697a06a0f"
+source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"bincode 0.5.9 (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.13 (registry+https://github.com/rust-lang/crates.io-index)",
"rand 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde 0.7.11 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 0.7.15 (registry+https://github.com/rust-lang/crates.io-index)",
"uuid 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
]
@@ -962,7 +962,7 @@ dependencies = [
[[package]]
name = "js"
version = "0.1.3"
-source = "git+https://github.com/servo/rust-mozjs#bc9add648b3174120d70d0bef3935912bd6f1313"
+source = "git+https://github.com/servo/rust-mozjs#14e4556d7cd3dc4fd5eaf5e19e725a1325be14e6"
dependencies = [
"heapsize 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
"lazy_static 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1028,7 +1028,7 @@ dependencies = [
"gfx_traits 0.0.1",
"heapsize 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
"heapsize_plugin 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
- "ipc-channel 0.4.0 (git+https://github.com/servo/ipc-channel)",
+ "ipc-channel 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.13 (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",
@@ -1040,7 +1040,7 @@ dependencies = [
"script_layout_interface 0.0.1",
"script_traits 0.0.1",
"selectors 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde_macros 0.7.11 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde_macros 0.7.15 (registry+https://github.com/rust-lang/crates.io-index)",
"smallvec 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)",
"string_cache 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)",
"style 0.0.1",
@@ -1064,7 +1064,7 @@ dependencies = [
"gfx_traits 0.0.1",
"heapsize 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
"heapsize_plugin 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
- "ipc-channel 0.4.0 (git+https://github.com/servo/ipc-channel)",
+ "ipc-channel 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
"layout 0.0.1",
"layout_traits 0.0.1",
"log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1076,7 +1076,7 @@ dependencies = [
"script_layout_interface 0.0.1",
"script_traits 0.0.1",
"serde_json 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde_macros 0.7.11 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde_macros 0.7.15 (registry+https://github.com/rust-lang/crates.io-index)",
"style 0.0.1",
"url 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
"util 0.0.1",
@@ -1088,7 +1088,7 @@ name = "layout_traits"
version = "0.0.1"
dependencies = [
"gfx 0.0.1",
- "ipc-channel 0.4.0 (git+https://github.com/servo/ipc-channel)",
+ "ipc-channel 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
"msg 0.0.1",
"net_traits 0.0.1",
"profile_traits 0.0.1",
@@ -1212,7 +1212,7 @@ version = "0.2.1"
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.7.11 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 0.7.15 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@@ -1221,8 +1221,8 @@ version = "1.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"mime 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "phf 0.7.15 (registry+https://github.com/rust-lang/crates.io-index)",
- "phf_codegen 0.7.15 (registry+https://github.com/rust-lang/crates.io-index)",
+ "phf 0.7.16 (registry+https://github.com/rust-lang/crates.io-index)",
+ "phf_codegen 0.7.16 (registry+https://github.com/rust-lang/crates.io-index)",
"unicase 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
@@ -1238,7 +1238,7 @@ dependencies = [
[[package]]
name = "mozjs_sys"
version = "0.0.0"
-source = "git+https://github.com/servo/mozjs#2af5849a97a9f18acd482940ba3fa0c6797ed7eb"
+source = "git+https://github.com/servo/mozjs#94eabc218780b696933122184e524bd35544c378"
dependencies = [
"libc 0.2.13 (registry+https://github.com/rust-lang/crates.io-index)",
"libz-sys 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1253,10 +1253,10 @@ dependencies = [
"heapsize 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
"heapsize_plugin 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
"hyper 0.9.10 (registry+https://github.com/rust-lang/crates.io-index)",
- "ipc-channel 0.4.0 (git+https://github.com/servo/ipc-channel)",
+ "ipc-channel 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
"plugins 0.0.1",
- "serde 0.7.11 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde_macros 0.7.11 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 0.7.15 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde_macros 0.7.15 (registry+https://github.com/rust-lang/crates.io-index)",
"url 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
"webrender_traits 0.2.0 (git+https://github.com/servo/webrender_traits)",
]
@@ -1274,7 +1274,7 @@ dependencies = [
"flate2 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)",
"hyper 0.9.10 (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.4.0 (git+https://github.com/servo/ipc-channel)",
+ "ipc-channel 0.4.0 (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)",
"matches 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1320,13 +1320,13 @@ dependencies = [
"heapsize_plugin 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
"hyper 0.9.10 (registry+https://github.com/rust-lang/crates.io-index)",
"image 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "ipc-channel 0.4.0 (git+https://github.com/servo/ipc-channel)",
+ "ipc-channel 0.4.0 (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)",
"msg 0.0.1",
"num-traits 0.1.32 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde 0.7.11 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde_macros 0.7.11 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 0.7.15 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde_macros 0.7.15 (registry+https://github.com/rust-lang/crates.io-index)",
"url 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
"util 0.0.1",
"uuid 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1428,7 +1428,7 @@ dependencies = [
"gleam 0.2.20 (registry+https://github.com/rust-lang/crates.io-index)",
"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)",
- "serde 0.7.11 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 0.7.15 (registry+https://github.com/rust-lang/crates.io-index)",
"x11 2.6.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
@@ -1491,42 +1491,42 @@ dependencies = [
[[package]]
name = "phf"
-version = "0.7.15"
+version = "0.7.16"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
- "phf_shared 0.7.15 (registry+https://github.com/rust-lang/crates.io-index)",
+ "phf_shared 0.7.16 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "phf_codegen"
-version = "0.7.15"
+version = "0.7.16"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
- "phf_generator 0.7.15 (registry+https://github.com/rust-lang/crates.io-index)",
- "phf_shared 0.7.15 (registry+https://github.com/rust-lang/crates.io-index)",
+ "phf_generator 0.7.16 (registry+https://github.com/rust-lang/crates.io-index)",
+ "phf_shared 0.7.16 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "phf_generator"
-version = "0.7.15"
+version = "0.7.16"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
- "phf_shared 0.7.15 (registry+https://github.com/rust-lang/crates.io-index)",
+ "phf_shared 0.7.16 (registry+https://github.com/rust-lang/crates.io-index)",
"rand 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "phf_macros"
-version = "0.7.15"
+version = "0.7.16"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
- "phf_generator 0.7.15 (registry+https://github.com/rust-lang/crates.io-index)",
- "phf_shared 0.7.15 (registry+https://github.com/rust-lang/crates.io-index)",
+ "phf_generator 0.7.16 (registry+https://github.com/rust-lang/crates.io-index)",
+ "phf_shared 0.7.16 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "phf_shared"
-version = "0.7.15"
+version = "0.7.16"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"unicase 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1554,13 +1554,12 @@ dependencies = [
[[package]]
name = "png"
-version = "0.5.1"
+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)",
"flate2 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)",
"inflate 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "libc 0.2.13 (registry+https://github.com/rust-lang/crates.io-index)",
"num-iter 0.1.32 (registry+https://github.com/rust-lang/crates.io-index)",
]
@@ -1569,15 +1568,15 @@ name = "profile"
version = "0.0.1"
dependencies = [
"heartbeats-simple 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "ipc-channel 0.4.0 (git+https://github.com/servo/ipc-channel)",
+ "ipc-channel 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.13 (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.71 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde 0.7.11 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 0.7.15 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_json 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde_macros 0.7.11 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde_macros 0.7.15 (registry+https://github.com/rust-lang/crates.io-index)",
"task_info 0.0.1",
"time 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)",
"util 0.0.1",
@@ -1587,32 +1586,32 @@ dependencies = [
name = "profile_traits"
version = "0.0.1"
dependencies = [
- "ipc-channel 0.4.0 (git+https://github.com/servo/ipc-channel)",
+ "ipc-channel 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
"plugins 0.0.1",
- "serde 0.7.11 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde_macros 0.7.11 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 0.7.15 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde_macros 0.7.15 (registry+https://github.com/rust-lang/crates.io-index)",
"time 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "quasi"
-version = "0.13.0"
+version = "0.16.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "quasi_codegen"
-version = "0.13.0"
+version = "0.16.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
- "aster 0.19.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "aster 0.22.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "quasi_macros"
-version = "0.13.0"
+version = "0.16.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
- "quasi_codegen 0.13.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "quasi_codegen 0.16.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@@ -1640,8 +1639,8 @@ dependencies = [
"heapsize_plugin 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
"num-traits 0.1.32 (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.7.11 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde_macros 0.7.11 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 0.7.15 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde_macros 0.7.15 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@@ -1725,7 +1724,7 @@ dependencies = [
"html5ever 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)",
"hyper 0.9.10 (registry+https://github.com/rust-lang/crates.io-index)",
"image 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "ipc-channel 0.4.0 (git+https://github.com/servo/ipc-channel)",
+ "ipc-channel 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
"js 0.1.3 (git+https://github.com/servo/rust-mozjs)",
"libc 0.2.13 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1736,8 +1735,8 @@ dependencies = [
"num-traits 0.1.32 (registry+https://github.com/rust-lang/crates.io-index)",
"offscreen_gl_context 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)",
"open 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "phf 0.7.15 (registry+https://github.com/rust-lang/crates.io-index)",
- "phf_macros 0.7.15 (registry+https://github.com/rust-lang/crates.io-index)",
+ "phf 0.7.16 (registry+https://github.com/rust-lang/crates.io-index)",
+ "phf_macros 0.7.16 (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)",
@@ -1749,7 +1748,7 @@ dependencies = [
"script_layout_interface 0.0.1",
"script_traits 0.0.1",
"selectors 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde 0.7.11 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 0.7.15 (registry+https://github.com/rust-lang/crates.io-index)",
"smallvec 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)",
"string_cache 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)",
"style 0.0.1",
@@ -1758,6 +1757,7 @@ dependencies = [
"url 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
"util 0.0.1",
"uuid 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "video-metadata 0.1.3 (git+https://github.com/GuillaumeGomez/video-metadata-rs)",
"webrender_traits 0.2.0 (git+https://github.com/servo/webrender_traits)",
"websocket 0.17.1 (registry+https://github.com/rust-lang/crates.io-index)",
"xml5ever 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1775,7 +1775,7 @@ dependencies = [
"gfx_traits 0.0.1",
"heapsize 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
"heapsize_plugin 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
- "ipc-channel 0.4.0 (git+https://github.com/servo/ipc-channel)",
+ "ipc-channel 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.13 (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",
@@ -1803,7 +1803,7 @@ dependencies = [
"gfx_traits 0.0.1",
"heapsize 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
"heapsize_plugin 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
- "ipc-channel 0.4.0 (git+https://github.com/servo/ipc-channel)",
+ "ipc-channel 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
"layers 0.2.6 (git+https://github.com/servo/rust-layers)",
"libc 0.2.13 (registry+https://github.com/rust-lang/crates.io-index)",
"msg 0.0.1",
@@ -1812,8 +1812,8 @@ dependencies = [
"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.7.11 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde_macros 0.7.11 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 0.7.15 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde_macros 0.7.15 (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)",
"url 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1843,23 +1843,23 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "serde"
-version = "0.7.11"
+version = "0.7.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "serde_codegen"
-version = "0.7.11"
+version = "0.7.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
- "aster 0.19.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "quasi 0.13.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "quasi_macros 0.13.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde_item 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "aster 0.22.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "quasi 0.16.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "quasi_macros 0.16.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde_codegen_internals 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
-name = "serde_item"
-version = "0.2.0"
+name = "serde_codegen_internals"
+version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
@@ -1868,15 +1868,15 @@ version = "0.7.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"num-traits 0.1.32 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde 0.7.11 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 0.7.15 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "serde_macros"
-version = "0.7.11"
+version = "0.7.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
- "serde_codegen 0.7.11 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde_codegen 0.7.15 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@@ -1898,7 +1898,7 @@ dependencies = [
"gfx 0.0.1",
"gleam 0.2.20 (registry+https://github.com/rust-lang/crates.io-index)",
"glutin_app 0.0.1",
- "ipc-channel 0.4.0 (git+https://github.com/servo/ipc-channel)",
+ "ipc-channel 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
"layout 0.0.1",
"layout_thread 0.0.1",
"libc 0.2.13 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -2054,9 +2054,9 @@ dependencies = [
"heapsize 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
"heapsize_plugin 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
"lazy_static 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "phf_generator 0.7.15 (registry+https://github.com/rust-lang/crates.io-index)",
- "phf_shared 0.7.15 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde 0.7.11 (registry+https://github.com/rust-lang/crates.io-index)",
+ "phf_generator 0.7.16 (registry+https://github.com/rust-lang/crates.io-index)",
+ "phf_shared 0.7.16 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 0.7.15 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@@ -2082,8 +2082,8 @@ dependencies = [
"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)",
"selectors 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde 0.7.11 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde_macros 0.7.11 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 0.7.15 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde_macros 0.7.15 (registry+https://github.com/rust-lang/crates.io-index)",
"smallvec 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)",
"string_cache 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)",
"style_traits 0.0.1",
@@ -2102,8 +2102,8 @@ dependencies = [
"heapsize 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
"heapsize_plugin 0.1.5 (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.7.11 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde_macros 0.7.11 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 0.7.15 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde_macros 0.7.15 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@@ -2185,8 +2185,9 @@ dependencies = [
[[package]]
name = "tinyfiledialogs"
version = "0.1.0"
-source = "git+https://github.com/jdm/tinyfiledialogs#3a30f8f95686195cb3bcecfc77ff77277a624a53"
+source = "git+https://github.com/jdm/tinyfiledialogs#54f6aa4f579edbc726b8a764fd759a6d6ed0dd84"
dependencies = [
+ "gcc 0.3.28 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.13 (registry+https://github.com/rust-lang/crates.io-index)",
]
@@ -2248,7 +2249,7 @@ dependencies = [
"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.7.11 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 0.7.15 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@@ -2282,14 +2283,14 @@ dependencies = [
"euclid 0.7.1 (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.6 (registry+https://github.com/rust-lang/crates.io-index)",
- "ipc-channel 0.4.0 (git+https://github.com/servo/ipc-channel)",
+ "ipc-channel 0.4.0 (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 0.2.13 (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.7.11 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde_macros 0.7.11 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 0.7.15 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde_macros 0.7.15 (registry+https://github.com/rust-lang/crates.io-index)",
"url 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
"xdg 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
@@ -2300,7 +2301,18 @@ version = "0.2.2"
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.7.11 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 0.7.15 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "video-metadata"
+version = "0.1.3"
+source = "git+https://github.com/GuillaumeGomez/video-metadata-rs#44c8d547f9212be5d368a38d9f1238d85bc6728e"
+dependencies = [
+ "gcc 0.3.28 (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.13 (registry+https://github.com/rust-lang/crates.io-index)",
+ "pkg-config 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@@ -2388,7 +2400,7 @@ dependencies = [
"euclid 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)",
"hyper 0.9.10 (registry+https://github.com/rust-lang/crates.io-index)",
"image 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "ipc-channel 0.4.0 (git+https://github.com/servo/ipc-channel)",
+ "ipc-channel 0.4.0 (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",
@@ -2404,7 +2416,7 @@ dependencies = [
[[package]]
name = "webrender"
version = "0.1.0"
-source = "git+https://github.com/servo/webrender#fd38ab8994be39ba194f56182af8c467b4f9f929"
+source = "git+https://github.com/servo/webrender#79b807160ea3c3cf558072813c51a59bbaccb8dd"
dependencies = [
"app_units 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)",
"bit-set 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -2415,7 +2427,7 @@ dependencies = [
"fnv 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
"freetype 0.1.0 (git+https://github.com/servo/rust-freetype)",
"gleam 0.2.20 (registry+https://github.com/rust-lang/crates.io-index)",
- "ipc-channel 0.4.0 (git+https://github.com/servo/ipc-channel)",
+ "ipc-channel 0.4.0 (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-traits 0.1.32 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -2428,7 +2440,7 @@ dependencies = [
[[package]]
name = "webrender_traits"
version = "0.2.0"
-source = "git+https://github.com/servo/webrender_traits#d86e51ace4fd1b43123e0490dc80f631be0726d0"
+source = "git+https://github.com/servo/webrender_traits#a26ebe4da490cc1fb60d830c73cbefb135b768b1"
dependencies = [
"app_units 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)",
"byteorder 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -2436,10 +2448,10 @@ dependencies = [
"euclid 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)",
"gleam 0.2.20 (registry+https://github.com/rust-lang/crates.io-index)",
"heapsize 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
- "ipc-channel 0.4.0 (git+https://github.com/servo/ipc-channel)",
+ "ipc-channel 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
"offscreen_gl_context 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde 0.7.11 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde_macros 0.7.11 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 0.7.15 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde_macros 0.7.15 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@@ -2520,8 +2532,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
"mac 0.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
- "phf 0.7.15 (registry+https://github.com/rust-lang/crates.io-index)",
- "phf_codegen 0.7.15 (registry+https://github.com/rust-lang/crates.io-index)",
+ "phf 0.7.16 (registry+https://github.com/rust-lang/crates.io-index)",
+ "phf_codegen 0.7.16 (registry+https://github.com/rust-lang/crates.io-index)",
"rustc-serialize 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)",
"string_cache 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)",
"tendril 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
diff --git a/ports/geckolib/Cargo.lock b/ports/geckolib/Cargo.lock
index bfdf613270d..405fadd6627 100644
--- a/ports/geckolib/Cargo.lock
+++ b/ports/geckolib/Cargo.lock
@@ -34,7 +34,7 @@ dependencies = [
"heapsize 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
"num-traits 0.1.32 (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.7.11 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 0.7.15 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@@ -139,7 +139,7 @@ dependencies = [
"log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
"num-traits 0.1.32 (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.7.11 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 0.7.15 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@@ -282,7 +282,7 @@ dependencies = [
[[package]]
name = "serde"
-version = "0.7.11"
+version = "0.7.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
@@ -298,7 +298,7 @@ dependencies = [
"gecko_bindings 0.0.1",
"heapsize 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.13 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde 0.7.11 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 0.7.15 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
diff --git a/ports/geckolib/data.rs b/ports/geckolib/data.rs
index 8e0b98b4266..be287d66a98 100644
--- a/ports/geckolib/data.rs
+++ b/ports/geckolib/data.rs
@@ -77,6 +77,17 @@ impl PerDocumentStyleData {
pub fn borrow_mut_from_raw<'a>(data: *mut RawServoStyleSet) -> &'a mut Self {
unsafe { &mut *(data as *mut PerDocumentStyleData) }
}
+
+ pub fn flush_stylesheets(&mut self) {
+ // The stylist wants to be flushed if either the stylesheets change or the
+ // device dimensions change. When we add support for media queries, we'll
+ // need to detect the latter case and trigger a flush as well.
+ if self.stylesheets_changed {
+ let _ = Arc::get_mut(&mut self.stylist).unwrap()
+ .update(&self.stylesheets, true);
+ self.stylesheets_changed = false;
+ }
+ }
}
impl Drop for PerDocumentStyleData {
diff --git a/ports/geckolib/gecko_bindings/bindings.rs b/ports/geckolib/gecko_bindings/bindings.rs
index 2b861dc7069..10d2bbb7c43 100644
--- a/ports/geckolib/gecko_bindings/bindings.rs
+++ b/ports/geckolib/gecko_bindings/bindings.rs
@@ -135,6 +135,7 @@ use structs::nsStyleCoord_CalcValue as CalcValue;
use structs::nsStyleCoord_Calc as Calc;
use structs::nsRestyleHint;
use structs::ServoElementSnapshot;
+use structs::nsChangeHint;
use structs::SheetParsingMode;
use structs::nsMainThreadPtrHandle;
use structs::nsMainThreadPtrHolder;
@@ -293,6 +294,10 @@ extern "C" {
pub fn Gecko_GetNodeFlags(node: *mut RawGeckoNode) -> u32;
pub fn Gecko_SetNodeFlags(node: *mut RawGeckoNode, flags: u32);
pub fn Gecko_UnsetNodeFlags(node: *mut RawGeckoNode, flags: u32);
+ pub fn Gecko_CalcAndStoreStyleDifference(element: *mut RawGeckoElement,
+ newstyle:
+ *mut ServoComputedValues)
+ -> nsChangeHint;
pub fn Gecko_EnsureTArrayCapacity(array: *mut ::std::os::raw::c_void,
capacity: usize, elem_size: usize);
pub fn Gecko_EnsureImageLayersLength(layers: *mut nsStyleImageLayers,
@@ -308,6 +313,8 @@ extern "C" {
pub fn Gecko_ReleaseCalcArbitraryThread(aPtr: *mut Calc);
pub fn Servo_StylesheetFromUTF8Bytes(bytes: *const u8, length: u32,
parsing_mode: SheetParsingMode,
+ base_bytes: *const u8,
+ base_length: u32,
base: *mut ThreadSafeURIHolder,
referrer: *mut ThreadSafeURIHolder,
principal:
@@ -369,7 +376,6 @@ extern "C" {
snapshot: *mut ServoElementSnapshot,
set: *mut RawServoStyleSet)
-> nsRestyleHint;
- pub fn Servo_StyleWorkerThreadCount() -> u32;
pub fn Gecko_Construct_nsStyleFont(ptr: *mut nsStyleFont);
pub fn Gecko_CopyConstruct_nsStyleFont(ptr: *mut nsStyleFont,
other: *const nsStyleFont);
diff --git a/ports/geckolib/gecko_bindings/structs_debug.rs b/ports/geckolib/gecko_bindings/structs_debug.rs
index 91731e2e941..1ac5b06026e 100644
--- a/ports/geckolib/gecko_bindings/structs_debug.rs
+++ b/ports/geckolib/gecko_bindings/structs_debug.rs
@@ -188,12 +188,6 @@ pub const NS_ERROR_MODULE_BASE_OFFSET: ::std::os::raw::c_uint = 69;
pub const MOZ_STRING_WITH_OBSOLETE_API: ::std::os::raw::c_uint = 1;
pub const NSID_LENGTH: ::std::os::raw::c_uint = 39;
pub const NS_NUMBER_OF_FLAGS_IN_REFCNT: ::std::os::raw::c_uint = 2;
-pub const _STL_PAIR_H: ::std::os::raw::c_uint = 1;
-pub const _GLIBCXX_UTILITY: ::std::os::raw::c_uint = 1;
-pub const __cpp_lib_tuple_element_t: ::std::os::raw::c_uint = 201402;
-pub const __cpp_lib_tuples_by_type: ::std::os::raw::c_uint = 201304;
-pub const __cpp_lib_exchange_function: ::std::os::raw::c_uint = 201304;
-pub const __cpp_lib_integer_sequence: ::std::os::raw::c_uint = 201304;
pub const NS_EVENT_STATE_HIGHEST_SERVO_BIT: ::std::os::raw::c_uint = 6;
pub const DOM_USER_DATA: ::std::os::raw::c_uint = 1;
pub const SMIL_MAPPED_ATTR_ANIMVAL: ::std::os::raw::c_uint = 2;
@@ -212,29 +206,6 @@ pub const NS_CORNER_BOTTOM_RIGHT_X: ::std::os::raw::c_uint = 4;
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_STYLE_CLIP_SHAPE_SIZING_NOBOX: ::std::os::raw::c_uint = 0;
-pub const NS_STYLE_CLIP_SHAPE_SIZING_CONTENT: ::std::os::raw::c_uint = 1;
-pub const NS_STYLE_CLIP_SHAPE_SIZING_PADDING: ::std::os::raw::c_uint = 2;
-pub const NS_STYLE_CLIP_SHAPE_SIZING_BORDER: ::std::os::raw::c_uint = 3;
-pub const NS_STYLE_CLIP_SHAPE_SIZING_MARGIN: ::std::os::raw::c_uint = 4;
-pub const NS_STYLE_CLIP_SHAPE_SIZING_FILL: ::std::os::raw::c_uint = 5;
-pub const NS_STYLE_CLIP_SHAPE_SIZING_STROKE: ::std::os::raw::c_uint = 6;
-pub const NS_STYLE_CLIP_SHAPE_SIZING_VIEW: ::std::os::raw::c_uint = 7;
-pub const NS_STYLE_BASIC_SHAPE_POLYGON: ::std::os::raw::c_uint = 0;
-pub const NS_STYLE_BASIC_SHAPE_CIRCLE: ::std::os::raw::c_uint = 1;
-pub const NS_STYLE_BASIC_SHAPE_ELLIPSE: ::std::os::raw::c_uint = 2;
-pub const NS_STYLE_BASIC_SHAPE_INSET: ::std::os::raw::c_uint = 3;
-pub const NS_STYLE_BOX_SHADOW_INSET: ::std::os::raw::c_uint = 0;
-pub const NS_STYLE_FLOAT_EDGE_CONTENT_BOX: ::std::os::raw::c_uint = 0;
-pub const NS_STYLE_FLOAT_EDGE_MARGIN_BOX: ::std::os::raw::c_uint = 1;
-pub const NS_STYLE_USER_FOCUS_NONE: ::std::os::raw::c_uint = 0;
-pub const NS_STYLE_USER_FOCUS_IGNORE: ::std::os::raw::c_uint = 1;
-pub const NS_STYLE_USER_FOCUS_NORMAL: ::std::os::raw::c_uint = 2;
-pub const NS_STYLE_USER_FOCUS_SELECT_ALL: ::std::os::raw::c_uint = 3;
-pub const NS_STYLE_USER_FOCUS_SELECT_BEFORE: ::std::os::raw::c_uint = 4;
-pub const NS_STYLE_USER_FOCUS_SELECT_AFTER: ::std::os::raw::c_uint = 5;
-pub const NS_STYLE_USER_FOCUS_SELECT_SAME: ::std::os::raw::c_uint = 6;
-pub const NS_STYLE_USER_FOCUS_SELECT_MENU: ::std::os::raw::c_uint = 7;
pub const NS_STYLE_USER_SELECT_NONE: ::std::os::raw::c_uint = 0;
pub const NS_STYLE_USER_SELECT_TEXT: ::std::os::raw::c_uint = 1;
pub const NS_STYLE_USER_SELECT_ELEMENT: ::std::os::raw::c_uint = 2;
@@ -376,6 +347,7 @@ pub const NS_STYLE_BORDER_STYLE_AUTO: ::std::os::raw::c_uint = 10;
pub const NS_STYLE_BORDER_IMAGE_REPEAT_STRETCH: ::std::os::raw::c_uint = 0;
pub const NS_STYLE_BORDER_IMAGE_REPEAT_REPEAT: ::std::os::raw::c_uint = 1;
pub const NS_STYLE_BORDER_IMAGE_REPEAT_ROUND: ::std::os::raw::c_uint = 2;
+pub const NS_STYLE_BORDER_IMAGE_REPEAT_SPACE: ::std::os::raw::c_uint = 3;
pub const NS_STYLE_BORDER_IMAGE_SLICE_NOFILL: ::std::os::raw::c_uint = 0;
pub const NS_STYLE_BORDER_IMAGE_SLICE_FILL: ::std::os::raw::c_uint = 1;
pub const NS_STYLE_CLEAR_NONE: ::std::os::raw::c_uint = 0;
@@ -511,10 +483,6 @@ pub const NS_STYLE_FLOAT_LEFT: ::std::os::raw::c_uint = 1;
pub const NS_STYLE_FLOAT_RIGHT: ::std::os::raw::c_uint = 2;
pub const NS_STYLE_FLOAT_INLINE_START: ::std::os::raw::c_uint = 3;
pub const NS_STYLE_FLOAT_INLINE_END: ::std::os::raw::c_uint = 4;
-pub const NS_STYLE_CLIP_PATH_NONE: ::std::os::raw::c_uint = 0;
-pub const NS_STYLE_CLIP_PATH_URL: ::std::os::raw::c_uint = 1;
-pub const NS_STYLE_CLIP_PATH_SHAPE: ::std::os::raw::c_uint = 2;
-pub const NS_STYLE_CLIP_PATH_BOX: ::std::os::raw::c_uint = 3;
pub const NS_STYLE_FILTER_NONE: ::std::os::raw::c_uint = 0;
pub const NS_STYLE_FILTER_URL: ::std::os::raw::c_uint = 1;
pub const NS_STYLE_FILTER_BLUR: ::std::os::raw::c_uint = 2;
@@ -1924,6 +1892,34 @@ fn bindgen_test_layout_NS_ConvertUTF8toUTF16() {
assert_eq!(::std::mem::align_of::<NS_ConvertUTF8toUTF16>() , 8usize);
}
pub type nsVoidableString = nsAutoString;
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct RefPtrTraits<U> {
+ pub _phantom0: ::std::marker::PhantomData<U>,
+}
+#[repr(C)]
+#[derive(Debug)]
+pub struct RefPtr<T> {
+ pub mRawPtr: *mut T,
+}
+#[repr(C)]
+#[derive(Debug)]
+pub struct RefPtr_Proxy<T, R, Args> {
+ pub mRawPtr: *mut T,
+ pub _phantom0: ::std::marker::PhantomData<R>,
+ pub _phantom1: ::std::marker::PhantomData<Args>,
+}
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct RefPtr_ConstRemovingRefPtrTraits<T, U> {
+ pub _phantom0: ::std::marker::PhantomData<T>,
+ pub _phantom1: ::std::marker::PhantomData<U>,
+}
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct RefPtrGetterAddRefs<T> {
+ pub mTargetSmartPtr: *mut RefPtr<T>,
+}
/**
* A "unique identifier". This is modeled after OSF DCE UUIDs.
*/
@@ -2080,34 +2076,6 @@ fn bindgen_test_layout_QITableEntry() {
assert_eq!(::std::mem::size_of::<QITableEntry>() , 16usize);
assert_eq!(::std::mem::align_of::<QITableEntry>() , 8usize);
}
-#[repr(C)]
-#[derive(Debug, Copy, Clone)]
-pub struct RefPtrTraits<U> {
- pub _phantom0: ::std::marker::PhantomData<U>,
-}
-#[repr(C)]
-#[derive(Debug)]
-pub struct RefPtr<T> {
- pub mRawPtr: *mut T,
-}
-#[repr(C)]
-#[derive(Debug)]
-pub struct RefPtr_Proxy<T, R, Args> {
- pub mRawPtr: *mut T,
- pub _phantom0: ::std::marker::PhantomData<R>,
- pub _phantom1: ::std::marker::PhantomData<Args>,
-}
-#[repr(C)]
-#[derive(Debug, Copy, Clone)]
-pub struct RefPtr_ConstRemovingRefPtrTraits<T, U> {
- pub _phantom0: ::std::marker::PhantomData<T>,
- pub _phantom1: ::std::marker::PhantomData<U>,
-}
-#[repr(C)]
-#[derive(Debug, Copy, Clone)]
-pub struct RefPtrGetterAddRefs<T> {
- pub mTargetSmartPtr: *mut RefPtr<T>,
-}
pub enum TileClient { }
#[repr(C)]
#[derive(Debug, Copy)]
@@ -2735,12 +2703,6 @@ impl ::std::clone::Clone for nsIExpandedPrincipal {
fn clone(&self) -> Self { *self }
}
#[repr(C)]
-#[derive(Debug, Copy, Clone)]
-pub struct _Make_integer_sequence<_Tp, _ISeq> {
- pub _phantom0: ::std::marker::PhantomData<_Tp>,
- pub _phantom1: ::std::marker::PhantomData<_ISeq>,
-}
-#[repr(C)]
#[derive(Debug, Copy)]
pub struct nsIURI {
pub _base: nsISupports,
@@ -2792,7 +2754,7 @@ impl ::std::clone::Clone for nsIRequest {
#[repr(C)]
#[derive(Debug, Copy)]
pub struct EventStates {
- pub mStates: ::std::os::raw::c_ulong,
+ pub mStates: ::std::os::raw::c_ulonglong,
}
impl ::std::clone::Clone for EventStates {
fn clone(&self) -> Self { *self }
@@ -2856,6 +2818,11 @@ pub enum nsNodeSupportsWeakRefTearoff { }
pub enum nsNodeWeakReference { }
pub enum nsDOMMutationObserver { }
pub enum ServoNodeData { }
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct DefaultDelete<> {
+ pub _phantom0: ::std::marker::PhantomData<ServoNodeData>,
+}
pub enum EventListenerManager { }
pub enum BoxQuadOptions { }
pub enum ConvertCoordinateOptions { }
@@ -2922,7 +2889,7 @@ fn bindgen_test_layout_nsMutationGuard() {
extern "C" {
#[link_name = "_ZN15nsMutationGuard11sGenerationE"]
pub static mut nsMutationGuard_consts_sGeneration:
- ::std::os::raw::c_ulong;
+ ::std::os::raw::c_ulonglong;
}
pub type Float = f32;
#[repr(i8)]
@@ -3022,6 +2989,7 @@ pub enum FontType {
SKIA = 3,
CAIRO = 4,
COREGRAPHICS = 5,
+ FONTCONFIG = 6,
}
#[repr(i8)]
#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)]
@@ -3918,7 +3886,43 @@ fn bindgen_test_layout_nsFont() {
}
#[repr(i8)]
#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)]
+pub enum StyleBasicShape { Polygon = 0, Circle = 1, Ellipse = 2, Inset = 3, }
+#[repr(i8)]
+#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)]
pub enum StyleBoxSizing { Content = 0, Border = 1, }
+#[repr(i8)]
+#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)]
+pub enum StyleBoxShadowType { Inset = 0, }
+#[repr(i8)]
+#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)]
+pub enum StyleClipPathType { None_ = 0, URL = 1, Shape = 2, Box = 3, }
+#[repr(i8)]
+#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)]
+pub enum StyleClipShapeSizing {
+ NoBox = 0,
+ Content = 1,
+ Padding = 2,
+ Border = 3,
+ Margin = 4,
+ Fill = 5,
+ Stroke = 6,
+ View = 7,
+}
+#[repr(i8)]
+#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)]
+pub enum StyleFloatEdge { ContentBox = 0, MarginBox = 1, }
+#[repr(i8)]
+#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)]
+pub enum StyleUserFocus {
+ None_ = 0,
+ Ignore = 1,
+ Normal = 2,
+ SelectAll = 3,
+ SelectBefore = 4,
+ SelectAfter = 5,
+ SelectSame = 6,
+ SelectMenu = 7,
+}
pub const eCSSProperty_COUNT_DUMMY: nsCSSProperty =
nsCSSProperty::eCSSProperty_z_index;
pub const eCSSProperty_all: nsCSSProperty =
@@ -4079,305 +4083,306 @@ pub enum nsCSSProperty {
eCSSProperty_grid_template_rows = 141,
eCSSProperty_height = 142,
eCSSProperty_hyphens = 143,
- eCSSProperty_image_orientation = 144,
- eCSSProperty_image_region = 145,
- eCSSProperty_image_rendering = 146,
- eCSSProperty_ime_mode = 147,
- eCSSProperty_inline_size = 148,
- eCSSProperty_isolation = 149,
- eCSSProperty_justify_content = 150,
- eCSSProperty_justify_items = 151,
- eCSSProperty_justify_self = 152,
- eCSSProperty__x_lang = 153,
- eCSSProperty_left = 154,
- eCSSProperty_letter_spacing = 155,
- eCSSProperty_lighting_color = 156,
- eCSSProperty_line_height = 157,
- eCSSProperty_list_style_image = 158,
- eCSSProperty_list_style_position = 159,
- eCSSProperty_list_style_type = 160,
- eCSSProperty_margin_block_end = 161,
- eCSSProperty_margin_block_start = 162,
- eCSSProperty_margin_bottom = 163,
- eCSSProperty_margin_inline_end = 164,
- eCSSProperty_margin_inline_start = 165,
- eCSSProperty_margin_left = 166,
- eCSSProperty_margin_right = 167,
- eCSSProperty_margin_top = 168,
- eCSSProperty_marker_end = 169,
- eCSSProperty_marker_mid = 170,
- eCSSProperty_marker_offset = 171,
- eCSSProperty_marker_start = 172,
- eCSSProperty_mask = 173,
- eCSSProperty_mask_type = 174,
- eCSSProperty_math_display = 175,
- eCSSProperty_math_variant = 176,
- eCSSProperty_max_block_size = 177,
- eCSSProperty_max_height = 178,
- eCSSProperty_max_inline_size = 179,
- eCSSProperty_max_width = 180,
- eCSSProperty_min_block_size = 181,
- eCSSProperty__moz_min_font_size_ratio = 182,
- eCSSProperty_min_height = 183,
- eCSSProperty_min_inline_size = 184,
- eCSSProperty_min_width = 185,
- eCSSProperty_mix_blend_mode = 186,
- eCSSProperty_object_fit = 187,
- eCSSProperty_object_position = 188,
- eCSSProperty_offset_block_end = 189,
- eCSSProperty_offset_block_start = 190,
- eCSSProperty_offset_inline_end = 191,
- eCSSProperty_offset_inline_start = 192,
- eCSSProperty_opacity = 193,
- eCSSProperty_order = 194,
- eCSSProperty_orient = 195,
- eCSSProperty_osx_font_smoothing = 196,
- eCSSProperty_outline_color = 197,
- eCSSProperty_outline_offset = 198,
- eCSSProperty__moz_outline_radius_bottomLeft = 199,
- eCSSProperty__moz_outline_radius_bottomRight = 200,
- eCSSProperty__moz_outline_radius_topLeft = 201,
- eCSSProperty__moz_outline_radius_topRight = 202,
- eCSSProperty_outline_style = 203,
- eCSSProperty_outline_width = 204,
- eCSSProperty_overflow_clip_box = 205,
- eCSSProperty_overflow_x = 206,
- eCSSProperty_overflow_y = 207,
- eCSSProperty_padding_block_end = 208,
- eCSSProperty_padding_block_start = 209,
- eCSSProperty_padding_bottom = 210,
- eCSSProperty_padding_inline_end = 211,
- eCSSProperty_padding_inline_start = 212,
- eCSSProperty_padding_left = 213,
- eCSSProperty_padding_right = 214,
- eCSSProperty_padding_top = 215,
- eCSSProperty_page_break_after = 216,
- eCSSProperty_page_break_before = 217,
- eCSSProperty_page_break_inside = 218,
- eCSSProperty_paint_order = 219,
- eCSSProperty_perspective = 220,
- eCSSProperty_perspective_origin = 221,
- eCSSProperty_pointer_events = 222,
- eCSSProperty_position = 223,
- eCSSProperty_quotes = 224,
- eCSSProperty_resize = 225,
- eCSSProperty_right = 226,
- eCSSProperty_ruby_align = 227,
- eCSSProperty_ruby_position = 228,
- eCSSProperty_script_level = 229,
- eCSSProperty_script_min_size = 230,
- eCSSProperty_script_size_multiplier = 231,
- eCSSProperty_scroll_behavior = 232,
- eCSSProperty_scroll_snap_coordinate = 233,
- eCSSProperty_scroll_snap_destination = 234,
- eCSSProperty_scroll_snap_points_x = 235,
- eCSSProperty_scroll_snap_points_y = 236,
- eCSSProperty_scroll_snap_type_x = 237,
- eCSSProperty_scroll_snap_type_y = 238,
- eCSSProperty_shape_rendering = 239,
- eCSSProperty__x_span = 240,
- eCSSProperty_stack_sizing = 241,
- eCSSProperty_stop_color = 242,
- eCSSProperty_stop_opacity = 243,
- eCSSProperty_stroke = 244,
- eCSSProperty_stroke_dasharray = 245,
- eCSSProperty_stroke_dashoffset = 246,
- eCSSProperty_stroke_linecap = 247,
- eCSSProperty_stroke_linejoin = 248,
- eCSSProperty_stroke_miterlimit = 249,
- eCSSProperty_stroke_opacity = 250,
- eCSSProperty_stroke_width = 251,
- eCSSProperty__x_system_font = 252,
- eCSSProperty__moz_tab_size = 253,
- eCSSProperty_table_layout = 254,
- eCSSProperty_text_align = 255,
- eCSSProperty_text_align_last = 256,
- eCSSProperty_text_anchor = 257,
- eCSSProperty_text_combine_upright = 258,
- eCSSProperty_text_decoration_color = 259,
- eCSSProperty_text_decoration_line = 260,
- eCSSProperty_text_decoration_style = 261,
- eCSSProperty_text_emphasis_color = 262,
- eCSSProperty_text_emphasis_position = 263,
- eCSSProperty_text_emphasis_style = 264,
- eCSSProperty__webkit_text_fill_color = 265,
- eCSSProperty_text_indent = 266,
- eCSSProperty_text_orientation = 267,
- eCSSProperty_text_overflow = 268,
- eCSSProperty_text_rendering = 269,
- eCSSProperty_text_shadow = 270,
- eCSSProperty_text_size_adjust = 271,
- eCSSProperty__webkit_text_stroke_color = 272,
- eCSSProperty__webkit_text_stroke_width = 273,
- eCSSProperty_text_transform = 274,
- eCSSProperty__x_text_zoom = 275,
- eCSSProperty_top = 276,
- eCSSProperty__moz_top_layer = 277,
- eCSSProperty_touch_action = 278,
- eCSSProperty_transform = 279,
- eCSSProperty_transform_box = 280,
- eCSSProperty_transform_origin = 281,
- eCSSProperty_transform_style = 282,
- eCSSProperty_transition_delay = 283,
- eCSSProperty_transition_duration = 284,
- eCSSProperty_transition_property = 285,
- eCSSProperty_transition_timing_function = 286,
- eCSSProperty_unicode_bidi = 287,
- eCSSProperty_user_focus = 288,
- eCSSProperty_user_input = 289,
- eCSSProperty_user_modify = 290,
- eCSSProperty_user_select = 291,
- eCSSProperty_vector_effect = 292,
- eCSSProperty_vertical_align = 293,
- eCSSProperty_visibility = 294,
- eCSSProperty_white_space = 295,
- eCSSProperty_width = 296,
- eCSSProperty_will_change = 297,
- eCSSProperty__moz_window_dragging = 298,
- eCSSProperty__moz_window_shadow = 299,
- eCSSProperty_word_break = 300,
- eCSSProperty_word_spacing = 301,
- eCSSProperty_overflow_wrap = 302,
- eCSSProperty_writing_mode = 303,
- eCSSProperty_z_index = 304,
- eCSSProperty_COUNT_no_shorthands = 305,
- eCSSProperty_animation = 306,
- eCSSProperty_background = 307,
- eCSSProperty_background_position = 308,
- eCSSProperty_border = 309,
- eCSSProperty_border_block_end = 310,
- eCSSProperty_border_block_start = 311,
- eCSSProperty_border_bottom = 312,
- eCSSProperty_border_color = 313,
- eCSSProperty_border_image = 314,
- eCSSProperty_border_inline_end = 315,
- eCSSProperty_border_inline_start = 316,
- eCSSProperty_border_left = 317,
- eCSSProperty_border_radius = 318,
- eCSSProperty_border_right = 319,
- eCSSProperty_border_style = 320,
- eCSSProperty_border_top = 321,
- eCSSProperty_border_width = 322,
- eCSSProperty__moz_column_rule = 323,
- eCSSProperty__moz_columns = 324,
- eCSSProperty_flex = 325,
- eCSSProperty_flex_flow = 326,
- eCSSProperty_font = 327,
- eCSSProperty_font_variant = 328,
- eCSSProperty_grid = 329,
- eCSSProperty_grid_area = 330,
- eCSSProperty_grid_column = 331,
- eCSSProperty_grid_gap = 332,
- eCSSProperty_grid_row = 333,
- eCSSProperty_grid_template = 334,
- eCSSProperty_list_style = 335,
- eCSSProperty_margin = 336,
- eCSSProperty_marker = 337,
- eCSSProperty_outline = 338,
- eCSSProperty__moz_outline_radius = 339,
- eCSSProperty_overflow = 340,
- eCSSProperty_padding = 341,
- eCSSProperty_scroll_snap_type = 342,
- eCSSProperty_text_decoration = 343,
- eCSSProperty_text_emphasis = 344,
- eCSSProperty__webkit_text_stroke = 345,
- eCSSProperty__moz_transform = 346,
- eCSSProperty_transition = 347,
- eCSSProperty_COUNT = 348,
- eCSSPropertyAlias_MozTransformOrigin = 349,
- eCSSPropertyAlias_MozPerspectiveOrigin = 350,
- eCSSPropertyAlias_MozPerspective = 351,
- eCSSPropertyAlias_MozTransformStyle = 352,
- eCSSPropertyAlias_MozBackfaceVisibility = 353,
- eCSSPropertyAlias_MozBorderImage = 354,
- eCSSPropertyAlias_MozTransition = 355,
- eCSSPropertyAlias_MozTransitionDelay = 356,
- eCSSPropertyAlias_MozTransitionDuration = 357,
- eCSSPropertyAlias_MozTransitionProperty = 358,
- eCSSPropertyAlias_MozTransitionTimingFunction = 359,
- eCSSPropertyAlias_MozAnimation = 360,
- eCSSPropertyAlias_MozAnimationDelay = 361,
- eCSSPropertyAlias_MozAnimationDirection = 362,
- eCSSPropertyAlias_MozAnimationDuration = 363,
- eCSSPropertyAlias_MozAnimationFillMode = 364,
- eCSSPropertyAlias_MozAnimationIterationCount = 365,
- eCSSPropertyAlias_MozAnimationName = 366,
- eCSSPropertyAlias_MozAnimationPlayState = 367,
- eCSSPropertyAlias_MozAnimationTimingFunction = 368,
- eCSSPropertyAlias_MozBoxSizing = 369,
- eCSSPropertyAlias_MozFontFeatureSettings = 370,
- eCSSPropertyAlias_MozFontLanguageOverride = 371,
- eCSSPropertyAlias_MozPaddingEnd = 372,
- eCSSPropertyAlias_MozPaddingStart = 373,
- eCSSPropertyAlias_MozMarginEnd = 374,
- eCSSPropertyAlias_MozMarginStart = 375,
- eCSSPropertyAlias_MozBorderEnd = 376,
- eCSSPropertyAlias_MozBorderEndColor = 377,
- eCSSPropertyAlias_MozBorderEndStyle = 378,
- eCSSPropertyAlias_MozBorderEndWidth = 379,
- eCSSPropertyAlias_MozBorderStart = 380,
- eCSSPropertyAlias_MozBorderStartColor = 381,
- eCSSPropertyAlias_MozBorderStartStyle = 382,
- eCSSPropertyAlias_MozBorderStartWidth = 383,
- eCSSPropertyAlias_MozHyphens = 384,
- eCSSPropertyAlias_MozTextAlignLast = 385,
- eCSSPropertyAlias_WebkitAnimation = 386,
- eCSSPropertyAlias_WebkitAnimationDelay = 387,
- eCSSPropertyAlias_WebkitAnimationDirection = 388,
- eCSSPropertyAlias_WebkitAnimationDuration = 389,
- eCSSPropertyAlias_WebkitAnimationFillMode = 390,
- eCSSPropertyAlias_WebkitAnimationIterationCount = 391,
- eCSSPropertyAlias_WebkitAnimationName = 392,
- eCSSPropertyAlias_WebkitAnimationPlayState = 393,
- eCSSPropertyAlias_WebkitAnimationTimingFunction = 394,
- eCSSPropertyAlias_WebkitFilter = 395,
- eCSSPropertyAlias_WebkitTextSizeAdjust = 396,
- eCSSPropertyAlias_WebkitTransform = 397,
- eCSSPropertyAlias_WebkitTransformOrigin = 398,
- eCSSPropertyAlias_WebkitTransformStyle = 399,
- eCSSPropertyAlias_WebkitBackfaceVisibility = 400,
- eCSSPropertyAlias_WebkitPerspective = 401,
- eCSSPropertyAlias_WebkitPerspectiveOrigin = 402,
- eCSSPropertyAlias_WebkitTransition = 403,
- eCSSPropertyAlias_WebkitTransitionDelay = 404,
- eCSSPropertyAlias_WebkitTransitionDuration = 405,
- eCSSPropertyAlias_WebkitTransitionProperty = 406,
- eCSSPropertyAlias_WebkitTransitionTimingFunction = 407,
- eCSSPropertyAlias_WebkitBorderRadius = 408,
- eCSSPropertyAlias_WebkitBorderTopLeftRadius = 409,
- eCSSPropertyAlias_WebkitBorderTopRightRadius = 410,
- eCSSPropertyAlias_WebkitBorderBottomLeftRadius = 411,
- eCSSPropertyAlias_WebkitBorderBottomRightRadius = 412,
- eCSSPropertyAlias_WebkitBackgroundClip = 413,
- eCSSPropertyAlias_WebkitBackgroundOrigin = 414,
- eCSSPropertyAlias_WebkitBackgroundSize = 415,
- eCSSPropertyAlias_WebkitBorderImage = 416,
- eCSSPropertyAlias_WebkitBoxShadow = 417,
- eCSSPropertyAlias_WebkitBoxSizing = 418,
- eCSSPropertyAlias_WebkitBoxFlex = 419,
- eCSSPropertyAlias_WebkitBoxOrdinalGroup = 420,
- eCSSPropertyAlias_WebkitBoxOrient = 421,
- eCSSPropertyAlias_WebkitBoxDirection = 422,
- eCSSPropertyAlias_WebkitBoxAlign = 423,
- eCSSPropertyAlias_WebkitBoxPack = 424,
- eCSSPropertyAlias_WebkitFlexDirection = 425,
- eCSSPropertyAlias_WebkitFlexWrap = 426,
- eCSSPropertyAlias_WebkitFlexFlow = 427,
- eCSSPropertyAlias_WebkitOrder = 428,
- eCSSPropertyAlias_WebkitFlex = 429,
- eCSSPropertyAlias_WebkitFlexGrow = 430,
- eCSSPropertyAlias_WebkitFlexShrink = 431,
- eCSSPropertyAlias_WebkitFlexBasis = 432,
- eCSSPropertyAlias_WebkitJustifyContent = 433,
- eCSSPropertyAlias_WebkitAlignItems = 434,
- eCSSPropertyAlias_WebkitAlignSelf = 435,
- eCSSPropertyAlias_WebkitAlignContent = 436,
- eCSSPropertyAlias_WebkitUserSelect = 437,
- eCSSProperty_COUNT_with_aliases = 438,
- eCSSPropertyExtra_all_properties = 439,
- eCSSPropertyExtra_x_none_value = 440,
- eCSSPropertyExtra_x_auto_value = 441,
- eCSSPropertyExtra_variable = 442,
+ eCSSProperty_initial_letter = 144,
+ eCSSProperty_image_orientation = 145,
+ eCSSProperty_image_region = 146,
+ eCSSProperty_image_rendering = 147,
+ eCSSProperty_ime_mode = 148,
+ eCSSProperty_inline_size = 149,
+ eCSSProperty_isolation = 150,
+ eCSSProperty_justify_content = 151,
+ eCSSProperty_justify_items = 152,
+ eCSSProperty_justify_self = 153,
+ eCSSProperty__x_lang = 154,
+ eCSSProperty_left = 155,
+ eCSSProperty_letter_spacing = 156,
+ eCSSProperty_lighting_color = 157,
+ eCSSProperty_line_height = 158,
+ eCSSProperty_list_style_image = 159,
+ eCSSProperty_list_style_position = 160,
+ eCSSProperty_list_style_type = 161,
+ eCSSProperty_margin_block_end = 162,
+ eCSSProperty_margin_block_start = 163,
+ eCSSProperty_margin_bottom = 164,
+ eCSSProperty_margin_inline_end = 165,
+ eCSSProperty_margin_inline_start = 166,
+ eCSSProperty_margin_left = 167,
+ eCSSProperty_margin_right = 168,
+ eCSSProperty_margin_top = 169,
+ eCSSProperty_marker_end = 170,
+ eCSSProperty_marker_mid = 171,
+ eCSSProperty_marker_offset = 172,
+ eCSSProperty_marker_start = 173,
+ eCSSProperty_mask = 174,
+ eCSSProperty_mask_type = 175,
+ eCSSProperty_math_display = 176,
+ eCSSProperty_math_variant = 177,
+ eCSSProperty_max_block_size = 178,
+ eCSSProperty_max_height = 179,
+ eCSSProperty_max_inline_size = 180,
+ eCSSProperty_max_width = 181,
+ eCSSProperty_min_block_size = 182,
+ eCSSProperty__moz_min_font_size_ratio = 183,
+ eCSSProperty_min_height = 184,
+ eCSSProperty_min_inline_size = 185,
+ eCSSProperty_min_width = 186,
+ eCSSProperty_mix_blend_mode = 187,
+ eCSSProperty_object_fit = 188,
+ eCSSProperty_object_position = 189,
+ eCSSProperty_offset_block_end = 190,
+ eCSSProperty_offset_block_start = 191,
+ eCSSProperty_offset_inline_end = 192,
+ eCSSProperty_offset_inline_start = 193,
+ eCSSProperty_opacity = 194,
+ eCSSProperty_order = 195,
+ eCSSProperty_orient = 196,
+ eCSSProperty_osx_font_smoothing = 197,
+ eCSSProperty_outline_color = 198,
+ eCSSProperty_outline_offset = 199,
+ eCSSProperty__moz_outline_radius_bottomLeft = 200,
+ eCSSProperty__moz_outline_radius_bottomRight = 201,
+ eCSSProperty__moz_outline_radius_topLeft = 202,
+ eCSSProperty__moz_outline_radius_topRight = 203,
+ eCSSProperty_outline_style = 204,
+ eCSSProperty_outline_width = 205,
+ eCSSProperty_overflow_clip_box = 206,
+ eCSSProperty_overflow_x = 207,
+ eCSSProperty_overflow_y = 208,
+ eCSSProperty_padding_block_end = 209,
+ eCSSProperty_padding_block_start = 210,
+ eCSSProperty_padding_bottom = 211,
+ eCSSProperty_padding_inline_end = 212,
+ eCSSProperty_padding_inline_start = 213,
+ eCSSProperty_padding_left = 214,
+ eCSSProperty_padding_right = 215,
+ eCSSProperty_padding_top = 216,
+ eCSSProperty_page_break_after = 217,
+ eCSSProperty_page_break_before = 218,
+ eCSSProperty_page_break_inside = 219,
+ eCSSProperty_paint_order = 220,
+ eCSSProperty_perspective = 221,
+ eCSSProperty_perspective_origin = 222,
+ eCSSProperty_pointer_events = 223,
+ eCSSProperty_position = 224,
+ eCSSProperty_quotes = 225,
+ eCSSProperty_resize = 226,
+ eCSSProperty_right = 227,
+ eCSSProperty_ruby_align = 228,
+ eCSSProperty_ruby_position = 229,
+ eCSSProperty_script_level = 230,
+ eCSSProperty_script_min_size = 231,
+ eCSSProperty_script_size_multiplier = 232,
+ eCSSProperty_scroll_behavior = 233,
+ eCSSProperty_scroll_snap_coordinate = 234,
+ eCSSProperty_scroll_snap_destination = 235,
+ eCSSProperty_scroll_snap_points_x = 236,
+ eCSSProperty_scroll_snap_points_y = 237,
+ eCSSProperty_scroll_snap_type_x = 238,
+ eCSSProperty_scroll_snap_type_y = 239,
+ eCSSProperty_shape_rendering = 240,
+ eCSSProperty__x_span = 241,
+ eCSSProperty_stack_sizing = 242,
+ eCSSProperty_stop_color = 243,
+ eCSSProperty_stop_opacity = 244,
+ eCSSProperty_stroke = 245,
+ eCSSProperty_stroke_dasharray = 246,
+ eCSSProperty_stroke_dashoffset = 247,
+ eCSSProperty_stroke_linecap = 248,
+ eCSSProperty_stroke_linejoin = 249,
+ eCSSProperty_stroke_miterlimit = 250,
+ eCSSProperty_stroke_opacity = 251,
+ eCSSProperty_stroke_width = 252,
+ eCSSProperty__x_system_font = 253,
+ eCSSProperty__moz_tab_size = 254,
+ eCSSProperty_table_layout = 255,
+ eCSSProperty_text_align = 256,
+ eCSSProperty_text_align_last = 257,
+ eCSSProperty_text_anchor = 258,
+ eCSSProperty_text_combine_upright = 259,
+ eCSSProperty_text_decoration_color = 260,
+ eCSSProperty_text_decoration_line = 261,
+ eCSSProperty_text_decoration_style = 262,
+ eCSSProperty_text_emphasis_color = 263,
+ eCSSProperty_text_emphasis_position = 264,
+ eCSSProperty_text_emphasis_style = 265,
+ eCSSProperty__webkit_text_fill_color = 266,
+ eCSSProperty_text_indent = 267,
+ eCSSProperty_text_orientation = 268,
+ eCSSProperty_text_overflow = 269,
+ eCSSProperty_text_rendering = 270,
+ eCSSProperty_text_shadow = 271,
+ eCSSProperty_text_size_adjust = 272,
+ eCSSProperty__webkit_text_stroke_color = 273,
+ eCSSProperty__webkit_text_stroke_width = 274,
+ eCSSProperty_text_transform = 275,
+ eCSSProperty__x_text_zoom = 276,
+ eCSSProperty_top = 277,
+ eCSSProperty__moz_top_layer = 278,
+ eCSSProperty_touch_action = 279,
+ eCSSProperty_transform = 280,
+ eCSSProperty_transform_box = 281,
+ eCSSProperty_transform_origin = 282,
+ eCSSProperty_transform_style = 283,
+ eCSSProperty_transition_delay = 284,
+ eCSSProperty_transition_duration = 285,
+ eCSSProperty_transition_property = 286,
+ eCSSProperty_transition_timing_function = 287,
+ eCSSProperty_unicode_bidi = 288,
+ eCSSProperty_user_focus = 289,
+ eCSSProperty_user_input = 290,
+ eCSSProperty_user_modify = 291,
+ eCSSProperty_user_select = 292,
+ eCSSProperty_vector_effect = 293,
+ eCSSProperty_vertical_align = 294,
+ eCSSProperty_visibility = 295,
+ eCSSProperty_white_space = 296,
+ eCSSProperty_width = 297,
+ eCSSProperty_will_change = 298,
+ eCSSProperty__moz_window_dragging = 299,
+ eCSSProperty__moz_window_shadow = 300,
+ eCSSProperty_word_break = 301,
+ eCSSProperty_word_spacing = 302,
+ eCSSProperty_overflow_wrap = 303,
+ eCSSProperty_writing_mode = 304,
+ eCSSProperty_z_index = 305,
+ eCSSProperty_COUNT_no_shorthands = 306,
+ eCSSProperty_animation = 307,
+ eCSSProperty_background = 308,
+ eCSSProperty_background_position = 309,
+ eCSSProperty_border = 310,
+ eCSSProperty_border_block_end = 311,
+ eCSSProperty_border_block_start = 312,
+ eCSSProperty_border_bottom = 313,
+ eCSSProperty_border_color = 314,
+ eCSSProperty_border_image = 315,
+ eCSSProperty_border_inline_end = 316,
+ eCSSProperty_border_inline_start = 317,
+ eCSSProperty_border_left = 318,
+ eCSSProperty_border_radius = 319,
+ eCSSProperty_border_right = 320,
+ eCSSProperty_border_style = 321,
+ eCSSProperty_border_top = 322,
+ eCSSProperty_border_width = 323,
+ eCSSProperty__moz_column_rule = 324,
+ eCSSProperty__moz_columns = 325,
+ eCSSProperty_flex = 326,
+ eCSSProperty_flex_flow = 327,
+ eCSSProperty_font = 328,
+ eCSSProperty_font_variant = 329,
+ eCSSProperty_grid = 330,
+ eCSSProperty_grid_area = 331,
+ eCSSProperty_grid_column = 332,
+ eCSSProperty_grid_gap = 333,
+ eCSSProperty_grid_row = 334,
+ eCSSProperty_grid_template = 335,
+ eCSSProperty_list_style = 336,
+ eCSSProperty_margin = 337,
+ eCSSProperty_marker = 338,
+ eCSSProperty_outline = 339,
+ eCSSProperty__moz_outline_radius = 340,
+ eCSSProperty_overflow = 341,
+ eCSSProperty_padding = 342,
+ eCSSProperty_scroll_snap_type = 343,
+ eCSSProperty_text_decoration = 344,
+ eCSSProperty_text_emphasis = 345,
+ eCSSProperty__webkit_text_stroke = 346,
+ eCSSProperty__moz_transform = 347,
+ eCSSProperty_transition = 348,
+ eCSSProperty_COUNT = 349,
+ eCSSPropertyAlias_MozTransformOrigin = 350,
+ eCSSPropertyAlias_MozPerspectiveOrigin = 351,
+ eCSSPropertyAlias_MozPerspective = 352,
+ eCSSPropertyAlias_MozTransformStyle = 353,
+ eCSSPropertyAlias_MozBackfaceVisibility = 354,
+ eCSSPropertyAlias_MozBorderImage = 355,
+ eCSSPropertyAlias_MozTransition = 356,
+ eCSSPropertyAlias_MozTransitionDelay = 357,
+ eCSSPropertyAlias_MozTransitionDuration = 358,
+ eCSSPropertyAlias_MozTransitionProperty = 359,
+ eCSSPropertyAlias_MozTransitionTimingFunction = 360,
+ eCSSPropertyAlias_MozAnimation = 361,
+ eCSSPropertyAlias_MozAnimationDelay = 362,
+ eCSSPropertyAlias_MozAnimationDirection = 363,
+ eCSSPropertyAlias_MozAnimationDuration = 364,
+ eCSSPropertyAlias_MozAnimationFillMode = 365,
+ eCSSPropertyAlias_MozAnimationIterationCount = 366,
+ eCSSPropertyAlias_MozAnimationName = 367,
+ eCSSPropertyAlias_MozAnimationPlayState = 368,
+ eCSSPropertyAlias_MozAnimationTimingFunction = 369,
+ eCSSPropertyAlias_MozBoxSizing = 370,
+ eCSSPropertyAlias_MozFontFeatureSettings = 371,
+ eCSSPropertyAlias_MozFontLanguageOverride = 372,
+ eCSSPropertyAlias_MozPaddingEnd = 373,
+ eCSSPropertyAlias_MozPaddingStart = 374,
+ eCSSPropertyAlias_MozMarginEnd = 375,
+ eCSSPropertyAlias_MozMarginStart = 376,
+ eCSSPropertyAlias_MozBorderEnd = 377,
+ eCSSPropertyAlias_MozBorderEndColor = 378,
+ eCSSPropertyAlias_MozBorderEndStyle = 379,
+ eCSSPropertyAlias_MozBorderEndWidth = 380,
+ eCSSPropertyAlias_MozBorderStart = 381,
+ eCSSPropertyAlias_MozBorderStartColor = 382,
+ eCSSPropertyAlias_MozBorderStartStyle = 383,
+ eCSSPropertyAlias_MozBorderStartWidth = 384,
+ eCSSPropertyAlias_MozHyphens = 385,
+ eCSSPropertyAlias_MozTextAlignLast = 386,
+ eCSSPropertyAlias_WebkitAnimation = 387,
+ eCSSPropertyAlias_WebkitAnimationDelay = 388,
+ eCSSPropertyAlias_WebkitAnimationDirection = 389,
+ eCSSPropertyAlias_WebkitAnimationDuration = 390,
+ eCSSPropertyAlias_WebkitAnimationFillMode = 391,
+ eCSSPropertyAlias_WebkitAnimationIterationCount = 392,
+ eCSSPropertyAlias_WebkitAnimationName = 393,
+ eCSSPropertyAlias_WebkitAnimationPlayState = 394,
+ eCSSPropertyAlias_WebkitAnimationTimingFunction = 395,
+ eCSSPropertyAlias_WebkitFilter = 396,
+ eCSSPropertyAlias_WebkitTextSizeAdjust = 397,
+ eCSSPropertyAlias_WebkitTransform = 398,
+ eCSSPropertyAlias_WebkitTransformOrigin = 399,
+ eCSSPropertyAlias_WebkitTransformStyle = 400,
+ eCSSPropertyAlias_WebkitBackfaceVisibility = 401,
+ eCSSPropertyAlias_WebkitPerspective = 402,
+ eCSSPropertyAlias_WebkitPerspectiveOrigin = 403,
+ eCSSPropertyAlias_WebkitTransition = 404,
+ eCSSPropertyAlias_WebkitTransitionDelay = 405,
+ eCSSPropertyAlias_WebkitTransitionDuration = 406,
+ eCSSPropertyAlias_WebkitTransitionProperty = 407,
+ eCSSPropertyAlias_WebkitTransitionTimingFunction = 408,
+ eCSSPropertyAlias_WebkitBorderRadius = 409,
+ eCSSPropertyAlias_WebkitBorderTopLeftRadius = 410,
+ eCSSPropertyAlias_WebkitBorderTopRightRadius = 411,
+ eCSSPropertyAlias_WebkitBorderBottomLeftRadius = 412,
+ eCSSPropertyAlias_WebkitBorderBottomRightRadius = 413,
+ eCSSPropertyAlias_WebkitBackgroundClip = 414,
+ eCSSPropertyAlias_WebkitBackgroundOrigin = 415,
+ eCSSPropertyAlias_WebkitBackgroundSize = 416,
+ eCSSPropertyAlias_WebkitBorderImage = 417,
+ eCSSPropertyAlias_WebkitBoxShadow = 418,
+ eCSSPropertyAlias_WebkitBoxSizing = 419,
+ eCSSPropertyAlias_WebkitBoxFlex = 420,
+ eCSSPropertyAlias_WebkitBoxOrdinalGroup = 421,
+ eCSSPropertyAlias_WebkitBoxOrient = 422,
+ eCSSPropertyAlias_WebkitBoxDirection = 423,
+ eCSSPropertyAlias_WebkitBoxAlign = 424,
+ eCSSPropertyAlias_WebkitBoxPack = 425,
+ eCSSPropertyAlias_WebkitFlexDirection = 426,
+ eCSSPropertyAlias_WebkitFlexWrap = 427,
+ eCSSPropertyAlias_WebkitFlexFlow = 428,
+ eCSSPropertyAlias_WebkitOrder = 429,
+ eCSSPropertyAlias_WebkitFlex = 430,
+ eCSSPropertyAlias_WebkitFlexGrow = 431,
+ eCSSPropertyAlias_WebkitFlexShrink = 432,
+ eCSSPropertyAlias_WebkitFlexBasis = 433,
+ eCSSPropertyAlias_WebkitJustifyContent = 434,
+ eCSSPropertyAlias_WebkitAlignItems = 435,
+ eCSSPropertyAlias_WebkitAlignSelf = 436,
+ eCSSPropertyAlias_WebkitAlignContent = 437,
+ eCSSPropertyAlias_WebkitUserSelect = 438,
+ eCSSProperty_COUNT_with_aliases = 439,
+ eCSSPropertyExtra_all_properties = 440,
+ eCSSPropertyExtra_x_none_value = 441,
+ eCSSPropertyExtra_x_auto_value = 442,
+ eCSSPropertyExtra_variable = 443,
}
#[repr(i32)]
#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)]
@@ -5145,11 +5150,24 @@ pub type nsStyleUnion = nsStyleCoord_h_unnamed_18;
* the unit is a must before asking for the value in any particular
* form.
*/
+ /** <div rustbindgen private accessor="unsafe"></div> */
#[repr(C)]
#[derive(Debug)]
pub struct nsStyleCoord {
- pub mUnit: nsStyleUnit,
- pub mValue: nsStyleUnion,
+ mUnit: nsStyleUnit,
+ mValue: nsStyleUnion,
+}
+impl nsStyleCoord {
+ #[inline]
+ pub unsafe fn get_mUnit(&self) -> &nsStyleUnit { &self.mUnit }
+ pub unsafe fn get_mUnit_mut(&mut self) -> &mut nsStyleUnit {
+ &mut self.mUnit
+ }
+ #[inline]
+ pub unsafe fn get_mValue(&self) -> &nsStyleUnion { &self.mValue }
+ pub unsafe fn get_mValue_mut(&mut self) -> &mut nsStyleUnion {
+ &mut self.mValue
+ }
}
#[repr(C)]
#[derive(Debug, Copy)]
@@ -5190,11 +5208,26 @@ fn bindgen_test_layout_nsStyleCoord() {
* This is commonly used to hold the widths of the borders, margins,
* or paddings of a box.
*/
+ /** <div rustbindgen private accessor="unsafe"></div> */
#[repr(C)]
#[derive(Debug)]
pub struct nsStyleSides {
- pub mUnits: [nsStyleUnit; 4usize],
- pub mValues: [nsStyleUnion; 4usize],
+ mUnits: [nsStyleUnit; 4usize],
+ mValues: [nsStyleUnion; 4usize],
+}
+impl nsStyleSides {
+ #[inline]
+ pub unsafe fn get_mUnits(&self) -> &[nsStyleUnit; 4usize] { &self.mUnits }
+ pub unsafe fn get_mUnits_mut(&mut self) -> &mut [nsStyleUnit; 4usize] {
+ &mut self.mUnits
+ }
+ #[inline]
+ pub unsafe fn get_mValues(&self) -> &[nsStyleUnion; 4usize] {
+ &self.mValues
+ }
+ pub unsafe fn get_mValues_mut(&mut self) -> &mut [nsStyleUnion; 4usize] {
+ &mut self.mValues
+ }
}
#[test]
fn bindgen_test_layout_nsStyleSides() {
@@ -5206,11 +5239,26 @@ fn bindgen_test_layout_nsStyleSides() {
* nsStyleCoord pairs. This is used to hold the dimensions of the
* corners of a box (for, e.g., border-radius and outline-radius).
*/
+ /** <div rustbindgen private accessor="unsafe"></div> */
#[repr(C)]
#[derive(Debug)]
pub struct nsStyleCorners {
- pub mUnits: [nsStyleUnit; 8usize],
- pub mValues: [nsStyleUnion; 8usize],
+ mUnits: [nsStyleUnit; 8usize],
+ mValues: [nsStyleUnion; 8usize],
+}
+impl nsStyleCorners {
+ #[inline]
+ pub unsafe fn get_mUnits(&self) -> &[nsStyleUnit; 8usize] { &self.mUnits }
+ pub unsafe fn get_mUnits_mut(&mut self) -> &mut [nsStyleUnit; 8usize] {
+ &mut self.mUnits
+ }
+ #[inline]
+ pub unsafe fn get_mValues(&self) -> &[nsStyleUnion; 8usize] {
+ &self.mValues
+ }
+ pub unsafe fn get_mValues_mut(&mut self) -> &mut [nsStyleUnion; 8usize] {
+ &mut self.mValues
+ }
}
#[test]
fn bindgen_test_layout_nsStyleCorners() {
@@ -5598,7 +5646,7 @@ pub struct nsStyleBorder {
pub mBorderImageFill: u8,
pub mBorderImageRepeatH: u8,
pub mBorderImageRepeatV: u8,
- pub mFloatEdge: u8,
+ pub mFloatEdge: StyleFloatEdge,
pub mBoxDecorationBreak: u8,
pub mComputedBorder: nsMargin,
pub mBorder: nsMargin,
@@ -5773,12 +5821,14 @@ pub struct nsStyleTextReset {
pub mTextOverflow: nsStyleTextOverflow,
pub mTextDecorationLine: u8,
pub mUnicodeBidi: u8,
+ pub mInitialLetterSink: nscoord,
+ pub mInitialLetterSize: f32,
pub mTextDecorationStyle: u8,
pub mTextDecorationColor: nscolor,
}
#[test]
fn bindgen_test_layout_nsStyleTextReset() {
- assert_eq!(::std::mem::size_of::<nsStyleTextReset>() , 64usize);
+ assert_eq!(::std::mem::size_of::<nsStyleTextReset>() , 80usize);
assert_eq!(::std::mem::align_of::<nsStyleTextReset>() , 8usize);
}
#[repr(C)]
@@ -5881,14 +5931,6 @@ pub enum nsTimingFunction_Type {
}
#[repr(i32)]
#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)]
-pub enum nsTimingFunction_StepSyntax {
- Keyword = 0,
- FunctionalWithoutKeyword = 1,
- FunctionalWithStartKeyword = 2,
- FunctionalWithEndKeyword = 3,
-}
-#[repr(i32)]
-#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)]
pub enum nsTimingFunction_Keyword { Implicit = 0, Explicit = 1, }
#[repr(C)]
#[derive(Debug, Copy)]
@@ -5930,7 +5972,6 @@ fn bindgen_test_layout_nsTimingFunction_nsStyleStruct_h_unnamed_23_nsStyleStruct
#[repr(C)]
#[derive(Debug, Copy)]
pub struct nsTimingFunction_nsStyleStruct_h_unnamed_23_nsStyleStruct_h_unnamed_25 {
- pub mStepSyntax: nsTimingFunction_StepSyntax,
pub mSteps: u32,
}
impl ::std::clone::Clone for
@@ -5940,7 +5981,7 @@ impl ::std::clone::Clone for
#[test]
fn bindgen_test_layout_nsTimingFunction_nsStyleStruct_h_unnamed_23_nsStyleStruct_h_unnamed_25() {
assert_eq!(::std::mem::size_of::<nsTimingFunction_nsStyleStruct_h_unnamed_23_nsStyleStruct_h_unnamed_25>()
- , 8usize);
+ , 4usize);
assert_eq!(::std::mem::align_of::<nsTimingFunction_nsStyleStruct_h_unnamed_23_nsStyleStruct_h_unnamed_25>()
, 4usize);
}
@@ -6171,7 +6212,7 @@ fn bindgen_test_layout_nsCursorImage() {
pub struct nsStyleUserInterface {
pub mUserInput: u8,
pub mUserModify: u8,
- pub mUserFocus: u8,
+ pub mUserFocus: StyleUserFocus,
pub mPointerEvents: u8,
pub mCursor: u8,
pub mCursorArrayLength: u32,
@@ -6334,9 +6375,9 @@ fn bindgen_test_layout_nsStyleBasicShape() {
#[repr(C)]
#[derive(Debug)]
pub struct nsStyleClipPath {
- pub mType: i32,
pub nsStyleClipPath_nsStyleStruct_h_unnamed_29: nsStyleClipPath_nsStyleStruct_h_unnamed_29,
- pub mSizingBox: u8,
+ pub mType: StyleClipPathType,
+ pub mSizingBox: StyleClipShapeSizing,
}
#[repr(C)]
#[derive(Debug, Copy)]
@@ -6358,7 +6399,7 @@ fn bindgen_test_layout_nsStyleClipPath_nsStyleStruct_h_unnamed_29() {
}
#[test]
fn bindgen_test_layout_nsStyleClipPath() {
- assert_eq!(::std::mem::size_of::<nsStyleClipPath>() , 24usize);
+ assert_eq!(::std::mem::size_of::<nsStyleClipPath>() , 16usize);
assert_eq!(::std::mem::align_of::<nsStyleClipPath>() , 8usize);
}
#[repr(C)]
@@ -6406,7 +6447,7 @@ pub struct nsStyleSVGReset {
}
#[test]
fn bindgen_test_layout_nsStyleSVGReset() {
- assert_eq!(::std::mem::size_of::<nsStyleSVGReset>() , 216usize);
+ assert_eq!(::std::mem::size_of::<nsStyleSVGReset>() , 208usize);
assert_eq!(::std::mem::align_of::<nsStyleSVGReset>() , 8usize);
}
#[repr(C)]
diff --git a/ports/geckolib/gecko_bindings/structs_release.rs b/ports/geckolib/gecko_bindings/structs_release.rs
index 75b061eb9bb..418b428cc16 100644
--- a/ports/geckolib/gecko_bindings/structs_release.rs
+++ b/ports/geckolib/gecko_bindings/structs_release.rs
@@ -188,12 +188,6 @@ pub const NS_ERROR_MODULE_BASE_OFFSET: ::std::os::raw::c_uint = 69;
pub const MOZ_STRING_WITH_OBSOLETE_API: ::std::os::raw::c_uint = 1;
pub const NSID_LENGTH: ::std::os::raw::c_uint = 39;
pub const NS_NUMBER_OF_FLAGS_IN_REFCNT: ::std::os::raw::c_uint = 2;
-pub const _STL_PAIR_H: ::std::os::raw::c_uint = 1;
-pub const _GLIBCXX_UTILITY: ::std::os::raw::c_uint = 1;
-pub const __cpp_lib_tuple_element_t: ::std::os::raw::c_uint = 201402;
-pub const __cpp_lib_tuples_by_type: ::std::os::raw::c_uint = 201304;
-pub const __cpp_lib_exchange_function: ::std::os::raw::c_uint = 201304;
-pub const __cpp_lib_integer_sequence: ::std::os::raw::c_uint = 201304;
pub const NS_EVENT_STATE_HIGHEST_SERVO_BIT: ::std::os::raw::c_uint = 6;
pub const DOM_USER_DATA: ::std::os::raw::c_uint = 1;
pub const SMIL_MAPPED_ATTR_ANIMVAL: ::std::os::raw::c_uint = 2;
@@ -212,29 +206,6 @@ pub const NS_CORNER_BOTTOM_RIGHT_X: ::std::os::raw::c_uint = 4;
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_STYLE_CLIP_SHAPE_SIZING_NOBOX: ::std::os::raw::c_uint = 0;
-pub const NS_STYLE_CLIP_SHAPE_SIZING_CONTENT: ::std::os::raw::c_uint = 1;
-pub const NS_STYLE_CLIP_SHAPE_SIZING_PADDING: ::std::os::raw::c_uint = 2;
-pub const NS_STYLE_CLIP_SHAPE_SIZING_BORDER: ::std::os::raw::c_uint = 3;
-pub const NS_STYLE_CLIP_SHAPE_SIZING_MARGIN: ::std::os::raw::c_uint = 4;
-pub const NS_STYLE_CLIP_SHAPE_SIZING_FILL: ::std::os::raw::c_uint = 5;
-pub const NS_STYLE_CLIP_SHAPE_SIZING_STROKE: ::std::os::raw::c_uint = 6;
-pub const NS_STYLE_CLIP_SHAPE_SIZING_VIEW: ::std::os::raw::c_uint = 7;
-pub const NS_STYLE_BASIC_SHAPE_POLYGON: ::std::os::raw::c_uint = 0;
-pub const NS_STYLE_BASIC_SHAPE_CIRCLE: ::std::os::raw::c_uint = 1;
-pub const NS_STYLE_BASIC_SHAPE_ELLIPSE: ::std::os::raw::c_uint = 2;
-pub const NS_STYLE_BASIC_SHAPE_INSET: ::std::os::raw::c_uint = 3;
-pub const NS_STYLE_BOX_SHADOW_INSET: ::std::os::raw::c_uint = 0;
-pub const NS_STYLE_FLOAT_EDGE_CONTENT_BOX: ::std::os::raw::c_uint = 0;
-pub const NS_STYLE_FLOAT_EDGE_MARGIN_BOX: ::std::os::raw::c_uint = 1;
-pub const NS_STYLE_USER_FOCUS_NONE: ::std::os::raw::c_uint = 0;
-pub const NS_STYLE_USER_FOCUS_IGNORE: ::std::os::raw::c_uint = 1;
-pub const NS_STYLE_USER_FOCUS_NORMAL: ::std::os::raw::c_uint = 2;
-pub const NS_STYLE_USER_FOCUS_SELECT_ALL: ::std::os::raw::c_uint = 3;
-pub const NS_STYLE_USER_FOCUS_SELECT_BEFORE: ::std::os::raw::c_uint = 4;
-pub const NS_STYLE_USER_FOCUS_SELECT_AFTER: ::std::os::raw::c_uint = 5;
-pub const NS_STYLE_USER_FOCUS_SELECT_SAME: ::std::os::raw::c_uint = 6;
-pub const NS_STYLE_USER_FOCUS_SELECT_MENU: ::std::os::raw::c_uint = 7;
pub const NS_STYLE_USER_SELECT_NONE: ::std::os::raw::c_uint = 0;
pub const NS_STYLE_USER_SELECT_TEXT: ::std::os::raw::c_uint = 1;
pub const NS_STYLE_USER_SELECT_ELEMENT: ::std::os::raw::c_uint = 2;
@@ -376,6 +347,7 @@ pub const NS_STYLE_BORDER_STYLE_AUTO: ::std::os::raw::c_uint = 10;
pub const NS_STYLE_BORDER_IMAGE_REPEAT_STRETCH: ::std::os::raw::c_uint = 0;
pub const NS_STYLE_BORDER_IMAGE_REPEAT_REPEAT: ::std::os::raw::c_uint = 1;
pub const NS_STYLE_BORDER_IMAGE_REPEAT_ROUND: ::std::os::raw::c_uint = 2;
+pub const NS_STYLE_BORDER_IMAGE_REPEAT_SPACE: ::std::os::raw::c_uint = 3;
pub const NS_STYLE_BORDER_IMAGE_SLICE_NOFILL: ::std::os::raw::c_uint = 0;
pub const NS_STYLE_BORDER_IMAGE_SLICE_FILL: ::std::os::raw::c_uint = 1;
pub const NS_STYLE_CLEAR_NONE: ::std::os::raw::c_uint = 0;
@@ -511,10 +483,6 @@ pub const NS_STYLE_FLOAT_LEFT: ::std::os::raw::c_uint = 1;
pub const NS_STYLE_FLOAT_RIGHT: ::std::os::raw::c_uint = 2;
pub const NS_STYLE_FLOAT_INLINE_START: ::std::os::raw::c_uint = 3;
pub const NS_STYLE_FLOAT_INLINE_END: ::std::os::raw::c_uint = 4;
-pub const NS_STYLE_CLIP_PATH_NONE: ::std::os::raw::c_uint = 0;
-pub const NS_STYLE_CLIP_PATH_URL: ::std::os::raw::c_uint = 1;
-pub const NS_STYLE_CLIP_PATH_SHAPE: ::std::os::raw::c_uint = 2;
-pub const NS_STYLE_CLIP_PATH_BOX: ::std::os::raw::c_uint = 3;
pub const NS_STYLE_FILTER_NONE: ::std::os::raw::c_uint = 0;
pub const NS_STYLE_FILTER_URL: ::std::os::raw::c_uint = 1;
pub const NS_STYLE_FILTER_BLUR: ::std::os::raw::c_uint = 2;
@@ -1924,6 +1892,34 @@ fn bindgen_test_layout_NS_ConvertUTF8toUTF16() {
assert_eq!(::std::mem::align_of::<NS_ConvertUTF8toUTF16>() , 8usize);
}
pub type nsVoidableString = nsAutoString;
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct RefPtrTraits<U> {
+ pub _phantom0: ::std::marker::PhantomData<U>,
+}
+#[repr(C)]
+#[derive(Debug)]
+pub struct RefPtr<T> {
+ pub mRawPtr: *mut T,
+}
+#[repr(C)]
+#[derive(Debug)]
+pub struct RefPtr_Proxy<T, R, Args> {
+ pub mRawPtr: *mut T,
+ pub _phantom0: ::std::marker::PhantomData<R>,
+ pub _phantom1: ::std::marker::PhantomData<Args>,
+}
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct RefPtr_ConstRemovingRefPtrTraits<T, U> {
+ pub _phantom0: ::std::marker::PhantomData<T>,
+ pub _phantom1: ::std::marker::PhantomData<U>,
+}
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct RefPtrGetterAddRefs<T> {
+ pub mTargetSmartPtr: *mut RefPtr<T>,
+}
/**
* A "unique identifier". This is modeled after OSF DCE UUIDs.
*/
@@ -2080,34 +2076,6 @@ fn bindgen_test_layout_QITableEntry() {
assert_eq!(::std::mem::size_of::<QITableEntry>() , 16usize);
assert_eq!(::std::mem::align_of::<QITableEntry>() , 8usize);
}
-#[repr(C)]
-#[derive(Debug, Copy, Clone)]
-pub struct RefPtrTraits<U> {
- pub _phantom0: ::std::marker::PhantomData<U>,
-}
-#[repr(C)]
-#[derive(Debug)]
-pub struct RefPtr<T> {
- pub mRawPtr: *mut T,
-}
-#[repr(C)]
-#[derive(Debug)]
-pub struct RefPtr_Proxy<T, R, Args> {
- pub mRawPtr: *mut T,
- pub _phantom0: ::std::marker::PhantomData<R>,
- pub _phantom1: ::std::marker::PhantomData<Args>,
-}
-#[repr(C)]
-#[derive(Debug, Copy, Clone)]
-pub struct RefPtr_ConstRemovingRefPtrTraits<T, U> {
- pub _phantom0: ::std::marker::PhantomData<T>,
- pub _phantom1: ::std::marker::PhantomData<U>,
-}
-#[repr(C)]
-#[derive(Debug, Copy, Clone)]
-pub struct RefPtrGetterAddRefs<T> {
- pub mTargetSmartPtr: *mut RefPtr<T>,
-}
pub enum TileClient { }
#[repr(C)]
#[derive(Debug, Copy)]
@@ -2714,12 +2682,6 @@ impl ::std::clone::Clone for nsIExpandedPrincipal {
fn clone(&self) -> Self { *self }
}
#[repr(C)]
-#[derive(Debug, Copy, Clone)]
-pub struct _Make_integer_sequence<_Tp, _ISeq> {
- pub _phantom0: ::std::marker::PhantomData<_Tp>,
- pub _phantom1: ::std::marker::PhantomData<_ISeq>,
-}
-#[repr(C)]
#[derive(Debug, Copy)]
pub struct nsIURI {
pub _base: nsISupports,
@@ -2771,7 +2733,7 @@ impl ::std::clone::Clone for nsIRequest {
#[repr(C)]
#[derive(Debug, Copy)]
pub struct EventStates {
- pub mStates: ::std::os::raw::c_ulong,
+ pub mStates: ::std::os::raw::c_ulonglong,
}
impl ::std::clone::Clone for EventStates {
fn clone(&self) -> Self { *self }
@@ -2835,6 +2797,11 @@ pub enum nsNodeSupportsWeakRefTearoff { }
pub enum nsNodeWeakReference { }
pub enum nsDOMMutationObserver { }
pub enum ServoNodeData { }
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct DefaultDelete<> {
+ pub _phantom0: ::std::marker::PhantomData<ServoNodeData>,
+}
pub enum EventListenerManager { }
pub enum BoxQuadOptions { }
pub enum ConvertCoordinateOptions { }
@@ -2901,7 +2868,7 @@ fn bindgen_test_layout_nsMutationGuard() {
extern "C" {
#[link_name = "_ZN15nsMutationGuard11sGenerationE"]
pub static mut nsMutationGuard_consts_sGeneration:
- ::std::os::raw::c_ulong;
+ ::std::os::raw::c_ulonglong;
}
pub type Float = f32;
#[repr(i8)]
@@ -3001,6 +2968,7 @@ pub enum FontType {
SKIA = 3,
CAIRO = 4,
COREGRAPHICS = 5,
+ FONTCONFIG = 6,
}
#[repr(i8)]
#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)]
@@ -3897,7 +3865,43 @@ fn bindgen_test_layout_nsFont() {
}
#[repr(i8)]
#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)]
+pub enum StyleBasicShape { Polygon = 0, Circle = 1, Ellipse = 2, Inset = 3, }
+#[repr(i8)]
+#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)]
pub enum StyleBoxSizing { Content = 0, Border = 1, }
+#[repr(i8)]
+#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)]
+pub enum StyleBoxShadowType { Inset = 0, }
+#[repr(i8)]
+#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)]
+pub enum StyleClipPathType { None_ = 0, URL = 1, Shape = 2, Box = 3, }
+#[repr(i8)]
+#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)]
+pub enum StyleClipShapeSizing {
+ NoBox = 0,
+ Content = 1,
+ Padding = 2,
+ Border = 3,
+ Margin = 4,
+ Fill = 5,
+ Stroke = 6,
+ View = 7,
+}
+#[repr(i8)]
+#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)]
+pub enum StyleFloatEdge { ContentBox = 0, MarginBox = 1, }
+#[repr(i8)]
+#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)]
+pub enum StyleUserFocus {
+ None_ = 0,
+ Ignore = 1,
+ Normal = 2,
+ SelectAll = 3,
+ SelectBefore = 4,
+ SelectAfter = 5,
+ SelectSame = 6,
+ SelectMenu = 7,
+}
pub const eCSSProperty_COUNT_DUMMY: nsCSSProperty =
nsCSSProperty::eCSSProperty_z_index;
pub const eCSSProperty_all: nsCSSProperty =
@@ -4058,305 +4062,306 @@ pub enum nsCSSProperty {
eCSSProperty_grid_template_rows = 141,
eCSSProperty_height = 142,
eCSSProperty_hyphens = 143,
- eCSSProperty_image_orientation = 144,
- eCSSProperty_image_region = 145,
- eCSSProperty_image_rendering = 146,
- eCSSProperty_ime_mode = 147,
- eCSSProperty_inline_size = 148,
- eCSSProperty_isolation = 149,
- eCSSProperty_justify_content = 150,
- eCSSProperty_justify_items = 151,
- eCSSProperty_justify_self = 152,
- eCSSProperty__x_lang = 153,
- eCSSProperty_left = 154,
- eCSSProperty_letter_spacing = 155,
- eCSSProperty_lighting_color = 156,
- eCSSProperty_line_height = 157,
- eCSSProperty_list_style_image = 158,
- eCSSProperty_list_style_position = 159,
- eCSSProperty_list_style_type = 160,
- eCSSProperty_margin_block_end = 161,
- eCSSProperty_margin_block_start = 162,
- eCSSProperty_margin_bottom = 163,
- eCSSProperty_margin_inline_end = 164,
- eCSSProperty_margin_inline_start = 165,
- eCSSProperty_margin_left = 166,
- eCSSProperty_margin_right = 167,
- eCSSProperty_margin_top = 168,
- eCSSProperty_marker_end = 169,
- eCSSProperty_marker_mid = 170,
- eCSSProperty_marker_offset = 171,
- eCSSProperty_marker_start = 172,
- eCSSProperty_mask = 173,
- eCSSProperty_mask_type = 174,
- eCSSProperty_math_display = 175,
- eCSSProperty_math_variant = 176,
- eCSSProperty_max_block_size = 177,
- eCSSProperty_max_height = 178,
- eCSSProperty_max_inline_size = 179,
- eCSSProperty_max_width = 180,
- eCSSProperty_min_block_size = 181,
- eCSSProperty__moz_min_font_size_ratio = 182,
- eCSSProperty_min_height = 183,
- eCSSProperty_min_inline_size = 184,
- eCSSProperty_min_width = 185,
- eCSSProperty_mix_blend_mode = 186,
- eCSSProperty_object_fit = 187,
- eCSSProperty_object_position = 188,
- eCSSProperty_offset_block_end = 189,
- eCSSProperty_offset_block_start = 190,
- eCSSProperty_offset_inline_end = 191,
- eCSSProperty_offset_inline_start = 192,
- eCSSProperty_opacity = 193,
- eCSSProperty_order = 194,
- eCSSProperty_orient = 195,
- eCSSProperty_osx_font_smoothing = 196,
- eCSSProperty_outline_color = 197,
- eCSSProperty_outline_offset = 198,
- eCSSProperty__moz_outline_radius_bottomLeft = 199,
- eCSSProperty__moz_outline_radius_bottomRight = 200,
- eCSSProperty__moz_outline_radius_topLeft = 201,
- eCSSProperty__moz_outline_radius_topRight = 202,
- eCSSProperty_outline_style = 203,
- eCSSProperty_outline_width = 204,
- eCSSProperty_overflow_clip_box = 205,
- eCSSProperty_overflow_x = 206,
- eCSSProperty_overflow_y = 207,
- eCSSProperty_padding_block_end = 208,
- eCSSProperty_padding_block_start = 209,
- eCSSProperty_padding_bottom = 210,
- eCSSProperty_padding_inline_end = 211,
- eCSSProperty_padding_inline_start = 212,
- eCSSProperty_padding_left = 213,
- eCSSProperty_padding_right = 214,
- eCSSProperty_padding_top = 215,
- eCSSProperty_page_break_after = 216,
- eCSSProperty_page_break_before = 217,
- eCSSProperty_page_break_inside = 218,
- eCSSProperty_paint_order = 219,
- eCSSProperty_perspective = 220,
- eCSSProperty_perspective_origin = 221,
- eCSSProperty_pointer_events = 222,
- eCSSProperty_position = 223,
- eCSSProperty_quotes = 224,
- eCSSProperty_resize = 225,
- eCSSProperty_right = 226,
- eCSSProperty_ruby_align = 227,
- eCSSProperty_ruby_position = 228,
- eCSSProperty_script_level = 229,
- eCSSProperty_script_min_size = 230,
- eCSSProperty_script_size_multiplier = 231,
- eCSSProperty_scroll_behavior = 232,
- eCSSProperty_scroll_snap_coordinate = 233,
- eCSSProperty_scroll_snap_destination = 234,
- eCSSProperty_scroll_snap_points_x = 235,
- eCSSProperty_scroll_snap_points_y = 236,
- eCSSProperty_scroll_snap_type_x = 237,
- eCSSProperty_scroll_snap_type_y = 238,
- eCSSProperty_shape_rendering = 239,
- eCSSProperty__x_span = 240,
- eCSSProperty_stack_sizing = 241,
- eCSSProperty_stop_color = 242,
- eCSSProperty_stop_opacity = 243,
- eCSSProperty_stroke = 244,
- eCSSProperty_stroke_dasharray = 245,
- eCSSProperty_stroke_dashoffset = 246,
- eCSSProperty_stroke_linecap = 247,
- eCSSProperty_stroke_linejoin = 248,
- eCSSProperty_stroke_miterlimit = 249,
- eCSSProperty_stroke_opacity = 250,
- eCSSProperty_stroke_width = 251,
- eCSSProperty__x_system_font = 252,
- eCSSProperty__moz_tab_size = 253,
- eCSSProperty_table_layout = 254,
- eCSSProperty_text_align = 255,
- eCSSProperty_text_align_last = 256,
- eCSSProperty_text_anchor = 257,
- eCSSProperty_text_combine_upright = 258,
- eCSSProperty_text_decoration_color = 259,
- eCSSProperty_text_decoration_line = 260,
- eCSSProperty_text_decoration_style = 261,
- eCSSProperty_text_emphasis_color = 262,
- eCSSProperty_text_emphasis_position = 263,
- eCSSProperty_text_emphasis_style = 264,
- eCSSProperty__webkit_text_fill_color = 265,
- eCSSProperty_text_indent = 266,
- eCSSProperty_text_orientation = 267,
- eCSSProperty_text_overflow = 268,
- eCSSProperty_text_rendering = 269,
- eCSSProperty_text_shadow = 270,
- eCSSProperty_text_size_adjust = 271,
- eCSSProperty__webkit_text_stroke_color = 272,
- eCSSProperty__webkit_text_stroke_width = 273,
- eCSSProperty_text_transform = 274,
- eCSSProperty__x_text_zoom = 275,
- eCSSProperty_top = 276,
- eCSSProperty__moz_top_layer = 277,
- eCSSProperty_touch_action = 278,
- eCSSProperty_transform = 279,
- eCSSProperty_transform_box = 280,
- eCSSProperty_transform_origin = 281,
- eCSSProperty_transform_style = 282,
- eCSSProperty_transition_delay = 283,
- eCSSProperty_transition_duration = 284,
- eCSSProperty_transition_property = 285,
- eCSSProperty_transition_timing_function = 286,
- eCSSProperty_unicode_bidi = 287,
- eCSSProperty_user_focus = 288,
- eCSSProperty_user_input = 289,
- eCSSProperty_user_modify = 290,
- eCSSProperty_user_select = 291,
- eCSSProperty_vector_effect = 292,
- eCSSProperty_vertical_align = 293,
- eCSSProperty_visibility = 294,
- eCSSProperty_white_space = 295,
- eCSSProperty_width = 296,
- eCSSProperty_will_change = 297,
- eCSSProperty__moz_window_dragging = 298,
- eCSSProperty__moz_window_shadow = 299,
- eCSSProperty_word_break = 300,
- eCSSProperty_word_spacing = 301,
- eCSSProperty_overflow_wrap = 302,
- eCSSProperty_writing_mode = 303,
- eCSSProperty_z_index = 304,
- eCSSProperty_COUNT_no_shorthands = 305,
- eCSSProperty_animation = 306,
- eCSSProperty_background = 307,
- eCSSProperty_background_position = 308,
- eCSSProperty_border = 309,
- eCSSProperty_border_block_end = 310,
- eCSSProperty_border_block_start = 311,
- eCSSProperty_border_bottom = 312,
- eCSSProperty_border_color = 313,
- eCSSProperty_border_image = 314,
- eCSSProperty_border_inline_end = 315,
- eCSSProperty_border_inline_start = 316,
- eCSSProperty_border_left = 317,
- eCSSProperty_border_radius = 318,
- eCSSProperty_border_right = 319,
- eCSSProperty_border_style = 320,
- eCSSProperty_border_top = 321,
- eCSSProperty_border_width = 322,
- eCSSProperty__moz_column_rule = 323,
- eCSSProperty__moz_columns = 324,
- eCSSProperty_flex = 325,
- eCSSProperty_flex_flow = 326,
- eCSSProperty_font = 327,
- eCSSProperty_font_variant = 328,
- eCSSProperty_grid = 329,
- eCSSProperty_grid_area = 330,
- eCSSProperty_grid_column = 331,
- eCSSProperty_grid_gap = 332,
- eCSSProperty_grid_row = 333,
- eCSSProperty_grid_template = 334,
- eCSSProperty_list_style = 335,
- eCSSProperty_margin = 336,
- eCSSProperty_marker = 337,
- eCSSProperty_outline = 338,
- eCSSProperty__moz_outline_radius = 339,
- eCSSProperty_overflow = 340,
- eCSSProperty_padding = 341,
- eCSSProperty_scroll_snap_type = 342,
- eCSSProperty_text_decoration = 343,
- eCSSProperty_text_emphasis = 344,
- eCSSProperty__webkit_text_stroke = 345,
- eCSSProperty__moz_transform = 346,
- eCSSProperty_transition = 347,
- eCSSProperty_COUNT = 348,
- eCSSPropertyAlias_MozTransformOrigin = 349,
- eCSSPropertyAlias_MozPerspectiveOrigin = 350,
- eCSSPropertyAlias_MozPerspective = 351,
- eCSSPropertyAlias_MozTransformStyle = 352,
- eCSSPropertyAlias_MozBackfaceVisibility = 353,
- eCSSPropertyAlias_MozBorderImage = 354,
- eCSSPropertyAlias_MozTransition = 355,
- eCSSPropertyAlias_MozTransitionDelay = 356,
- eCSSPropertyAlias_MozTransitionDuration = 357,
- eCSSPropertyAlias_MozTransitionProperty = 358,
- eCSSPropertyAlias_MozTransitionTimingFunction = 359,
- eCSSPropertyAlias_MozAnimation = 360,
- eCSSPropertyAlias_MozAnimationDelay = 361,
- eCSSPropertyAlias_MozAnimationDirection = 362,
- eCSSPropertyAlias_MozAnimationDuration = 363,
- eCSSPropertyAlias_MozAnimationFillMode = 364,
- eCSSPropertyAlias_MozAnimationIterationCount = 365,
- eCSSPropertyAlias_MozAnimationName = 366,
- eCSSPropertyAlias_MozAnimationPlayState = 367,
- eCSSPropertyAlias_MozAnimationTimingFunction = 368,
- eCSSPropertyAlias_MozBoxSizing = 369,
- eCSSPropertyAlias_MozFontFeatureSettings = 370,
- eCSSPropertyAlias_MozFontLanguageOverride = 371,
- eCSSPropertyAlias_MozPaddingEnd = 372,
- eCSSPropertyAlias_MozPaddingStart = 373,
- eCSSPropertyAlias_MozMarginEnd = 374,
- eCSSPropertyAlias_MozMarginStart = 375,
- eCSSPropertyAlias_MozBorderEnd = 376,
- eCSSPropertyAlias_MozBorderEndColor = 377,
- eCSSPropertyAlias_MozBorderEndStyle = 378,
- eCSSPropertyAlias_MozBorderEndWidth = 379,
- eCSSPropertyAlias_MozBorderStart = 380,
- eCSSPropertyAlias_MozBorderStartColor = 381,
- eCSSPropertyAlias_MozBorderStartStyle = 382,
- eCSSPropertyAlias_MozBorderStartWidth = 383,
- eCSSPropertyAlias_MozHyphens = 384,
- eCSSPropertyAlias_MozTextAlignLast = 385,
- eCSSPropertyAlias_WebkitAnimation = 386,
- eCSSPropertyAlias_WebkitAnimationDelay = 387,
- eCSSPropertyAlias_WebkitAnimationDirection = 388,
- eCSSPropertyAlias_WebkitAnimationDuration = 389,
- eCSSPropertyAlias_WebkitAnimationFillMode = 390,
- eCSSPropertyAlias_WebkitAnimationIterationCount = 391,
- eCSSPropertyAlias_WebkitAnimationName = 392,
- eCSSPropertyAlias_WebkitAnimationPlayState = 393,
- eCSSPropertyAlias_WebkitAnimationTimingFunction = 394,
- eCSSPropertyAlias_WebkitFilter = 395,
- eCSSPropertyAlias_WebkitTextSizeAdjust = 396,
- eCSSPropertyAlias_WebkitTransform = 397,
- eCSSPropertyAlias_WebkitTransformOrigin = 398,
- eCSSPropertyAlias_WebkitTransformStyle = 399,
- eCSSPropertyAlias_WebkitBackfaceVisibility = 400,
- eCSSPropertyAlias_WebkitPerspective = 401,
- eCSSPropertyAlias_WebkitPerspectiveOrigin = 402,
- eCSSPropertyAlias_WebkitTransition = 403,
- eCSSPropertyAlias_WebkitTransitionDelay = 404,
- eCSSPropertyAlias_WebkitTransitionDuration = 405,
- eCSSPropertyAlias_WebkitTransitionProperty = 406,
- eCSSPropertyAlias_WebkitTransitionTimingFunction = 407,
- eCSSPropertyAlias_WebkitBorderRadius = 408,
- eCSSPropertyAlias_WebkitBorderTopLeftRadius = 409,
- eCSSPropertyAlias_WebkitBorderTopRightRadius = 410,
- eCSSPropertyAlias_WebkitBorderBottomLeftRadius = 411,
- eCSSPropertyAlias_WebkitBorderBottomRightRadius = 412,
- eCSSPropertyAlias_WebkitBackgroundClip = 413,
- eCSSPropertyAlias_WebkitBackgroundOrigin = 414,
- eCSSPropertyAlias_WebkitBackgroundSize = 415,
- eCSSPropertyAlias_WebkitBorderImage = 416,
- eCSSPropertyAlias_WebkitBoxShadow = 417,
- eCSSPropertyAlias_WebkitBoxSizing = 418,
- eCSSPropertyAlias_WebkitBoxFlex = 419,
- eCSSPropertyAlias_WebkitBoxOrdinalGroup = 420,
- eCSSPropertyAlias_WebkitBoxOrient = 421,
- eCSSPropertyAlias_WebkitBoxDirection = 422,
- eCSSPropertyAlias_WebkitBoxAlign = 423,
- eCSSPropertyAlias_WebkitBoxPack = 424,
- eCSSPropertyAlias_WebkitFlexDirection = 425,
- eCSSPropertyAlias_WebkitFlexWrap = 426,
- eCSSPropertyAlias_WebkitFlexFlow = 427,
- eCSSPropertyAlias_WebkitOrder = 428,
- eCSSPropertyAlias_WebkitFlex = 429,
- eCSSPropertyAlias_WebkitFlexGrow = 430,
- eCSSPropertyAlias_WebkitFlexShrink = 431,
- eCSSPropertyAlias_WebkitFlexBasis = 432,
- eCSSPropertyAlias_WebkitJustifyContent = 433,
- eCSSPropertyAlias_WebkitAlignItems = 434,
- eCSSPropertyAlias_WebkitAlignSelf = 435,
- eCSSPropertyAlias_WebkitAlignContent = 436,
- eCSSPropertyAlias_WebkitUserSelect = 437,
- eCSSProperty_COUNT_with_aliases = 438,
- eCSSPropertyExtra_all_properties = 439,
- eCSSPropertyExtra_x_none_value = 440,
- eCSSPropertyExtra_x_auto_value = 441,
- eCSSPropertyExtra_variable = 442,
+ eCSSProperty_initial_letter = 144,
+ eCSSProperty_image_orientation = 145,
+ eCSSProperty_image_region = 146,
+ eCSSProperty_image_rendering = 147,
+ eCSSProperty_ime_mode = 148,
+ eCSSProperty_inline_size = 149,
+ eCSSProperty_isolation = 150,
+ eCSSProperty_justify_content = 151,
+ eCSSProperty_justify_items = 152,
+ eCSSProperty_justify_self = 153,
+ eCSSProperty__x_lang = 154,
+ eCSSProperty_left = 155,
+ eCSSProperty_letter_spacing = 156,
+ eCSSProperty_lighting_color = 157,
+ eCSSProperty_line_height = 158,
+ eCSSProperty_list_style_image = 159,
+ eCSSProperty_list_style_position = 160,
+ eCSSProperty_list_style_type = 161,
+ eCSSProperty_margin_block_end = 162,
+ eCSSProperty_margin_block_start = 163,
+ eCSSProperty_margin_bottom = 164,
+ eCSSProperty_margin_inline_end = 165,
+ eCSSProperty_margin_inline_start = 166,
+ eCSSProperty_margin_left = 167,
+ eCSSProperty_margin_right = 168,
+ eCSSProperty_margin_top = 169,
+ eCSSProperty_marker_end = 170,
+ eCSSProperty_marker_mid = 171,
+ eCSSProperty_marker_offset = 172,
+ eCSSProperty_marker_start = 173,
+ eCSSProperty_mask = 174,
+ eCSSProperty_mask_type = 175,
+ eCSSProperty_math_display = 176,
+ eCSSProperty_math_variant = 177,
+ eCSSProperty_max_block_size = 178,
+ eCSSProperty_max_height = 179,
+ eCSSProperty_max_inline_size = 180,
+ eCSSProperty_max_width = 181,
+ eCSSProperty_min_block_size = 182,
+ eCSSProperty__moz_min_font_size_ratio = 183,
+ eCSSProperty_min_height = 184,
+ eCSSProperty_min_inline_size = 185,
+ eCSSProperty_min_width = 186,
+ eCSSProperty_mix_blend_mode = 187,
+ eCSSProperty_object_fit = 188,
+ eCSSProperty_object_position = 189,
+ eCSSProperty_offset_block_end = 190,
+ eCSSProperty_offset_block_start = 191,
+ eCSSProperty_offset_inline_end = 192,
+ eCSSProperty_offset_inline_start = 193,
+ eCSSProperty_opacity = 194,
+ eCSSProperty_order = 195,
+ eCSSProperty_orient = 196,
+ eCSSProperty_osx_font_smoothing = 197,
+ eCSSProperty_outline_color = 198,
+ eCSSProperty_outline_offset = 199,
+ eCSSProperty__moz_outline_radius_bottomLeft = 200,
+ eCSSProperty__moz_outline_radius_bottomRight = 201,
+ eCSSProperty__moz_outline_radius_topLeft = 202,
+ eCSSProperty__moz_outline_radius_topRight = 203,
+ eCSSProperty_outline_style = 204,
+ eCSSProperty_outline_width = 205,
+ eCSSProperty_overflow_clip_box = 206,
+ eCSSProperty_overflow_x = 207,
+ eCSSProperty_overflow_y = 208,
+ eCSSProperty_padding_block_end = 209,
+ eCSSProperty_padding_block_start = 210,
+ eCSSProperty_padding_bottom = 211,
+ eCSSProperty_padding_inline_end = 212,
+ eCSSProperty_padding_inline_start = 213,
+ eCSSProperty_padding_left = 214,
+ eCSSProperty_padding_right = 215,
+ eCSSProperty_padding_top = 216,
+ eCSSProperty_page_break_after = 217,
+ eCSSProperty_page_break_before = 218,
+ eCSSProperty_page_break_inside = 219,
+ eCSSProperty_paint_order = 220,
+ eCSSProperty_perspective = 221,
+ eCSSProperty_perspective_origin = 222,
+ eCSSProperty_pointer_events = 223,
+ eCSSProperty_position = 224,
+ eCSSProperty_quotes = 225,
+ eCSSProperty_resize = 226,
+ eCSSProperty_right = 227,
+ eCSSProperty_ruby_align = 228,
+ eCSSProperty_ruby_position = 229,
+ eCSSProperty_script_level = 230,
+ eCSSProperty_script_min_size = 231,
+ eCSSProperty_script_size_multiplier = 232,
+ eCSSProperty_scroll_behavior = 233,
+ eCSSProperty_scroll_snap_coordinate = 234,
+ eCSSProperty_scroll_snap_destination = 235,
+ eCSSProperty_scroll_snap_points_x = 236,
+ eCSSProperty_scroll_snap_points_y = 237,
+ eCSSProperty_scroll_snap_type_x = 238,
+ eCSSProperty_scroll_snap_type_y = 239,
+ eCSSProperty_shape_rendering = 240,
+ eCSSProperty__x_span = 241,
+ eCSSProperty_stack_sizing = 242,
+ eCSSProperty_stop_color = 243,
+ eCSSProperty_stop_opacity = 244,
+ eCSSProperty_stroke = 245,
+ eCSSProperty_stroke_dasharray = 246,
+ eCSSProperty_stroke_dashoffset = 247,
+ eCSSProperty_stroke_linecap = 248,
+ eCSSProperty_stroke_linejoin = 249,
+ eCSSProperty_stroke_miterlimit = 250,
+ eCSSProperty_stroke_opacity = 251,
+ eCSSProperty_stroke_width = 252,
+ eCSSProperty__x_system_font = 253,
+ eCSSProperty__moz_tab_size = 254,
+ eCSSProperty_table_layout = 255,
+ eCSSProperty_text_align = 256,
+ eCSSProperty_text_align_last = 257,
+ eCSSProperty_text_anchor = 258,
+ eCSSProperty_text_combine_upright = 259,
+ eCSSProperty_text_decoration_color = 260,
+ eCSSProperty_text_decoration_line = 261,
+ eCSSProperty_text_decoration_style = 262,
+ eCSSProperty_text_emphasis_color = 263,
+ eCSSProperty_text_emphasis_position = 264,
+ eCSSProperty_text_emphasis_style = 265,
+ eCSSProperty__webkit_text_fill_color = 266,
+ eCSSProperty_text_indent = 267,
+ eCSSProperty_text_orientation = 268,
+ eCSSProperty_text_overflow = 269,
+ eCSSProperty_text_rendering = 270,
+ eCSSProperty_text_shadow = 271,
+ eCSSProperty_text_size_adjust = 272,
+ eCSSProperty__webkit_text_stroke_color = 273,
+ eCSSProperty__webkit_text_stroke_width = 274,
+ eCSSProperty_text_transform = 275,
+ eCSSProperty__x_text_zoom = 276,
+ eCSSProperty_top = 277,
+ eCSSProperty__moz_top_layer = 278,
+ eCSSProperty_touch_action = 279,
+ eCSSProperty_transform = 280,
+ eCSSProperty_transform_box = 281,
+ eCSSProperty_transform_origin = 282,
+ eCSSProperty_transform_style = 283,
+ eCSSProperty_transition_delay = 284,
+ eCSSProperty_transition_duration = 285,
+ eCSSProperty_transition_property = 286,
+ eCSSProperty_transition_timing_function = 287,
+ eCSSProperty_unicode_bidi = 288,
+ eCSSProperty_user_focus = 289,
+ eCSSProperty_user_input = 290,
+ eCSSProperty_user_modify = 291,
+ eCSSProperty_user_select = 292,
+ eCSSProperty_vector_effect = 293,
+ eCSSProperty_vertical_align = 294,
+ eCSSProperty_visibility = 295,
+ eCSSProperty_white_space = 296,
+ eCSSProperty_width = 297,
+ eCSSProperty_will_change = 298,
+ eCSSProperty__moz_window_dragging = 299,
+ eCSSProperty__moz_window_shadow = 300,
+ eCSSProperty_word_break = 301,
+ eCSSProperty_word_spacing = 302,
+ eCSSProperty_overflow_wrap = 303,
+ eCSSProperty_writing_mode = 304,
+ eCSSProperty_z_index = 305,
+ eCSSProperty_COUNT_no_shorthands = 306,
+ eCSSProperty_animation = 307,
+ eCSSProperty_background = 308,
+ eCSSProperty_background_position = 309,
+ eCSSProperty_border = 310,
+ eCSSProperty_border_block_end = 311,
+ eCSSProperty_border_block_start = 312,
+ eCSSProperty_border_bottom = 313,
+ eCSSProperty_border_color = 314,
+ eCSSProperty_border_image = 315,
+ eCSSProperty_border_inline_end = 316,
+ eCSSProperty_border_inline_start = 317,
+ eCSSProperty_border_left = 318,
+ eCSSProperty_border_radius = 319,
+ eCSSProperty_border_right = 320,
+ eCSSProperty_border_style = 321,
+ eCSSProperty_border_top = 322,
+ eCSSProperty_border_width = 323,
+ eCSSProperty__moz_column_rule = 324,
+ eCSSProperty__moz_columns = 325,
+ eCSSProperty_flex = 326,
+ eCSSProperty_flex_flow = 327,
+ eCSSProperty_font = 328,
+ eCSSProperty_font_variant = 329,
+ eCSSProperty_grid = 330,
+ eCSSProperty_grid_area = 331,
+ eCSSProperty_grid_column = 332,
+ eCSSProperty_grid_gap = 333,
+ eCSSProperty_grid_row = 334,
+ eCSSProperty_grid_template = 335,
+ eCSSProperty_list_style = 336,
+ eCSSProperty_margin = 337,
+ eCSSProperty_marker = 338,
+ eCSSProperty_outline = 339,
+ eCSSProperty__moz_outline_radius = 340,
+ eCSSProperty_overflow = 341,
+ eCSSProperty_padding = 342,
+ eCSSProperty_scroll_snap_type = 343,
+ eCSSProperty_text_decoration = 344,
+ eCSSProperty_text_emphasis = 345,
+ eCSSProperty__webkit_text_stroke = 346,
+ eCSSProperty__moz_transform = 347,
+ eCSSProperty_transition = 348,
+ eCSSProperty_COUNT = 349,
+ eCSSPropertyAlias_MozTransformOrigin = 350,
+ eCSSPropertyAlias_MozPerspectiveOrigin = 351,
+ eCSSPropertyAlias_MozPerspective = 352,
+ eCSSPropertyAlias_MozTransformStyle = 353,
+ eCSSPropertyAlias_MozBackfaceVisibility = 354,
+ eCSSPropertyAlias_MozBorderImage = 355,
+ eCSSPropertyAlias_MozTransition = 356,
+ eCSSPropertyAlias_MozTransitionDelay = 357,
+ eCSSPropertyAlias_MozTransitionDuration = 358,
+ eCSSPropertyAlias_MozTransitionProperty = 359,
+ eCSSPropertyAlias_MozTransitionTimingFunction = 360,
+ eCSSPropertyAlias_MozAnimation = 361,
+ eCSSPropertyAlias_MozAnimationDelay = 362,
+ eCSSPropertyAlias_MozAnimationDirection = 363,
+ eCSSPropertyAlias_MozAnimationDuration = 364,
+ eCSSPropertyAlias_MozAnimationFillMode = 365,
+ eCSSPropertyAlias_MozAnimationIterationCount = 366,
+ eCSSPropertyAlias_MozAnimationName = 367,
+ eCSSPropertyAlias_MozAnimationPlayState = 368,
+ eCSSPropertyAlias_MozAnimationTimingFunction = 369,
+ eCSSPropertyAlias_MozBoxSizing = 370,
+ eCSSPropertyAlias_MozFontFeatureSettings = 371,
+ eCSSPropertyAlias_MozFontLanguageOverride = 372,
+ eCSSPropertyAlias_MozPaddingEnd = 373,
+ eCSSPropertyAlias_MozPaddingStart = 374,
+ eCSSPropertyAlias_MozMarginEnd = 375,
+ eCSSPropertyAlias_MozMarginStart = 376,
+ eCSSPropertyAlias_MozBorderEnd = 377,
+ eCSSPropertyAlias_MozBorderEndColor = 378,
+ eCSSPropertyAlias_MozBorderEndStyle = 379,
+ eCSSPropertyAlias_MozBorderEndWidth = 380,
+ eCSSPropertyAlias_MozBorderStart = 381,
+ eCSSPropertyAlias_MozBorderStartColor = 382,
+ eCSSPropertyAlias_MozBorderStartStyle = 383,
+ eCSSPropertyAlias_MozBorderStartWidth = 384,
+ eCSSPropertyAlias_MozHyphens = 385,
+ eCSSPropertyAlias_MozTextAlignLast = 386,
+ eCSSPropertyAlias_WebkitAnimation = 387,
+ eCSSPropertyAlias_WebkitAnimationDelay = 388,
+ eCSSPropertyAlias_WebkitAnimationDirection = 389,
+ eCSSPropertyAlias_WebkitAnimationDuration = 390,
+ eCSSPropertyAlias_WebkitAnimationFillMode = 391,
+ eCSSPropertyAlias_WebkitAnimationIterationCount = 392,
+ eCSSPropertyAlias_WebkitAnimationName = 393,
+ eCSSPropertyAlias_WebkitAnimationPlayState = 394,
+ eCSSPropertyAlias_WebkitAnimationTimingFunction = 395,
+ eCSSPropertyAlias_WebkitFilter = 396,
+ eCSSPropertyAlias_WebkitTextSizeAdjust = 397,
+ eCSSPropertyAlias_WebkitTransform = 398,
+ eCSSPropertyAlias_WebkitTransformOrigin = 399,
+ eCSSPropertyAlias_WebkitTransformStyle = 400,
+ eCSSPropertyAlias_WebkitBackfaceVisibility = 401,
+ eCSSPropertyAlias_WebkitPerspective = 402,
+ eCSSPropertyAlias_WebkitPerspectiveOrigin = 403,
+ eCSSPropertyAlias_WebkitTransition = 404,
+ eCSSPropertyAlias_WebkitTransitionDelay = 405,
+ eCSSPropertyAlias_WebkitTransitionDuration = 406,
+ eCSSPropertyAlias_WebkitTransitionProperty = 407,
+ eCSSPropertyAlias_WebkitTransitionTimingFunction = 408,
+ eCSSPropertyAlias_WebkitBorderRadius = 409,
+ eCSSPropertyAlias_WebkitBorderTopLeftRadius = 410,
+ eCSSPropertyAlias_WebkitBorderTopRightRadius = 411,
+ eCSSPropertyAlias_WebkitBorderBottomLeftRadius = 412,
+ eCSSPropertyAlias_WebkitBorderBottomRightRadius = 413,
+ eCSSPropertyAlias_WebkitBackgroundClip = 414,
+ eCSSPropertyAlias_WebkitBackgroundOrigin = 415,
+ eCSSPropertyAlias_WebkitBackgroundSize = 416,
+ eCSSPropertyAlias_WebkitBorderImage = 417,
+ eCSSPropertyAlias_WebkitBoxShadow = 418,
+ eCSSPropertyAlias_WebkitBoxSizing = 419,
+ eCSSPropertyAlias_WebkitBoxFlex = 420,
+ eCSSPropertyAlias_WebkitBoxOrdinalGroup = 421,
+ eCSSPropertyAlias_WebkitBoxOrient = 422,
+ eCSSPropertyAlias_WebkitBoxDirection = 423,
+ eCSSPropertyAlias_WebkitBoxAlign = 424,
+ eCSSPropertyAlias_WebkitBoxPack = 425,
+ eCSSPropertyAlias_WebkitFlexDirection = 426,
+ eCSSPropertyAlias_WebkitFlexWrap = 427,
+ eCSSPropertyAlias_WebkitFlexFlow = 428,
+ eCSSPropertyAlias_WebkitOrder = 429,
+ eCSSPropertyAlias_WebkitFlex = 430,
+ eCSSPropertyAlias_WebkitFlexGrow = 431,
+ eCSSPropertyAlias_WebkitFlexShrink = 432,
+ eCSSPropertyAlias_WebkitFlexBasis = 433,
+ eCSSPropertyAlias_WebkitJustifyContent = 434,
+ eCSSPropertyAlias_WebkitAlignItems = 435,
+ eCSSPropertyAlias_WebkitAlignSelf = 436,
+ eCSSPropertyAlias_WebkitAlignContent = 437,
+ eCSSPropertyAlias_WebkitUserSelect = 438,
+ eCSSProperty_COUNT_with_aliases = 439,
+ eCSSPropertyExtra_all_properties = 440,
+ eCSSPropertyExtra_x_none_value = 441,
+ eCSSPropertyExtra_x_auto_value = 442,
+ eCSSPropertyExtra_variable = 443,
}
#[repr(i32)]
#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)]
@@ -5124,11 +5129,24 @@ pub type nsStyleUnion = nsStyleCoord_h_unnamed_18;
* the unit is a must before asking for the value in any particular
* form.
*/
+ /** <div rustbindgen private accessor="unsafe"></div> */
#[repr(C)]
#[derive(Debug)]
pub struct nsStyleCoord {
- pub mUnit: nsStyleUnit,
- pub mValue: nsStyleUnion,
+ mUnit: nsStyleUnit,
+ mValue: nsStyleUnion,
+}
+impl nsStyleCoord {
+ #[inline]
+ pub unsafe fn get_mUnit(&self) -> &nsStyleUnit { &self.mUnit }
+ pub unsafe fn get_mUnit_mut(&mut self) -> &mut nsStyleUnit {
+ &mut self.mUnit
+ }
+ #[inline]
+ pub unsafe fn get_mValue(&self) -> &nsStyleUnion { &self.mValue }
+ pub unsafe fn get_mValue_mut(&mut self) -> &mut nsStyleUnion {
+ &mut self.mValue
+ }
}
#[repr(C)]
#[derive(Debug, Copy)]
@@ -5169,11 +5187,26 @@ fn bindgen_test_layout_nsStyleCoord() {
* This is commonly used to hold the widths of the borders, margins,
* or paddings of a box.
*/
+ /** <div rustbindgen private accessor="unsafe"></div> */
#[repr(C)]
#[derive(Debug)]
pub struct nsStyleSides {
- pub mUnits: [nsStyleUnit; 4usize],
- pub mValues: [nsStyleUnion; 4usize],
+ mUnits: [nsStyleUnit; 4usize],
+ mValues: [nsStyleUnion; 4usize],
+}
+impl nsStyleSides {
+ #[inline]
+ pub unsafe fn get_mUnits(&self) -> &[nsStyleUnit; 4usize] { &self.mUnits }
+ pub unsafe fn get_mUnits_mut(&mut self) -> &mut [nsStyleUnit; 4usize] {
+ &mut self.mUnits
+ }
+ #[inline]
+ pub unsafe fn get_mValues(&self) -> &[nsStyleUnion; 4usize] {
+ &self.mValues
+ }
+ pub unsafe fn get_mValues_mut(&mut self) -> &mut [nsStyleUnion; 4usize] {
+ &mut self.mValues
+ }
}
#[test]
fn bindgen_test_layout_nsStyleSides() {
@@ -5185,11 +5218,26 @@ fn bindgen_test_layout_nsStyleSides() {
* nsStyleCoord pairs. This is used to hold the dimensions of the
* corners of a box (for, e.g., border-radius and outline-radius).
*/
+ /** <div rustbindgen private accessor="unsafe"></div> */
#[repr(C)]
#[derive(Debug)]
pub struct nsStyleCorners {
- pub mUnits: [nsStyleUnit; 8usize],
- pub mValues: [nsStyleUnion; 8usize],
+ mUnits: [nsStyleUnit; 8usize],
+ mValues: [nsStyleUnion; 8usize],
+}
+impl nsStyleCorners {
+ #[inline]
+ pub unsafe fn get_mUnits(&self) -> &[nsStyleUnit; 8usize] { &self.mUnits }
+ pub unsafe fn get_mUnits_mut(&mut self) -> &mut [nsStyleUnit; 8usize] {
+ &mut self.mUnits
+ }
+ #[inline]
+ pub unsafe fn get_mValues(&self) -> &[nsStyleUnion; 8usize] {
+ &self.mValues
+ }
+ pub unsafe fn get_mValues_mut(&mut self) -> &mut [nsStyleUnion; 8usize] {
+ &mut self.mValues
+ }
}
#[test]
fn bindgen_test_layout_nsStyleCorners() {
@@ -5576,7 +5624,7 @@ pub struct nsStyleBorder {
pub mBorderImageFill: u8,
pub mBorderImageRepeatH: u8,
pub mBorderImageRepeatV: u8,
- pub mFloatEdge: u8,
+ pub mFloatEdge: StyleFloatEdge,
pub mBoxDecorationBreak: u8,
pub mComputedBorder: nsMargin,
pub mBorder: nsMargin,
@@ -5751,12 +5799,14 @@ pub struct nsStyleTextReset {
pub mTextOverflow: nsStyleTextOverflow,
pub mTextDecorationLine: u8,
pub mUnicodeBidi: u8,
+ pub mInitialLetterSink: nscoord,
+ pub mInitialLetterSize: f32,
pub mTextDecorationStyle: u8,
pub mTextDecorationColor: nscolor,
}
#[test]
fn bindgen_test_layout_nsStyleTextReset() {
- assert_eq!(::std::mem::size_of::<nsStyleTextReset>() , 64usize);
+ assert_eq!(::std::mem::size_of::<nsStyleTextReset>() , 80usize);
assert_eq!(::std::mem::align_of::<nsStyleTextReset>() , 8usize);
}
#[repr(C)]
@@ -5859,14 +5909,6 @@ pub enum nsTimingFunction_Type {
}
#[repr(i32)]
#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)]
-pub enum nsTimingFunction_StepSyntax {
- Keyword = 0,
- FunctionalWithoutKeyword = 1,
- FunctionalWithStartKeyword = 2,
- FunctionalWithEndKeyword = 3,
-}
-#[repr(i32)]
-#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)]
pub enum nsTimingFunction_Keyword { Implicit = 0, Explicit = 1, }
#[repr(C)]
#[derive(Debug, Copy)]
@@ -5908,7 +5950,6 @@ fn bindgen_test_layout_nsTimingFunction_nsStyleStruct_h_unnamed_23_nsStyleStruct
#[repr(C)]
#[derive(Debug, Copy)]
pub struct nsTimingFunction_nsStyleStruct_h_unnamed_23_nsStyleStruct_h_unnamed_25 {
- pub mStepSyntax: nsTimingFunction_StepSyntax,
pub mSteps: u32,
}
impl ::std::clone::Clone for
@@ -5918,7 +5959,7 @@ impl ::std::clone::Clone for
#[test]
fn bindgen_test_layout_nsTimingFunction_nsStyleStruct_h_unnamed_23_nsStyleStruct_h_unnamed_25() {
assert_eq!(::std::mem::size_of::<nsTimingFunction_nsStyleStruct_h_unnamed_23_nsStyleStruct_h_unnamed_25>()
- , 8usize);
+ , 4usize);
assert_eq!(::std::mem::align_of::<nsTimingFunction_nsStyleStruct_h_unnamed_23_nsStyleStruct_h_unnamed_25>()
, 4usize);
}
@@ -6148,7 +6189,7 @@ fn bindgen_test_layout_nsCursorImage() {
pub struct nsStyleUserInterface {
pub mUserInput: u8,
pub mUserModify: u8,
- pub mUserFocus: u8,
+ pub mUserFocus: StyleUserFocus,
pub mPointerEvents: u8,
pub mCursor: u8,
pub mCursorArrayLength: u32,
@@ -6311,9 +6352,9 @@ fn bindgen_test_layout_nsStyleBasicShape() {
#[repr(C)]
#[derive(Debug)]
pub struct nsStyleClipPath {
- pub mType: i32,
pub nsStyleClipPath_nsStyleStruct_h_unnamed_29: nsStyleClipPath_nsStyleStruct_h_unnamed_29,
- pub mSizingBox: u8,
+ pub mType: StyleClipPathType,
+ pub mSizingBox: StyleClipShapeSizing,
}
#[repr(C)]
#[derive(Debug, Copy)]
@@ -6335,7 +6376,7 @@ fn bindgen_test_layout_nsStyleClipPath_nsStyleStruct_h_unnamed_29() {
}
#[test]
fn bindgen_test_layout_nsStyleClipPath() {
- assert_eq!(::std::mem::size_of::<nsStyleClipPath>() , 24usize);
+ assert_eq!(::std::mem::size_of::<nsStyleClipPath>() , 16usize);
assert_eq!(::std::mem::align_of::<nsStyleClipPath>() , 8usize);
}
#[repr(C)]
@@ -6383,7 +6424,7 @@ pub struct nsStyleSVGReset {
}
#[test]
fn bindgen_test_layout_nsStyleSVGReset() {
- assert_eq!(::std::mem::size_of::<nsStyleSVGReset>() , 208usize);
+ assert_eq!(::std::mem::size_of::<nsStyleSVGReset>() , 200usize);
assert_eq!(::std::mem::align_of::<nsStyleSVGReset>() , 8usize);
}
#[repr(C)]
diff --git a/ports/geckolib/gecko_bindings/sugar/ns_style_coord.rs b/ports/geckolib/gecko_bindings/sugar/ns_style_coord.rs
index 33dff1a705d..a13f08ea37b 100644
--- a/ports/geckolib/gecko_bindings/sugar/ns_style_coord.rs
+++ b/ports/geckolib/gecko_bindings/sugar/ns_style_coord.rs
@@ -3,24 +3,29 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
use bindings::{Gecko_ResetStyleCoord, Gecko_SetStyleCoordCalcValue, Gecko_AddRefCalcArbitraryThread};
-use std::mem::transmute;
use structs::{nsStyleCoord_Calc, nsStyleUnit, nsStyleUnion, nsStyleCoord, nsStyleSides, nsStyleCorners};
use structs::{nsStyleCoord_CalcValue, nscoord};
impl CoordData for nsStyleCoord {
#[inline]
fn unit(&self) -> nsStyleUnit {
- self.mUnit
+ unsafe {
+ *self.get_mUnit()
+ }
}
#[inline]
fn union(&self) -> nsStyleUnion {
- self.mValue
+ unsafe {
+ *self.get_mValue()
+ }
}
}
impl CoordDataMut for nsStyleCoord {
unsafe fn values_mut(&mut self) -> (&mut nsStyleUnit, &mut nsStyleUnion) {
- (&mut self.mUnit, &mut self.mValue)
+ let unit = self.get_mUnit_mut() as *mut _;
+ let value = self.get_mValue_mut() as *mut _;
+ (&mut *unit, &mut *value)
}
}
@@ -53,26 +58,36 @@ pub struct SidesDataMut<'a> {
impl<'a> CoordData for SidesData<'a> {
#[inline]
fn unit(&self) -> nsStyleUnit {
- self.sides.mUnits[self.index]
+ unsafe {
+ self.sides.get_mUnits()[self.index]
+ }
}
#[inline]
fn union(&self) -> nsStyleUnion {
- self.sides.mValues[self.index]
+ unsafe {
+ self.sides.get_mValues()[self.index]
+ }
}
}
impl<'a> CoordData for SidesDataMut<'a> {
#[inline]
fn unit(&self) -> nsStyleUnit {
- self.sides.mUnits[self.index]
+ unsafe {
+ self.sides.get_mUnits()[self.index]
+ }
}
#[inline]
fn union(&self) -> nsStyleUnion {
- self.sides.mValues[self.index]
+ unsafe {
+ self.sides.get_mValues()[self.index]
+ }
}
}
impl<'a> CoordDataMut for SidesDataMut<'a> {
unsafe fn values_mut(&mut self) -> (&mut nsStyleUnit, &mut nsStyleUnion) {
- (&mut self.sides.mUnits[self.index], &mut self.sides.mValues[self.index])
+ let unit = &mut self.sides.get_mUnits_mut()[self.index] as *mut _;
+ let value = &mut self.sides.get_mValues_mut()[self.index] as *mut _;
+ (&mut *unit, &mut *value)
}
}
@@ -104,23 +119,33 @@ pub struct CornersDataMut<'a> {
impl<'a> CoordData for CornersData<'a> {
fn unit(&self) -> nsStyleUnit {
- self.corners.mUnits[self.index]
+ unsafe {
+ self.corners.get_mUnits()[self.index]
+ }
}
fn union(&self) -> nsStyleUnion {
- self.corners.mValues[self.index]
+ unsafe {
+ self.corners.get_mValues()[self.index]
+ }
}
}
impl<'a> CoordData for CornersDataMut<'a> {
fn unit(&self) -> nsStyleUnit {
- self.corners.mUnits[self.index]
+ unsafe {
+ self.corners.get_mUnits()[self.index]
+ }
}
fn union(&self) -> nsStyleUnion {
- self.corners.mValues[self.index]
+ unsafe {
+ self.corners.get_mValues()[self.index]
+ }
}
}
impl<'a> CoordDataMut for CornersDataMut<'a> {
unsafe fn values_mut(&mut self) -> (&mut nsStyleUnit, &mut nsStyleUnion) {
- (&mut self.corners.mUnits[self.index], &mut self.corners.mValues[self.index])
+ let unit = &mut self.corners.get_mUnits_mut()[self.index] as *mut _;
+ let value = &mut self.corners.get_mValues_mut()[self.index] as *mut _;
+ (&mut *unit, &mut *value)
}
}
@@ -179,6 +204,13 @@ pub trait CoordDataMut : CoordData {
}
}
+ #[inline]
+ unsafe fn copy_from_unchecked<T: CoordData>(&mut self, other: &T) {
+ let (unit, union) = self.values_mut();
+ *unit = other.unit();
+ *union = other.union();
+ }
+
#[inline(always)]
fn set_value(&mut self, value: CoordDataValue) {
use self::CoordDataValue::*;
@@ -254,7 +286,7 @@ pub trait CoordDataMut : CoordData {
#[inline]
unsafe fn as_calc_mut(&mut self) -> &mut nsStyleCoord_Calc {
debug_assert!(self.unit() == nsStyleUnit::eStyleUnit_Calc);
- transmute(*self.union().mPointer.as_mut() as *mut nsStyleCoord_Calc)
+ &mut *(*self.union().mPointer.as_mut() as *mut nsStyleCoord_Calc)
}
#[inline]
@@ -328,6 +360,6 @@ pub trait CoordData {
#[inline]
unsafe fn as_calc(&self) -> &nsStyleCoord_Calc {
debug_assert!(self.unit() == nsStyleUnit::eStyleUnit_Calc);
- transmute(*self.union().mPointer.as_ref() as *const nsStyleCoord_Calc)
+ &*(*self.union().mPointer.as_ref() as *const nsStyleCoord_Calc)
}
}
diff --git a/ports/geckolib/gecko_bindings/tools/regen.py b/ports/geckolib/gecko_bindings/tools/regen.py
index 74fd3beb8ff..821a5e475a7 100755
--- a/ports/geckolib/gecko_bindings/tools/regen.py
+++ b/ports/geckolib/gecko_bindings/tools/regen.py
@@ -25,7 +25,7 @@ COMPILATION_TARGETS = {
"-allow-unknown-types", "-no-bitfield-methods",
"-no-type-renaming", "-no-namespaced-constants",
"-DTRACING=1", "-DIMPL_LIBXUL", "-DMOZ_STYLO_BINDINGS=1",
- "-DMOZILLA_INTERNAL_API",
+ "-DMOZILLA_INTERNAL_API", "-DRUST_BINDGEN",
],
"search_dirs": [
"{}/dist/include",
@@ -98,7 +98,6 @@ COMPILATION_TARGETS = {
"ImageValue", "URLValue", "URLValueData", "nsIPrincipal",
"nsDataHashtable", "imgIRequest"
],
- "unsafe_field_types": ["nsStyleUnion", "nsStyleUnit"],
},
# Generation of the ffi bindings.
"bindings": {
@@ -127,8 +126,7 @@ COMPILATION_TARGETS = {
"nsStyleImageLayers::Layer", "nsStyleImageLayers::LayerType",
"nsStyleUnit", "nsStyleUnion", "nsStyleCoord::CalcValue",
"nsStyleCoord::Calc", "nsRestyleHint", "ServoElementSnapshot",
-
- "SheetParsingMode", "nsMainThreadPtrHandle",
+ "nsChangeHint", "SheetParsingMode", "nsMainThreadPtrHandle",
"nsMainThreadPtrHolder", "nscolor", "nsFont", "FontFamilyList",
"FontFamilyType", "nsIAtom",
],
@@ -212,7 +210,7 @@ def build(objdir, target_name, kind_name=None,
if os.path.isdir(bindgen):
bindgen = ["cargo", "run", "--manifest-path",
- os.path.join(bindgen, "Cargo.toml"), "--"]
+ os.path.join(bindgen, "Cargo.toml"), "--features", "llvm_stable", "--"]
else:
bindgen = [bindgen]
@@ -257,11 +255,6 @@ def build(objdir, target_name, kind_name=None,
flags.append("-match")
flags.append(header.format(objdir))
- if "unsafe_field_types" in current_target:
- for ty in current_target["unsafe_field_types"]:
- flags.append("-unsafe-field-type")
- flags.append(ty.format(objdir))
-
if "blacklist" in current_target:
for ty in current_target["blacklist"]:
flags.append("-blacklist-type")
diff --git a/ports/geckolib/glue.rs b/ports/geckolib/glue.rs
index 95f316f5cc1..87e69aabef0 100644
--- a/ports/geckolib/glue.rs
+++ b/ports/geckolib/glue.rs
@@ -81,8 +81,6 @@ pub extern "C" fn Servo_Initialize() -> () {
fn restyle_subtree(node: GeckoNode, raw_data: *mut RawServoStyleSet) {
debug_assert!(node.is_element() || node.is_text_node());
- let per_doc_data = unsafe { &mut *(raw_data as *mut PerDocumentStyleData) };
-
// Force the creation of our lazily-constructed initial computed values on
// the main thread, since it's not safe to call elsewhere.
//
@@ -92,10 +90,9 @@ fn restyle_subtree(node: GeckoNode, raw_data: *mut RawServoStyleSet) {
// along in startup than the sensible place to call Servo_Initialize.
ComputedValues::initial_values();
- let _needs_dirtying = Arc::get_mut(&mut per_doc_data.stylist).unwrap()
- .update(&per_doc_data.stylesheets,
- per_doc_data.stylesheets_changed);
- per_doc_data.stylesheets_changed = false;
+ // The stylist consumes stylesheets lazily.
+ let per_doc_data = unsafe { &mut *(raw_data as *mut PerDocumentStyleData) };
+ per_doc_data.flush_stylesheets();
let local_context_data =
LocalStyleContextCreationInfo::new(per_doc_data.new_animations_sender.clone());
@@ -113,13 +110,13 @@ fn restyle_subtree(node: GeckoNode, raw_data: *mut RawServoStyleSet) {
timer: Timer::new(),
};
- if node.is_dirty() || node.has_dirty_descendants() {
- if per_doc_data.num_threads == 1 {
- sequential::traverse_dom::<GeckoNode, RecalcStyleOnly>(node, &shared_style_context);
- } else {
- parallel::traverse_dom::<GeckoNode, RecalcStyleOnly>(node, &shared_style_context,
- &mut per_doc_data.work_queue);
- }
+ // We ensure this is true before calling Servo_RestyleSubtree()
+ debug_assert!(node.is_dirty() || node.has_dirty_descendants());
+ if per_doc_data.num_threads == 1 {
+ sequential::traverse_dom::<GeckoNode, RecalcStyleOnly>(node, &shared_style_context);
+ } else {
+ parallel::traverse_dom::<GeckoNode, RecalcStyleOnly>(node, &shared_style_context,
+ &mut per_doc_data.work_queue);
}
}
@@ -156,6 +153,8 @@ pub extern "C" fn Servo_DropNodeData(data: *mut ServoNodeData) -> () {
pub extern "C" fn Servo_StylesheetFromUTF8Bytes(bytes: *const u8,
length: u32,
mode: SheetParsingMode,
+ base_bytes: *const u8,
+ base_length: u32,
base: *mut ThreadSafeURIHolder,
referrer: *mut ThreadSafeURIHolder,
principal: *mut ThreadSafePrincipalHolder)
@@ -168,8 +167,8 @@ pub extern "C" fn Servo_StylesheetFromUTF8Bytes(bytes: *const u8,
SheetParsingMode::eAgentSheetFeatures => Origin::UserAgent,
};
- // FIXME(heycam): Pass in the real base URL.
- let url = Url::parse("about:none").unwrap();
+ let base_str = unsafe { from_utf8_unchecked(slice::from_raw_parts(base_bytes, base_length as usize)) };
+ let url = Url::parse(base_str).unwrap();
let extra_data = ParserContextExtraData {
base: Some(GeckoArcURI::new(base)),
referrer: Some(GeckoArcURI::new(referrer)),
@@ -274,7 +273,9 @@ pub extern "C" fn Servo_GetComputedValuesForAnonymousBox(parent_style_or_null: *
pseudo_tag: *mut nsIAtom,
raw_data: *mut RawServoStyleSet)
-> *mut ServoComputedValues {
+ // The stylist consumes stylesheets lazily.
let data = PerDocumentStyleData::borrow_mut_from_raw(raw_data);
+ data.flush_stylesheets();
let pseudo = match pseudo_element_from_atom(pseudo_tag, /* ua_stylesheet = */ true) {
Ok(pseudo) => pseudo,
@@ -319,7 +320,9 @@ pub extern "C" fn Servo_GetComputedValuesForPseudoElement(parent_style: *mut Ser
};
+ // The stylist consumes stylesheets lazily.
let data = PerDocumentStyleData::borrow_mut_from_raw(raw_data);
+ data.flush_stylesheets();
let element = unsafe { GeckoElement::from_raw(match_element) };
diff --git a/ports/geckolib/string_cache/Cargo.toml b/ports/geckolib/string_cache/Cargo.toml
index 864afbfce3a..bca87223593 100644
--- a/ports/geckolib/string_cache/Cargo.toml
+++ b/ports/geckolib/string_cache/Cargo.toml
@@ -20,4 +20,4 @@ cfg-if = "0.1.0"
gecko_bindings = {version = "0.0.1", path = "../gecko_bindings"}
heapsize = "0.3.5"
libc = "0.2"
-serde = "0.7.11"
+serde = "0.7.15"
diff --git a/python/mach_bootstrap.py b/python/mach_bootstrap.py
index 0b5a31c7459..d63f66492d5 100644
--- a/python/mach_bootstrap.py
+++ b/python/mach_bootstrap.py
@@ -135,6 +135,7 @@ def _activate_virtualenv(topdir):
requirements_paths = [
os.path.join("python", "requirements.txt"),
os.path.join("tests", "wpt", "harness", "requirements.txt"),
+ os.path.join("tests", "wpt", "harness", "requirements_firefox.txt"),
os.path.join("tests", "wpt", "harness", "requirements_servo.txt"),
]
for req_rel_path in requirements_paths:
diff --git a/python/servo/build_commands.py b/python/servo/build_commands.py
index f344b050f4e..df727e2776f 100644
--- a/python/servo/build_commands.py
+++ b/python/servo/build_commands.py
@@ -236,6 +236,9 @@ class MachCommands(CommandBase):
cargo_binary = "cargo" + BIN_SUFFIX
+ if sys.platform == "win32" or sys.platform == "msys":
+ env["RUSTFLAGS"] = "-C link-args=-Wl,--subsystem,windows"
+
status = call(
[cargo_binary, "build"] + opts,
env=env, cwd=self.servo_crate(), verbose=verbose)
diff --git a/python/servo/package_commands.py b/python/servo/package_commands.py
index d3d7877c674..1bd91e6eae1 100644
--- a/python/servo/package_commands.py
+++ b/python/servo/package_commands.py
@@ -9,8 +9,11 @@
from __future__ import print_function, unicode_literals
-import os
+import sys
import os.path as path
+sys.path.append(path.join(path.dirname(sys.argv[0]), "components", "style", "properties", "Mako-0.9.1.zip"))
+
+import os
import shutil
import subprocess
import tarfile
@@ -24,7 +27,9 @@ from mach.decorators import (
Command,
)
-from servo.command_base import CommandBase, cd, BuildNotFound, is_macosx
+from mako.template import Template
+
+from servo.command_base import CommandBase, cd, BuildNotFound, is_macosx, is_windows
from servo.post_build_commands import find_dep_path_newest
@@ -42,6 +47,11 @@ def otool(s):
yield l.split(' ', 1)[0][1:]
+def listfiles(directory):
+ return [f for f in os.listdir(directory)
+ if path.isfile(path.join(directory, f))]
+
+
def install_name_tool(old, new, binary):
try:
subprocess.check_call(['install_name_tool', '-change', old, '@executable_path/' + new, binary])
@@ -76,7 +86,7 @@ class PackageCommands(CommandBase):
env["ANT_FLAVOR"] = "release"
dev_flag = ""
- target_dir = os.path.dirname(binary_path)
+ target_dir = path.dirname(binary_path)
output_apk = "{}.apk".format(binary_path)
try:
with cd(path.join("support", "android", "build-apk")):
@@ -91,7 +101,7 @@ class PackageCommands(CommandBase):
dir_to_app = dir_to_dmg + '/Servo.app'
dir_to_resources = dir_to_app + '/Contents/Resources/'
dir_to_root = '/'.join(binary_path.split('/')[:-3])
- if os.path.exists(dir_to_dmg):
+ if path.exists(dir_to_dmg):
print("Cleaning up from previous packaging")
delete(dir_to_dmg)
browserhtml_path = find_dep_path_newest('browserhtml', binary_path)
@@ -123,7 +133,7 @@ class PackageCommands(CommandBase):
continue
need_relinked = set(otool(f))
new_path = dir_to_app + '/Contents/MacOS/' + f.split('/')[-1]
- if not os.path.exists(new_path):
+ if not path.exists(new_path):
shutil.copyfile(f, new_path)
for dylib in need_relinked:
if '/System/Library' in dylib or '/usr/lib' in dylib or 'servo' in dylib:
@@ -153,6 +163,45 @@ class PackageCommands(CommandBase):
print("Cleaning up")
delete(dir_to_dmg)
print("Packaged Servo into " + dmg_path)
+ elif is_windows():
+ dir_to_package = path.dirname(binary_path)
+ dir_to_root = self.get_top_dir()
+ dir_to_msi = path.join(dir_to_package, 'msi')
+ if path.exists(dir_to_msi):
+ print("Cleaning up from previous packaging")
+ delete(dir_to_msi)
+ os.makedirs(dir_to_msi)
+ top_path = dir_to_root
+ 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.")
+ return 1
+ browserhtml_path = path.join(browserhtml_path, "out")
+ # generate Servo.wxs
+ template_path = path.join(dir_to_root, "support", "windows", "Servo.wxs.mako")
+ template = Template(open(template_path).read())
+ wxs_path = path.join(dir_to_msi, "Servo.wxs")
+ open(wxs_path, "w").write(template.render(
+ exe_path=dir_to_package,
+ top_path=top_path,
+ browserhtml_path=browserhtml_path))
+ # run candle and light
+ print("Creating MSI")
+ try:
+ with cd(dir_to_msi):
+ subprocess.check_call(['candle', wxs_path])
+ except subprocess.CalledProcessError as e:
+ print("WiX candle exited with return value %d" % e.returncode)
+ return e.returncode
+ try:
+ wxsobj_path = "{}.wixobj".format(path.splitext(wxs_path)[0])
+ with cd(dir_to_msi):
+ subprocess.check_call(['light', wxsobj_path])
+ except subprocess.CalledProcessError as e:
+ print("WiX light exited with return value %d" % e.returncode)
+ return e.returncode
+ msi_path = path.join(dir_to_msi, "Servo.msi")
+ print("Packaged Servo into {}".format(msi_path))
else:
dir_to_package = '/'.join(binary_path.split('/')[:-1])
dir_to_root = '/'.join(binary_path.split('/')[:-3])
diff --git a/python/servo/testing_commands.py b/python/servo/testing_commands.py
index b4c045d4a70..4776a9209d1 100644
--- a/python/servo/testing_commands.py
+++ b/python/servo/testing_commands.py
@@ -209,6 +209,9 @@ class MachCommands(CommandBase):
env = self.build_env()
env["RUST_BACKTRACE"] = "1"
+ if sys.platform == "win32" or sys.platform == "msys":
+ env["RUSTFLAGS"] = "-C link-args=-Wl,--subsystem,windows"
+
result = call(args, env=env, cwd=self.servo_crate())
if result != 0:
return result
diff --git a/python/tidy/servo_tidy/licenseck.py b/python/tidy/servo_tidy/licenseck.py
index 03113da507d..75819bcefd2 100644
--- a/python/tidy/servo_tidy/licenseck.py
+++ b/python/tidy/servo_tidy/licenseck.py
@@ -32,6 +32,14 @@ licenses = [
""",
"""\
+#!/usr/bin/env python3
+
+# 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 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/.
diff --git a/python/tidy/servo_tidy_tests/test_tidy.py b/python/tidy/servo_tidy_tests/test_tidy.py
index 8db19a5efd7..6497fa016b7 100644
--- a/python/tidy/servo_tidy_tests/test_tidy.py
+++ b/python/tidy/servo_tidy_tests/test_tidy.py
@@ -93,6 +93,7 @@ class CheckTidiness(unittest.TestCase):
def test_toml(self):
errors = tidy.collect_errors_for_files(iterFile('test.toml'), [tidy.check_toml], [], print_text=False)
self.assertEqual('found asterisk instead of minimum version number', errors.next()[2])
+ self.assertEqual('.toml file should contain a valid license.', errors.next()[2])
self.assertNoMoreErrors(errors)
def test_modeline(self):
@@ -130,12 +131,12 @@ class CheckTidiness(unittest.TestCase):
file_list = tidy.get_file_list(base_path, only_changed_files=False,
exclude_dirs=[])
lst = list(file_list)
- self.assertEqual([os.path.join(base_path, 'whee', 'test.rs')], lst)
+ self.assertEqual([os.path.join(base_path, 'whee', 'test.rs'), os.path.join(base_path, 'whee', 'foo', 'bar.rs')], lst)
file_list = tidy.get_file_list(base_path, only_changed_files=False,
- exclude_dirs=[os.path.join(base_path,'whee')])
+ exclude_dirs=[os.path.join(base_path, 'whee', 'foo')])
lst = list(file_list)
- self.assertEqual([], lst)
+ self.assertEqual([os.path.join(base_path, 'whee', 'test.rs')], lst)
def do_tests():
suite = unittest.TestLoader().loadTestsFromTestCase(CheckTidiness)
- unittest.TextTestRunner(verbosity=2).run(suite)
+ return 0 if unittest.TextTestRunner(verbosity=2).run(suite).wasSuccessful() else 1
diff --git a/resources/Servo.ico b/resources/Servo.ico
new file mode 100644
index 00000000000..71d38a0c147
--- /dev/null
+++ b/resources/Servo.ico
Binary files differ
diff --git a/resources/servo.css b/resources/servo.css
index 8ec5e17bbf0..858d59226c2 100644
--- a/resources/servo.css
+++ b/resources/servo.css
@@ -9,7 +9,7 @@ input {
color: black;
font-family: sans-serif;
font-size: 0.8333em;
- white-space: nowrap;
+ white-space: pre;
text-align: left;
line-height: 1.8;
}
@@ -24,7 +24,7 @@ textarea {
color: black;
font-family: sans-serif;
font-size: 0.8333em;
- white-space: pre;
+ white-space: pre-wrap;
}
input::selection,
diff --git a/resources/shaders/blur.fs.glsl b/resources/shaders/blur.fs.glsl
index c20a774f488..2af2a7ebabb 100644
--- a/resources/shaders/blur.fs.glsl
+++ b/resources/shaders/blur.fs.glsl
@@ -28,7 +28,7 @@ void main(void) {
lColorTexCoord.x <= 1.0 &&
lColorTexCoord.y >= 0.0 &&
lColorTexCoord.y <= 1.0 ?
- Texture(sDiffuse, lColorTexCoord * sourceTextureUvSize + sourceTextureUvOrigin) :
+ texture(sDiffuse, lColorTexCoord * sourceTextureUvSize + sourceTextureUvOrigin) :
vec4(0.0);
// Alpha must be premultiplied in order to properly blur the alpha channel.
diff --git a/resources/shaders/box_shadow.fs.glsl b/resources/shaders/box_shadow.fs.glsl
index 5d7c6db6d59..e71ba6a193b 100644
--- a/resources/shaders/box_shadow.fs.glsl
+++ b/resources/shaders/box_shadow.fs.glsl
@@ -141,6 +141,8 @@ void main(void) {
vec2 radii = vBorderRadii.xy;
float sigma = vBlurRadius / 2.0;
float value = color(pos, p0Rect, p1Rect, radii, sigma);
- SetFragColor(vec4(vColor.rgb, max(value, 0.0)));
+
+ value = max(value, 0.0);
+ SetFragColor(vec4(vColor.rgb, vColor.a == 0.0 ? 1.0 - value : value));
}
diff --git a/resources/shaders/debug_color.fs.glsl b/resources/shaders/debug_color.fs.glsl
index 658ac27488c..e9aae641382 100644
--- a/resources/shaders/debug_color.fs.glsl
+++ b/resources/shaders/debug_color.fs.glsl
@@ -4,5 +4,5 @@
void main(void)
{
- SetFragColor(vColor);
+ oFragColor = vColor;
}
diff --git a/resources/shaders/debug_font.fs.glsl b/resources/shaders/debug_font.fs.glsl
index 8b68e085cfb..a10e0da4ceb 100644
--- a/resources/shaders/debug_font.fs.glsl
+++ b/resources/shaders/debug_font.fs.glsl
@@ -5,9 +5,9 @@
void main(void)
{
#ifdef SERVO_ES2
- float alpha = Texture(sDiffuse, vColorTexCoord.xy).a;
+ float alpha = texture(sDiffuse, vColorTexCoord.xy).a;
#else
- float alpha = Texture(sDiffuse, vColorTexCoord.xy).r;
+ float alpha = texture(sDiffuse, vColorTexCoord.xy).r;
#endif
- SetFragColor(vec4(vColor.xyz, vColor.w * alpha));
+ oFragColor = vec4(vColor.xyz, vColor.w * alpha);
}
diff --git a/resources/shaders/es2_common.vs.glsl b/resources/shaders/es2_common.vs.glsl
index 91d72015e49..ccb8c3dcec5 100644
--- a/resources/shaders/es2_common.vs.glsl
+++ b/resources/shaders/es2_common.vs.glsl
@@ -65,6 +65,6 @@ vec2 SnapToPixels(vec2 pos)
// Snap the vertex to pixel position to guarantee correct texture
// sampling when using bilinear filtering.
- // TODO(gw): Do we ever get negative coords here?
+ // TODO(gw): ES2 doesn't have round(). Do we ever get negative coords here?
return floor(0.5 + pos * uDevicePixelRatio) / uDevicePixelRatio;
}
diff --git a/resources/shaders/gl3_common.vs.glsl b/resources/shaders/gl3_common.vs.glsl
index e24cef9437e..cffcfc80eb7 100644
--- a/resources/shaders/gl3_common.vs.glsl
+++ b/resources/shaders/gl3_common.vs.glsl
@@ -62,8 +62,5 @@ vec2 SnapToPixels(vec2 pos)
{
// Snap the vertex to pixel position to guarantee correct texture
// sampling when using bilinear filtering.
-
- // Don't use round() because its behavior is implementation-defined on 0.5.
- // TODO: Do we ever get negative coords here?
- return floor(0.5 + pos * uDevicePixelRatio) / uDevicePixelRatio;
+ return round(pos * uDevicePixelRatio) / uDevicePixelRatio;
}
diff --git a/resources/shaders/prim_shared.glsl b/resources/shaders/prim_shared.glsl
new file mode 100644
index 00000000000..7c21cada7fa
--- /dev/null
+++ b/resources/shaders/prim_shared.glsl
@@ -0,0 +1,180 @@
+#line 1
+/* 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/. */
+
+#define PST_INVALID uint(0)
+#define PST_TOP_LEFT uint(1)
+#define PST_TOP_RIGHT uint(2)
+#define PST_BOTTOM_LEFT uint(3)
+#define PST_BOTTOM_RIGHT uint(4)
+#define PST_TOP uint(5)
+#define PST_LEFT uint(6)
+#define PST_BOTTOM uint(7)
+#define PST_RIGHT uint(8)
+
+// Border styles as defined in webrender_traits/types.rs
+#define BORDER_STYLE_NONE uint(0)
+#define BORDER_STYLE_SOLID uint(1)
+#define BORDER_STYLE_DOUBLE uint(2)
+#define BORDER_STYLE_DOTTED uint(3)
+#define BORDER_STYLE_DASHED uint(4)
+#define BORDER_STYLE_HIDDEN uint(5)
+#define BORDER_STYLE_GROOVE uint(6)
+#define BORDER_STYLE_RIDGE uint(7)
+#define BORDER_STYLE_INSET uint(8)
+#define BORDER_STYLE_OUTSET uint(9)
+
+#ifdef WR_VERTEX_SHADER
+struct Layer {
+ mat4 transform;
+ mat4 inv_transform;
+ ivec4 world_clip_rect;
+ vec4 screen_vertices[4];
+};
+
+layout(std140) uniform Layers {
+ Layer layers[WR_MAX_PRIM_LAYERS];
+};
+
+struct Tile {
+ uvec4 actual_rect;
+ uvec4 target_rect;
+};
+
+layout(std140) uniform Tiles {
+ Tile tiles[WR_MAX_PRIM_TILES];
+};
+
+struct PrimitiveInfo {
+ uvec4 layer_tile_part;
+ vec4 local_clip_rect;
+ vec4 local_rect;
+};
+
+struct ClipCorner {
+ vec4 rect;
+ vec4 outer_inner_radius;
+};
+
+struct Clip {
+ vec4 rect;
+ ClipCorner top_left;
+ ClipCorner top_right;
+ ClipCorner bottom_left;
+ ClipCorner bottom_right;
+};
+
+bool ray_plane(vec3 normal, vec3 point, vec3 ray_origin, vec3 ray_dir, out float t)
+{
+ float denom = dot(normal, ray_dir);
+ if (denom > 1e-6) {
+ vec3 d = point - ray_origin;
+ t = dot(d, normal) / denom;
+ return t >= 0.0;
+ }
+
+ return false;
+}
+
+vec4 untransform(vec2 ref, vec3 n, vec3 a, mat4 inv_transform) {
+ vec3 p = vec3(ref, -10000.0);
+ vec3 d = vec3(0, 0, 1.0);
+
+ float t;
+ ray_plane(n, a, p, d, t);
+ vec3 c = p + d * t;
+
+ vec4 r = inv_transform * vec4(c, 1.0);
+ return r;
+}
+
+vec3 get_layer_pos(vec2 pos, uint layer_index) {
+ Layer layer = layers[layer_index];
+ vec3 a = layer.screen_vertices[0].xyz / layer.screen_vertices[0].w;
+ vec3 b = layer.screen_vertices[3].xyz / layer.screen_vertices[3].w;
+ vec3 c = layer.screen_vertices[2].xyz / layer.screen_vertices[2].w;
+ vec3 n = normalize(cross(b-a, c-a));
+ vec4 local_pos = untransform(pos, n, a, layer.inv_transform);
+ return local_pos.xyw;
+}
+
+struct Rect {
+ vec2 p0;
+ vec2 p1;
+};
+
+struct VertexInfo {
+ Rect local_rect;
+ vec2 local_clamped_pos;
+ vec2 global_clamped_pos;
+};
+
+VertexInfo write_vertex(PrimitiveInfo info) {
+ Layer layer = layers[info.layer_tile_part.x];
+ Tile tile = tiles[info.layer_tile_part.y];
+
+ vec2 p0 = floor(0.5 + info.local_rect.xy * uDevicePixelRatio) / uDevicePixelRatio;
+ vec2 p1 = floor(0.5 + (info.local_rect.xy + info.local_rect.zw) * uDevicePixelRatio) / uDevicePixelRatio;
+
+ vec2 local_pos = mix(p0, p1, aPosition.xy);
+
+ vec2 cp0 = floor(0.5 + info.local_clip_rect.xy * uDevicePixelRatio) / uDevicePixelRatio;
+ vec2 cp1 = floor(0.5 + (info.local_clip_rect.xy + info.local_clip_rect.zw) * uDevicePixelRatio) / uDevicePixelRatio;
+ local_pos = clamp(local_pos, cp0, cp1);
+
+ vec4 world_pos = layer.transform * vec4(local_pos, 0, 1);
+ world_pos.xyz /= world_pos.w;
+
+ vec2 device_pos = world_pos.xy * uDevicePixelRatio;
+
+ vec2 clamped_pos = clamp(device_pos,
+ vec2(tile.actual_rect.xy),
+ vec2(tile.actual_rect.xy + tile.actual_rect.zw));
+
+ clamped_pos = clamp(clamped_pos,
+ vec2(layer.world_clip_rect.xy),
+ vec2(layer.world_clip_rect.xy + layer.world_clip_rect.zw));
+
+ vec4 local_clamped_pos = layer.inv_transform * vec4(clamped_pos / uDevicePixelRatio, world_pos.z, 1);
+ local_clamped_pos.xyz /= local_clamped_pos.w;
+
+ vec2 final_pos = clamped_pos + vec2(tile.target_rect.xy) - vec2(tile.actual_rect.xy);
+
+ gl_Position = uTransform * vec4(final_pos, 0, 1);
+
+ VertexInfo vi = VertexInfo(Rect(p0, p1), local_clamped_pos.xy, clamped_pos.xy);
+ return vi;
+}
+#endif
+
+#ifdef WR_FRAGMENT_SHADER
+void do_clip(vec2 pos, vec4 clip_rect, vec4 radius) {
+ vec2 ref_tl = clip_rect.xy + vec2( radius.x, radius.x);
+ vec2 ref_tr = clip_rect.zy + vec2(-radius.y, radius.y);
+ vec2 ref_br = clip_rect.zw + vec2(-radius.z, -radius.z);
+ vec2 ref_bl = clip_rect.xw + vec2( radius.w, -radius.w);
+
+ float d_tl = distance(pos, ref_tl);
+ float d_tr = distance(pos, ref_tr);
+ float d_br = distance(pos, ref_br);
+ float d_bl = distance(pos, ref_bl);
+
+ bool out0 = pos.x < ref_tl.x && pos.y < ref_tl.y && d_tl > radius.x;
+ bool out1 = pos.x > ref_tr.x && pos.y < ref_tr.y && d_tr > radius.y;
+ bool out2 = pos.x > ref_br.x && pos.y > ref_br.y && d_br > radius.z;
+ bool out3 = pos.x < ref_bl.x && pos.y > ref_bl.y && d_bl > radius.w;
+
+ // TODO(gw): Alpha anti-aliasing based on edge distance!
+ if (out0 || out1 || out2 || out3) {
+ discard;
+ }
+}
+
+bool point_in_rect(vec2 p, vec2 p0, vec2 p1) {
+ return p.x >= p0.x &&
+ p.y >= p0.y &&
+ p.x <= p1.x &&
+ p.y <= p1.y;
+}
+#endif
diff --git a/resources/shaders/ps_angle_gradient.fs.glsl b/resources/shaders/ps_angle_gradient.fs.glsl
new file mode 100644
index 00000000000..944b90979f6
--- /dev/null
+++ b/resources/shaders/ps_angle_gradient.fs.glsl
@@ -0,0 +1,39 @@
+/* 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/. */
+
+float offset(int index) {
+ return vOffsets[index / 4][index % 4];
+}
+
+float linearStep(float lo, float hi, float x) {
+ float d = hi - lo;
+ float v = x - lo;
+ if (d != 0.0) {
+ v /= d;
+ }
+ return clamp(v, 0.0, 1.0);
+}
+
+void main(void) {
+ float angle = atan(-vEndPoint.y + vStartPoint.y,
+ vEndPoint.x - vStartPoint.x);
+ float sa = sin(angle);
+ float ca = cos(angle);
+
+ float sx = vStartPoint.x * ca - vStartPoint.y * sa;
+ float ex = vEndPoint.x * ca - vEndPoint.y * sa;
+ float d = ex - sx;
+
+ float x = vPos.x * ca - vPos.y * sa;
+
+ oFragColor = mix(vColors[0],
+ vColors[1],
+ linearStep(sx + d * offset(0), sx + d * offset(1), x));
+
+ for (int i=1 ; i < vStopCount-1 ; ++i) {
+ oFragColor = mix(oFragColor,
+ vColors[i+1],
+ linearStep(sx + d * offset(i), sx + d * offset(i+1), x));
+ }
+}
diff --git a/resources/shaders/ps_angle_gradient.glsl b/resources/shaders/ps_angle_gradient.glsl
new file mode 100644
index 00000000000..fae2211af50
--- /dev/null
+++ b/resources/shaders/ps_angle_gradient.glsl
@@ -0,0 +1,13 @@
+/* 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/. */
+
+#define MAX_STOPS_PER_ANGLE_GRADIENT 8
+
+flat varying int vStopCount;
+flat varying float vAngle;
+flat varying vec2 vStartPoint;
+flat varying vec2 vEndPoint;
+varying vec2 vPos;
+flat varying vec4 vColors[MAX_STOPS_PER_ANGLE_GRADIENT];
+flat varying vec4 vOffsets[MAX_STOPS_PER_ANGLE_GRADIENT/4];
diff --git a/resources/shaders/ps_angle_gradient.vs.glsl b/resources/shaders/ps_angle_gradient.vs.glsl
new file mode 100644
index 00000000000..16296967bdb
--- /dev/null
+++ b/resources/shaders/ps_angle_gradient.vs.glsl
@@ -0,0 +1,38 @@
+#line 1
+/* 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/. */
+
+struct AngleGradient {
+ PrimitiveInfo info;
+ vec4 start_end_point;
+ uvec4 stop_count;
+ vec4 colors[MAX_STOPS_PER_ANGLE_GRADIENT];
+ vec4 offsets[MAX_STOPS_PER_ANGLE_GRADIENT/4];
+};
+
+layout(std140) uniform Items {
+ AngleGradient gradients[WR_MAX_PRIM_ITEMS];
+};
+
+void main(void) {
+ AngleGradient gradient = gradients[gl_InstanceID];
+ VertexInfo vi = write_vertex(gradient.info);
+
+ vStopCount = int(gradient.stop_count.x);
+ vPos = vi.local_clamped_pos;
+
+ // Snap the start/end points to device pixel units.
+ // I'm not sure this is entirely correct, but the
+ // old render path does this, and it is needed to
+ // make the angle gradient ref tests pass. It might
+ // be better to fix this higher up in DL construction
+ // and not snap here?
+ vStartPoint = floor(0.5 + gradient.start_end_point.xy * uDevicePixelRatio) / uDevicePixelRatio;
+ vEndPoint = floor(0.5 + gradient.start_end_point.zw * uDevicePixelRatio) / uDevicePixelRatio;
+
+ for (int i=0 ; i < int(gradient.stop_count.x) ; ++i) {
+ vColors[i] = gradient.colors[i];
+ vOffsets[i] = gradient.offsets[i];
+ }
+}
diff --git a/resources/shaders/ps_blend.fs.glsl b/resources/shaders/ps_blend.fs.glsl
new file mode 100644
index 00000000000..12ccbf0b6cf
--- /dev/null
+++ b/resources/shaders/ps_blend.fs.glsl
@@ -0,0 +1,10 @@
+/* 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/. */
+
+uniform sampler2D sCache;
+
+void main(void) {
+ vec4 color = texture(sCache, vUv);
+ oFragColor = vec4(color.rgb, color.a * vOpacity);
+}
diff --git a/resources/shaders/ps_blend.glsl b/resources/shaders/ps_blend.glsl
new file mode 100644
index 00000000000..773cf91e27e
--- /dev/null
+++ b/resources/shaders/ps_blend.glsl
@@ -0,0 +1,6 @@
+/* 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/. */
+
+varying vec2 vUv;
+varying float vOpacity;
diff --git a/resources/shaders/ps_blend.vs.glsl b/resources/shaders/ps_blend.vs.glsl
new file mode 100644
index 00000000000..eb61903b5cc
--- /dev/null
+++ b/resources/shaders/ps_blend.vs.glsl
@@ -0,0 +1,29 @@
+#line 1
+/* 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/. */
+
+struct Blend {
+ uvec4 target_rect;
+ uvec4 src_rect;
+ vec4 opacity;
+};
+
+layout(std140) uniform Items {
+ Blend blends[WR_MAX_PRIM_ITEMS];
+};
+
+void main(void) {
+ Blend blend = blends[gl_InstanceID];
+
+ vec2 local_pos = mix(vec2(blend.target_rect.xy),
+ vec2(blend.target_rect.xy + blend.target_rect.zw),
+ aPosition.xy);
+
+ vec2 st0 = vec2(blend.src_rect.xy) / 2048.0;
+ vec2 st1 = vec2(blend.src_rect.xy + blend.src_rect.zw) / 2048.0;
+ vUv = mix(st0, st1, aPosition.xy);
+ vOpacity = blend.opacity.x;
+
+ gl_Position = uTransform * vec4(local_pos, 0, 1);
+}
diff --git a/resources/shaders/ps_border.fs.glsl b/resources/shaders/ps_border.fs.glsl
new file mode 100644
index 00000000000..042b56f1d0a
--- /dev/null
+++ b/resources/shaders/ps_border.fs.glsl
@@ -0,0 +1,184 @@
+/* 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/. */
+
+// draw a circle at position aDesiredPos with a aRadius
+vec4 drawCircle(vec2 aPixel, vec2 aDesiredPos, float aRadius, vec3 aColor) {
+ float farFromCenter = length(aDesiredPos - aPixel) - aRadius;
+ float pixelInCircle = 1.00 - clamp(farFromCenter, 0.0, 1.0);
+ return vec4(aColor, pixelInCircle);
+}
+
+// Draw a rectangle at aRect fill it with aColor. Only works on non-rotated
+// rects.
+vec4 drawRect(vec2 aPixel, vec4 aRect, vec3 aColor) {
+ // GLSL origin is bottom left, positive Y is up
+ bool inRect = (aRect.x <= aPixel.x) && (aPixel.x <= aRect.x + aRect.z) &&
+ (aPixel.y >= aRect.y) && (aPixel.y <= aRect.y + aRect.w);
+ return vec4(aColor, float(inRect));
+}
+
+vec4 draw_dotted_edge() {
+ // Everything here should be in device pixels.
+ // We want the dot to be roughly the size of the whole border spacing
+ float border_spacing = min(vBorders.w, vBorders.z);
+ float radius = floor(border_spacing / 2.0);
+ float diameter = radius * 2.0;
+ // The amount of space between dots. 2.2 was chosen because it looks kind of
+ // like firefox.
+ float circleSpacing = diameter * 2.2;
+
+ vec2 size = vec2(vBorders.z, vBorders.w);
+ // Get our position within this specific segment
+ vec2 position = vDevicePos - vBorders.xy;
+
+ // Break our position into square tiles with circles in them.
+ vec2 circleCount = floor(size / circleSpacing);
+ circleCount = max(circleCount, 1.0);
+
+ vec2 distBetweenCircles = size / circleCount;
+ vec2 circleCenter = distBetweenCircles / 2.0;
+
+ // Find out which tile this pixel belongs to.
+ vec2 destTile = floor(position / distBetweenCircles);
+ destTile = destTile * distBetweenCircles;
+
+ // Where we want to draw the actual circle.
+ vec2 tileCenter = destTile + circleCenter;
+
+ // Find the position within the tile
+ vec2 positionInTile = mod(position, distBetweenCircles);
+ vec2 finalPosition = positionInTile + destTile;
+
+ vec4 white = vec4(1.0, 1.0, 1.0, 1.0);
+ // See if we should draw a circle or not
+ vec4 circleColor = drawCircle(finalPosition, tileCenter, radius, vVerticalColor.xyz);
+ return mix(white, circleColor, circleColor.a);
+}
+
+// Our current edge calculation is based only on
+// the size of the border-size, but we need to draw
+// the dashes in the center of the segment we're drawing.
+// This calculates how much to nudge and which axis to nudge on.
+vec2 get_dashed_nudge_factor(vec2 dash_size, bool is_corner) {
+ if (is_corner) {
+ return vec2(0.0, 0.0);
+ }
+
+ bool xAxisFudge = vBorders.z > vBorders.w;
+ if (xAxisFudge) {
+ return vec2(dash_size.x / 2.0, 0);
+ } else {
+ return vec2(0.0, dash_size.y / 2.0);
+ }
+}
+
+vec4 draw_dashed_edge(bool is_corner) {
+ // Everything here should be in device pixels.
+ // We want the dot to be roughly the size of the whole border spacing
+ // 5.5 here isn't a magic number, it's just what mostly looks like FF/Chrome
+ float dash_interval = min(vBorders.w, vBorders.z) * 5.5;
+ vec2 edge_size = vec2(vBorders.z, vBorders.w);
+ vec2 dash_size = vec2(dash_interval / 2.0, dash_interval / 2.0);
+ vec2 position = vDevicePos - vBorders.xy;
+
+ vec2 dash_count = floor(edge_size/ dash_interval);
+ vec2 dist_between_dashes = edge_size / dash_count;
+
+ vec2 target_rect_index = floor(position / dist_between_dashes);
+ vec2 target_rect_loc = target_rect_index * dist_between_dashes;
+ target_rect_loc += get_dashed_nudge_factor(dash_size, is_corner);
+ vec4 target_rect = vec4(target_rect_loc, dash_size);
+
+ vec4 white = vec4(1.0, 1.0, 1.0, 1.0);
+ vec4 target_colored_rect = drawRect(position, target_rect, vVerticalColor.xyz);
+ return mix(white, target_colored_rect, target_colored_rect.a);
+}
+
+void draw_dotted_border(void) {
+ switch (vBorderPart) {
+ // These are the layer tile part PrimitivePart as uploaded by the tiling.rs
+ case PST_TOP_LEFT:
+ case PST_TOP_RIGHT:
+ case PST_BOTTOM_LEFT:
+ case PST_BOTTOM_RIGHT:
+ {
+ // TODO: Fix for corners with a border-radius
+ oFragColor = draw_dotted_edge();
+ break;
+ }
+ case PST_BOTTOM:
+ case PST_TOP:
+ case PST_LEFT:
+ case PST_RIGHT:
+ {
+ oFragColor = draw_dotted_edge();
+ break;
+ }
+ }
+}
+
+void draw_dashed_border(void) {
+ switch (vBorderPart) {
+ // These are the layer tile part PrimitivePart as uploaded by the tiling.rs
+ case PST_TOP_LEFT:
+ case PST_TOP_RIGHT:
+ case PST_BOTTOM_LEFT:
+ case PST_BOTTOM_RIGHT:
+ {
+ // TODO: Fix for corners with a border-radius
+ bool is_corner = true;
+ oFragColor = draw_dashed_edge(is_corner);
+ break;
+ }
+ case PST_BOTTOM:
+ case PST_TOP:
+ case PST_LEFT:
+ case PST_RIGHT:
+ {
+ bool is_corner = false;
+ oFragColor = draw_dashed_edge(is_corner);
+ break;
+ }
+ }
+}
+
+void main(void) {
+ if (vRadii.x > 0.0 &&
+ (distance(vRefPoint, vLocalPos) > vRadii.x ||
+ distance(vRefPoint, vLocalPos) < vRadii.z)) {
+ discard;
+ }
+
+ switch (vBorderStyle) {
+ case BORDER_STYLE_DASHED:
+ {
+ draw_dashed_border();
+ break;
+ }
+ case BORDER_STYLE_DOTTED:
+ {
+ draw_dotted_border();
+ break;
+ }
+ case BORDER_STYLE_OUTSET:
+ case BORDER_STYLE_INSET:
+ {
+ float color = step(0.0, vF);
+ oFragColor = mix(vVerticalColor, vHorizontalColor, color);
+ break;
+ }
+ case BORDER_STYLE_NONE:
+ case BORDER_STYLE_SOLID:
+ {
+ float color = step(0.0, vF);
+ oFragColor = mix(vHorizontalColor, vVerticalColor, color);
+ break;
+ }
+ default:
+ {
+ discard;
+ break;
+ }
+ }
+}
diff --git a/resources/shaders/ps_border.glsl b/resources/shaders/ps_border.glsl
new file mode 100644
index 00000000000..26a1a6601e9
--- /dev/null
+++ b/resources/shaders/ps_border.glsl
@@ -0,0 +1,24 @@
+#line 1
+
+/* 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/. */
+
+// These two are interpolated
+varying float vF; // This is a weighting as we get closer to the bottom right corner?
+
+// These are not changing.
+flat varying vec4 vVerticalColor; // The vertical color, e.g. top/bottom
+flat varying vec4 vHorizontalColor; // The horizontal color e.g. left/right
+flat varying vec4 vRadii; // The border radius from CSS border-radius
+
+// These are in device space
+varying vec2 vLocalPos; // The clamped position in local space.
+varying vec2 vDevicePos; // The clamped position in device space.
+flat varying vec4 vBorders; // the rect of the border in (x, y, width, height) form
+
+// for corners, this is the beginning of the corner.
+// For the lines, this is the top left of the line.
+flat varying vec2 vRefPoint;
+flat varying uint vBorderStyle;
+flat varying uint vBorderPart; // Which part of the border we're drawing.
diff --git a/resources/shaders/ps_border.vs.glsl b/resources/shaders/ps_border.vs.glsl
new file mode 100644
index 00000000000..99026b74eff
--- /dev/null
+++ b/resources/shaders/ps_border.vs.glsl
@@ -0,0 +1,113 @@
+#line 1
+/* 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/. */
+
+struct Border {
+ PrimitiveInfo info;
+ vec4 verticalColor;
+ vec4 horizontalColor;
+ vec4 radii;
+ uvec4 border_style_trbl;
+};
+
+layout(std140) uniform Items {
+ Border borders[WR_MAX_PRIM_ITEMS];
+};
+
+uint get_border_style(Border a_border, uint a_edge) {
+ switch (a_edge) {
+ case PST_TOP:
+ case PST_TOP_LEFT:
+ return a_border.border_style_trbl.x;
+ case PST_BOTTOM_LEFT:
+ case PST_LEFT:
+ return a_border.border_style_trbl.z;
+ case PST_BOTTOM_RIGHT:
+ case PST_BOTTOM:
+ return a_border.border_style_trbl.w;
+ case PST_TOP_RIGHT:
+ case PST_RIGHT:
+ return a_border.border_style_trbl.y;
+ }
+}
+
+void main(void) {
+ Border border = borders[gl_InstanceID];
+ VertexInfo vi = write_vertex(border.info);
+
+ // Just our boring radius position.
+ vRadii = border.radii;
+
+ float x0, y0, x1, y1;
+ vBorderPart = border.info.layer_tile_part.z;
+ switch (vBorderPart) {
+ // These are the layer tile part PrimitivePart as uploaded by the tiling.rs
+ case PST_TOP_LEFT:
+ x0 = border.info.local_rect.x;
+ y0 = border.info.local_rect.y;
+ // These are width / heights
+ x1 = border.info.local_rect.x + border.info.local_rect.z;
+ y1 = border.info.local_rect.y + border.info.local_rect.w;
+
+ // The radius here is the border-radius. This is 0, so vRefPoint will
+ // just be the top left (x,y) corner.
+ vRefPoint = vec2(x0, y0) + vRadii.xy;
+ break;
+ case PST_TOP_RIGHT:
+ x0 = border.info.local_rect.x + border.info.local_rect.z;
+ y0 = border.info.local_rect.y;
+ x1 = border.info.local_rect.x;
+ y1 = border.info.local_rect.y + border.info.local_rect.w;
+ vRefPoint = vec2(x0, y0) + vec2(-vRadii.x, vRadii.y);
+ break;
+ case PST_BOTTOM_LEFT:
+ x0 = border.info.local_rect.x;
+ y0 = border.info.local_rect.y + border.info.local_rect.w;
+ x1 = border.info.local_rect.x + border.info.local_rect.z;
+ y1 = border.info.local_rect.y;
+ vRefPoint = vec2(x0, y0) + vec2(vRadii.x, -vRadii.y);
+ break;
+ case PST_BOTTOM_RIGHT:
+ x0 = border.info.local_rect.x;
+ y0 = border.info.local_rect.y;
+ x1 = border.info.local_rect.x + border.info.local_rect.z;
+ y1 = border.info.local_rect.y + border.info.local_rect.w;
+ vRefPoint = vec2(x1, y1) + vec2(-vRadii.x, -vRadii.y);
+ break;
+ case PST_TOP:
+ case PST_LEFT:
+ case PST_BOTTOM:
+ case PST_RIGHT:
+ vRefPoint = border.info.local_rect.xy;
+ x0 = border.info.local_rect.x;
+ y0 = border.info.local_rect.y;
+ x1 = border.info.local_rect.x + border.info.local_rect.z;
+ y1 = border.info.local_rect.y + border.info.local_rect.w;
+ break;
+ }
+
+ vBorderStyle = get_border_style(border, vBorderPart);
+
+ // y1 - y0 is the height of the corner / line
+ // x1 - x0 is the width of the corner / line.
+ float width = x1 - x0;
+ float height = y1 - y0;
+ // This is just a weighting of the pixel colors it seems?
+ vF = (vi.local_clamped_pos.x - x0) * height - (vi.local_clamped_pos.y - y0) * width;
+
+ // This is what was currently sent.
+ vVerticalColor = border.verticalColor;
+ vHorizontalColor = border.horizontalColor;
+
+ // Local space
+ vLocalPos = vi.local_clamped_pos.xy;
+
+ // These are in device space
+ vDevicePos = vi.global_clamped_pos;
+
+ // These are in device space
+ vBorders = vec4(border.info.local_rect.x, border.info.local_rect.y,
+ border.info.local_rect.z,
+ border.info.local_rect.w) * uDevicePixelRatio;
+}
diff --git a/resources/shaders/ps_box_shadow.fs.glsl b/resources/shaders/ps_box_shadow.fs.glsl
new file mode 100644
index 00000000000..9c485cba9fe
--- /dev/null
+++ b/resources/shaders/ps_box_shadow.fs.glsl
@@ -0,0 +1,151 @@
+/* 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 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/. */
+
+// See http://asciimath.org to render the equations here.
+
+// The Gaussian function used for blurring:
+//
+// G_sigma(x) = 1/sqrt(2 pi sigma^2) e^(-x^2/(2 sigma^2))
+float gauss(float x, float sigma) {
+ float sigmaPow2 = sigma * sigma;
+ return 1.0 / sqrt(6.283185307179586 * sigmaPow2) * exp(-(x * x) / (2.0 * sigmaPow2));
+}
+
+// An approximation of the error function, which is related to the integral of the Gaussian
+// function:
+//
+// "erf"(x) = 2/sqrt(pi) int_0^x e^(-t^2) dt
+// ~~ 1 - 1 / (1 + a_1 x + a_2 x^2 + a_3 x^3 + a_4 x^4)^4
+//
+// where:
+//
+// a_1 = 0.278393, a_2 = 0.230389, a_3 = 0.000972, a_4 = 0.078108
+//
+// This approximation is accurate to `5 xx 10^-4`, more than accurate enough for our purposes.
+//
+// See: https://en.wikipedia.org/wiki/Error_function#Approximation_with_elementary_functions
+float erf(float x) {
+ bool negative = x < 0.0;
+ if (negative)
+ x = -x;
+ float x2 = x * x;
+ float x3 = x2 * x;
+ float x4 = x2 * x2;
+ float denom = 1.0 + 0.278393 * x + 0.230389 * x2 + 0.000972 * x3 + 0.078108 * x4;
+ float result = 1.0 - 1.0 / (denom * denom * denom * denom);
+ return negative ? -result : result;
+}
+
+// A useful helper for calculating integrals of the Gaussian function via the error function:
+//
+// "erf"_sigma(x) = 2 int 1/sqrt(2 pi sigma^2) e^(-x^2/(2 sigma^2)) dx
+// = "erf"(x/(sigma sqrt(2)))
+float erfSigma(float x, float sigma) {
+ return erf(x / (sigma * 1.4142135623730951));
+}
+
+// Returns the blurred color value from the box itself (not counting any rounded corners). `p_0` is
+// the vector distance to the top left corner of the box; `p_1` is the vector distance to its
+// bottom right corner.
+//
+// "colorFromRect"_sigma(p_0, p_1)
+// = int_{p_{0_y}}^{p_{1_y}} int_{p_{1_x}}^{p_{0_x}} G_sigma(y) G_sigma(x) dx dy
+// = 1/4 ("erf"_sigma(p_{1_x}) - "erf"_sigma(p_{0_x}))
+// ("erf"_sigma(p_{1_y}) - "erf"_sigma(p_{0_y}))
+float colorFromRect(vec2 p0, vec2 p1, float sigma) {
+ return (erfSigma(p1.x, sigma) - erfSigma(p0.x, sigma)) *
+ (erfSigma(p1.y, sigma) - erfSigma(p0.y, sigma)) / 4.0;
+}
+
+// Returns the `x` coordinate on the ellipse with the given radii for the given `y` coordinate:
+//
+// "ellipsePoint"(y, y_0, a, b) = a sqrt(1 - ((y - y_0) / b)^2)
+float ellipsePoint(float y, float y0, vec2 radii) {
+ float bStep = (y - y0) / radii.y;
+ return radii.x * sqrt(1.0 - bStep * bStep);
+}
+
+// A helper function to compute the value that needs to be subtracted to accommodate the border
+// corners.
+//
+// "colorCutout"_sigma(x_{0_l}, x_{0_r}, y_0, y_{min}, y_{max}, a, b)
+// = int_{y_{min}}^{y_{max}}
+// int_{x_{0_r} + "ellipsePoint"(y, y_0, a, b)}^{x_{0_r} + a} G_sigma(y) G_sigma(x) dx
+// + int_{x_{0_l} - a}^{x_{0_l} - "ellipsePoint"(y, y_0, a, b)} G_sigma(y) G_sigma(x)
+// dx dy
+// = int_{y_{min}}^{y_{max}} 1/2 G_sigma(y)
+// ("erf"_sigma(x_{0_r} + a) - "erf"_sigma(x_{0_r} + "ellipsePoint"(y, y_0, a, b)) +
+// "erf"_sigma(x_{0_l} - "ellipsePoint"(y, y_0, a, b)) - "erf"_sigma(x_{0_l} - a))
+//
+// with the outer integral evaluated numerically.
+float colorCutoutGeneral(float x0l,
+ float x0r,
+ float y0,
+ float yMin,
+ float yMax,
+ vec2 radii,
+ float sigma) {
+ float sum = 0.0;
+ for (float y = yMin; y <= yMax; y += 1.0) {
+ float xEllipsePoint = ellipsePoint(y, y0, radii);
+ sum += gauss(y, sigma) *
+ (erfSigma(x0r + radii.x, sigma) - erfSigma(x0r + xEllipsePoint, sigma) +
+ erfSigma(x0l - xEllipsePoint, sigma) - erfSigma(x0l - radii.x, sigma));
+ }
+ return sum / 2.0;
+}
+
+// The value that needs to be subtracted to accommodate the top border corners.
+float colorCutoutTop(float x0l, float x0r, float y0, vec2 radii, float sigma) {
+ return colorCutoutGeneral(x0l, x0r, y0, y0, y0 + radii.y, radii, sigma);
+}
+
+// The value that needs to be subtracted to accommodate the bottom border corners.
+float colorCutoutBottom(float x0l, float x0r, float y0, vec2 radii, float sigma) {
+ return colorCutoutGeneral(x0l, x0r, y0, y0 - radii.y, y0, radii, sigma);
+}
+
+// The blurred color value for the point at `pos` with the top left corner of the box at
+// `p_{0_"rect"}` and the bottom right corner of the box at `p_{1_"rect"}`.
+float color(vec2 pos, vec2 p0Rect, vec2 p1Rect, vec2 radii, float sigma) {
+ // Compute the vector distances `p_0` and `p_1`.
+ vec2 p0 = p0Rect - pos, p1 = p1Rect - pos;
+
+ // Compute the basic color `"colorFromRect"_sigma(p_0, p_1)`. This is all we have to do if
+ // the box is unrounded.
+ float cRect = colorFromRect(p0, p1, sigma);
+ if (radii.x == 0.0 || radii.y == 0.0)
+ return cRect;
+
+ // Compute the inner corners of the box, taking border radii into account: `x_{0_l}`,
+ // `y_{0_t}`, `x_{0_r}`, and `y_{0_b}`.
+ float x0l = p0.x + radii.x;
+ float y0t = p1.y - radii.y;
+ float x0r = p1.x - radii.x;
+ float y0b = p0.y + radii.y;
+
+ // Compute the final color:
+ //
+ // "colorFromRect"_sigma(p_0, p_1) -
+ // ("colorCutoutTop"_sigma(x_{0_l}, x_{0_r}, y_{0_t}, a, b) +
+ // "colorCutoutBottom"_sigma(x_{0_l}, x_{0_r}, y_{0_b}, a, b))
+ float cCutoutTop = colorCutoutTop(x0l, x0r, y0t, radii, sigma);
+ float cCutoutBottom = colorCutoutBottom(x0l, x0r, y0b, radii, sigma);
+ return cRect - (cCutoutTop + cCutoutBottom);
+}
+
+void main(void) {
+ vec2 pos = vPos.xy;
+ vec2 p0Rect = vBoxShadowRect.xy, p1Rect = vBoxShadowRect.zw;
+ vec2 radii = vBorderRadii.xy;
+ float sigma = vBlurRadius / 2.0;
+ float value = color(pos, p0Rect, p1Rect, radii, sigma);
+
+ value = max(value, 0.0);
+ oFragColor = vColor * vec4(1.0, 1.0, 1.0, vInverted == 1.0 ? 1.0 - value : value);
+}
diff --git a/resources/shaders/ps_box_shadow.glsl b/resources/shaders/ps_box_shadow.glsl
new file mode 100644
index 00000000000..26fdba588f3
--- /dev/null
+++ b/resources/shaders/ps_box_shadow.glsl
@@ -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/. */
+
+varying vec2 vPos;
+flat varying vec4 vColor;
+flat varying vec2 vBorderRadii;
+flat varying float vBlurRadius;
+flat varying vec4 vBoxShadowRect;
+flat varying vec4 vSrcRect;
+flat varying float vInverted;
diff --git a/resources/shaders/ps_box_shadow.vs.glsl b/resources/shaders/ps_box_shadow.vs.glsl
new file mode 100644
index 00000000000..cfcdacfa675
--- /dev/null
+++ b/resources/shaders/ps_box_shadow.vs.glsl
@@ -0,0 +1,29 @@
+#line 1
+/* 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/. */
+
+struct BoxShadow {
+ PrimitiveInfo info;
+ vec4 color;
+ vec4 border_radii_blur_radius_inverted;
+ vec4 bs_rect;
+ vec4 src_rect;
+};
+
+layout(std140) uniform Items {
+ BoxShadow boxshadows[WR_MAX_PRIM_ITEMS];
+};
+
+void main(void) {
+ BoxShadow bs = boxshadows[gl_InstanceID];
+ VertexInfo vi = write_vertex(bs.info);
+
+ vPos = vi.local_clamped_pos;
+ vColor = bs.color;
+ vBorderRadii = bs.border_radii_blur_radius_inverted.xy;
+ vBlurRadius = bs.border_radii_blur_radius_inverted.z;
+ vBoxShadowRect = vec4(bs.bs_rect.xy, bs.bs_rect.xy + bs.bs_rect.zw);
+ vSrcRect = vec4(bs.src_rect.xy, bs.src_rect.xy + bs.src_rect.zw);
+ vInverted = bs.border_radii_blur_radius_inverted.w;
+}
diff --git a/resources/shaders/ps_clear.fs.glsl b/resources/shaders/ps_clear.fs.glsl
new file mode 100644
index 00000000000..5ad3065f78d
--- /dev/null
+++ b/resources/shaders/ps_clear.fs.glsl
@@ -0,0 +1,7 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+void main(void) {
+ oFragColor = vec4(1, 1, 1, 1);
+}
diff --git a/resources/shaders/ps_clear.glsl b/resources/shaders/ps_clear.glsl
new file mode 100644
index 00000000000..e0032240a4d
--- /dev/null
+++ b/resources/shaders/ps_clear.glsl
@@ -0,0 +1,3 @@
+/* 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/. */
diff --git a/resources/shaders/ps_clear.vs.glsl b/resources/shaders/ps_clear.vs.glsl
new file mode 100644
index 00000000000..5d3012fe46c
--- /dev/null
+++ b/resources/shaders/ps_clear.vs.glsl
@@ -0,0 +1,23 @@
+#line 1
+
+/* 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/. */
+
+struct ClearTile {
+ uvec4 rect;
+};
+
+layout(std140) uniform Tiles {
+ ClearTile tiles[WR_MAX_CLEAR_TILES];
+};
+
+
+void main() {
+ ClearTile tile = tiles[gl_InstanceID];
+
+ vec4 rect = vec4(tile.rect);
+
+ vec4 pos = vec4(mix(rect.xy, rect.xy + rect.zw, aPosition.xy), 0, 1);
+ gl_Position = uTransform * pos;
+}
diff --git a/resources/shaders/ps_composite.fs.glsl b/resources/shaders/ps_composite.fs.glsl
new file mode 100644
index 00000000000..c4e4099655b
--- /dev/null
+++ b/resources/shaders/ps_composite.fs.glsl
@@ -0,0 +1,320 @@
+#line 1
+
+/* 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/. */
+
+#define COMPOSITE_KIND_MIX_BLEND_MODE 0
+#define COMPOSITE_KIND_FILTER 1
+
+uniform sampler2D sCache;
+
+vec3 rgbToHsv(vec3 c) {
+ float value = max(max(c.r, c.g), c.b);
+
+ float chroma = value - min(min(c.r, c.g), c.b);
+ if (chroma == 0.0) {
+ return vec3(0.0);
+ }
+ float saturation = chroma / value;
+
+ float hue;
+ if (c.r == value)
+ hue = (c.g - c.b) / chroma;
+ else if (c.g == value)
+ hue = 2.0 + (c.b - c.r) / chroma;
+ else // if (c.b == value)
+ hue = 4.0 + (c.r - c.g) / chroma;
+
+ hue *= 1.0/6.0;
+ if (hue < 0.0)
+ hue += 1.0;
+ return vec3(hue, saturation, value);
+}
+
+vec3 hsvToRgb(vec3 c) {
+ if (c.s == 0.0) {
+ return vec3(c.z);
+ }
+
+ float hue = c.x * 6.0;
+ int sector = int(hue);
+ float residualHue = hue - float(sector);
+
+ vec3 pqt = c.z * vec3(1.0 - c.y, 1.0 - c.y * residualHue, 1.0 - c.y * (1.0 - residualHue));
+ if (sector == 0)
+ return vec3(c.z, pqt.z, pqt.x);
+ if (sector == 1)
+ return vec3(pqt.y, c.z, pqt.x);
+ if (sector == 2)
+ return vec3(pqt.x, c.z, pqt.z);
+ if (sector == 3)
+ return vec3(pqt.x, pqt.y, c.z);
+ if (sector == 4)
+ return vec3(pqt.z, pqt.x, c.z);
+ return vec3(c.z, pqt.x, pqt.y);
+}
+
+float gauss(float x, float sigma) {
+ if (sigma == 0.0)
+ return 1.0;
+ return (1.0 / sqrt(6.283185307179586 * sigma * sigma)) * exp(-(x * x) / (2.0 * sigma * sigma));
+}
+
+vec4 Blur(float radius, vec2 direction) {
+ // TODO(gw): Support blur in WR2!
+ return vec4(1, 1, 1, 1);
+}
+
+vec4 Contrast(vec4 Cs, float amount) {
+ return vec4(Cs.rgb * amount - 0.5 * amount + 0.5, 1.0);
+}
+
+vec4 Grayscale(vec4 Cs, float amount) {
+ float ia = 1.0 - amount;
+ return mat4(vec4(0.2126 + 0.7874 * ia, 0.2126 - 0.2126 * ia, 0.2126 - 0.2126 * ia, 0.0),
+ vec4(0.7152 - 0.7152 * ia, 0.7152 + 0.2848 * ia, 0.7152 - 0.7152 * ia, 0.0),
+ vec4(0.0722 - 0.0722 * ia, 0.0722 - 0.0722 * ia, 0.0722 + 0.9278 * ia, 0.0),
+ vec4(0.0, 0.0, 0.0, 1.0)) * Cs;
+}
+
+vec4 HueRotate(vec4 Cs, float amount) {
+ vec3 CsHsv = rgbToHsv(Cs.rgb);
+ CsHsv.x = mod(CsHsv.x + amount / 6.283185307179586, 1.0);
+ return vec4(hsvToRgb(CsHsv), Cs.a);
+}
+
+vec4 Invert(vec4 Cs, float amount) {
+ return mix(Cs, vec4(1.0, 1.0, 1.0, Cs.a) - vec4(Cs.rgb, 0.0), amount);
+}
+
+vec4 Saturate(vec4 Cs, float amount) {
+ return vec4(hsvToRgb(min(vec3(1.0, amount, 1.0) * rgbToHsv(Cs.rgb), vec3(1.0))), Cs.a);
+}
+
+vec4 Sepia(vec4 Cs, float amount) {
+ float ia = 1.0 - amount;
+ return mat4(vec4(0.393 + 0.607 * ia, 0.349 - 0.349 * ia, 0.272 - 0.272 * ia, 0.0),
+ vec4(0.769 - 0.769 * ia, 0.686 + 0.314 * ia, 0.534 - 0.534 * ia, 0.0),
+ vec4(0.189 - 0.189 * ia, 0.168 - 0.168 * ia, 0.131 + 0.869 * ia, 0.0),
+ vec4(0.0, 0.0, 0.0, 1.0)) * Cs;
+}
+
+vec3 Multiply(vec3 Cb, vec3 Cs) {
+ return Cb * Cs;
+}
+
+vec3 Screen(vec3 Cb, vec3 Cs) {
+ return Cb + Cs - (Cb * Cs);
+}
+
+vec3 HardLight(vec3 Cb, vec3 Cs) {
+ vec3 m = Multiply(Cb, 2.0 * Cs);
+ vec3 s = Screen(Cb, 2.0 * Cs - 1.0);
+ vec3 edge = vec3(0.5, 0.5, 0.5);
+ return mix(m, s, step(edge, Cs));
+}
+
+// TODO: Worth doing with mix/step? Check GLSL output.
+float ColorDodge(float Cb, float Cs) {
+ if (Cb == 0.0)
+ return 0.0;
+ else if (Cs == 1.0)
+ return 1.0;
+ else
+ return min(1.0, Cb / (1.0 - Cs));
+}
+
+// TODO: Worth doing with mix/step? Check GLSL output.
+float ColorBurn(float Cb, float Cs) {
+ if (Cb == 1.0)
+ return 1.0;
+ else if (Cs == 0.0)
+ return 0.0;
+ else
+ return 1.0 - min(1.0, (1.0 - Cb) / Cs);
+}
+
+float SoftLight(float Cb, float Cs) {
+ if (Cs <= 0.5) {
+ return Cb - (1.0 - 2.0 * Cs) * Cb * (1.0 - Cb);
+ } else {
+ float D;
+
+ if (Cb <= 0.25)
+ D = ((16.0 * Cb - 12.0) * Cb + 4.0) * Cb;
+ else
+ D = sqrt(Cb);
+
+ return Cb + (2.0 * Cs - 1.0) * (D - Cb);
+ }
+}
+
+vec3 Difference(vec3 Cb, vec3 Cs) {
+ return abs(Cb - Cs);
+}
+
+vec3 Exclusion(vec3 Cb, vec3 Cs) {
+ return Cb + Cs - 2.0 * Cb * Cs;
+}
+
+// These functions below are taken from the spec.
+// There's probably a much quicker way to implement
+// them in GLSL...
+float Sat(vec3 c) {
+ return max(c.r, max(c.g, c.b)) - min(c.r, min(c.g, c.b));
+}
+
+float Lum(vec3 c) {
+ vec3 f = vec3(0.3, 0.59, 0.11);
+ return dot(c, f);
+}
+
+vec3 ClipColor(vec3 C) {
+ float L = Lum(C);
+ float n = min(C.r, min(C.g, C.b));
+ float x = max(C.r, max(C.g, C.b));
+
+ if (n < 0.0)
+ C = L + (((C - L) * L) / (L - n));
+
+ if (x > 1.0)
+ C = L + (((C - L) * (1.0 - L)) / (x - L));
+
+ return C;
+}
+
+vec3 SetLum(vec3 C, float l) {
+ float d = l - Lum(C);
+ return ClipColor(C + d);
+}
+
+void SetSatInner(inout float Cmin, inout float Cmid, inout float Cmax, float s) {
+ if (Cmax > Cmin) {
+ Cmid = (((Cmid - Cmin) * s) / (Cmax - Cmin));
+ Cmax = s;
+ } else {
+ Cmid = 0.0;
+ Cmax = 0.0;
+ }
+ Cmin = 0.0;
+}
+
+vec3 SetSat(vec3 C, float s) {
+ if (C.r <= C.g) {
+ if (C.g <= C.b) {
+ SetSatInner(C.r, C.g, C.b, s);
+ } else {
+ if (C.r <= C.b) {
+ SetSatInner(C.r, C.b, C.g, s);
+ } else {
+ SetSatInner(C.b, C.r, C.g, s);
+ }
+ }
+ } else {
+ if (C.r <= C.b) {
+ SetSatInner(C.g, C.r, C.b, s);
+ } else {
+ if (C.g <= C.b) {
+ SetSatInner(C.g, C.b, C.r, s);
+ } else {
+ SetSatInner(C.b, C.g, C.r, s);
+ }
+ }
+ }
+ return C;
+}
+
+vec3 Hue(vec3 Cb, vec3 Cs) {
+ return SetLum(SetSat(Cs, Sat(Cb)), Lum(Cb));
+}
+
+vec3 Saturation(vec3 Cb, vec3 Cs) {
+ return SetLum(SetSat(Cb, Sat(Cs)), Lum(Cb));
+}
+
+vec3 Color(vec3 Cb, vec3 Cs) {
+ return SetLum(Cs, Lum(Cb));
+}
+
+vec3 Luminosity(vec3 Cb, vec3 Cs) {
+ return SetLum(Cb, Lum(Cs));
+}
+
+void main(void) {
+ vec4 Cs = texture(sCache, vUv1);
+ vec4 Cb = texture(sCache, vUv0);
+
+ // TODO(gw): This is a hack that's (probably) wrong.
+ // Instead of drawing the tile rect, draw the
+ // stacking context bounds instead?
+ if (Cs.a == 0.0) {
+ oFragColor = Cb;
+ return;
+ }
+
+ int kind = vInfo.x;
+ int op = vInfo.y;
+ float amount = vAmount;
+
+ // Return yellow if none of the branches match (shouldn't happen).
+ vec4 result = vec4(1.0, 1.0, 0.0, 1.0);
+
+ switch (kind) {
+ case COMPOSITE_KIND_MIX_BLEND_MODE:
+ if (op == 2) {
+ result.rgb = Screen(Cb.rgb, Cs.rgb);
+ } else if (op == 3) {
+ result.rgb = HardLight(Cs.rgb, Cb.rgb); // Overlay is inverse of Hardlight
+ } else if (op == 6) {
+ result.r = ColorDodge(Cb.r, Cs.r);
+ result.g = ColorDodge(Cb.g, Cs.g);
+ result.b = ColorDodge(Cb.b, Cs.b);
+ } else if (op == 7) {
+ result.r = ColorBurn(Cb.r, Cs.r);
+ result.g = ColorBurn(Cb.g, Cs.g);
+ result.b = ColorBurn(Cb.b, Cs.b);
+ } else if (op == 8) {
+ result.rgb = HardLight(Cb.rgb, Cs.rgb);
+ } else if (op == 9) {
+ result.r = SoftLight(Cb.r, Cs.r);
+ result.g = SoftLight(Cb.g, Cs.g);
+ result.b = SoftLight(Cb.b, Cs.b);
+ } else if (op == 10) {
+ result.rgb = Difference(Cb.rgb, Cs.rgb);
+ } else if (op == 11) {
+ result.rgb = Exclusion(Cb.rgb, Cs.rgb);
+ } else if (op == 12) {
+ result.rgb = Hue(Cb.rgb, Cs.rgb);
+ } else if (op == 13) {
+ result.rgb = Saturation(Cb.rgb, Cs.rgb);
+ } else if (op == 14) {
+ result.rgb = Color(Cb.rgb, Cs.rgb);
+ } else if (op == 15) {
+ result.rgb = Luminosity(Cb.rgb, Cs.rgb);
+ }
+ break;
+ case COMPOSITE_KIND_FILTER:
+ if (op == 0) {
+ // Gaussian blur is specially handled:
+ result = Cs;// Blur(amount, vec2(0,0));
+ } else {
+ if (op == 1) {
+ result = Contrast(Cs, amount);
+ } else if (op == 2) {
+ result = Grayscale(Cs, amount);
+ } else if (op == 3) {
+ result = HueRotate(Cs, amount);
+ } else if (op == 4) {
+ result = Invert(Cs, amount);
+ } else if (op == 5) {
+ result = Saturate(Cs, amount);
+ } else if (op == 6) {
+ result = Sepia(Cs, amount);
+ }
+ }
+ break;
+ }
+
+ oFragColor = result;
+}
diff --git a/resources/shaders/ps_composite.glsl b/resources/shaders/ps_composite.glsl
new file mode 100644
index 00000000000..68a8f978103
--- /dev/null
+++ b/resources/shaders/ps_composite.glsl
@@ -0,0 +1,8 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+varying vec2 vUv0;
+varying vec2 vUv1;
+flat varying ivec2 vInfo;
+flat varying float vAmount;
diff --git a/resources/shaders/ps_composite.vs.glsl b/resources/shaders/ps_composite.vs.glsl
new file mode 100644
index 00000000000..c7f9cd05538
--- /dev/null
+++ b/resources/shaders/ps_composite.vs.glsl
@@ -0,0 +1,37 @@
+#line 1
+/* 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/. */
+
+struct Composite {
+ uvec4 src0;
+ uvec4 src1;
+ uvec4 target_rect;
+ ivec4 info;
+ vec4 amount;
+};
+
+layout(std140) uniform Items {
+ Composite composites[WR_MAX_PRIM_ITEMS];
+};
+
+void main(void) {
+ Composite composite = composites[gl_InstanceID];
+
+ vec2 local_pos = mix(vec2(composite.target_rect.xy),
+ vec2(composite.target_rect.xy + composite.target_rect.zw),
+ aPosition.xy);
+
+ vec2 st0 = vec2(composite.src0.xy) / 2048.0;
+ vec2 st1 = vec2(composite.src0.xy + composite.src0.zw) / 2048.0;
+ vUv0 = mix(st0, st1, aPosition.xy);
+
+ st0 = vec2(composite.src1.xy) / 2048.0;
+ st1 = vec2(composite.src1.xy + composite.src1.zw) / 2048.0;
+ vUv1 = mix(st0, st1, aPosition.xy);
+
+ vInfo = composite.info.xy;
+ vAmount = composite.amount.x;
+
+ gl_Position = uTransform * vec4(local_pos, 0, 1);
+}
diff --git a/resources/shaders/ps_gradient.fs.glsl b/resources/shaders/ps_gradient.fs.glsl
new file mode 100644
index 00000000000..b25faec6f54
--- /dev/null
+++ b/resources/shaders/ps_gradient.fs.glsl
@@ -0,0 +1,8 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+void main(void) {
+ do_clip(vPos, vClipRect, vClipRadius);
+ oFragColor = mix(vColor0, vColor1, vF);
+}
diff --git a/resources/shaders/ps_gradient.glsl b/resources/shaders/ps_gradient.glsl
new file mode 100644
index 00000000000..4b1efa7644d
--- /dev/null
+++ b/resources/shaders/ps_gradient.glsl
@@ -0,0 +1,10 @@
+/* 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/. */
+
+varying float vF;
+varying vec2 vPos;
+flat varying vec4 vColor0;
+flat varying vec4 vColor1;
+flat varying vec4 vClipRect;
+flat varying vec4 vClipRadius;
diff --git a/resources/shaders/ps_gradient.vs.glsl b/resources/shaders/ps_gradient.vs.glsl
new file mode 100644
index 00000000000..60977165a2c
--- /dev/null
+++ b/resources/shaders/ps_gradient.vs.glsl
@@ -0,0 +1,45 @@
+#line 1
+/* 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/. */
+
+#define DIR_HORIZONTAL uint(0)
+#define DIR_VERTICAL uint(1)
+
+struct Gradient {
+ PrimitiveInfo info;
+ vec4 color0;
+ vec4 color1;
+ uvec4 dir;
+ Clip clip;
+};
+
+layout(std140) uniform Items {
+ Gradient gradients[WR_MAX_PRIM_ITEMS];
+};
+
+void main(void) {
+ Gradient gradient = gradients[gl_InstanceID];
+ VertexInfo vi = write_vertex(gradient.info);
+
+ vec2 f = (vi.local_clamped_pos - gradient.info.local_rect.xy) / gradient.info.local_rect.zw;
+
+ switch (gradient.dir.x) {
+ case DIR_HORIZONTAL:
+ vF = f.x;
+ break;
+ case DIR_VERTICAL:
+ vF = f.y;
+ break;
+ }
+
+ vClipRect = vec4(gradient.clip.rect.xy, gradient.clip.rect.xy + gradient.clip.rect.zw);
+ vClipRadius = vec4(gradient.clip.top_left.outer_inner_radius.x,
+ gradient.clip.top_right.outer_inner_radius.x,
+ gradient.clip.bottom_right.outer_inner_radius.x,
+ gradient.clip.bottom_left.outer_inner_radius.x);
+ vPos = vi.local_clamped_pos;
+
+ vColor0 = gradient.color0;
+ vColor1 = gradient.color1;
+}
diff --git a/resources/shaders/ps_image.fs.glsl b/resources/shaders/ps_image.fs.glsl
new file mode 100644
index 00000000000..a7d96850057
--- /dev/null
+++ b/resources/shaders/ps_image.fs.glsl
@@ -0,0 +1,8 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+void main(void) {
+ vec2 st = vTextureOffset + vTextureSize * fract(vUv);
+ oFragColor = texture(sDiffuse, st);
+}
diff --git a/resources/shaders/ps_image.glsl b/resources/shaders/ps_image.glsl
new file mode 100644
index 00000000000..e2c59d9ff69
--- /dev/null
+++ b/resources/shaders/ps_image.glsl
@@ -0,0 +1,7 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+varying vec2 vUv; // Location within the CSS box to draw.
+flat varying vec2 vTextureOffset; // Offset of this image into the texture atlas.
+flat varying vec2 vTextureSize; // Size of the image in the texture atlas.
diff --git a/resources/shaders/ps_image.vs.glsl b/resources/shaders/ps_image.vs.glsl
new file mode 100644
index 00000000000..0f6bcba6eba
--- /dev/null
+++ b/resources/shaders/ps_image.vs.glsl
@@ -0,0 +1,24 @@
+#line 1
+/* 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/. */
+
+struct Image {
+ PrimitiveInfo info;
+ vec4 st_rect; // Location of the image texture in the texture atlas.
+ vec4 stretch_size; // Size of the actual image.
+};
+
+layout(std140) uniform Items {
+ Image images[WR_MAX_PRIM_ITEMS];
+};
+
+void main(void) {
+ Image image = images[gl_InstanceID];
+ VertexInfo vi = write_vertex(image.info);
+
+ // vUv will contain how many times this image has wrapped around the image size.
+ vUv = (vi.local_clamped_pos - vi.local_rect.p0) / image.stretch_size.xy;
+ vTextureSize = image.st_rect.zw - image.st_rect.xy;
+ vTextureOffset = image.st_rect.xy;
+}
diff --git a/resources/shaders/ps_image_clip.fs.glsl b/resources/shaders/ps_image_clip.fs.glsl
new file mode 100644
index 00000000000..2ec824e4414
--- /dev/null
+++ b/resources/shaders/ps_image_clip.fs.glsl
@@ -0,0 +1,9 @@
+/* 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/. */
+
+void main(void) {
+ do_clip(vPos, vClipRect, vClipRadius);
+ vec2 st = vTextureOffset + vTextureSize * fract(vUv);
+ oFragColor = texture(sDiffuse, st);
+}
diff --git a/resources/shaders/ps_image_clip.glsl b/resources/shaders/ps_image_clip.glsl
new file mode 100644
index 00000000000..4ddd1a53290
--- /dev/null
+++ b/resources/shaders/ps_image_clip.glsl
@@ -0,0 +1,10 @@
+/* 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/. */
+
+varying vec2 vUv; // Location within the CSS box to draw.
+varying vec2 vPos;
+flat varying vec2 vTextureOffset; // Offset of this image into the texture atlas.
+flat varying vec2 vTextureSize; // Size of the image in the texture atlas.
+flat varying vec4 vClipRect;
+flat varying vec4 vClipRadius;
diff --git a/resources/shaders/ps_image_clip.vs.glsl b/resources/shaders/ps_image_clip.vs.glsl
new file mode 100644
index 00000000000..89c6198f990
--- /dev/null
+++ b/resources/shaders/ps_image_clip.vs.glsl
@@ -0,0 +1,32 @@
+#line 1
+/* 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/. */
+
+struct Image {
+ PrimitiveInfo info;
+ vec4 st_rect; // Location of the image texture in the texture atlas.
+ vec4 stretch_size; // Size of the actual image.
+ Clip clip;
+};
+
+layout(std140) uniform Items {
+ Image images[WR_MAX_PRIM_ITEMS];
+};
+
+void main(void) {
+ Image image = images[gl_InstanceID];
+ VertexInfo vi = write_vertex(image.info);
+
+ vClipRect = vec4(image.clip.rect.xy, image.clip.rect.xy + image.clip.rect.zw);
+ vClipRadius = vec4(image.clip.top_left.outer_inner_radius.x,
+ image.clip.top_right.outer_inner_radius.x,
+ image.clip.bottom_right.outer_inner_radius.x,
+ image.clip.bottom_left.outer_inner_radius.x);
+ vPos = vi.local_clamped_pos;
+
+ // vUv will contain how many times this image has wrapped around the image size.
+ vUv = (vi.local_clamped_pos - image.info.local_rect.xy) / image.stretch_size.xy;
+ vTextureSize = image.st_rect.zw - image.st_rect.xy;
+ vTextureOffset = image.st_rect.xy;
+}
diff --git a/resources/shaders/ps_image_transform.fs.glsl b/resources/shaders/ps_image_transform.fs.glsl
new file mode 100644
index 00000000000..57fdc563ade
--- /dev/null
+++ b/resources/shaders/ps_image_transform.fs.glsl
@@ -0,0 +1,13 @@
+/* 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/. */
+
+void main(void) {
+ vec2 pos = vPos.xy / vPos.z;
+
+ if (!point_in_rect(pos, vRect.xy, vRect.xy + vRect.zw)) {
+ discard;
+ }
+
+ oFragColor = texture(sDiffuse, vUv / vPos.z);
+}
diff --git a/resources/shaders/ps_image_transform.glsl b/resources/shaders/ps_image_transform.glsl
new file mode 100644
index 00000000000..77c0eb20719
--- /dev/null
+++ b/resources/shaders/ps_image_transform.glsl
@@ -0,0 +1,8 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+varying vec2 vUv;
+
+varying vec3 vPos;
+flat varying vec4 vRect;
diff --git a/resources/shaders/ps_image_transform.vs.glsl b/resources/shaders/ps_image_transform.vs.glsl
new file mode 100644
index 00000000000..b9fcf7c24c2
--- /dev/null
+++ b/resources/shaders/ps_image_transform.vs.glsl
@@ -0,0 +1,65 @@
+#line 1
+/* 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/. */
+
+struct Image {
+ PrimitiveInfo info;
+ vec4 st_rect;
+ vec4 stretch_size; // Size of the actual image.
+};
+
+layout(std140) uniform Items {
+ Image images[WR_MAX_PRIM_ITEMS];
+};
+
+void main(void) {
+ Image image = images[gl_InstanceID];
+ Layer layer = layers[image.info.layer_tile_part.x];
+ Tile tile = tiles[image.info.layer_tile_part.y];
+
+ vec2 p0 = image.info.local_rect.xy;
+ vec2 p1 = image.info.local_rect.xy + vec2(image.info.local_rect.z, 0.0);
+ vec2 p2 = image.info.local_rect.xy + vec2(0.0, image.info.local_rect.w);
+ vec2 p3 = image.info.local_rect.xy + image.info.local_rect.zw;
+
+ vec4 t0 = layer.transform * vec4(p0, 0, 1);
+ vec4 t1 = layer.transform * vec4(p1, 0, 1);
+ vec4 t2 = layer.transform * vec4(p2, 0, 1);
+ vec4 t3 = layer.transform * vec4(p3, 0, 1);
+
+ vec2 tp0 = t0.xy / t0.w;
+ vec2 tp1 = t1.xy / t1.w;
+ vec2 tp2 = t2.xy / t2.w;
+ vec2 tp3 = t3.xy / t3.w;
+
+ vec2 min_pos = min(tp0.xy, min(tp1.xy, min(tp2.xy, tp3.xy)));
+ vec2 max_pos = max(tp0.xy, max(tp1.xy, max(tp2.xy, tp3.xy)));
+
+ vec2 min_pos_clamped = clamp(min_pos * uDevicePixelRatio,
+ vec2(tile.actual_rect.xy),
+ vec2(tile.actual_rect.xy + tile.actual_rect.zw));
+
+ vec2 max_pos_clamped = clamp(max_pos * uDevicePixelRatio,
+ vec2(tile.actual_rect.xy),
+ vec2(tile.actual_rect.xy + tile.actual_rect.zw));
+
+ vec2 clamped_pos = mix(min_pos_clamped,
+ max_pos_clamped,
+ aPosition.xy);
+
+ vec3 layer_pos = get_layer_pos(clamped_pos / uDevicePixelRatio, image.info.layer_tile_part.x);
+
+ vRect = image.info.local_rect;
+ vPos = layer_pos;
+
+ vec2 f = (layer_pos.xy - image.info.local_rect.xy) / image.info.local_rect.zw;
+
+ vUv = mix(image.st_rect.xy,
+ image.st_rect.zw,
+ f);
+
+ vec2 final_pos = clamped_pos + vec2(tile.target_rect.xy) - vec2(tile.actual_rect.xy);
+
+ gl_Position = uTransform * vec4(final_pos, 0, 1);
+}
diff --git a/resources/shaders/ps_rectangle.fs.glsl b/resources/shaders/ps_rectangle.fs.glsl
new file mode 100644
index 00000000000..61837732d31
--- /dev/null
+++ b/resources/shaders/ps_rectangle.fs.glsl
@@ -0,0 +1,7 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+void main(void) {
+ oFragColor = vColor;
+}
diff --git a/resources/shaders/ps_rectangle.glsl b/resources/shaders/ps_rectangle.glsl
new file mode 100644
index 00000000000..6fcfc4255bf
--- /dev/null
+++ b/resources/shaders/ps_rectangle.glsl
@@ -0,0 +1,5 @@
+/* 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/. */
+
+varying vec4 vColor;
diff --git a/resources/shaders/ps_rectangle.vs.glsl b/resources/shaders/ps_rectangle.vs.glsl
new file mode 100644
index 00000000000..01a4e5dc185
--- /dev/null
+++ b/resources/shaders/ps_rectangle.vs.glsl
@@ -0,0 +1,19 @@
+#line 1
+/* 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/. */
+
+struct Rectangle {
+ PrimitiveInfo info;
+ vec4 color;
+};
+
+layout(std140) uniform Items {
+ Rectangle rects[WR_MAX_PRIM_ITEMS];
+};
+
+void main(void) {
+ Rectangle rect = rects[gl_InstanceID];
+ write_vertex(rect.info);
+ vColor = rect.color;
+}
diff --git a/resources/shaders/ps_rectangle_clip.fs.glsl b/resources/shaders/ps_rectangle_clip.fs.glsl
new file mode 100644
index 00000000000..fe3af9162ad
--- /dev/null
+++ b/resources/shaders/ps_rectangle_clip.fs.glsl
@@ -0,0 +1,9 @@
+/* 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/. */
+
+void main(void) {
+ do_clip(vPos, vClipRect, vClipRadius);
+
+ oFragColor = vColor;
+}
diff --git a/resources/shaders/ps_rectangle_clip.glsl b/resources/shaders/ps_rectangle_clip.glsl
new file mode 100644
index 00000000000..3d50dd162a5
--- /dev/null
+++ b/resources/shaders/ps_rectangle_clip.glsl
@@ -0,0 +1,10 @@
+#line 1
+
+/* 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/. */
+
+varying vec4 vColor;
+varying vec2 vPos;
+flat varying vec4 vClipRect;
+flat varying vec4 vClipRadius;
diff --git a/resources/shaders/ps_rectangle_clip.vs.glsl b/resources/shaders/ps_rectangle_clip.vs.glsl
new file mode 100644
index 00000000000..b181638d010
--- /dev/null
+++ b/resources/shaders/ps_rectangle_clip.vs.glsl
@@ -0,0 +1,28 @@
+#line 1
+/* 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/. */
+
+struct Rectangle {
+ PrimitiveInfo info;
+ vec4 color;
+ Clip clip;
+};
+
+layout(std140) uniform Items {
+ Rectangle rects[WR_MAX_PRIM_ITEMS];
+};
+
+void main(void) {
+ Rectangle rect = rects[gl_InstanceID];
+ VertexInfo vi = write_vertex(rect.info);
+
+ vClipRect = vec4(rect.clip.rect.xy, rect.clip.rect.xy + rect.clip.rect.zw);
+ vClipRadius = vec4(rect.clip.top_left.outer_inner_radius.x,
+ rect.clip.top_right.outer_inner_radius.x,
+ rect.clip.bottom_right.outer_inner_radius.x,
+ rect.clip.bottom_left.outer_inner_radius.x);
+ vPos = vi.local_clamped_pos;
+
+ vColor = rect.color;
+}
diff --git a/resources/shaders/ps_rectangle_transform.fs.glsl b/resources/shaders/ps_rectangle_transform.fs.glsl
new file mode 100644
index 00000000000..a8ac40a8451
--- /dev/null
+++ b/resources/shaders/ps_rectangle_transform.fs.glsl
@@ -0,0 +1,13 @@
+/* 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/. */
+
+void main(void) {
+ vec2 pos = vPos.xy / vPos.z;
+
+ if (!point_in_rect(pos, vRect.xy, vRect.xy + vRect.zw)) {
+ discard;
+ }
+
+ oFragColor = vColor;
+}
diff --git a/resources/shaders/ps_rectangle_transform.glsl b/resources/shaders/ps_rectangle_transform.glsl
new file mode 100644
index 00000000000..0ae7f839aa9
--- /dev/null
+++ b/resources/shaders/ps_rectangle_transform.glsl
@@ -0,0 +1,8 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+varying vec4 vColor;
+
+varying vec3 vPos;
+flat varying vec4 vRect;
diff --git a/resources/shaders/ps_rectangle_transform.vs.glsl b/resources/shaders/ps_rectangle_transform.vs.glsl
new file mode 100644
index 00000000000..0df46710492
--- /dev/null
+++ b/resources/shaders/ps_rectangle_transform.vs.glsl
@@ -0,0 +1,59 @@
+#line 1
+/* 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/. */
+
+struct Rectangle {
+ PrimitiveInfo info;
+ vec4 color;
+};
+
+layout(std140) uniform Items {
+ Rectangle rects[WR_MAX_PRIM_ITEMS];
+};
+
+void main(void) {
+ Rectangle rect = rects[gl_InstanceID];
+ Layer layer = layers[rect.info.layer_tile_part.x];
+ Tile tile = tiles[rect.info.layer_tile_part.y];
+
+ vec2 p0 = rect.info.local_rect.xy;
+ vec2 p1 = rect.info.local_rect.xy + vec2(rect.info.local_rect.z, 0.0);
+ vec2 p2 = rect.info.local_rect.xy + vec2(0.0, rect.info.local_rect.w);
+ vec2 p3 = rect.info.local_rect.xy + rect.info.local_rect.zw;
+
+ vec4 t0 = layer.transform * vec4(p0, 0, 1);
+ vec4 t1 = layer.transform * vec4(p1, 0, 1);
+ vec4 t2 = layer.transform * vec4(p2, 0, 1);
+ vec4 t3 = layer.transform * vec4(p3, 0, 1);
+
+ vec2 tp0 = t0.xy / t0.w;
+ vec2 tp1 = t1.xy / t1.w;
+ vec2 tp2 = t2.xy / t2.w;
+ vec2 tp3 = t3.xy / t3.w;
+
+ vec2 min_pos = min(tp0.xy, min(tp1.xy, min(tp2.xy, tp3.xy)));
+ vec2 max_pos = max(tp0.xy, max(tp1.xy, max(tp2.xy, tp3.xy)));
+
+ vec2 min_pos_clamped = clamp(min_pos * uDevicePixelRatio,
+ vec2(tile.actual_rect.xy),
+ vec2(tile.actual_rect.xy + tile.actual_rect.zw));
+
+ vec2 max_pos_clamped = clamp(max_pos * uDevicePixelRatio,
+ vec2(tile.actual_rect.xy),
+ vec2(tile.actual_rect.xy + tile.actual_rect.zw));
+
+ vec2 clamped_pos = mix(min_pos_clamped,
+ max_pos_clamped,
+ aPosition.xy);
+
+ vec3 layer_pos = get_layer_pos(clamped_pos / uDevicePixelRatio, rect.info.layer_tile_part.x);
+
+ vRect = rect.info.local_rect;
+ vPos = layer_pos;
+ vColor = rect.color;
+
+ vec2 final_pos = clamped_pos + vec2(tile.target_rect.xy) - vec2(tile.actual_rect.xy);
+
+ gl_Position = uTransform * vec4(final_pos, 0, 1);
+}
diff --git a/resources/shaders/ps_text.fs.glsl b/resources/shaders/ps_text.fs.glsl
new file mode 100644
index 00000000000..175102f790e
--- /dev/null
+++ b/resources/shaders/ps_text.fs.glsl
@@ -0,0 +1,8 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+void main(void) {
+ float a = texture(sDiffuse, vUv).a;
+ oFragColor = vec4(vColor.rgb, vColor.a * a);
+}
diff --git a/resources/shaders/ps_text.glsl b/resources/shaders/ps_text.glsl
new file mode 100644
index 00000000000..dad284fb0a2
--- /dev/null
+++ b/resources/shaders/ps_text.glsl
@@ -0,0 +1,6 @@
+/* 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/. */
+
+flat varying vec4 vColor;
+varying vec2 vUv;
diff --git a/resources/shaders/ps_text.vs.glsl b/resources/shaders/ps_text.vs.glsl
new file mode 100644
index 00000000000..39e72bf8688
--- /dev/null
+++ b/resources/shaders/ps_text.vs.glsl
@@ -0,0 +1,26 @@
+#line 1
+/* 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/. */
+
+struct Glyph {
+ PrimitiveInfo info;
+ vec4 color;
+ vec4 st_rect;
+};
+
+layout(std140) uniform Items {
+ Glyph glyphs[WR_MAX_PRIM_ITEMS];
+};
+
+void main(void) {
+ Glyph glyph = glyphs[gl_InstanceID];
+ VertexInfo vi = write_vertex(glyph.info);
+
+ vec2 f = (vi.local_clamped_pos - vi.local_rect.p0) / (vi.local_rect.p1 - vi.local_rect.p0);
+
+ vColor = glyph.color;
+ vUv = mix(glyph.st_rect.xy,
+ glyph.st_rect.zw,
+ f);
+}
diff --git a/resources/shaders/shared.glsl b/resources/shaders/shared.glsl
new file mode 100644
index 00000000000..4696272d0f4
--- /dev/null
+++ b/resources/shaders/shared.glsl
@@ -0,0 +1,45 @@
+/* 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/. */
+
+//======================================================================================
+// Vertex shader attributes and uniforms
+//======================================================================================
+#ifdef WR_VERTEX_SHADER
+ #define varying out
+
+ // Uniform inputs
+ uniform mat4 uTransform; // Orthographic projection
+ uniform float uDevicePixelRatio;
+
+ // Attribute inputs
+ in vec3 aPosition;
+#endif
+
+//======================================================================================
+// Fragment shader attributes and uniforms
+//======================================================================================
+#ifdef WR_FRAGMENT_SHADER
+ precision highp float;
+
+ #define varying in
+
+ // Uniform inputs
+ uniform sampler2D sDiffuse;
+ uniform sampler2D sMask;
+
+ // Fragment shader outputs
+ out vec4 oFragColor;
+#endif
+
+//======================================================================================
+// Interpolator definitions
+//======================================================================================
+
+//======================================================================================
+// VS only types and UBOs
+//======================================================================================
+
+//======================================================================================
+// VS only functions
+//======================================================================================
diff --git a/resources/shaders/shared_other.glsl b/resources/shaders/shared_other.glsl
new file mode 100644
index 00000000000..847fd1c143c
--- /dev/null
+++ b/resources/shaders/shared_other.glsl
@@ -0,0 +1,64 @@
+/* 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/. */
+
+//======================================================================================
+// Vertex shader attributes and uniforms
+//======================================================================================
+#ifdef WR_VERTEX_SHADER
+ in vec4 aColorTexCoordRectTop;
+ in vec4 aColorRectTL;
+
+ // box-shadow
+ in vec4 aBorderPosition;
+ in vec4 aBorderRadii;
+ in float aBlurRadius;
+
+ // blur
+ in vec2 aDestTextureSize;
+ in vec2 aSourceTextureSize;
+#endif
+
+//======================================================================================
+// Fragment shader attributes and uniforms
+//======================================================================================
+#ifdef WR_FRAGMENT_SHADER
+ uniform vec2 uDirection;
+#endif
+
+//======================================================================================
+// Interpolator definitions
+//======================================================================================
+
+// Hacks to be removed (needed for text etc)
+varying vec2 vColorTexCoord;
+varying vec4 vColor;
+
+// box_shadow
+varying vec2 vPosition;
+varying vec4 vBorderPosition;
+varying vec4 vBorderRadii;
+varying float vBlurRadius;
+
+// blur
+varying vec2 vSourceTextureSize;
+varying vec2 vDestTextureSize;
+
+//======================================================================================
+// VS only types and UBOs
+//======================================================================================
+
+//======================================================================================
+// VS only functions
+//======================================================================================
+
+//======================================================================================
+// FS only functions
+//======================================================================================
+#ifdef WR_FRAGMENT_SHADER
+
+void SetFragColor(vec4 color) {
+ oFragColor = color;
+}
+
+#endif
diff --git a/rust-nightly-date b/rust-nightly-date
index 570434df0cb..03237ba6f69 100644
--- a/rust-nightly-date
+++ b/rust-nightly-date
@@ -1 +1 @@
-2016-06-24
+2016-07-25
diff --git a/support/windows/Servo.wxs.mako b/support/windows/Servo.wxs.mako
new file mode 100644
index 00000000000..dab08c418ca
--- /dev/null
+++ b/support/windows/Servo.wxs.mako
@@ -0,0 +1,215 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
+ <Product Name="Servo Tech Demo"
+ Manufacturer="Mozilla Research"
+ Id="5807391a-3a17-476b-a5d2-5f1912569762"
+ UpgradeCode="060cd15d-eab1-4614-b438-3988e3efdcf1"
+ Language="1033"
+ Codepage="1252"
+ Version="1.0.0">
+ <Package Id="*"
+ Keywords="Installer"
+ Description="Servo Tech Demo Installer"
+ Manufacturer="Mozilla Research"
+ InstallerVersion="200"
+ Platform="x64"
+ Languages="1033"
+ SummaryCodepage="1252"
+ Compressed="yes"/>
+ <Media Id="1"
+ Cabinet="Servo.cab"
+ EmbedCab="yes"/>
+ <Directory Id="TARGETDIR" Name="SourceDir">
+ <Directory Id="ProgramFiles64Folder" Name="PFiles">
+ <Directory Id="MozResearch" Name="Mozilla Research">
+ <Directory Id="INSTALLDIR" Name="Servo Tech Demo">
+ <Component Id="Servo"
+ Guid="95bcea71-78bb-4ec8-9766-44bc01443840"
+ Win64="yes">
+ <File Id="ServoEXE"
+ Name="servo.exe"
+ DiskId="1"
+ Source="${windowize(exe_path)}\servo.exe"
+ KeyPath="yes">
+ <Shortcut Id="StartMenuServoTechDemo"
+ Directory="ProgramMenuDir"
+ Name="Servo Tech Demo"
+ WorkingDirectory="INSTALLDIR"
+ Icon="Servo.ico"
+ IconIndex="0"
+ Arguments="-w --pref dom.mozbrowser.enabled --pref shell.builtin-key-shortcuts.enabled=false browserhtml\index.html"
+ Advertise="yes"/>
+ </File>
+ <File Id="ServoManifest"
+ Name="servo.exe.manifest"
+ 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"/>
+ <File Id="AVUtil"
+ Name="avutil-55.dll"
+ Source="C:\msys64\mingw64\bin\avutil-55.dll"
+ DiskId="1"/>
+ <File Id="AVFormat"
+ Name="avformat-57.dll"
+ Source="C:\msys64\mingw64\bin\avformat-57.dll"
+ DiskId="1"/>
+ </Component>
+
+ <Directory Id="EtcDir" Name="etc">
+ <Directory Id="FontsDir" Name="fonts">
+ <Component Id="FontsDir"
+ Guid="8d37ee61-9237-438d-b976-f163bd6b0578"
+ Win64="yes">
+ <File Id="ServoFontsConfig"
+ KeyPath="yes"
+ Name="fonts.conf"
+ Source="${windowize(top_path)}\support\windows\fonts.conf"
+ DiskId="1"/>
+ </Component>
+ </Directory>
+ </Directory>
+
+ ${include_directory(path.join(top_path, "resources"), "resources")}
+ ${include_directory(browserhtml_path, "browserhtml")}
+ </Directory>
+ </Directory>
+ </Directory>
+
+ <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"/>
+ <RegistryValue Root="HKCU"
+ Key="Software\Mozilla Research\Servo Tech Demo"
+ Type="string"
+ Value=""
+ KeyPath="yes"/>
+ </Component>
+ </Directory>
+ </Directory>
+ </Directory>
+
+ <Feature Id="Complete" Level="1">
+ <ComponentRef Id="Servo"/>
+ <ComponentRef Id="FontsDir"/>
+ % for c in components:
+ <ComponentRef Id="${c}"/>
+ % endfor
+ <ComponentRef Id="ProgramMenuDir"/>
+ </Feature>
+
+ <Icon Id="Servo.ico" SourceFile="${windowize(top_path)}\resources\Servo.ico"/>
+ </Product>
+</Wix>
+<%!
+import os
+import os.path as path
+import re
+import uuid
+
+def make_id(s):
+ return "Id{}".format(s.replace("-", "_").replace("/", "_"))
+
+def listfiles(directory):
+ return [f for f in os.listdir(directory)
+ if path.isfile(path.join(directory, f))]
+
+def listdirs(directory):
+ return [f for f in os.listdir(directory)
+ if path.isdir(path.join(directory, f))]
+
+def windowize(p):
+ if not p.startswith("/"):
+ return p
+ return re.sub("^/([^/])+", "\\1:", p)
+
+components = []
+%>
+<%def name="include_directory(d, n)">
+<Directory Id="${make_id(path.basename(d))}" Name="${n}">
+ <Component Id="${make_id(path.basename(d))}"
+ Guid="${uuid.uuid4()}"
+ Win64="yes">
+ <CreateFolder/>
+ <% components.append(make_id(path.basename(d))) %>
+ % for f in listfiles(d):
+ <File Id="${make_id(path.join(d, f))}"
+ Name="${f}"
+ Source="${windowize(path.join(d, f))}"
+ DiskId="1"/>
+ % endfor
+ </Component>
+
+ % for f in listdirs(d):
+ ${include_directory(path.join(d, f), f)}
+ % endfor
+</Directory>
+</%def>
diff --git a/support/windows/fonts.conf b/support/windows/fonts.conf
new file mode 100644
index 00000000000..904c9832eb9
--- /dev/null
+++ b/support/windows/fonts.conf
@@ -0,0 +1,777 @@
+<?xml version="1.0"?>
+<!DOCTYPE fontconfig SYSTEM "fonts.dtd">
+<fontconfig>
+ <dir>C:\Windows\Fonts</dir>
+<!--
+ Accept deprecated 'mono' alias, replacing it with 'monospace'
+-->
+ <match target="pattern">
+ <test qual="any" name="family">
+ <string>mono</string>
+ </test>
+ <edit name="family" mode="assign" binding="same">
+ <string>monospace</string>
+ </edit>
+ </match>
+
+<!--
+ Accept alternate 'sans serif' spelling, replacing it with 'sans-serif'
+-->
+ <match target="pattern">
+ <test qual="any" name="family">
+ <string>sans serif</string>
+ </test>
+ <edit name="family" mode="assign" binding="same">
+ <string>sans-serif</string>
+ </edit>
+ </match>
+
+<!--
+ Accept deprecated 'sans' alias, replacing it with 'sans-serif'
+-->
+ <match target="pattern">
+ <test qual="any" name="family">
+ <string>sans</string>
+ </test>
+ <edit name="family" mode="assign" binding="same">
+ <string>sans-serif</string>
+ </edit>
+ </match>
+
+
+
+<!-- Font cache directory list -->
+
+<cachedir>~/.fontconfig</cachedir>
+
+
+
+
+<!--
+ Mark common families with their generics so we'll get
+ something reasonable
+-->
+
+<!--
+ Serif faces
+ -->
+ <alias>
+ <family>Nazli</family>
+ <default><family>serif</family></default>
+ </alias>
+ <alias>
+ <family>Lotoos</family>
+ <default><family>serif</family></default>
+ </alias>
+ <alias>
+ <family>Mitra</family>
+ <default><family>serif</family></default>
+ </alias>
+ <alias>
+ <family>Ferdosi</family>
+ <default><family>serif</family></default>
+ </alias>
+ <alias>
+ <family>Badr</family>
+ <default><family>serif</family></default>
+ </alias>
+ <alias>
+ <family>Zar</family>
+ <default><family>serif</family></default>
+ </alias>
+ <alias>
+ <family>Titr</family>
+ <default><family>serif</family></default>
+ </alias>
+ <alias>
+ <family>Jadid</family>
+ <default><family>serif</family></default>
+ </alias>
+ <alias>
+ <family>Kochi Mincho</family>
+ <default><family>serif</family></default>
+ </alias>
+ <alias>
+ <family>AR PL SungtiL GB</family>
+ <default><family>serif</family></default>
+ </alias>
+ <alias>
+ <family>AR PL Mingti2L Big5</family>
+ <default><family>serif</family></default>
+ </alias>
+ <alias>
+ <family>MS 明朝</family>
+ <default><family>serif</family></default>
+ </alias>
+ <alias>
+ <family>NanumMyeongjo</family>
+ <default><family>serif</family></default>
+ </alias>
+ <alias>
+ <family>UnBatang</family>
+ <default><family>serif</family></default>
+ </alias>
+ <alias>
+ <family>Baekmuk Batang</family>
+ <default><family>serif</family></default>
+ </alias>
+ <alias>
+ <family>MgOpen Canonica</family>
+ <default><family>serif</family></default>
+ </alias>
+ <alias>
+ <family>Sazanami Mincho</family>
+ <default><family>serif</family></default>
+ </alias>
+ <alias>
+ <family>AR PL ZenKai Uni</family>
+ <default><family>serif</family></default>
+ </alias>
+ <alias>
+ <family>ZYSong18030</family>
+ <default><family>serif</family></default>
+ </alias>
+ <alias>
+ <family>FreeSerif</family>
+ <default><family>serif</family></default>
+ </alias>
+ <alias>
+ <family>SimSun</family>
+ <default><family>serif</family></default>
+ </alias>
+<!--
+ Sans-serif faces
+ -->
+ <alias>
+ <family>Arshia</family>
+ <default><family>sans-serif</family></default>
+ </alias>
+ <alias>
+ <family>Elham</family>
+ <default><family>sans-serif</family></default>
+ </alias>
+ <alias>
+ <family>Farnaz</family>
+ <default><family>sans-serif</family></default>
+ </alias>
+ <alias>
+ <family>Nasim</family>
+ <default><family>sans-serif</family></default>
+ </alias>
+ <alias>
+ <family>Sina</family>
+ <default><family>sans-serif</family></default>
+ </alias>
+ <alias>
+ <family>Roya</family>
+ <default><family>sans-serif</family></default>
+ </alias>
+ <alias>
+ <family>Koodak</family>
+ <default><family>sans-serif</family></default>
+ </alias>
+ <alias>
+ <family>Terafik</family>
+ <default><family>sans-serif</family></default>
+ </alias>
+ <alias>
+ <family>Kochi Gothic</family>
+ <default><family>sans-serif</family></default>
+ </alias>
+ <alias>
+ <family>AR PL KaitiM GB</family>
+ <default><family>sans-serif</family></default>
+ </alias>
+ <alias>
+ <family>AR PL KaitiM Big5</family>
+ <default><family>sans-serif</family></default>
+ </alias>
+ <alias>
+ <family>MS ゴシック</family>
+ <default><family>sans-serif</family></default>
+ </alias>
+ <alias>
+ <family>NanumGothic</family>
+ <default><family>sans-serif</family></default>
+ </alias>
+ <alias>
+ <family>UnDotum</family>
+ <default><family>sans-serif</family></default>
+ </alias>
+ <alias>
+ <family>Baekmuk Dotum</family>
+ <default><family>sans-serif</family></default>
+ </alias>
+ <alias>
+ <family>MgOpen Modata</family>
+ <default><family>sans-serif</family></default>
+ </alias>
+ <alias>
+ <family>Sazanami Gothic</family>
+ <default><family>sans-serif</family></default>
+ </alias>
+ <alias>
+ <family>AR PL ShanHeiSun Uni</family>
+ <default><family>sans-serif</family></default>
+ </alias>
+ <alias>
+ <family>ZYSong18030</family>
+ <default><family>sans-serif</family></default>
+ </alias>
+ <alias>
+ <family>FreeSans</family>
+ <default><family>sans-serif</family></default>
+ </alias>
+<!--
+ Monospace faces
+ -->
+ <alias>
+ <family>NSimSun</family>
+ <default><family>monospace</family></default>
+ </alias>
+ <alias>
+ <family>ZYSong18030</family>
+ <default><family>monospace</family></default>
+ </alias>
+ <alias>
+ <family>NanumGothicCoding</family>
+ <default><family>monospace</family></default>
+ </alias>
+ <alias>
+ <family>FreeMono</family>
+ <default><family>monospace</family></default>
+ </alias>
+
+<!--
+ Fantasy faces
+ -->
+ <alias>
+ <family>Homa</family>
+ <default><family>fantasy</family></default>
+ </alias>
+ <alias>
+ <family>Kamran</family>
+ <default><family>fantasy</family></default>
+ </alias>
+ <alias>
+ <family>Fantezi</family>
+ <default><family>fantasy</family></default>
+ </alias>
+ <alias>
+ <family>Tabassom</family>
+ <default><family>fantasy</family></default>
+ </alias>
+
+<!--
+ Cursive faces
+ -->
+ <alias>
+ <family>IranNastaliq</family>
+ <default><family>cursive</family></default>
+ </alias>
+ <alias>
+ <family>Nafees Nastaleeq</family>
+ <default><family>cursive</family></default>
+ </alias>
+
+<!--
+ Mark common families with their generics so we'll get
+ something reasonable
+-->
+
+<!--
+ Serif faces
+ -->
+ <alias>
+ <family>Bitstream Vera Serif</family>
+ <default><family>serif</family></default>
+ </alias>
+ <alias>
+ <family>DejaVu Serif</family>
+ <default><family>serif</family></default>
+ </alias>
+ <alias>
+ <family>Liberation Serif</family>
+ <default><family>serif</family></default>
+ </alias>
+ <alias>
+ <family>Times New Roman</family>
+ <default><family>serif</family></default>
+ </alias>
+ <alias>
+ <family>Times</family>
+ <default><family>serif</family></default>
+ </alias>
+ <alias>
+ <family>Nimbus Roman No9 L</family>
+ <default><family>serif</family></default>
+ </alias>
+ <alias>
+ <family>Nimbus Roman</family>
+ <default><family>serif</family></default>
+ </alias>
+ <alias>
+ <family>Luxi Serif</family>
+ <default><family>serif</family></default>
+ </alias>
+ <alias>
+ <family>Thorndale AMT</family>
+ <default><family>serif</family></default>
+ </alias>
+ <alias>
+ <family>Thorndale</family>
+ <default><family>serif</family></default>
+ </alias>
+ <alias>
+ <family>Georgia</family>
+ <default><family>serif</family></default>
+ </alias>
+ <alias>
+ <family>Garamond</family>
+ <default><family>serif</family></default>
+ </alias>
+ <alias>
+ <family>Palatino Linotype</family>
+ <default><family>serif</family></default>
+ </alias>
+<!--
+ Sans-serif faces
+ -->
+ <alias>
+ <family>Bitstream Vera Sans</family>
+ <default><family>sans-serif</family></default>
+ </alias>
+ <alias>
+ <family>DejaVu Sans</family>
+ <default><family>sans-serif</family></default>
+ </alias>
+ <alias>
+ <family>Liberation Sans</family>
+ <default><family>sans-serif</family></default>
+ </alias>
+ <alias>
+ <family>Arial</family>
+ <default><family>sans-serif</family></default>
+ </alias>
+ <alias>
+ <family>Helvetica</family>
+ <default><family>sans-serif</family></default>
+ </alias>
+ <alias>
+ <family>Verdana</family>
+ <default><family>sans-serif</family></default>
+ </alias>
+ <alias>
+ <family>Albany AMT</family>
+ <default><family>sans-serif</family></default>
+ </alias>
+ <alias>
+ <family>Albany</family>
+ <default><family>sans-serif</family></default>
+ </alias>
+ <alias>
+ <family>Nimbus Sans L</family>
+ <default><family>sans-serif</family></default>
+ </alias>
+ <alias>
+ <family>Nimbus Sans</family>
+ <default><family>sans-serif</family></default>
+ </alias>
+ <alias>
+ <family>Luxi Sans</family>
+ <default><family>sans-serif</family></default>
+ </alias>
+ <alias>
+ <family>Trebuchet MS</family>
+ <default><family>sans-serif</family></default>
+ </alias>
+<!--
+ Monospace faces
+ -->
+ <alias>
+ <family>Bitstream Vera Sans Mono</family>
+ <default><family>monospace</family></default>
+ </alias>
+ <alias>
+ <family>DejaVu Sans Mono</family>
+ <default><family>monospace</family></default>
+ </alias>
+ <alias>
+ <family>Liberation Mono</family>
+ <default><family>monospace</family></default>
+ </alias>
+ <alias>
+ <family>Inconsolata</family>
+ <default><family>monospace</family></default>
+ </alias>
+ <alias>
+ <family>Courier New</family>
+ <default><family>monospace</family></default>
+ </alias>
+ <alias>
+ <family>Courier</family>
+ <default><family>monospace</family></default>
+ </alias>
+ <alias>
+ <family>Andale Mono</family>
+ <default><family>monospace</family></default>
+ </alias>
+ <alias>
+ <family>Luxi Mono</family>
+ <default><family>monospace</family></default>
+ </alias>
+ <alias>
+ <family>Cumberland AMT</family>
+ <default><family>monospace</family></default>
+ </alias>
+ <alias>
+ <family>Cumberland</family>
+ <default><family>monospace</family></default>
+ </alias>
+ <alias>
+ <family>Nimbus Mono L</family>
+ <default><family>monospace</family></default>
+ </alias>
+ <alias>
+ <family>Nimbus Mono</family>
+ <default><family>monospace</family></default>
+ </alias>
+<!--
+ Fantasy faces
+ -->
+ <alias>
+ <family>Impact</family>
+ <default><family>fantasy</family></default>
+ </alias>
+ <alias>
+ <family>Copperplate Gothic Std</family>
+ <default><family>fantasy</family></default>
+ </alias>
+ <alias>
+ <family>Cooper Std</family>
+ <default><family>fantasy</family></default>
+ </alias>
+ <alias>
+ <family>Bauhaus Std</family>
+ <default><family>fantasy</family></default>
+ </alias>
+<!--
+ Cursive faces
+ -->
+ <alias>
+ <family>ITC Zapf Chancery Std</family>
+ <default><family>cursive</family></default>
+ </alias>
+ <alias>
+ <family>Zapfino</family>
+ <default><family>cursive</family></default>
+ </alias>
+ <alias>
+ <family>Comic Sans MS</family>
+ <default><family>cursive</family></default>
+ </alias>
+
+<!--
+ If the font still has no generic name, add sans-serif
+ -->
+ <match target="pattern">
+ <test qual="all" name="family" compare="not_eq">
+ <string>sans-serif</string>
+ </test>
+ <test qual="all" name="family" compare="not_eq">
+ <string>serif</string>
+ </test>
+ <test qual="all" name="family" compare="not_eq">
+ <string>monospace</string>
+ </test>
+ <edit name="family" mode="append_last">
+ <string>sans-serif</string>
+ </edit>
+ </match>
+ <alias>
+ <family>serif</family>
+ <prefer>
+ <family>Bitstream Vera Serif</family>
+ <family>DejaVu Serif</family>
+ <family>Times New Roman</family>
+ <family>Thorndale AMT</family>
+ <family>Luxi Serif</family>
+ <family>Nimbus Roman No9 L</family>
+ <family>Nimbus Roman</family>
+ <family>Times</family>
+ </prefer>
+ </alias>
+ <alias>
+ <family>sans-serif</family>
+ <prefer>
+ <family>Bitstream Vera Sans</family>
+ <family>DejaVu Sans</family>
+ <family>Verdana</family>
+ <family>Arial</family>
+ <family>Albany AMT</family>
+ <family>Luxi Sans</family>
+ <family>Nimbus Sans L</family>
+ <family>Nimbus Sans</family>
+ <family>Helvetica</family>
+ <family>Lucida Sans Unicode</family>
+ <family>BPG Glaho International</family> <!-- lat,cyr,arab,geor -->
+ <family>Tahoma</family> <!-- lat,cyr,greek,heb,arab,thai -->
+ </prefer>
+ </alias>
+ <alias>
+ <family>monospace</family>
+ <prefer>
+ <family>Bitstream Vera Sans Mono</family>
+ <family>DejaVu Sans Mono</family>
+ <family>Inconsolata</family>
+ <family>Andale Mono</family>
+ <family>Courier New</family>
+ <family>Cumberland AMT</family>
+ <family>Luxi Mono</family>
+ <family>Nimbus Mono L</family>
+ <family>Nimbus Mono</family>
+ <family>Courier</family>
+ </prefer>
+ </alias>
+<!--
+ Fantasy faces
+ -->
+ <alias>
+ <family>fantasy</family>
+ <prefer>
+ <family>Impact</family>
+ <family>Copperplate Gothic Std</family>
+ <family>Cooper Std</family>
+ <family>Bauhaus Std</family>
+ </prefer>
+ </alias>
+<!--
+ Cursive faces
+ -->
+ <alias>
+ <family>cursive</family>
+ <prefer>
+ <family>ITC Zapf Chancery Std</family>
+ <family>Zapfino</family>
+ <family>Comic Sans MS</family>
+ </prefer>
+ </alias>
+
+ <alias>
+ <family>serif</family>
+ <prefer>
+ <family>Artsounk</family> <!-- armenian -->
+ <family>BPG UTF8 M</family> <!-- georgian -->
+ <family>Kinnari</family> <!-- thai -->
+ <family>Norasi</family> <!-- thai -->
+ <family>Frank Ruehl</family> <!-- hebrew -->
+ <family>Dror</family> <!-- hebrew -->
+ <family>JG LaoTimes</family> <!-- lao -->
+ <family>Saysettha Unicode</family> <!-- lao -->
+ <family>Pigiarniq</family> <!-- canadian syllabics -->
+ <family>B Davat</family> <!-- arabic (fa) -->
+ <family>B Compset</family> <!-- arabic (fa) -->
+ <family>Kacst-Qr</family> <!-- arabic (ar) -->
+ <family>Urdu Nastaliq Unicode</family> <!-- arabic (ur) -->
+ <family>Raghindi</family> <!-- devanagari -->
+ <family>Mukti Narrow</family> <!-- bengali -->
+ <family>malayalam</family> <!-- malayalam -->
+ <family>Sampige</family> <!-- kannada -->
+ <family>padmaa</family> <!-- gujarati -->
+ <family>Hapax Berbère</family> <!-- tifinagh -->
+ <family>MS Mincho</family> <!-- han (ja) -->
+ <family>SimSun</family> <!-- han (zh-cn,zh-tw) -->
+ <family>PMingLiu</family> <!-- han (zh-tw) -->
+ <family>WenQuanYi Zen Hei</family> <!-- han (zh-cn,zh-tw) -->
+ <family>WenQuanYi Bitmap Song</family> <!-- han (zh-cn,zh-tw) -->
+ <family>AR PL ShanHeiSun Uni</family> <!-- han (ja,zh-cn,zh-tw) -->
+ <family>AR PL New Sung</family> <!-- han (zh-cn,zh-tw) -->
+ <family>ZYSong18030</family> <!-- han (zh-cn,zh-tw) -->
+ <family>HanyiSong</family> <!-- han (zh-cn,zh-tw) -->
+ <family>MgOpen Canonica</family>
+ <family>Sazanami Mincho</family>
+ <family>IPAMonaMincho</family>
+ <family>IPAMincho</family>
+ <family>Kochi Mincho</family>
+ <family>AR PL SungtiL GB</family>
+ <family>AR PL Mingti2L Big5</family>
+ <family>AR PL Zenkai Uni</family>
+ <family>MS 明朝</family>
+ <family>ZYSong18030</family>
+ <family>NanumMyeongjo</family> <!-- hangul (ko) -->
+ <family>UnBatang</family> <!-- hangul (ko) -->
+ <family>Baekmuk Batang</family> <!-- hangul (ko) -->
+ <family>KacstQura</family>
+ <family>Frank Ruehl CLM</family>
+ <family>Lohit Bengali</family>
+ <family>Lohit Gujarati</family>
+ <family>Lohit Hindi</family>
+ <family>Lohit Marathi</family>
+ <family>Lohit Maithili</family>
+ <family>Lohit Kashmiri</family>
+ <family>Lohit Konkani</family>
+ <family>Lohit Nepali</family>
+ <family>Lohit Sindhi</family>
+ <family>Lohit Punjabi</family>
+ <family>Lohit Tamil</family>
+ <family>Meera</family>
+ <family>Lohit Malayalam</family>
+ <family>Lohit Kannada</family>
+ <family>Lohit Telugu</family>
+ <family>Lohit Oriya</family>
+ <family>LKLUG</family>
+ </prefer>
+ </alias>
+ <alias>
+ <family>sans-serif</family>
+ <prefer>
+ <family>Nachlieli</family> <!-- hebrew -->
+ <family>Lucida Sans Unicode</family>
+ <family>Yudit Unicode</family>
+ <family>Kerkis</family> <!-- greek -->
+ <family>ArmNet Helvetica</family> <!-- armenian -->
+ <family>Artsounk</family> <!-- armenian -->
+ <family>BPG UTF8 M</family> <!-- georgian -->
+ <family>Waree</family> <!-- thai -->
+ <family>Loma</family> <!-- thai -->
+ <family>Garuda</family> <!-- thai -->
+ <family>Umpush</family> <!-- thai -->
+ <family>Saysettha Unicode</family> <!-- lao? -->
+ <family>JG Lao Old Arial</family> <!-- lao -->
+ <family>GF Zemen Unicode</family> <!-- ethiopic -->
+ <family>Pigiarniq</family> <!-- canadian syllabics -->
+ <family>B Davat</family> <!-- arabic (fa) -->
+ <family>B Compset</family> <!-- arabic (fa) -->
+ <family>Kacst-Qr</family> <!-- arabic (ar) -->
+ <family>Urdu Nastaliq Unicode</family> <!-- arabic (ur) -->
+ <family>Raghindi</family> <!-- devanagari -->
+ <family>Mukti Narrow</family> <!-- bengali -->
+ <family>malayalam</family> <!-- malayalam -->
+ <family>Sampige</family> <!-- kannada -->
+ <family>padmaa</family> <!-- gujarati -->
+ <family>Hapax Berbère</family> <!-- tifinagh -->
+ <family>MS Gothic</family> <!-- han (ja) -->
+ <family>UmePlus P Gothic</family> <!-- han (ja) -->
+ <!-- chinese fonts are actually serifed -->
+ <family>SimSun</family> <!-- han (zh-cn,zh-tw) -->
+ <family>PMingLiu</family> <!-- han (zh-tw) -->
+ <family>WenQuanYi Zen Hei</family> <!-- han (zh-cn,zh-tw) -->
+ <family>WenQuanYi Bitmap Song</family> <!-- han (zh-cn,zh-tw) -->
+ <family>AR PL ShanHeiSun Uni</family> <!--han (ja,zh-cn,zh-tw) -->
+ <family>AR PL New Sung</family> <!-- han (zh-cn,zh-tw) -->
+ <family>MgOpen Modata</family>
+ <family>VL Gothic</family>
+ <family>IPAMonaGothic</family>
+ <family>IPAGothic</family>
+ <family>Sazanami Gothic</family>
+ <family>Kochi Gothic</family>
+ <family>AR PL KaitiM GB</family>
+ <family>AR PL KaitiM Big5</family>
+ <family>AR PL ShanHeiSun Uni</family>
+ <family>AR PL SungtiL GB</family>
+ <family>AR PL Mingti2L Big5</family>
+ <family>MS ゴシック</family>
+ <family>ZYSong18030</family> <!-- han (zh-cn,zh-tw) -->
+ <family>TSCu_Paranar</family> <!-- tamil -->
+ <family>NanumGothic</family> <!-- hangul (ko) -->
+ <family>UnDotum</family> <!-- hangul (ko) -->
+ <family>Baekmuk Dotum</family> <!-- hangul (ko) -->
+ <family>Baekmuk Gulim</family> <!-- hangul (ko) -->
+ <family>KacstQura</family>
+ <family>Lohit Bengali</family>
+ <family>Lohit Gujarati</family>
+ <family>Lohit Hindi</family>
+ <family>Lohit Marathi</family>
+ <family>Lohit Maithili</family>
+ <family>Lohit Kashmiri</family>
+ <family>Lohit Konkani</family>
+ <family>Lohit Nepali</family>
+ <family>Lohit Sindhi</family>
+ <family>Lohit Punjabi</family>
+ <family>Lohit Tamil</family>
+ <family>Meera</family>
+ <family>Lohit Malayalam</family>
+ <family>Lohit Kannada</family>
+ <family>Lohit Telugu</family>
+ <family>Lohit Oriya</family>
+ <family>LKLUG</family>
+ </prefer>
+ </alias>
+ <alias>
+ <family>monospace</family>
+ <prefer>
+ <family>Miriam Mono</family> <!-- hebrew -->
+ <family>VL Gothic</family>
+ <family>IPAMonaGothic</family>
+ <family>IPAGothic</family>
+ <family>Sazanami Gothic</family>
+ <family>Kochi Gothic</family>
+ <family>AR PL KaitiM GB</family>
+ <family>MS Gothic</family> <!-- han (ja) -->
+ <family>UmePlus Gothic</family> <!-- han (ja) -->
+ <family>NSimSun</family> <!-- han (zh-cn,zh-tw) -->
+ <family>MingLiu</family> <!-- han (zh-tw) -->
+ <family>AR PL ShanHeiSun Uni</family> <!-- han (ja,zh-cn,zh-tw) -->
+ <family>AR PL New Sung Mono</family> <!-- han (zh-cn,zh-tw) -->
+ <family>HanyiSong</family> <!-- han (zh-cn) -->
+ <family>AR PL SungtiL GB</family>
+ <family>AR PL Mingti2L Big5</family>
+ <family>ZYSong18030</family> <!-- han (zh-cn,zh-tw) -->
+ <family>NanumGothicCoding</family> <!-- hangul (ko) -->
+ <family>NanumGothic</family> <!-- hangul (ko) -->
+ <family>UnDotum</family> <!-- hangul (ko) -->
+ <family>Baekmuk Dotum</family> <!-- hangul (ko) -->
+ <family>Baekmuk Gulim</family> <!-- hangul (ko) -->
+ <family>TlwgTypo</family> <!-- thai -->
+ <family>TlwgTypist</family> <!-- thai -->
+ <family>TlwgTypewriter</family> <!-- thai -->
+ <family>TlwgMono</family> <!-- thai -->
+ <family>Hasida</family> <!-- hebrew -->
+ <family>Mitra Mono</family> <!-- bengali -->
+ <family>GF Zemen Unicode</family> <!-- ethiopic -->
+ <family>Hapax Berbère</family> <!-- tifinagh -->
+ <family>Lohit Bengali</family>
+ <family>Lohit Gujarati</family>
+ <family>Lohit Hindi</family>
+ <family>Lohit Marathi</family>
+ <family>Lohit Maithili</family>
+ <family>Lohit Kashmiri</family>
+ <family>Lohit Konkani</family>
+ <family>Lohit Nepali</family>
+ <family>Lohit Sindhi</family>
+ <family>Lohit Punjabi</family>
+ <family>Lohit Tamil</family>
+ <family>Meera</family>
+ <family>Lohit Malayalam</family>
+ <family>Lohit Kannada</family>
+ <family>Lohit Telugu</family>
+ <family>Lohit Oriya</family>
+ <family>LKLUG</family>
+ </prefer>
+ </alias>
+ <alias>
+ <family>serif</family>
+ <prefer>
+ <family>FreeSerif</family>
+ <family>Code2000</family>
+ <family>Code2001</family> <!-- plane1 and beyond -->
+ </prefer>
+ </alias>
+ <alias>
+ <family>sans-serif</family>
+ <prefer>
+ <family>FreeSans</family>
+ <family>Arial Unicode MS</family>
+ <family>Arial Unicode</family>
+ <family>Code2000</family> <!-- almost everything; serif actually -->
+ <family>Code2001</family> <!-- plane1 and beyond -->
+ </prefer>
+ </alias>
+ <alias>
+ <family>monospace</family>
+ <prefer>
+ <family>FreeMono</family>
+ </prefer>
+ </alias>
+
+</fontconfig>
diff --git a/tests/html/bluetooth/bluetooth_battery_level.html b/tests/html/bluetooth/bluetooth_battery_level.html
new file mode 100644
index 00000000000..77dccf1e40c
--- /dev/null
+++ b/tests/html/bluetooth/bluetooth_battery_level.html
@@ -0,0 +1,36 @@
+<!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: []};
+
+ 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 Battery Service...');
+ var service = server.getPrimaryService('battery_service');
+
+ log('Getting Battery Level Characteristic...');
+ var characteristic = service.getCharacteristic('battery_level');
+
+ log('Reading Battery Level...');
+ var value = asciiToDecimal(characteristic.readValue());
+ log('> Battery Level is ' + value + '%');
+ } catch(err) {
+ log(err);
+ }
+ }
+ </script>
+</body>
+</html>
diff --git a/tests/html/bluetooth_battery_level.html b/tests/html/bluetooth/bluetooth_battery_level_with_filter.html
index 8618df07859..269aa4e5ab2 100644
--- a/tests/html/bluetooth_battery_level.html
+++ b/tests/html/bluetooth/bluetooth_battery_level_with_filter.html
@@ -1,23 +1,24 @@
<!DOCTYPE html>
<html>
-<title>Battery Level</title>
+<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']}], optinalServices: []};
+ var options = {filters: [{services: ['battery_service']}], optionalServices: []};
var filterName = document.getElementById('name').value;
if (filterName)
- options.filters.push({name: filterName});
+ options.filters[0].name = filterName;
var filterNamePrefix = document.getElementById('namePrefix').value;
if (filterNamePrefix)
- options.filters.push({namePrefix: filterNamePrefix});
+ options.filters[0].namePrefix = filterNamePrefix;
try {
log('Requesting Bluetooth Device...');
@@ -34,28 +35,12 @@
var characteristic = service.getCharacteristic('battery_level');
log('Reading Battery Level...');
- var value = AsciiToDecimal(characteristic.readValue());
+ var value = asciiToDecimal(characteristic.readValue());
log('> Battery Level is ' + value + '%');
} catch(err) {
log(err);
}
}
-
- function clear() {
- document.getElementById("log").textContent = "";
- }
-
- function log(line) {
- document.getElementById("log").textContent += line + '\n';
- }
-
- function AsciiToDecimal(bytestr) {
- var result = [];
- for(i = 0; i < bytestr.length; i++) {
- result[i] = bytestr[i].charCodeAt(0) ;
- }
- return result;
- }
</script>
</body>
</html>
diff --git a/tests/html/bluetooth_characteristic_info.html b/tests/html/bluetooth/bluetooth_characteristic_info.html
index 84cebd83014..d3eb3a2d255 100644
--- a/tests/html/bluetooth_characteristic_info.html
+++ b/tests/html/bluetooth/bluetooth_characteristic_info.html
@@ -6,14 +6,19 @@
<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);
- var characteristicUuid = document.getElementById('characteristic').value;
if (characteristicUuid.startsWith('0x'))
characteristicUuid = parseInt(characteristicUuid, 16);
@@ -43,27 +48,11 @@
log('> Queued Write: ' + characteristic.properties.reliableWrite);
log('> Writable Auxiliaries: ' + characteristic.properties.writableAuxiliaries);
characteristic.readValue();
- log('> Characteristic value: ' + AsciiToDecimal(characteristic.value));
+ log('> Characteristic value: ' + asciiToDecimal(characteristic.value));
} catch(err) {
log(err);
}
}
-
- function clear() {
- document.getElementById("log").textContent = "";
- }
-
- function log(line) {
- document.getElementById("log").textContent += line + '\n';
- }
-
- function AsciiToDecimal(bytestr) {
- var result = [];
- for(i = 0; i < bytestr.length; i++) {
- result[i] = bytestr[i].charCodeAt(0) ;
- }
- return result;
- }
</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
new file mode 100644
index 00000000000..45b60128de9
--- /dev/null
+++ b/tests/html/bluetooth/bluetooth_characteristic_read_value_test_cases.html
@@ -0,0 +1,66 @@
+<!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();
+ try {
+ log('Requesting Bluetooth Device...');
+ var device = window.navigator.bluetooth.requestDevice({filters: [{services: ['heart_rate']}]});
+
+ log('Connecting to GATTserver on device...');
+ var server = device.gatt.connect();
+
+ log('Getting Primary Service "heart_rate"...');
+ var primaryService = server.getPrimaryService('heart_rate');
+
+ log('Getting Characteristic "' + testCases[testNumber].characteristic + '"...');
+ var characteristic = primaryService.getCharacteristic(testCases[testNumber].characteristic);
+
+ log('Characteristic found!');
+
+ if (testCases[testNumber].mustDisconnect) {
+ log('Disconnecting from server...');
+ device.gatt.disconnect();
+ }
+
+ log('Reading the value of the Characteristic...');
+ characteristic.readValue();
+ log('> Characteristic value: ' + asciiToDecimal(characteristic.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
new file mode 100644
index 00000000000..db9d9ce084f
--- /dev/null
+++ b/tests/html/bluetooth/bluetooth_characteristic_write_value_test_cases.html
@@ -0,0 +1,80 @@
+<!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();
+ try {
+ log('Requesting Bluetooth Device...');
+ var device = window.navigator.bluetooth.requestDevice({filters: [{services: [0x1234]}]});
+
+ log('Connecting to GATTserver on device...');
+ var server = device.gatt.connect();
+
+ log('Getting Primary Service "Test Service"...');
+ var primaryService = server.getPrimaryService(0x1234);
+
+ log('Getting Characteristic "' + testCases[testNumber].characteristic + '"...');
+ var characteristic = primaryService.getCharacteristic(testCases[testNumber].characteristic);
+
+ log('Characteristic found!');
+
+ log('Reading the old value of the Characteristic...');
+ characteristic.readValue();
+ log('> Characteristic value: ' + asciiToDecimal(characteristic.value));
+
+ if (testCases[testNumber].mustDisconnect) {
+ log('Disconnecting from server...');
+ device.gatt.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...');
+ }
+
+ characteristic.writeValue(testCases[testNumber].valueToWrite);
+
+ log('Reading the new value of the Characteristic...');
+ characteristic.readValue();
+ log('> Characteristic value: ' + asciiToDecimal(characteristic.value));
+ } catch(err) {
+ log(err);
+ }
+ }
+
+ populate(testCases);
+ </script>
+</body>
+</html>
diff --git a/tests/html/bluetooth_descriptor_info.html b/tests/html/bluetooth/bluetooth_descriptor_info.html
index c657d217697..47d9e294295 100644
--- a/tests/html/bluetooth_descriptor_info.html
+++ b/tests/html/bluetooth/bluetooth_descriptor_info.html
@@ -7,18 +7,23 @@
<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);
- var characteristicUuid = document.getElementById('characteristic').value;
if (characteristicUuid.startsWith('0x'))
characteristicUuid = parseInt(characteristicUuid, 16);
- var descriptorUuid = document.getElementById('descriptor').value;
if (descriptorUuid.startsWith('0x'))
descriptorUuid = parseInt(descriptorUuid, 16);
@@ -42,27 +47,11 @@
log('> Descriptor characteristic: ' + descriptor.characteristic.uuid);
log('> Descriptor UUID: ' + descriptor.uuid);
descriptor.readValue();
- log('> Descriptor value: ' + AsciiToDecimal(descriptor.value));
+ log('> Descriptor value: ' + asciiToDecimal(descriptor.value));
} catch(err) {
log(err);
}
}
-
- function clear() {
- document.getElementById("log").textContent = "";
- }
-
- function log(line) {
- document.getElementById("log").textContent += line + '\n';
- }
-
- function AsciiToDecimal(bytestr) {
- var result = [];
- for(i = 0; i < bytestr.length; i++) {
- result[i] = bytestr[i].charCodeAt(0) ;
- }
- return result;
- }
</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
new file mode 100644
index 00000000000..8a2e553652b
--- /dev/null
+++ b/tests/html/bluetooth/bluetooth_descriptor_read_value_test_cases.html
@@ -0,0 +1,57 @@
+<!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();
+ try {
+ log('Requesting Bluetooth Device...');
+ var device = window.navigator.bluetooth.requestDevice({filters: [{services: ['heart_rate']}]});
+
+ log('Connecting to GATTserver on device...');
+ var server = device.gatt.connect();
+
+ log('Getting Primary Service "heart_rate"...');
+ var primaryService = server.getPrimaryService('heart_rate');
+
+ log('Getting Characteristic "heart_rate_measurement"...');
+ var characteristic = primaryService.getCharacteristic('heart_rate_measurement');
+
+ log('Getting Descriptor "' + testCases[testNumber].descriptor + '"...');
+ var descriptor = characteristic.getDescriptor(testCases[testNumber].descriptor);
+
+ log('Descriptor found!');
+ if (testCases[testNumber].mustDisconnect) {
+ log('Disconecting from GATTserver');
+ device.gatt.disconnect();
+ }
+ log("Reading descriptor's value...");
+ descriptor.readValue();
+ log('> Descriptor value: ' + asciiToDecimal(descriptor.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
new file mode 100644
index 00000000000..0553023ca7c
--- /dev/null
+++ b/tests/html/bluetooth/bluetooth_descriptor_write_value_test_cases.html
@@ -0,0 +1,71 @@
+<!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();
+ try {
+ log('Requesting Bluetooth Device...');
+ var device = window.navigator.bluetooth.requestDevice({filters: [{services: [0x1234]}]});
+
+ log('Connecting to GATTserver on device...');
+ var server = device.gatt.connect();
+
+ log('Getting Primary Service "Test Service"...');
+ var primaryService = server.getPrimaryService(0x1234);
+
+ log('Getting Characteristic "Test Characteristic (0x2345)"...');
+ var characteristic = primaryService.getCharacteristic(0x2345);
+
+ log('Characteristic found!');
+
+ log('Getting Descriptor "' + testCases[testNumber].descriptor + '"...');
+ var descriptor = characteristic.getDescriptor(testCases[testNumber].descriptor);
+
+ log('Reading the old value of the Descriptor...');
+ descriptor.readValue();
+ log('> Descriptor value: ' + asciiToDecimal(descriptor.value));
+
+ if (testCases[testNumber].mustDisconnect) {
+ log('Disconnecting from server...');
+ device.gatt.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...');
+ }
+
+ descriptor.writeValue(testCases[testNumber].valueToWrite);
+
+ log('Reading the new value of the Descriptor...');
+ descriptor.readValue();
+ log('> Descriptor value: ' + asciiToDecimal(descriptor.value));
+ } catch(err) {
+ log(err);
+ }
+ }
+
+ populate(testCases);
+ </script>
+</body>
+</html>
diff --git a/tests/html/bluetooth_device_disconnect.html b/tests/html/bluetooth/bluetooth_device_disconnect.html
index 715d3d16a24..3f9771dfee6 100644
--- a/tests/html/bluetooth_device_disconnect.html
+++ b/tests/html/bluetooth/bluetooth_device_disconnect.html
@@ -9,33 +9,34 @@
<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 options = {filters: [{}]};
var filterService = document.getElementById('service').value;
- if (filterService.startsWith('0x'))
- filterService = parseInt(filterService, 16);
-
- if (filterService)
- options.filters.push({services: [filterService]});
+ 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.push({name: filterName});
+ options.filters[0].name = filterName;
var filterNamePrefix = document.getElementById('namePrefix').value;
if (filterNamePrefix)
- options.filters.push({namePrefix: filterNamePrefix});
-
- bluetoothDevice = null;
+ options.filters[0].namePrefix = filterNamePrefix;
try {
+ clear();
log('Requesting Bluetooth Device...');
bluetoothDevice = window.navigator.bluetooth.requestDevice(options);
+ log('Connecting to Bluetooth Device...');
connect();
} catch(err) {
log(err);
@@ -45,7 +46,7 @@
function onDisconnectButtonClick() {
clear();
if (!bluetoothDevice)
- return;
+ return log('> There is no connected Bluetooth Device instance, from which we can disconnect');
try {
log('Disconnecting from Bluetooth Device...');
@@ -63,32 +64,24 @@
function onReconnectButtonClick() {
clear();
if (!bluetoothDevice)
- log('> There is no connected Bluetooth Device instance')
+ 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() {
try {
- log('Connecting to Bluetooth Device...');
- bluetoothDevice.gatt.connect();
+ log('Result of the connect() method of the GATT Server: ' + bluetoothDevice.gatt.connect());
log('> Bluetooth Device connected: ' + bluetoothDevice.gatt.connected);
} catch(err) {
log(err);
}
}
-
- function clear() {
- document.getElementById("log").textContent = "";
- }
-
- function log(line) {
- document.getElementById("log").textContent += line + '\n';
- }
</script>
</body>
</html>
diff --git a/tests/html/bluetooth_device_info.html b/tests/html/bluetooth/bluetooth_device_info.html
index 906dc200362..6df38acbeae 100644
--- a/tests/html/bluetooth_device_info.html
+++ b/tests/html/bluetooth/bluetooth_device_info.html
@@ -7,17 +7,18 @@
<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: [], optinalServices: []};
+ var options = {filters: [], optionalServices: []};
var filterService = document.getElementById('service').value;
- if (filterService.startsWith('0x'))
- filterService = parseInt(filterService, 16);
-
- if (filterService)
+ if (filterService) {
+ if (filterService.startsWith('0x'))
+ filterService = parseInt(filterService, 16);
options.filters.push({services: [filterService]});
+ }
var filterName = document.getElementById('name').value;
if (filterName)
@@ -41,14 +42,6 @@
log(err);
}
}
-
- function clear() {
- document.getElementById("log").textContent = "";
- }
-
- function log(line) {
- document.getElementById("log").textContent += line + '\n';
- }
</script>
</body>
</html>
diff --git a/tests/html/bluetooth/bluetooth_functions.js b/tests/html/bluetooth/bluetooth_functions.js
new file mode 100644
index 00000000000..b0f73c79c0a
--- /dev/null
+++ b/tests/html/bluetooth/bluetooth_functions.js
@@ -0,0 +1,32 @@
+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
new file mode 100644
index 00000000000..5c9c2fe4f73
--- /dev/null
+++ b/tests/html/bluetooth/bluetooth_get_characteristic_test_cases.html
@@ -0,0 +1,82 @@
+<!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();
+ try {
+ log('Requesting Bluetooth Device...');
+ var device = window.navigator.bluetooth.requestDevice(testCases[testNumber].options);
+
+ log('Connecting to GATTserver on device...');
+ var server = device.gatt.connect();
+
+ log('Getting Primary Service "' + testCases[testNumber].service + '"...');
+ var primaryService = server.getPrimaryService(testCases[testNumber].service);
+
+ log('Getting Characteristic "' + testCases[testNumber].characteristic + '"...');
+ var characteristic = primaryService.getCharacteristic(testCases[testNumber].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);
+ characteristic.readValue();
+ log('> Characteristic value: ' + asciiToDecimal(characteristic.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
new file mode 100644
index 00000000000..81c3e42bb47
--- /dev/null
+++ b/tests/html/bluetooth/bluetooth_get_characteristics_test_cases.html
@@ -0,0 +1,87 @@
+<!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();
+ try {
+ log('Requesting Bluetooth Device...');
+ var device = window.navigator.bluetooth.requestDevice(testCases[testNumber].options);
+
+ log('Connecting to GATTserver on device...');
+ var server = device.gatt.connect();
+
+ log('Getting Primary Service "' + testCases[testNumber].service + '"...');
+ var primaryService = server.getPrimaryService(testCases[testNumber].service);
+
+ log('Getting Characteristic "' + testCases[testNumber].characteristic + '"...');
+ var characteristics = primaryService.getCharacteristics(testCases[testNumber].characteristic);
+
+ 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();
+ log('> 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
new file mode 100644
index 00000000000..e37a0dabd28
--- /dev/null
+++ b/tests/html/bluetooth/bluetooth_get_descriptor_test_cases.html
@@ -0,0 +1,66 @@
+<!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();
+ try {
+ log('Requesting Bluetooth Device...');
+ var device = window.navigator.bluetooth.requestDevice({filters: [{services: ['heart_rate']}]});
+
+ log('Connecting to GATTserver on device...');
+ var server = device.gatt.connect();
+
+ log('Getting Primary Service "heart_rate"...');
+ var primaryService = server.getPrimaryService('heart_rate');
+
+ log('Getting Characteristic "heart_rate_measurement"...');
+ var characteristic = primaryService.getCharacteristic('heart_rate_measurement');
+
+ log('Getting Descriptor "' + testCases[testNumber] + '"...');
+ var descriptor = characteristic.getDescriptor(testCases[testNumber]);
+
+ log('Descriptor found!');
+ log('> Descriptor characteristic: ' + descriptor.characteristic.uuid);
+ log('> Descriptor UUID: ' + descriptor.uuid);
+ descriptor.readValue();
+ log('> Descriptor value: ' + asciiToDecimal(descriptor.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
new file mode 100644
index 00000000000..3c71e27267c
--- /dev/null
+++ b/tests/html/bluetooth/bluetooth_get_descriptors_test_cases.html
@@ -0,0 +1,68 @@
+<!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();
+ try {
+ log('Requesting Bluetooth Device...');
+ var device = window.navigator.bluetooth.requestDevice({filters: [{services: ['heart_rate']}]});
+
+ log('Connecting to GATTserver on device...');
+ var server = device.gatt.connect();
+
+ log('Getting Primary Service "heart_rate"...');
+ var primaryService = server.getPrimaryService('heart_rate');
+
+ log('Getting Characteristic "heart_rate_measurement"...');
+ var characteristic = primaryService.getCharacteristic('heart_rate_measurement');
+
+ log('Getting Descriptors "' + testCases[testNumber] + '"...');
+ var descriptors = characteristic.getDescriptors(testCases[testNumber]);
+
+ for(i = 0; i < descriptors.length; ++i) {
+ log('> #' + (i+1));
+ log('> UUID: ' + descriptors[i].uuid);
+ descriptors[i].readValue();
+ log('> Descriptor value: ' + asciiToDecimal(descriptors[i].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
new file mode 100644
index 00000000000..54e877546b5
--- /dev/null
+++ b/tests/html/bluetooth/bluetooth_get_included_service_test_cases.html
@@ -0,0 +1,66 @@
+<!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();
+ try {
+ log('Requesting Bluetooth Device...');
+ var device = window.navigator.bluetooth.requestDevice(testCases[testNumber].options);
+
+ log('Connecting to GATTserver on device...');
+ var server = device.gatt.connect();
+
+ log('Getting Primary Service "' + testCases[testNumber].requestedService + '"...');
+ var primaryService = server.getPrimaryService(testCases[testNumber].requestedService);
+
+ log('Getting Included Service "' + testCases[testNumber].requestedIncludedService + '"...')
+ var includedService = primaryService.getIncludedService(testCases[testNumber].requestedIncludedService);
+
+ 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
new file mode 100644
index 00000000000..f0291469de7
--- /dev/null
+++ b/tests/html/bluetooth/bluetooth_get_included_services_test_cases.html
@@ -0,0 +1,68 @@
+<!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();
+ try {
+ log('Requesting Bluetooth Device...');
+ var device = window.navigator.bluetooth.requestDevice(testCases[testNumber].options);
+
+ log('Connecting to GATTserver on device...');
+ var server = device.gatt.connect();
+
+ log('Getting Primary Service "' + testCases[testNumber].requestedService + '"...');
+ var primaryService = server.getPrimaryService(testCases[testNumber].requestedService);
+
+ log('Getting Included Service "' + testCases[testNumber].requestedIncludedService + '"...')
+ var includedServices = primaryService.getIncludedServices(testCases[testNumber].requestedIncludedService);
+
+ 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
new file mode 100644
index 00000000000..160703754cf
--- /dev/null
+++ b/tests/html/bluetooth/bluetooth_get_primary_service_test_cases.html
@@ -0,0 +1,74 @@
+<!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();
+ try {
+ log('Requesting Bluetooth Device...');
+ var device = window.navigator.bluetooth.requestDevice(testCases[testNumber].options);
+
+ log('Connecting to GATTserver on device...');
+ var server = device.gatt.connect();
+
+ log('Getting Primary Service "' + testCases[testNumber].requestedService + '"...');
+ var primaryService = server.getPrimaryService(testCases[testNumber].requestedService);
+
+ log('Primary Service found on device: ' + primaryService.device.name);
+ log('> UUID: ' + primaryService.uuid);
+ log('> Is primary: ' + primaryService.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
new file mode 100644
index 00000000000..4a00c0efa32
--- /dev/null
+++ b/tests/html/bluetooth/bluetooth_get_primary_services_test_cases.html
@@ -0,0 +1,75 @@
+<!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();
+ try {
+ log('Requesting Bluetooth Device...');
+ var device = window.navigator.bluetooth.requestDevice(testCases[testNumber].options);
+
+ log('Connecting to GATTserver on device...');
+ var server = device.gatt.connect();
+
+ log('Getting Primary Service "' + testCases[testNumber].requestedService + '"...');
+ var primaryServices = server.getPrimaryServices(testCases[testNumber].requestedService);
+
+ for(i = 0; i < primaryServices.length; ++i) {
+ log('> #' + (i+1));
+ log('> UUID: ' + primaryServices[i].uuid);
+ log('> Is primary: ' + primaryServices[i].isPrimary);
+ }
+ } catch(err) {
+ log(err);
+ }
+ }
+
+ populate(testCases);
+ </script>
+</body>
+</html>
diff --git a/tests/html/bluetooth_included_service_info.html b/tests/html/bluetooth/bluetooth_included_service_info.html
index 76a351606b7..094ce5fd6a5 100644
--- a/tests/html/bluetooth_included_service_info.html
+++ b/tests/html/bluetooth/bluetooth_included_service_info.html
@@ -7,17 +7,18 @@
<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: [], optinalServices: []};
+ var options = {filters: [], optionalServices: []};
var filterService = document.getElementById('service').value;
- if (filterService.startsWith('0x'))
- filterService = parseInt(filterService, 16);
-
- if (filterService)
+ if (filterService) {
+ if (filterService.startsWith('0x'))
+ filterService = parseInt(filterService, 16);
options.filters.push({services: [filterService]});
+ }
var filterName = document.getElementById('name').value;
if (filterName)
@@ -49,14 +50,6 @@
log(err);
}
}
-
- function clear() {
- document.getElementById("log").textContent = "";
- }
-
- function log(line) {
- document.getElementById("log").textContent += line + '\n';
- }
</script>
</body>
</html>
diff --git a/tests/html/bluetooth_primary_service_info.html b/tests/html/bluetooth/bluetooth_primary_service_info.html
index 606d342c85d..3187400b00a 100644
--- a/tests/html/bluetooth_primary_service_info.html
+++ b/tests/html/bluetooth/bluetooth_primary_service_info.html
@@ -7,17 +7,18 @@
<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: [], optinalServices: []};
+ var options = {filters: [], optionalServices: []};
var filterService = document.getElementById('service').value;
- if (filterService.startsWith('0x'))
- filterService = parseInt(filterService, 16);
-
- if (filterService)
+ if (filterService) {
+ if (filterService.startsWith('0x'))
+ filterService = parseInt(filterService, 16);
options.filters.push({services: [filterService]});
+ }
var filterName = document.getElementById('name').value;
if (filterName)
@@ -44,14 +45,6 @@
log(err);
}
}
-
- function clear() {
- document.getElementById("log").textContent = "";
- }
-
- function log(line) {
- document.getElementById("log").textContent += line + '\n';
- }
</script>
</body>
</html>
diff --git a/tests/html/bluetooth/bluetooth_primary_services_info.html b/tests/html/bluetooth/bluetooth_primary_services_info.html
new file mode 100644
index 00000000000..cab413f8360
--- /dev/null
+++ b/tests/html/bluetooth/bluetooth_primary_services_info.html
@@ -0,0 +1,57 @@
+<!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});
+
+ try {
+ log('Requesting Bluetooth Device...');
+ var device = window.navigator.bluetooth.requestDevice(options);
+
+ log('Connecting to GATTserver on device...');
+ var server = device.gatt.connect();
+
+ log('Getting Primary Service...');
+ var primaryServices;
+ if (filterService) {
+ primaryServices = server.getPrimaryServices(filterService);
+ } else {
+ primaryServices = server.getPrimaryServices();
+ }
+ log('> List of Services on the current device:');
+ for(i = 0; i < primaryServices.length; ++i) {
+ log('> #' + (i+1));
+ log('> UUID: ' + primaryServices[i].uuid);
+ log('> Is primary: ' + primaryServices[i].isPrimary);
+ }
+ } 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
new file mode 100644
index 00000000000..4e42fdeeeab
--- /dev/null
+++ b/tests/html/bluetooth/bluetooth_request_device_test_cases.html
@@ -0,0 +1,73 @@
+<!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();
+ try {
+ log('Requesting Bluetooth Device...');
+ var device = window.navigator.bluetooth.requestDevice(testCases[testNumber]);
+
+ 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/gfx/Cargo.toml b/tests/unit/gfx/Cargo.toml
index 6a3ad210458..060bb09b01e 100644
--- a/tests/unit/gfx/Cargo.toml
+++ b/tests/unit/gfx/Cargo.toml
@@ -11,5 +11,5 @@ doctest = false
[dependencies]
gfx = {path = "../../../components/gfx"}
-ipc-channel = {git = "https://github.com/servo/ipc-channel"}
+ipc-channel = "0.4.0"
style = {path = "../../../components/style"}
diff --git a/tests/unit/net/Cargo.toml b/tests/unit/net/Cargo.toml
index 77da7edc652..3f87e8fe429 100644
--- a/tests/unit/net/Cargo.toml
+++ b/tests/unit/net/Cargo.toml
@@ -15,7 +15,7 @@ cookie = "0.2"
devtools_traits = {path = "../../../components/devtools_traits"}
flate2 = "0.2.0"
hyper = "0.9.9"
-ipc-channel = {git = "https://github.com/servo/ipc-channel"}
+ipc-channel = "0.4.0"
msg = {path = "../../../components/msg"}
net = {path = "../../../components/net"}
net_traits = {path = "../../../components/net_traits"}
diff --git a/tests/unit/net/fetch.rs b/tests/unit/net/fetch.rs
index c59be9349d3..f2fe7500a51 100644
--- a/tests/unit/net/fetch.rs
+++ b/tests/unit/net/fetch.rs
@@ -2,23 +2,31 @@
* 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 hyper::header::{AccessControlAllowCredentials, AccessControlAllowHeaders, AccessControlAllowOrigin};
-use hyper::header::{AccessControlAllowMethods, AccessControlMaxAge};
-use hyper::header::{AccessControlRequestHeaders, AccessControlRequestMethod};
-use hyper::header::{CacheControl, ContentLanguage, ContentType, Expires, LastModified};
-use hyper::header::{Headers, HttpDate, Location, SetCookie, Pragma};
+use devtools_traits::DevtoolsControlMsg;
+use devtools_traits::HttpRequest as DevtoolsHttpRequest;
+use devtools_traits::HttpResponse as DevtoolsHttpResponse;
+use http_loader::{expect_devtools_http_request, expect_devtools_http_response};
+use hyper::LanguageTag;
+use hyper::header::{Accept, AccessControlAllowCredentials, AccessControlAllowHeaders, AccessControlAllowOrigin};
+use hyper::header::{AccessControlAllowMethods, AccessControlMaxAge, AcceptLanguage, AcceptEncoding};
+use hyper::header::{AccessControlRequestHeaders, AccessControlRequestMethod, UserAgent, Date};
+use hyper::header::{CacheControl, ContentLanguage, ContentLength, ContentType, Expires, LastModified};
+use hyper::header::{Headers, HttpDate, Host, Location, SetCookie, Pragma, Encoding, qitem};
+use hyper::http::RawStatus;
use hyper::method::Method;
use hyper::mime::{Mime, TopLevel, SubLevel};
use hyper::server::{Handler, Listening, Server};
use hyper::server::{Request as HyperRequest, Response as HyperResponse};
use hyper::status::StatusCode;
use hyper::uri::RequestUri;
+use msg::constellation_msg::PipelineId;
use net::fetch::cors_cache::CORSCache;
use net::fetch::methods::{FetchContext, fetch, fetch_with_cors_cache};
use net::http_loader::HttpState;
use net_traits::FetchTaskTarget;
use net_traits::request::{Origin, RedirectMode, Referer, Request, RequestMode};
use net_traits::response::{CacheState, Response, ResponseBody, ResponseType};
+use std::borrow::Cow;
use std::fs::File;
use std::io::Read;
use std::rc::Rc;
@@ -31,16 +39,19 @@ use unicase::UniCase;
use url::{Origin as UrlOrigin, Url};
use util::resource_files::resources_dir_path;
+const DEFAULT_USER_AGENT: &'static str = "Such Browser. Very Layout. Wow.";
+
// TODO write a struct that impls Handler for storing test values
struct FetchResponseCollector {
sender: Sender<Response>,
}
-fn new_fetch_context() -> FetchContext {
+fn new_fetch_context(dc: Option<Sender<DevtoolsControlMsg>>) -> FetchContext {
FetchContext {
state: HttpState::new(),
- user_agent: "Such Browser. Very Layout. Wow.".into(),
+ user_agent: DEFAULT_USER_AGENT.into(),
+ devtools_chan: dc,
}
}
impl FetchTaskTarget for FetchResponseCollector {
@@ -54,14 +65,14 @@ impl FetchTaskTarget for FetchResponseCollector {
}
}
-fn fetch_async(request: Request, target: Box<FetchTaskTarget + Send>) {
+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());
+ fetch(Rc::new(request), &mut Some(target), new_fetch_context(dc));
});
}
-fn fetch_sync(request: Request) -> Response {
- fetch(Rc::new(request), &mut None, new_fetch_context())
+fn fetch_sync(request: Request, dc: Option<Sender<DevtoolsControlMsg>>) -> Response {
+ fetch(Rc::new(request), &mut None, new_fetch_context(dc))
}
fn make_server<H: Handler + 'static>(handler: H) -> (Listening, Url) {
@@ -83,9 +94,9 @@ fn test_fetch_response_is_not_network_error() {
let (mut server, url) = make_server(handler);
let origin = Origin::Origin(url.origin());
- let request = Request::new(url, Some(origin), false);
+ let request = Request::new(url, Some(origin), false, None);
*request.referer.borrow_mut() = Referer::NoReferer;
- let fetch_response = fetch_sync(request);
+ let fetch_response = fetch_sync(request, None);
let _ = server.close();
if fetch_response.is_network_error() {
@@ -102,9 +113,9 @@ fn test_fetch_response_body_matches_const_message() {
let (mut server, url) = make_server(handler);
let origin = Origin::Origin(url.origin());
- let request = Request::new(url, Some(origin), false);
+ let request = Request::new(url, Some(origin), false, None);
*request.referer.borrow_mut() = Referer::NoReferer;
- let fetch_response = fetch_sync(request);
+ let fetch_response = fetch_sync(request, None);
let _ = server.close();
assert!(!fetch_response.is_network_error());
@@ -122,9 +133,9 @@ fn test_fetch_response_body_matches_const_message() {
fn test_fetch_aboutblank() {
let url = Url::parse("about:blank").unwrap();
let origin = Origin::Origin(url.origin());
- let request = Request::new(url, Some(origin), false);
+ let request = Request::new(url, Some(origin), false, None);
*request.referer.borrow_mut() = Referer::NoReferer;
- let fetch_response = fetch_sync(request);
+ let fetch_response = fetch_sync(request, None);
assert!(!fetch_response.is_network_error());
assert!(*fetch_response.body.lock().unwrap() == ResponseBody::Done(vec![]));
}
@@ -133,10 +144,10 @@ fn test_fetch_aboutblank() {
fn test_fetch_data() {
let url = Url::parse("data:text/html,<p>Servo</p>").unwrap();
let origin = Origin::Origin(url.origin());
- let request = Request::new(url, Some(origin), false);
+ let request = Request::new(url, Some(origin), false, None);
request.same_origin_data.set(true);
let expected_resp_body = "<p>Servo</p>".to_owned();
- let fetch_response = fetch_sync(request);
+ let fetch_response = fetch_sync(request, None);
assert!(!fetch_response.is_network_error());
assert_eq!(fetch_response.headers.len(), 1);
@@ -162,10 +173,10 @@ fn test_fetch_file() {
let url = Url::from_file_path(path.clone()).unwrap();
let origin = Origin::Origin(url.origin());
- let request = Request::new(url, Some(origin), false);
+ let request = Request::new(url, Some(origin), false, None);
request.same_origin_data.set(true);
- let fetch_response = fetch_sync(request);
+ let fetch_response = fetch_sync(request, None);
assert!(!fetch_response.is_network_error());
assert_eq!(fetch_response.headers.len(), 1);
let content_type: &ContentType = fetch_response.headers.get().unwrap();
@@ -203,11 +214,11 @@ fn test_cors_preflight_fetch() {
let (mut server, url) = make_server(handler);
let origin = Origin::Origin(UrlOrigin::new_opaque());
- let mut request = Request::new(url, Some(origin), false);
+ let mut request = Request::new(url, Some(origin), false, None);
*request.referer.borrow_mut() = Referer::NoReferer;
request.use_cors_preflight = true;
request.mode = RequestMode::CORSMode;
- let fetch_response = fetch_sync(request);
+ let fetch_response = fetch_sync(request, None);
let _ = server.close();
assert!(!fetch_response.is_network_error());
@@ -240,15 +251,17 @@ fn test_cors_preflight_cache_fetch() {
let (mut server, url) = make_server(handler);
let origin = Origin::Origin(UrlOrigin::new_opaque());
- let mut request = Request::new(url.clone(), Some(origin.clone()), false);
+ let mut request = Request::new(url.clone(), Some(origin.clone()), false, None);
*request.referer.borrow_mut() = Referer::NoReferer;
request.use_cors_preflight = true;
request.mode = RequestMode::CORSMode;
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());
- let fetch_response1 = fetch_with_cors_cache(wrapped_request1.clone(), &mut cache, &mut None, new_fetch_context());
+ 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 _ = server.close();
assert!(!fetch_response0.is_network_error() && !fetch_response1.is_network_error());
@@ -289,12 +302,12 @@ fn test_cors_preflight_fetch_network_error() {
let (mut server, url) = make_server(handler);
let origin = Origin::Origin(UrlOrigin::new_opaque());
- let mut request = Request::new(url, Some(origin), false);
+ let mut request = Request::new(url, Some(origin), false, None);
*request.method.borrow_mut() = Method::Extension("CHICKEN".to_owned());
*request.referer.borrow_mut() = Referer::NoReferer;
request.use_cors_preflight = true;
request.mode = RequestMode::CORSMode;
- let fetch_response = fetch_sync(request);
+ let fetch_response = fetch_sync(request, None);
let _ = server.close();
assert!(fetch_response.is_network_error());
@@ -313,9 +326,9 @@ fn test_fetch_response_is_basic_filtered() {
let (mut server, url) = make_server(handler);
let origin = Origin::Origin(url.origin());
- let request = Request::new(url, Some(origin), false);
+ let request = Request::new(url, Some(origin), false, None);
*request.referer.borrow_mut() = Referer::NoReferer;
- let fetch_response = fetch_sync(request);
+ let fetch_response = fetch_sync(request, None);
let _ = server.close();
assert!(!fetch_response.is_network_error());
@@ -358,10 +371,10 @@ fn test_fetch_response_is_cors_filtered() {
// an origin mis-match will stop it from defaulting to a basic filtered response
let origin = Origin::Origin(UrlOrigin::new_opaque());
- let mut request = Request::new(url, Some(origin), false);
+ let mut request = Request::new(url, Some(origin), false, None);
*request.referer.borrow_mut() = Referer::NoReferer;
request.mode = RequestMode::CORSMode;
- let fetch_response = fetch_sync(request);
+ let fetch_response = fetch_sync(request, None);
let _ = server.close();
assert!(!fetch_response.is_network_error());
@@ -390,9 +403,9 @@ fn test_fetch_response_is_opaque_filtered() {
// an origin mis-match will fall through to an Opaque filtered response
let origin = Origin::Origin(UrlOrigin::new_opaque());
- let request = Request::new(url, Some(origin), false);
+ let request = Request::new(url, Some(origin), false, None);
*request.referer.borrow_mut() = Referer::NoReferer;
- let fetch_response = fetch_sync(request);
+ let fetch_response = fetch_sync(request, None);
let _ = server.close();
assert!(!fetch_response.is_network_error());
@@ -437,10 +450,10 @@ fn test_fetch_response_is_opaque_redirect_filtered() {
let (mut server, url) = make_server(handler);
let origin = Origin::Origin(url.origin());
- let request = Request::new(url, Some(origin), false);
+ let request = Request::new(url, Some(origin), false, None);
*request.referer.borrow_mut() = Referer::NoReferer;
request.redirect_mode.set(RedirectMode::Manual);
- let fetch_response = fetch_sync(request);
+ let fetch_response = fetch_sync(request, None);
let _ = server.close();
assert!(!fetch_response.is_network_error());
@@ -471,13 +484,13 @@ fn test_fetch_with_local_urls_only() {
let do_fetch = |url: Url| {
let origin = Origin::Origin(url.origin());
- let mut request = Request::new(url, Some(origin), false);
+ let mut request = Request::new(url, Some(origin), false, None);
*request.referer.borrow_mut() = Referer::NoReferer;
// Set the flag.
request.local_urls_only = true;
- fetch_sync(request)
+ fetch_sync(request, None)
};
let local_url = Url::parse("about:blank").unwrap();
@@ -512,9 +525,9 @@ fn setup_server_and_fetch(message: &'static [u8], redirect_cap: u32) -> Response
let (mut server, url) = make_server(handler);
let origin = Origin::Origin(url.origin());
- let request = Request::new(url, Some(origin), false);
+ let request = Request::new(url, Some(origin), false, None);
*request.referer.borrow_mut() = Referer::NoReferer;
- let fetch_response = fetch_sync(request);
+ let fetch_response = fetch_sync(request, None);
let _ = server.close();
fetch_response
}
@@ -595,11 +608,11 @@ fn test_fetch_redirect_updates_method_runner(tx: Sender<bool>, status_code: Stat
let (mut server, url) = make_server(handler);
let origin = Origin::Origin(url.origin());
- let request = Request::new(url, Some(origin), false);
+ let request = Request::new(url, Some(origin), false, None);
*request.referer.borrow_mut() = Referer::NoReferer;
*request.method.borrow_mut() = method;
- let _ = fetch_sync(request);
+ let _ = fetch_sync(request, None);
let _ = server.close();
}
@@ -670,7 +683,7 @@ fn test_fetch_async_returns_complete_response() {
let (mut server, url) = make_server(handler);
let origin = Origin::Origin(url.origin());
- let request = Request::new(url, Some(origin), false);
+ let request = Request::new(url, Some(origin), false, None);
*request.referer.borrow_mut() = Referer::NoReferer;
let (tx, rx) = channel();
@@ -678,7 +691,7 @@ fn test_fetch_async_returns_complete_response() {
sender: tx.clone()
});
- fetch_async(request, listener);
+ fetch_async(request, listener, None);
let fetch_response = rx.recv().unwrap();
let _ = server.close();
@@ -695,7 +708,7 @@ fn test_opaque_filtered_fetch_async_returns_complete_response() {
// an origin mis-match will fall through to an Opaque filtered response
let origin = Origin::Origin(UrlOrigin::new_opaque());
- let request = Request::new(url, Some(origin), false);
+ let request = Request::new(url, Some(origin), false, None);
*request.referer.borrow_mut() = Referer::NoReferer;
let (tx, rx) = channel();
@@ -703,7 +716,7 @@ fn test_opaque_filtered_fetch_async_returns_complete_response() {
sender: tx.clone()
});
- fetch_async(request, listener);
+ fetch_async(request, listener, None);
let fetch_response = rx.recv().unwrap();
let _ = server.close();
@@ -735,7 +748,7 @@ fn test_opaque_redirect_filtered_fetch_async_returns_complete_response() {
let (mut server, url) = make_server(handler);
let origin = Origin::Origin(url.origin());
- let request = Request::new(url, Some(origin), false);
+ let request = Request::new(url, Some(origin), false, None);
*request.referer.borrow_mut() = Referer::NoReferer;
request.redirect_mode.set(RedirectMode::Manual);
@@ -744,10 +757,83 @@ fn test_opaque_redirect_filtered_fetch_async_returns_complete_response() {
sender: tx.clone()
});
- fetch_async(request, listener);
+ fetch_async(request, listener, None);
let fetch_response = rx.recv().unwrap();
let _ = server.close();
assert_eq!(fetch_response.response_type, ResponseType::OpaqueRedirect);
assert_eq!(response_is_done(&fetch_response), true);
}
+
+#[test]
+fn test_fetch_with_devtools() {
+ static MESSAGE: &'static [u8] = b"Yay!";
+ let handler = move |_: HyperRequest, response: HyperResponse| {
+ response.send(MESSAGE).unwrap();
+ };
+
+ let (mut server, url) = make_server(handler);
+
+ let origin = Origin::Origin(url.origin());
+ let pipeline_id = PipelineId::fake_root_pipeline_id();
+ let request = Request::new(url.clone(), Some(origin), false, Some(pipeline_id));
+ *request.referer.borrow_mut() = Referer::NoReferer;
+
+ let (devtools_chan, devtools_port) = channel::<DevtoolsControlMsg>();
+
+ let _ = fetch_sync(request, Some(devtools_chan));
+ let _ = server.close();
+
+ // notification received from devtools
+ let devhttprequest = expect_devtools_http_request(&devtools_port);
+ let mut devhttpresponse = expect_devtools_http_response(&devtools_port);
+
+ //Creating default headers for request
+ let mut headers = Headers::new();
+
+ headers.set(AcceptEncoding(vec![
+ qitem(Encoding::Gzip),
+ qitem(Encoding::Deflate),
+ qitem(Encoding::EncodingExt("br".to_owned()))
+ ]));
+
+ headers.set(Host { hostname: url.host_str().unwrap().to_owned() , port: url.port().to_owned() });
+
+ let accept = Accept(vec![qitem(Mime(TopLevel::Star, SubLevel::Star, vec![]))]);
+ headers.set(accept);
+
+ let mut en_us: LanguageTag = Default::default();
+ en_us.language = Some("en".to_owned());
+ en_us.region = Some("US".to_owned());
+ headers.set(AcceptLanguage(vec![qitem(en_us)]));
+
+ headers.set(UserAgent(DEFAULT_USER_AGENT.to_owned()));
+
+ let httprequest = DevtoolsHttpRequest {
+ url: url,
+ method: Method::Get,
+ headers: headers,
+ body: None,
+ pipeline_id: pipeline_id,
+ startedDateTime: devhttprequest.startedDateTime,
+ timeStamp: devhttprequest.timeStamp,
+ connect_time: devhttprequest.connect_time,
+ send_time: devhttprequest.send_time,
+ is_xhr: true,
+ };
+
+ let content = "Yay!";
+ let mut response_headers = Headers::new();
+ response_headers.set(ContentLength(content.len() as u64));
+ devhttpresponse.headers.as_mut().unwrap().remove::<Date>();
+
+ let httpresponse = DevtoolsHttpResponse {
+ headers: Some(response_headers),
+ status: Some(RawStatus(200, Cow::Borrowed("OK"))),
+ body: None,
+ pipeline_id: pipeline_id,
+ };
+
+ assert_eq!(devhttprequest, httprequest);
+ assert_eq!(devhttpresponse, httpresponse);
+}
diff --git a/tests/unit/net/filemanager_thread.rs b/tests/unit/net/filemanager_thread.rs
index 40549eb2101..7266157481a 100644
--- a/tests/unit/net/filemanager_thread.rs
+++ b/tests/unit/net/filemanager_thread.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 ipc_channel::ipc::{self, IpcSender};
-use net::filemanager_thread::{FileManagerThreadFactory, UIProvider};
+use ipc_channel::ipc;
+use net::filemanager_thread::{FileManager, UIProvider};
use net_traits::blob_url_store::BlobURLStoreError;
-use net_traits::filemanager_thread::{FilterPattern, FileManagerThreadMsg, FileManagerThreadError};
+use net_traits::filemanager_thread::{FilterPattern, FileManagerThreadMsg, FileManagerThreadError, ReadFileProgress};
use std::fs::File;
use std::io::Read;
use std::path::PathBuf;
@@ -16,54 +16,73 @@ struct TestProvider;
impl UIProvider for TestProvider {
fn open_file_dialog(&self, _path: &str, _patterns: Vec<FilterPattern>) -> Option<String> {
- Some("test.txt".to_string())
+ Some("test.jpeg".to_string())
}
fn open_file_dialog_multi(&self, _path: &str, _patterns: Vec<FilterPattern>) -> Option<Vec<String>> {
- Some(vec!["test.txt".to_string()])
+ Some(vec!["test.jpeg".to_string()])
}
}
#[test]
fn test_filemanager() {
- let chan: IpcSender<FileManagerThreadMsg> = FileManagerThreadFactory::new(TEST_PROVIDER);
+ let filemanager = FileManager::new(TEST_PROVIDER);
- // Try to open a dummy file "tests/unit/net/test.txt" in tree
- let mut handler = File::open("test.txt").expect("test.txt is stolen");
+ // Try to open a dummy file "tests/unit/net/test.jpeg" in tree
+ let mut handler = File::open("test.jpeg").expect("test.jpeg is stolen");
let mut test_file_content = vec![];
handler.read_to_end(&mut test_file_content)
- .expect("Read tests/unit/net/test.txt error");
+ .expect("Read tests/unit/net/test.jpeg error");
let patterns = vec![FilterPattern(".txt".to_string())];
let origin = "test.com".to_string();
{
- // Try to select a dummy file "tests/unit/net/test.txt"
+ // Try to select a dummy file "tests/unit/net/test.jpeg"
let (tx, rx) = ipc::channel().unwrap();
- chan.send(FileManagerThreadMsg::SelectFile(patterns.clone(), tx, origin.clone(), None)).unwrap();
+ filemanager.handle(FileManagerThreadMsg::SelectFile(patterns.clone(), tx, origin.clone(), None), None);
let selected = rx.recv().expect("Broken channel")
- .expect("The file manager failed to find test.txt");
+ .expect("The file manager failed to find test.jpeg");
// Expecting attributes conforming the spec
- assert!(selected.filename == PathBuf::from("test.txt"));
- assert!(selected.type_string == "text/plain".to_string());
+ assert_eq!(selected.filename, PathBuf::from("test.jpeg"));
+ assert_eq!(selected.type_string, "image/jpeg".to_string());
// Test by reading, expecting same content
{
let (tx2, rx2) = ipc::channel().unwrap();
- chan.send(FileManagerThreadMsg::ReadFile(tx2, selected.id.clone(), false, origin.clone())).unwrap();
+ filemanager.handle(FileManagerThreadMsg::ReadFile(tx2, selected.id.clone(), false, origin.clone()), None);
let msg = rx2.recv().expect("Broken channel");
- let blob_buf = msg.expect("File manager reading failure is unexpected");
- assert_eq!(test_file_content, blob_buf.bytes, "Read content differs");
+ if let ReadFileProgress::Meta(blob_buf) = msg.expect("File manager reading failure is unexpected") {
+ let mut bytes = blob_buf.bytes;
+
+ loop {
+ match rx2.recv().expect("Broken channel").expect("File manager reading failure is unexpected") {
+ ReadFileProgress::Meta(_) => {
+ panic!("Invalid FileManager reply");
+ }
+ ReadFileProgress::Partial(mut bytes_in) => {
+ bytes.append(&mut bytes_in);
+ }
+ ReadFileProgress::EOF => {
+ break;
+ }
+ }
+ }
+
+ assert_eq!(test_file_content, bytes, "Read content differs");
+ } else {
+ panic!("Invalid FileManager reply");
+ }
}
// Delete the id
{
let (tx2, rx2) = ipc::channel().unwrap();
- chan.send(FileManagerThreadMsg::DecRef(selected.id.clone(), origin.clone(), tx2)).unwrap();
+ filemanager.handle(FileManagerThreadMsg::DecRef(selected.id.clone(), origin.clone(), tx2), None);
let ret = rx2.recv().expect("Broken channel");
assert!(ret.is_ok(), "DecRef is not okay");
@@ -72,7 +91,7 @@ fn test_filemanager() {
// Test by reading again, expecting read error because we invalidated the id
{
let (tx2, rx2) = ipc::channel().unwrap();
- chan.send(FileManagerThreadMsg::ReadFile(tx2, selected.id.clone(), false, origin.clone())).unwrap();
+ filemanager.handle(FileManagerThreadMsg::ReadFile(tx2, selected.id.clone(), false, origin.clone()), None);
let msg = rx2.recv().expect("Broken channel");
@@ -84,13 +103,4 @@ fn test_filemanager() {
}
}
}
-
- let _ = chan.send(FileManagerThreadMsg::Exit);
-
- {
- let (tx, rx) = ipc::channel().unwrap();
- let _ = chan.send(FileManagerThreadMsg::SelectFile(patterns.clone(), tx, origin.clone(), None));
-
- assert!(rx.try_recv().is_err(), "The thread should not respond normally after exited");
- }
}
diff --git a/tests/unit/net/http_loader.rs b/tests/unit/net/http_loader.rs
index dad9d3d945c..53f79178aab 100644
--- a/tests/unit/net/http_loader.rs
+++ b/tests/unit/net/http_loader.rs
@@ -339,7 +339,7 @@ impl HttpRequest for AssertMustHaveBodyRequest {
}
}
-fn expect_devtools_http_request(devtools_port: &Receiver<DevtoolsControlMsg>) -> DevtoolsHttpRequest {
+pub fn expect_devtools_http_request(devtools_port: &Receiver<DevtoolsControlMsg>) -> DevtoolsHttpRequest {
match devtools_port.recv().unwrap() {
DevtoolsControlMsg::FromChrome(
ChromeToDevtoolsControlMsg::NetworkEvent(_, net_event)) => {
@@ -355,7 +355,7 @@ fn expect_devtools_http_request(devtools_port: &Receiver<DevtoolsControlMsg>) ->
}
}
-fn expect_devtools_http_response(devtools_port: &Receiver<DevtoolsControlMsg>) -> DevtoolsHttpResponse {
+pub fn expect_devtools_http_response(devtools_port: &Receiver<DevtoolsControlMsg>) -> DevtoolsHttpResponse {
match devtools_port.recv().unwrap() {
DevtoolsControlMsg::FromChrome(
ChromeToDevtoolsControlMsg::NetworkEvent(_, net_event_response)) => {
@@ -526,6 +526,7 @@ fn test_request_and_response_data_with_network_messages() {
timeStamp: devhttprequest.timeStamp,
connect_time: devhttprequest.connect_time,
send_time: devhttprequest.send_time,
+ is_xhr: false,
};
let content = "Yay!";
@@ -586,6 +587,52 @@ fn test_request_and_response_message_from_devtool_without_pipeline_id() {
assert!(devtools_port.try_recv().is_err());
}
+#[test]
+fn test_redirected_request_to_devtools() {
+ struct Factory;
+
+ impl HttpRequestFactory for Factory {
+ type R = MockRequest;
+
+ fn create(&self, url: Url, method: Method, _: Headers) -> Result<MockRequest, LoadError> {
+ if url.domain().unwrap() == "mozilla.com" {
+ assert_eq!(Method::Post, method);
+ Ok(MockRequest::new(ResponseType::Redirect("http://mozilla.org".to_owned())))
+ } else {
+ assert_eq!(Method::Get, method);
+ Ok(MockRequest::new(ResponseType::Text(<[_]>::to_vec("Yay!".as_bytes()))))
+ }
+ }
+ }
+
+ let url = Url::parse("http://mozilla.com").unwrap();
+ let mut load_data = LoadData::new(LoadContext::Browsing, url.clone(), &HttpTest);
+
+ load_data.method = Method::Post;
+
+ let http_state = HttpState::new();
+ let ui_provider = TestProvider::new();
+ let (devtools_chan, devtools_port) = mpsc::channel::<DevtoolsControlMsg>();
+
+ let _ = load(&load_data, &ui_provider, &http_state, Some(devtools_chan), &Factory,
+ DEFAULT_USER_AGENT.to_owned(), &CancellationListener::new(None), None);
+
+ let devhttprequest = expect_devtools_http_request(&devtools_port);
+ let devhttpresponse = expect_devtools_http_response(&devtools_port);
+
+ assert!(devhttprequest.method == Method::Post);
+ assert!(devhttprequest.url == url);
+ assert!(devhttpresponse.status == Some(RawStatus(301, Cow::Borrowed("Moved Permanently"))));
+
+ let devhttprequest = expect_devtools_http_request(&devtools_port);
+ let devhttpresponse = expect_devtools_http_response(&devtools_port);
+ let url = Url::parse("http://mozilla.org").unwrap();
+
+ assert!(devhttprequest.method == Method::Get);
+ assert!(devhttprequest.url == url);
+ assert!(devhttpresponse.status == Some(RawStatus(200, Cow::Borrowed("Ok"))));
+}
+
#[test]
diff --git a/tests/unit/net/resource_thread.rs b/tests/unit/net/resource_thread.rs
index 1820ea73039..b6da4f4f524 100644
--- a/tests/unit/net/resource_thread.rs
+++ b/tests/unit/net/resource_thread.rs
@@ -4,7 +4,6 @@
use ipc_channel::ipc;
use msg::constellation_msg::{PipelineId, ReferrerPolicy};
-use net::filemanager_thread::{FileManagerThreadFactory, TFDProvider};
use net::resource_thread::new_core_resource_thread;
use net_traits::hosts::{parse_hostsfile, host_replacement};
use net_traits::{CoreResourceMsg, LoadData, LoadConsumer, LoadContext};
@@ -16,8 +15,6 @@ use std::net::IpAddr;
use std::sync::mpsc::channel;
use url::Url;
-const TFD_PROVIDER: &'static TFDProvider = &TFDProvider;
-
fn ip(s: &str) -> IpAddr {
s.parse().unwrap()
}
@@ -40,8 +37,8 @@ impl LoadOrigin for ResourceTest {
fn test_exit() {
let (tx, _rx) = ipc::channel().unwrap();
let (sender, receiver) = ipc::channel().unwrap();
- let filemanager_chan = FileManagerThreadFactory::new(TFD_PROVIDER);
- let (resource_thread, _) = new_core_resource_thread("".to_owned(), None, ProfilerChan(tx), filemanager_chan);
+ let (resource_thread, _) = new_core_resource_thread(
+ "".to_owned(), None, ProfilerChan(tx), None);
resource_thread.send(CoreResourceMsg::Exit(sender)).unwrap();
receiver.recv().unwrap();
}
@@ -50,8 +47,8 @@ fn test_exit() {
fn test_bad_scheme() {
let (tx, _rx) = ipc::channel().unwrap();
let (sender, receiver) = ipc::channel().unwrap();
- let filemanager_chan = FileManagerThreadFactory::new(TFD_PROVIDER);
- let (resource_thread, _) = new_core_resource_thread("".to_owned(), None, ProfilerChan(tx), filemanager_chan);
+ let (resource_thread, _) = new_core_resource_thread(
+ "".to_owned(), None, ProfilerChan(tx), None);
let (start_chan, start) = ipc::channel().unwrap();
let url = Url::parse("bogus://whatever").unwrap();
resource_thread.send(CoreResourceMsg::Load(LoadData::new(LoadContext::Browsing, url, &ResourceTest),
@@ -230,8 +227,8 @@ fn test_cancelled_listener() {
let (tx, _rx) = ipc::channel().unwrap();
let (exit_sender, exit_receiver) = ipc::channel().unwrap();
- let filemanager_chan = FileManagerThreadFactory::new(TFD_PROVIDER);
- let (resource_thread, _) = new_core_resource_thread("".to_owned(), None, ProfilerChan(tx), filemanager_chan);
+ let (resource_thread, _) = new_core_resource_thread(
+ "".to_owned(), None, ProfilerChan(tx), None);
let (sender, receiver) = ipc::channel().unwrap();
let (id_sender, id_receiver) = ipc::channel().unwrap();
let (sync_sender, sync_receiver) = ipc::channel().unwrap();
diff --git a/tests/unit/net/test.jpeg b/tests/unit/net/test.jpeg
index 1a0bdb7acd1..08f084cf549 100644
--- a/tests/unit/net/test.jpeg
+++ b/tests/unit/net/test.jpeg
Binary files differ
diff --git a/tests/unit/net/test.txt b/tests/unit/net/test.txt
deleted file mode 100644
index 75bdfe4ef1c..00000000000
--- a/tests/unit/net/test.txt
+++ /dev/null
@@ -1 +0,0 @@
-hello, servo \ No newline at end of file
diff --git a/tests/unit/profile/Cargo.toml b/tests/unit/profile/Cargo.toml
index f8f9b8de25e..0c79370271c 100644
--- a/tests/unit/profile/Cargo.toml
+++ b/tests/unit/profile/Cargo.toml
@@ -12,4 +12,4 @@ doctest = false
[dependencies]
profile = {path = "../../../components/profile"}
profile_traits = {path = "../../../components/profile_traits"}
-ipc-channel = {git = "https://github.com/servo/ipc-channel"}
+ipc-channel = "0.4.0"
diff --git a/tests/unit/style/attr.rs b/tests/unit/style/attr.rs
index 4ae614eae2d..0521df3a690 100644
--- a/tests/unit/style/attr.rs
+++ b/tests/unit/style/attr.rs
@@ -15,6 +15,24 @@ fn test_parse_double() {
}
#[test]
+fn test_parse_double_negative_prefix() {
+ let value = String::from("-5.6");
+ match AttrValue::from_double(value, 0.0) {
+ AttrValue::Double(_, num) => assert_eq!(num, -5.6f64),
+ _ => panic!("expected a double value")
+ }
+}
+
+#[test]
+fn test_parse_double_positive_prefix() {
+ let value = String::from("+5.6");
+ match AttrValue::from_double(value, 0.0) {
+ AttrValue::Double(_, num) => assert_eq!(num, 5.6f64),
+ _ => panic!("expected a double value")
+ }
+}
+
+#[test]
fn test_from_limited_i32_should_be_default_when_less_than_0() {
let value = String::from("-1");
match AttrValue::from_limited_i32(value, 0) {
diff --git a/tests/unit/util/lib.rs b/tests/unit/util/lib.rs
index 1ad4e55d965..96506d5973c 100644
--- a/tests/unit/util/lib.rs
+++ b/tests/unit/util/lib.rs
@@ -8,4 +8,5 @@ extern crate util;
mod opts;
mod prefs;
+mod remutex;
mod thread;
diff --git a/tests/unit/util/remutex.rs b/tests/unit/util/remutex.rs
new file mode 100644
index 00000000000..a005d761d5f
--- /dev/null
+++ b/tests/unit/util/remutex.rs
@@ -0,0 +1,89 @@
+// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// 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.
+
+// These tests came from https://github.com/rust-lang/rust/blob/master/src/libstd/sys/common/remutex.rs
+
+use std::cell::RefCell;
+use std::sync::Arc;
+use std::thread;
+use util::remutex::{ReentrantMutex, ReentrantMutexGuard};
+
+#[test]
+fn smoke() {
+ let m = ReentrantMutex::new(());
+ {
+ let a = m.lock().unwrap();
+ {
+ let b = m.lock().unwrap();
+ {
+ let c = m.lock().unwrap();
+ assert_eq!(*c, ());
+ }
+ assert_eq!(*b, ());
+ }
+ assert_eq!(*a, ());
+ }
+}
+
+#[test]
+fn is_mutex() {
+ let m = Arc::new(ReentrantMutex::new(RefCell::new(0)));
+ let m2 = m.clone();
+ let lock = m.lock().unwrap();
+ let child = thread::spawn(move || {
+ let lock = m2.lock().unwrap();
+ assert_eq!(*lock.borrow(), 4950);
+ });
+ for i in 0..100 {
+ let lock = m.lock().unwrap();
+ *lock.borrow_mut() += i;
+ }
+ drop(lock);
+ child.join().unwrap();
+}
+
+#[test]
+fn trylock_works() {
+ let m = Arc::new(ReentrantMutex::new(()));
+ let m2 = m.clone();
+ let _lock = m.try_lock().unwrap();
+ let _lock2 = m.try_lock().unwrap();
+ thread::spawn(move || {
+ let lock = m2.try_lock();
+ assert!(lock.is_err());
+ }).join().unwrap();
+ let _lock3 = m.try_lock().unwrap();
+}
+
+pub struct Answer<'a>(pub ReentrantMutexGuard<'a, RefCell<u32>>);
+impl<'a> Drop for Answer<'a> {
+ fn drop(&mut self) {
+ *self.0.borrow_mut() = 42;
+ }
+}
+
+#[test]
+fn poison_works() {
+ let m = Arc::new(ReentrantMutex::new(RefCell::new(0)));
+ let mc = m.clone();
+ let result = thread::spawn(move ||{
+ let lock = mc.lock().unwrap();
+ *lock.borrow_mut() = 1;
+ let lock2 = mc.lock().unwrap();
+ *lock.borrow_mut() = 2;
+ let _answer = Answer(lock2);
+ println!("Intentionally panicking.");
+ panic!("What the answer to my lifetimes dilemma is?");
+ }).join();
+ assert!(result.is_err());
+ let r = m.lock().err().unwrap().into_inner();
+ assert_eq!(*r.borrow(), 42);
+}
+
diff --git a/tests/wpt/README.md b/tests/wpt/README.md
index e0aa6406c41..76073333c46 100644
--- a/tests/wpt/README.md
+++ b/tests/wpt/README.md
@@ -77,6 +77,18 @@ first adding the following to the system's hosts file:
and then running `python serve` from `tests/wpt/web-platform-tests`.
Then navigate Servo to `http://web-platform.test:8000/path/to/test`.
+Running the tests in Firefox
+----------------------------
+
+When working with tests, you may want to compare Servo's result with Firefox.
+You can supply `--product firefox` along with the path to a Firefox binary (as
+well as few more odds and ends) to run tests in Firefox from your Servo
+checkout:
+
+ GECKO="$HOME/projects/mozilla/gecko"
+ GECKO_BINS="$GECKO/obj-firefox-release-artifact/dist/Nightly.app/Contents/MacOS"
+ ./mach test-wpt dom --product firefox --binary $GECKO_BINS/firefox --certutil-binary $GECKO_BINS/certutil --prefs-root $GECKO/testing/profiles
+
Updating test expectations
==========================
@@ -191,5 +203,4 @@ MANIFEST.json can be regenerated automatically with the mach command `update-man
This is equivalent to running
- ./mach test-wpt --manifest-update SKIP_TESTS
-
+ ./mach test-wpt --manifest-update SKIP_TESTS
diff --git a/tests/wpt/config.ini b/tests/wpt/config.ini
index abd24963da4..7673f0aab8e 100644
--- a/tests/wpt/config.ini
+++ b/tests/wpt/config.ini
@@ -1,6 +1,7 @@
[products]
servo =
servodriver =
+firefox =
[web-platform-tests]
remote_url = https://github.com/w3c/web-platform-tests.git
diff --git a/tests/wpt/include.ini b/tests/wpt/include.ini
index d37502e0356..867bfa03b5c 100644
--- a/tests/wpt/include.ini
+++ b/tests/wpt/include.ini
@@ -17,6 +17,12 @@ skip: true
skip: false
[eventsource]
skip: false
+[fetch]
+ skip: true
+ [api]
+ skip: true
+ [headers]
+ skip: false
[FileAPI]
skip: false
[hr-time]
diff --git a/tests/wpt/metadata-css/css-transforms-1_dev/html/css-transforms-3d-on-anonymous-block-001.htm.ini b/tests/wpt/metadata-css/css-transforms-1_dev/html/css-transforms-3d-on-anonymous-block-001.htm.ini
index 605b45575ea..09c75600242 100644
--- a/tests/wpt/metadata-css/css-transforms-1_dev/html/css-transforms-3d-on-anonymous-block-001.htm.ini
+++ b/tests/wpt/metadata-css/css-transforms-1_dev/html/css-transforms-3d-on-anonymous-block-001.htm.ini
@@ -1,4 +1,2 @@
[css-transforms-3d-on-anonymous-block-001.htm]
type: reftest
- expected:
- if os == "linux": FAIL
diff --git a/tests/wpt/metadata-css/css-transforms-1_dev/html/transform-input-019.htm.ini b/tests/wpt/metadata-css/css-transforms-1_dev/html/transform-input-019.htm.ini
index e82b6718013..8e2a7b49f90 100644
--- a/tests/wpt/metadata-css/css-transforms-1_dev/html/transform-input-019.htm.ini
+++ b/tests/wpt/metadata-css/css-transforms-1_dev/html/transform-input-019.htm.ini
@@ -1,3 +1,4 @@
[transform-input-019.htm]
type: reftest
- expected: FAIL
+ expected:
+ if os == "linux": FAIL
diff --git a/tests/wpt/metadata-css/css21_dev/html4/margin-collapse-clear-002.htm.ini b/tests/wpt/metadata-css/css21_dev/html4/margin-collapse-clear-002.htm.ini
deleted file mode 100644
index ea6943c1c80..00000000000
--- a/tests/wpt/metadata-css/css21_dev/html4/margin-collapse-clear-002.htm.ini
+++ /dev/null
@@ -1,3 +0,0 @@
-[margin-collapse-clear-002.htm]
- type: reftest
- expected: FAIL
diff --git a/tests/wpt/metadata-css/css21_dev/html4/margin-collapse-clear-003.htm.ini b/tests/wpt/metadata-css/css21_dev/html4/margin-collapse-clear-003.htm.ini
deleted file mode 100644
index ef6e83de26c..00000000000
--- a/tests/wpt/metadata-css/css21_dev/html4/margin-collapse-clear-003.htm.ini
+++ /dev/null
@@ -1,3 +0,0 @@
-[margin-collapse-clear-003.htm]
- type: reftest
- expected: FAIL
diff --git a/tests/wpt/metadata-css/css21_dev/html4/margin-collapse-clear-008.htm.ini b/tests/wpt/metadata-css/css21_dev/html4/margin-collapse-clear-008.htm.ini
deleted file mode 100644
index 4a1f3812c59..00000000000
--- a/tests/wpt/metadata-css/css21_dev/html4/margin-collapse-clear-008.htm.ini
+++ /dev/null
@@ -1,3 +0,0 @@
-[margin-collapse-clear-008.htm]
- type: reftest
- expected: FAIL
diff --git a/tests/wpt/metadata-css/css21_dev/html4/margin-collapse-clear-009.htm.ini b/tests/wpt/metadata-css/css21_dev/html4/margin-collapse-clear-009.htm.ini
deleted file mode 100644
index 62b047475e6..00000000000
--- a/tests/wpt/metadata-css/css21_dev/html4/margin-collapse-clear-009.htm.ini
+++ /dev/null
@@ -1,3 +0,0 @@
-[margin-collapse-clear-009.htm]
- type: reftest
- expected: FAIL
diff --git a/tests/wpt/metadata/FileAPI/FileReaderSync.worker.js.ini b/tests/wpt/metadata/FileAPI/FileReaderSync.worker.js.ini
index 3e0c3c418dc..249873f6547 100644
--- a/tests/wpt/metadata/FileAPI/FileReaderSync.worker.js.ini
+++ b/tests/wpt/metadata/FileAPI/FileReaderSync.worker.js.ini
@@ -1,9 +1,5 @@
[FileReaderSync.worker]
type: testharness
- expected: ERROR
- [Interface]
- expected: FAIL
-
[readAsText]
expected: FAIL
diff --git a/tests/wpt/metadata/FileAPI/blob/Blob-XHR-revoke.html.ini b/tests/wpt/metadata/FileAPI/blob/Blob-XHR-revoke.html.ini
index b7e66c83a20..6fb7d0ba5ca 100644
--- a/tests/wpt/metadata/FileAPI/blob/Blob-XHR-revoke.html.ini
+++ b/tests/wpt/metadata/FileAPI/blob/Blob-XHR-revoke.html.ini
@@ -2,4 +2,3 @@
type: testharness
expected: CRASH
bug: https://github.com/servo/servo/issues/10539
-
diff --git a/tests/wpt/metadata/FileAPI/file/File-constructor.html.ini b/tests/wpt/metadata/FileAPI/file/File-constructor.html.ini
index d9c18b41655..1134394834f 100644
--- a/tests/wpt/metadata/FileAPI/file/File-constructor.html.ini
+++ b/tests/wpt/metadata/FileAPI/file/File-constructor.html.ini
@@ -12,7 +12,3 @@
expected: FAIL
bug: https://github.com/servo/servo/issues/10911
- [Using special character in fileName]
- expected: FAIL
- bug: https://github.com/w3c/FileAPI/issues/41
-
diff --git a/tests/wpt/metadata/FileAPI/idlharness.html.ini b/tests/wpt/metadata/FileAPI/idlharness.html.ini
index 1957439c798..a2b56459bec 100644
--- a/tests/wpt/metadata/FileAPI/idlharness.html.ini
+++ b/tests/wpt/metadata/FileAPI/idlharness.html.ini
@@ -30,3 +30,12 @@
[FileReader interface: calling readAsArrayBuffer(Blob) on new FileReader() with too few arguments must throw TypeError]
expected: FAIL
+ [FileReader interface: operation readAsBinaryString(Blob)]
+ expected: FAIL
+
+ [FileReader interface: new FileReader() must inherit property "readAsBinaryString" with the proper type (1)]
+ expected: FAIL
+
+ [FileReader interface: calling readAsBinaryString(Blob) on new FileReader() with too few arguments must throw TypeError]
+ expected: FAIL
+
diff --git a/tests/wpt/metadata/FileAPI/idlharness.worker.js.ini b/tests/wpt/metadata/FileAPI/idlharness.worker.js.ini
index 2123dd254f3..1c1a2484345 100644
--- a/tests/wpt/metadata/FileAPI/idlharness.worker.js.ini
+++ b/tests/wpt/metadata/FileAPI/idlharness.worker.js.ini
@@ -12,18 +12,6 @@
[FileReader interface: calling readAsArrayBuffer(Blob) on new FileReader() with too few arguments must throw TypeError]
expected: FAIL
- [FileReaderSync interface: existence and properties of interface object]
- expected: FAIL
-
- [FileReaderSync interface object length]
- expected: FAIL
-
- [FileReaderSync interface: existence and properties of interface prototype object]
- expected: FAIL
-
- [FileReaderSync interface: existence and properties of interface prototype object's "constructor" property]
- expected: FAIL
-
[FileReaderSync interface: operation readAsArrayBuffer(Blob)]
expected: FAIL
@@ -33,12 +21,6 @@
[FileReaderSync interface: operation readAsDataURL(Blob)]
expected: FAIL
- [FileReaderSync must be primary interface of new FileReaderSync()]
- expected: FAIL
-
- [Stringification of new FileReaderSync()]
- expected: FAIL
-
[FileReaderSync interface: new FileReaderSync() must inherit property "readAsArrayBuffer" with the proper type (0)]
expected: FAIL
@@ -57,9 +39,6 @@
[FileReaderSync interface: calling readAsDataURL(Blob) on new FileReaderSync() with too few arguments must throw TypeError]
expected: FAIL
- [FileReaderSync interface object name]
- expected: FAIL
-
[Window interface: existence and properties of interface object]
expected: FAIL
@@ -75,15 +54,27 @@
[Event interface: existence and properties of interface object]
expected: FAIL
- [Blob interface: existence and properties of interface object]
+ [FileReader interface: operation readAsBinaryString(Blob)]
+ expected: FAIL
+
+ [FileReader interface: new FileReader() must inherit property "readAsBinaryString" with the proper type (1)]
+ expected: FAIL
+
+ [FileReader interface: calling readAsBinaryString(Blob) on new FileReader() with too few arguments must throw TypeError]
+ expected: FAIL
+
+ [FileReaderSync interface: operation readAsBinaryString(Blob)]
+ expected: FAIL
+
+ [FileReaderSync interface: new FileReaderSync() must inherit property "readAsBinaryString" with the proper type (1)]
expected: FAIL
- [File interface: existence and properties of interface object]
+ [FileReaderSync interface: calling readAsBinaryString(Blob) on new FileReaderSync() with too few arguments must throw TypeError]
expected: FAIL
- [FileList interface: existence and properties of interface object]
+ [FileReaderSync interface: new FileReaderSync() must inherit property "readAsText" with the proper type (2)]
expected: FAIL
- [FileReader interface: existence and properties of interface object]
+ [FileReaderSync interface: new FileReaderSync() must inherit property "readAsDataURL" with the proper type (3)]
expected: FAIL
diff --git a/tests/wpt/metadata/MANIFEST.json b/tests/wpt/metadata/MANIFEST.json
index cb936f17478..5606390b636 100644
--- a/tests/wpt/metadata/MANIFEST.json
+++ b/tests/wpt/metadata/MANIFEST.json
@@ -15226,6 +15226,10 @@
"url": "/dom/nodes/prepend-on-Document.html"
},
{
+ "path": "dom/nodes/remove-row.html",
+ "url": "/dom/nodes/remove-row.html"
+ },
+ {
"path": "dom/nodes/remove-unscopable.html",
"url": "/dom/nodes/remove-unscopable.html"
},
@@ -37201,15 +37205,29 @@
]
},
"local_changes": {
- "deleted": [],
+ "deleted": [
+ "dom/nodes/remove-row.html"
+ ],
"deleted_reftests": {},
"items": {
"testharness": {
+ "html/semantics/interactive-elements/the-dialog-element/dialog-open.html": [
+ {
+ "path": "html/semantics/interactive-elements/the-dialog-element/dialog-open.html",
+ "url": "/html/semantics/interactive-elements/the-dialog-element/dialog-open.html"
+ }
+ ],
"html/semantics/scripting-1/the-script-element/script-charset-03.html": [
{
"path": "html/semantics/scripting-1/the-script-element/script-charset-03.html",
"url": "/html/semantics/scripting-1/the-script-element/script-charset-03.html"
}
+ ],
+ "html/semantics/tabular-data/the-table-element/remove-row.html": [
+ {
+ "path": "html/semantics/tabular-data/the-table-element/remove-row.html",
+ "url": "/html/semantics/tabular-data/the-table-element/remove-row.html"
+ }
]
}
},
diff --git a/tests/wpt/metadata/dom/nodes/getElementsByClassName-21.htm.ini b/tests/wpt/metadata/dom/nodes/getElementsByClassName-21.htm.ini
deleted file mode 100644
index 143ad1185c4..00000000000
--- a/tests/wpt/metadata/dom/nodes/getElementsByClassName-21.htm.ini
+++ /dev/null
@@ -1,5 +0,0 @@
-[getElementsByClassName-21.htm]
- type: testharness
- [delete element from collection]
- expected: FAIL
-
diff --git a/tests/wpt/metadata/fetch/api/headers/headers-basic.html.ini b/tests/wpt/metadata/fetch/api/headers/headers-basic.html.ini
new file mode 100644
index 00000000000..16379eaa71a
--- /dev/null
+++ b/tests/wpt/metadata/fetch/api/headers/headers-basic.html.ini
@@ -0,0 +1,44 @@
+[headers-basic.html]
+ type: testharness
+ [Create headers from empty object]
+ expected: FAIL
+
+ [Create headers with sequence]
+ expected: FAIL
+
+ [Create headers with OpenEndedDictionary]
+ expected: FAIL
+
+ [Create headers with existing headers]
+ expected: FAIL
+
+ [Check append method]
+ expected: FAIL
+
+ [Check set method]
+ expected: FAIL
+
+ [Check has method]
+ expected: FAIL
+
+ [Check delete method]
+ expected: FAIL
+
+ [Check get method]
+ expected: FAIL
+
+ [Check keys method]
+ expected: FAIL
+
+ [Check values method]
+ expected: FAIL
+
+ [Check entries method]
+ expected: FAIL
+
+ [Check Symbol.iterator method]
+ expected: FAIL
+
+ [Check forEach method]
+ expected: FAIL
+
diff --git a/tests/wpt/metadata/fetch/api/headers/headers-casing.html.ini b/tests/wpt/metadata/fetch/api/headers/headers-casing.html.ini
new file mode 100644
index 00000000000..c9b0c365129
--- /dev/null
+++ b/tests/wpt/metadata/fetch/api/headers/headers-casing.html.ini
@@ -0,0 +1,14 @@
+[headers-casing.html]
+ type: testharness
+ [Create headers, names use characters with different case]
+ expected: FAIL
+
+ [Check append method, names use characters with different case]
+ expected: FAIL
+
+ [Check set method, names use characters with different case]
+ expected: FAIL
+
+ [Check delete method, names use characters with different case]
+ expected: FAIL
+
diff --git a/tests/wpt/metadata/fetch/api/headers/headers-combine.html.ini b/tests/wpt/metadata/fetch/api/headers/headers-combine.html.ini
new file mode 100644
index 00000000000..1403b64a1c8
--- /dev/null
+++ b/tests/wpt/metadata/fetch/api/headers/headers-combine.html.ini
@@ -0,0 +1,14 @@
+[headers-combine.html]
+ type: testharness
+ [Create headers using same name for different values]
+ expected: FAIL
+
+ [Check delete and has methods when using same name for different values]
+ expected: FAIL
+
+ [Check set methods when called with already used name]
+ expected: FAIL
+
+ [Check append methods when called with already used name]
+ expected: FAIL
+
diff --git a/tests/wpt/metadata/fetch/api/headers/headers-errors.html.ini b/tests/wpt/metadata/fetch/api/headers/headers-errors.html.ini
new file mode 100644
index 00000000000..96439e158ec
--- /dev/null
+++ b/tests/wpt/metadata/fetch/api/headers/headers-errors.html.ini
@@ -0,0 +1,8 @@
+[headers-errors.html]
+ type: testharness
+ [Headers forEach throws if argument is not callable]
+ expected: FAIL
+
+ [Headers forEach loop should stop if callback is throwing exception]
+ expected: FAIL
+
diff --git a/tests/wpt/metadata/fetch/api/headers/headers-idl.html.ini b/tests/wpt/metadata/fetch/api/headers/headers-idl.html.ini
new file mode 100644
index 00000000000..5a6cbcf6505
--- /dev/null
+++ b/tests/wpt/metadata/fetch/api/headers/headers-idl.html.ini
@@ -0,0 +1,3 @@
+[headers-idl.html]
+ type: testharness
+ expected: TIMEOUT
diff --git a/tests/wpt/metadata/fetch/api/headers/headers-normalize.html.ini b/tests/wpt/metadata/fetch/api/headers/headers-normalize.html.ini
new file mode 100644
index 00000000000..1ba80cd1437
--- /dev/null
+++ b/tests/wpt/metadata/fetch/api/headers/headers-normalize.html.ini
@@ -0,0 +1,11 @@
+[headers-normalize.html]
+ type: testharness
+ [Create headers with not normalized values]
+ expected: FAIL
+
+ [Check append method whith not normalized values]
+ expected: FAIL
+
+ [Check set method whith not normalized values]
+ expected: FAIL
+
diff --git a/tests/wpt/metadata/fetch/api/headers/headers-structure.html.ini b/tests/wpt/metadata/fetch/api/headers/headers-structure.html.ini
new file mode 100644
index 00000000000..6c517acf6ab
--- /dev/null
+++ b/tests/wpt/metadata/fetch/api/headers/headers-structure.html.ini
@@ -0,0 +1,12 @@
+[headers-structure.html]
+ type: testharness
+ expected: OK
+ [Headers has entries method]
+ expected: FAIL
+
+ [Headers has keys method]
+ expected: FAIL
+
+ [Headers has values method]
+ expected: FAIL
+
diff --git a/tests/wpt/metadata/html/browsers/browsing-the-web/history-traversal/PopStateEvent.html.ini b/tests/wpt/metadata/html/browsers/browsing-the-web/history-traversal/PopStateEvent.html.ini
deleted file mode 100644
index bd6d242444a..00000000000
--- a/tests/wpt/metadata/html/browsers/browsing-the-web/history-traversal/PopStateEvent.html.ini
+++ /dev/null
@@ -1,5 +0,0 @@
-[PopStateEvent.html]
- type: testharness
- [Dispatching a synthetic PopStateEvent]
- expected: FAIL
-
diff --git a/tests/wpt/metadata/html/browsers/browsing-the-web/history-traversal/browsing_context_name_cross_origin.html.ini b/tests/wpt/metadata/html/browsers/browsing-the-web/history-traversal/browsing_context_name_cross_origin.html.ini
index ee105e85389..2dac566a5d3 100644
--- a/tests/wpt/metadata/html/browsers/browsing-the-web/history-traversal/browsing_context_name_cross_origin.html.ini
+++ b/tests/wpt/metadata/html/browsers/browsing-the-web/history-traversal/browsing_context_name_cross_origin.html.ini
@@ -1,5 +1,3 @@
[browsing_context_name_cross_origin.html]
type: testharness
- [Restoring window.name on cross-origin history traversal]
- expected: FAIL
-
+ disabled: see https://github.com/whatwg/html/issues/490
diff --git a/tests/wpt/metadata/html/browsers/browsing-the-web/history-traversal/persisted-user-state-restoration/scroll-restoration-basic.html.ini b/tests/wpt/metadata/html/browsers/browsing-the-web/history-traversal/persisted-user-state-restoration/scroll-restoration-basic.html.ini
index 3e73c51da3a..5e99880706b 100644
--- a/tests/wpt/metadata/html/browsers/browsing-the-web/history-traversal/persisted-user-state-restoration/scroll-restoration-basic.html.ini
+++ b/tests/wpt/metadata/html/browsers/browsing-the-web/history-traversal/persisted-user-state-restoration/scroll-restoration-basic.html.ini
@@ -3,9 +3,6 @@
[Default value is "auto"]
expected: FAIL
- [It is writable]
- expected: FAIL
-
[Invalid values are ignored]
expected: FAIL
diff --git a/tests/wpt/metadata/html/browsers/history/the-history-interface/001.html.ini b/tests/wpt/metadata/html/browsers/history/the-history-interface/001.html.ini
index b3538369e2e..46c10baad28 100644
--- a/tests/wpt/metadata/html/browsers/history/the-history-interface/001.html.ini
+++ b/tests/wpt/metadata/html/browsers/history/the-history-interface/001.html.ini
@@ -1,3 +1,101 @@
[001.html]
type: testharness
- expected: TIMEOUT
+ [history.length should update when loading pages in an iframe]
+ expected: FAIL
+
+ [history.length should update when setting location.hash]
+ expected: FAIL
+
+ [history.pushState must exist]
+ expected: FAIL
+
+ [history.pushState must exist within iframes]
+ expected: FAIL
+
+ [initial history.state should be null]
+ expected: FAIL
+
+ [history.length should update when pushing a state]
+ expected: FAIL
+
+ [history.state should update after a state is pushed]
+ expected: FAIL
+
+ [traversing history must traverse pushed states]
+ expected: FAIL
+
+ [pushState must not be allowed to create invalid URLs]
+ expected: FAIL
+
+ [pushState must not be allowed to create cross-origin URLs]
+ expected: FAIL
+
+ [pushState must not be allowed to create cross-origin URLs (about:blank)]
+ expected: FAIL
+
+ [pushState must not be allowed to create cross-origin URLs (data:URI)]
+ expected: FAIL
+
+ [security errors are expected to be thrown in the context of the document that owns the history object]
+ expected: FAIL
+
+ [location.hash must be allowed to change (part 1)]
+ expected: FAIL
+
+ [location.hash must be allowed to change (part 2)]
+ expected: FAIL
+
+ [pushState must not alter location.hash when no URL is provided]
+ expected: FAIL
+
+ [pushState must remove all history after the current state]
+ expected: FAIL
+
+ [pushState must be able to set location.hash]
+ expected: FAIL
+
+ [pushState must remove any tasks queued by the history traversal task source]
+ expected: FAIL
+
+ [pushState must be able to set location.pathname]
+ expected: FAIL
+
+ [pushState must be able to set absolute URLs to the same host]
+ expected: FAIL
+
+ [pushState must not be able to use a function as data]
+ expected: FAIL
+
+ [pushState must not be able to use a DOM node as data]
+ expected: FAIL
+
+ [pushState must not be able to use an error object as data]
+ expected: FAIL
+
+ [security errors are expected to be thrown in the context of the document that owns the history object (2)]
+ expected: FAIL
+
+ [pushState must be able to make structured clones of complex objects]
+ expected: FAIL
+
+ [history.state should also reference a clone of the original object]
+ expected: FAIL
+
+ [popstate event should fire when navigation occurs]
+ expected: FAIL
+
+ [popstate event should pass the state data]
+ expected: FAIL
+
+ [state data should cope with circular object references]
+ expected: FAIL
+
+ [state data should be a clone of the original object, not a reference to it]
+ expected: FAIL
+
+ [history.state should also reference a clone of the original object (2)]
+ expected: FAIL
+
+ [history.state should be a separate clone of the object, not a reference to the object passed to the event handler]
+ expected: FAIL
+
diff --git a/tests/wpt/metadata/html/browsers/history/the-history-interface/002.html.ini b/tests/wpt/metadata/html/browsers/history/the-history-interface/002.html.ini
index 29a2058d988..1228df18521 100644
--- a/tests/wpt/metadata/html/browsers/history/the-history-interface/002.html.ini
+++ b/tests/wpt/metadata/html/browsers/history/the-history-interface/002.html.ini
@@ -1,3 +1,98 @@
[002.html]
type: testharness
- expected: TIMEOUT
+ [history.length should update when loading pages in an iframe]
+ expected: FAIL
+
+ [history.length should update when setting location.hash]
+ expected: FAIL
+
+ [history.replaceState must exist]
+ expected: FAIL
+
+ [history.replaceState must exist within iframes]
+ expected: FAIL
+
+ [initial history.state should be null]
+ expected: FAIL
+
+ [history.length should not update when replacing a state with no URL]
+ expected: FAIL
+
+ [history.state should update after a state is pushed]
+ expected: FAIL
+
+ [hash should not change when replaceState is called without a URL]
+ expected: FAIL
+
+ [history.length should not update when replacing a state with a URL]
+ expected: FAIL
+
+ [hash should change when replaceState is called with a URL]
+ expected: FAIL
+
+ [replaceState must replace the existing state without altering the forward history]
+ expected: FAIL
+
+ [replaceState must not be allowed to create invalid URLs]
+ expected: FAIL
+
+ [replaceState must not be allowed to create cross-origin URLs]
+ expected: FAIL
+
+ [replaceState must not be allowed to create cross-origin URLs (about:blank)]
+ expected: FAIL
+
+ [replaceState must not be allowed to create cross-origin URLs (data:URI)]
+ expected: FAIL
+
+ [security errors are expected to be thrown in the context of the document that owns the history object]
+ expected: FAIL
+
+ [replaceState must be able to set location.pathname]
+ expected: FAIL
+
+ [replaceState must be able to set absolute URLs to the same host]
+ expected: FAIL
+
+ [replaceState must not remove any tasks queued by the history traversal task source]
+ expected: FAIL
+
+ [.go must queue a task with the history traversal task source (run asynchronously)]
+ expected: FAIL
+
+ [replaceState must not be able to use a function as data]
+ expected: FAIL
+
+ [replaceState must not be able to use a DOM node as data]
+ expected: FAIL
+
+ [replaceState must not be able to use an error object as data]
+ expected: FAIL
+
+ [security errors are expected to be thrown in the context of the document that owns the history object (2)]
+ expected: FAIL
+
+ [replaceState must be able to make structured clones of complex objects]
+ expected: FAIL
+
+ [history.state should also reference a clone of the original object]
+ expected: FAIL
+
+ [popstate event should fire when navigation occurs]
+ expected: FAIL
+
+ [popstate event should pass the state data]
+ expected: FAIL
+
+ [state data should cope with circular object references]
+ expected: FAIL
+
+ [state data should be a clone of the original object, not a reference to it]
+ expected: FAIL
+
+ [history.state should also reference a clone of the original object (2)]
+ expected: FAIL
+
+ [history.state should be a separate clone of the object, not a reference to the object passed to the event handler]
+ expected: FAIL
+
diff --git a/tests/wpt/metadata/html/browsers/history/the-history-interface/004.html.ini b/tests/wpt/metadata/html/browsers/history/the-history-interface/004.html.ini
index 2c1c228a251..fa42d1a0762 100644
--- a/tests/wpt/metadata/html/browsers/history/the-history-interface/004.html.ini
+++ b/tests/wpt/metadata/html/browsers/history/the-history-interface/004.html.ini
@@ -1,3 +1,11 @@
[004.html]
type: testharness
- expected: TIMEOUT
+ [.go commands should be queued until the thread has ended]
+ expected: FAIL
+
+ [browser needs to support hashchange events for this testcase]
+ expected: FAIL
+
+ [queued .go commands should all be executed when the queue is processed]
+ expected: FAIL
+
diff --git a/tests/wpt/metadata/html/browsers/history/the-history-interface/005.html.ini b/tests/wpt/metadata/html/browsers/history/the-history-interface/005.html.ini
index 4982b00f15c..76099606688 100644
--- a/tests/wpt/metadata/html/browsers/history/the-history-interface/005.html.ini
+++ b/tests/wpt/metadata/html/browsers/history/the-history-interface/005.html.ini
@@ -1,6 +1,11 @@
[005.html]
type: testharness
- expected: TIMEOUT
[history.pushState support is needed for this testcase]
expected: FAIL
+ [<body onpopstate="..."> should register a listener for the popstate event]
+ expected: FAIL
+
+ [window.onpopstate should register a listener for the popstate event]
+ expected: FAIL
+
diff --git a/tests/wpt/metadata/html/browsers/history/the-history-interface/007.html.ini b/tests/wpt/metadata/html/browsers/history/the-history-interface/007.html.ini
index e346ad78fcf..5c3b95e454e 100644
--- a/tests/wpt/metadata/html/browsers/history/the-history-interface/007.html.ini
+++ b/tests/wpt/metadata/html/browsers/history/the-history-interface/007.html.ini
@@ -1,6 +1,5 @@
[007.html]
type: testharness
- expected: TIMEOUT
[history.state should initially be null]
expected: FAIL
@@ -10,3 +9,15 @@
[history.state should reflect pushed state]
expected: FAIL
+ [popstate event should fire before onload fires]
+ expected: FAIL
+
+ [the correct state should be restored when navigating during initial load]
+ expected: FAIL
+
+ [history.state should reflect the navigated state onload]
+ expected: FAIL
+
+ [history.state should reflect the navigated state after onload]
+ expected: FAIL
+
diff --git a/tests/wpt/metadata/html/browsers/history/the-location-interface/location_assign_about_blank.html.ini b/tests/wpt/metadata/html/browsers/history/the-location-interface/location_assign_about_blank.html.ini
deleted file mode 100644
index c144ee2f49f..00000000000
--- a/tests/wpt/metadata/html/browsers/history/the-location-interface/location_assign_about_blank.html.ini
+++ /dev/null
@@ -1,5 +0,0 @@
-[location_assign_about_blank.html]
- type: testharness
- [location.assign with initial about:blank browsing context]
- expected: FAIL
-
diff --git a/tests/wpt/metadata/html/dom/interfaces.html.ini b/tests/wpt/metadata/html/dom/interfaces.html.ini
index 63aaf524f22..9cf7bd0c315 100644
--- a/tests/wpt/metadata/html/dom/interfaces.html.ini
+++ b/tests/wpt/metadata/html/dom/interfaces.html.ini
@@ -1572,15 +1572,9 @@
[HTMLUListElement interface: attribute type]
expected: FAIL
- [HTMLLIElement interface: attribute value]
- expected: FAIL
-
[HTMLLIElement interface: attribute type]
expected: FAIL
- [HTMLLIElement interface: document.createElement("li") must inherit property "value" with the proper type (0)]
- expected: FAIL
-
[HTMLLIElement interface: document.createElement("li") must inherit property "type" with the proper type (1)]
expected: FAIL
@@ -3237,9 +3231,6 @@
[HTMLAreaElement interface: document.createElement("area") must inherit property "noHref" with the proper type (10)]
expected: FAIL
- [HTMLTableElement interface: operation deleteRow(long)]
- expected: FAIL
-
[HTMLTableElement interface: attribute sortable]
expected: FAIL
@@ -3267,12 +3258,6 @@
[HTMLTableElement interface: attribute cellSpacing]
expected: FAIL
- [HTMLTableElement interface: document.createElement("table") must inherit property "deleteRow" with the proper type (13)]
- expected: FAIL
-
- [HTMLTableElement interface: calling deleteRow(long) on document.createElement("table") with too few arguments must throw TypeError]
- expected: FAIL
-
[HTMLTableElement interface: document.createElement("table") must inherit property "sortable" with the proper type (14)]
expected: FAIL
@@ -5613,45 +5598,18 @@
[BarProp interface: attribute visible]
expected: FAIL
- [History interface: existence and properties of interface object]
- expected: FAIL
-
- [History interface object length]
- expected: FAIL
-
- [History interface: existence and properties of interface prototype object]
- expected: FAIL
-
- [History interface: existence and properties of interface prototype object's "constructor" property]
- expected: FAIL
-
[History interface: attribute length]
expected: FAIL
[History interface: attribute state]
expected: FAIL
- [History interface: operation go(long)]
- expected: FAIL
-
- [History interface: operation back()]
- expected: FAIL
-
- [History interface: operation forward()]
- expected: FAIL
-
[History interface: operation pushState(any,DOMString,DOMString)]
expected: FAIL
[History interface: operation replaceState(any,DOMString,DOMString)]
expected: FAIL
- [History must be primary interface of window.history]
- expected: FAIL
-
- [Stringification of window.history]
- expected: FAIL
-
[History interface: window.history must inherit property "length" with the proper type (0)]
expected: FAIL
@@ -5661,9 +5619,6 @@
[History interface: window.history must inherit property "go" with the proper type (2)]
expected: FAIL
- [History interface: calling go(long) on window.history with too few arguments must throw TypeError]
- expected: FAIL
-
[History interface: window.history must inherit property "back" with the proper type (3)]
expected: FAIL
@@ -7236,9 +7191,6 @@
[BarProp interface object name]
expected: FAIL
- [History interface object name]
- expected: FAIL
-
[ApplicationCache interface object name]
expected: FAIL
@@ -7290,15 +7242,6 @@
[History interface: window.history must inherit property "state" with the proper type (2)]
expected: FAIL
- [History interface: window.history must inherit property "go" with the proper type (3)]
- expected: FAIL
-
- [History interface: window.history must inherit property "back" with the proper type (4)]
- expected: FAIL
-
- [History interface: window.history must inherit property "forward" with the proper type (5)]
- expected: FAIL
-
[History interface: window.history must inherit property "pushState" with the proper type (6)]
expected: FAIL
diff --git a/tests/wpt/metadata/html/dom/reflection-grouping.html.ini b/tests/wpt/metadata/html/dom/reflection-grouping.html.ini
index 7ecf978bf18..ab78b68717b 100644
--- a/tests/wpt/metadata/html/dom/reflection-grouping.html.ini
+++ b/tests/wpt/metadata/html/dom/reflection-grouping.html.ini
@@ -6303,186 +6303,6 @@
[li.tabIndex: IDL set to -2147483648 followed by getAttribute()]
expected: FAIL
- [li.value: typeof IDL attribute]
- expected: FAIL
-
- [li.value: IDL get with DOM attribute unset]
- expected: FAIL
-
- [li.value: setAttribute() to -36 followed by IDL get]
- expected: FAIL
-
- [li.value: setAttribute() to -1 followed by IDL get]
- expected: FAIL
-
- [li.value: setAttribute() to 0 followed by IDL get]
- expected: FAIL
-
- [li.value: setAttribute() to 1 followed by IDL get]
- expected: FAIL
-
- [li.value: setAttribute() to 2147483647 followed by IDL get]
- expected: FAIL
-
- [li.value: setAttribute() to -2147483648 followed by IDL get]
- expected: FAIL
-
- [li.value: setAttribute() to 2147483648 followed by IDL get]
- expected: FAIL
-
- [li.value: setAttribute() to -2147483649 followed by IDL get]
- expected: FAIL
-
- [li.value: setAttribute() to 4294967295 followed by IDL get]
- expected: FAIL
-
- [li.value: setAttribute() to 4294967296 followed by IDL get]
- expected: FAIL
-
- [li.value: setAttribute() to "" followed by IDL get]
- expected: FAIL
-
- [li.value: setAttribute() to "-1" followed by IDL get]
- expected: FAIL
-
- [li.value: setAttribute() to "-0" followed by IDL get]
- expected: FAIL
-
- [li.value: setAttribute() to "0" followed by IDL get]
- expected: FAIL
-
- [li.value: setAttribute() to "1" followed by IDL get]
- expected: FAIL
-
- [li.value: setAttribute() to " \\0\\x01\\x02\\x03\\x04\\x05\\x06\\x07 \\b\\t\\n\\v\\f\\r\\x0e\\x0f \\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17 \\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f foo " followed by IDL get]
- expected: FAIL
-
- [li.value: setAttribute() to "\\t7" followed by IDL get]
- expected: FAIL
-
- [li.value: setAttribute() to "\\v7" followed by IDL get]
- expected: FAIL
-
- [li.value: setAttribute() to "\\f7" followed by IDL get]
- expected: FAIL
-
- [li.value: setAttribute() to " 7" followed by IDL get]
- expected: FAIL
-
- [li.value: setAttribute() to " 7" followed by IDL get]
- expected: FAIL
-
- [li.value: setAttribute() to "7" followed by IDL get]
- expected: FAIL
-
- [li.value: setAttribute() to "\\n7" followed by IDL get]
- expected: FAIL
-
- [li.value: setAttribute() to "\\r7" followed by IDL get]
- expected: FAIL
-
- [li.value: setAttribute() to "
7" followed by IDL get]
- expected: FAIL
-
- [li.value: setAttribute() to "
7" followed by IDL get]
- expected: FAIL
-
- [li.value: setAttribute() to " 7" followed by IDL get]
- expected: FAIL
-
- [li.value: setAttribute() to "᠎7" followed by IDL get]
- expected: FAIL
-
- [li.value: setAttribute() to " 7" followed by IDL get]
- expected: FAIL
-
- [li.value: setAttribute() to " 7" followed by IDL get]
- expected: FAIL
-
- [li.value: setAttribute() to " 7" followed by IDL get]
- expected: FAIL
-
- [li.value: setAttribute() to " 7" followed by IDL get]
- expected: FAIL
-
- [li.value: setAttribute() to " 7" followed by IDL get]
- expected: FAIL
-
- [li.value: setAttribute() to " 7" followed by IDL get]
- expected: FAIL
-
- [li.value: setAttribute() to " 7" followed by IDL get]
- expected: FAIL
-
- [li.value: setAttribute() to " 7" followed by IDL get]
- expected: FAIL
-
- [li.value: setAttribute() to " 7" followed by IDL get]
- expected: FAIL
-
- [li.value: setAttribute() to " 7" followed by IDL get]
- expected: FAIL
-
- [li.value: setAttribute() to " 7" followed by IDL get]
- expected: FAIL
-
- [li.value: setAttribute() to " 7" followed by IDL get]
- expected: FAIL
-
- [li.value: setAttribute() to " 7" followed by IDL get]
- expected: FAIL
-
- [li.value: setAttribute() to undefined followed by IDL get]
- expected: FAIL
-
- [li.value: setAttribute() to 1.5 followed by IDL get]
- expected: FAIL
-
- [li.value: setAttribute() to true followed by IDL get]
- expected: FAIL
-
- [li.value: setAttribute() to false followed by IDL get]
- expected: FAIL
-
- [li.value: setAttribute() to object "[object Object\]" followed by IDL get]
- expected: FAIL
-
- [li.value: setAttribute() to NaN followed by IDL get]
- expected: FAIL
-
- [li.value: setAttribute() to Infinity followed by IDL get]
- expected: FAIL
-
- [li.value: setAttribute() to -Infinity followed by IDL get]
- expected: FAIL
-
- [li.value: setAttribute() to "\\0" followed by IDL get]
- expected: FAIL
-
- [li.value: setAttribute() to object "2" followed by IDL get]
- expected: FAIL
-
- [li.value: setAttribute() to object "3" followed by IDL get]
- expected: FAIL
-
- [li.value: IDL set to -36 followed by getAttribute()]
- expected: FAIL
-
- [li.value: IDL set to -1 followed by getAttribute()]
- expected: FAIL
-
- [li.value: IDL set to 0 followed by getAttribute()]
- expected: FAIL
-
- [li.value: IDL set to 1 followed by getAttribute()]
- expected: FAIL
-
- [li.value: IDL set to 2147483647 followed by getAttribute()]
- expected: FAIL
-
- [li.value: IDL set to -2147483648 followed by getAttribute()]
- expected: FAIL
-
[li.type: typeof IDL attribute]
expected: FAIL
diff --git a/tests/wpt/metadata/workers/interfaces/WorkerGlobalScope/close/sending-messages.html.ini b/tests/wpt/metadata/html/semantics/embedded-content/media-elements/error-codes/error.html.ini
index 379fec0c3ec..7280d3b7e4f 100644
--- a/tests/wpt/metadata/workers/interfaces/WorkerGlobalScope/close/sending-messages.html.ini
+++ b/tests/wpt/metadata/html/semantics/embedded-content/media-elements/error-codes/error.html.ini
@@ -1,6 +1,6 @@
-[sending-messages.html]
+[error.html]
type: testharness
expected: TIMEOUT
- [close() and sending messages]
+ [audio.error after successful load]
expected: TIMEOUT
diff --git a/tests/wpt/metadata/html/semantics/embedded-content/media-elements/event_loadeddata.html.ini b/tests/wpt/metadata/html/semantics/embedded-content/media-elements/event_loadeddata.html.ini
index efd785bce04..249d3fa61f6 100644
--- a/tests/wpt/metadata/html/semantics/embedded-content/media-elements/event_loadeddata.html.ini
+++ b/tests/wpt/metadata/html/semantics/embedded-content/media-elements/event_loadeddata.html.ini
@@ -7,3 +7,6 @@
[setting src attribute on autoplay video should trigger loadeddata event]
expected: NOTRUN
+ [setting src attribute on autoplay audio should trigger loadeddata event]
+ expected: NOTRUN
+
diff --git a/tests/wpt/metadata/html/semantics/embedded-content/media-elements/event_loadeddata_noautoplay.html.ini b/tests/wpt/metadata/html/semantics/embedded-content/media-elements/event_loadeddata_noautoplay.html.ini
new file mode 100644
index 00000000000..7c16b52bdbe
--- /dev/null
+++ b/tests/wpt/metadata/html/semantics/embedded-content/media-elements/event_loadeddata_noautoplay.html.ini
@@ -0,0 +1,6 @@
+[event_loadeddata_noautoplay.html]
+ type: testharness
+ expected: TIMEOUT
+ [setting src attribute on non-autoplay audio should trigger loadeddata event]
+ expected: NOTRUN
+
diff --git a/tests/wpt/metadata/html/semantics/embedded-content/media-elements/event_loadedmetadata.html.ini b/tests/wpt/metadata/html/semantics/embedded-content/media-elements/event_loadedmetadata.html.ini
new file mode 100644
index 00000000000..90e0b6b2fad
--- /dev/null
+++ b/tests/wpt/metadata/html/semantics/embedded-content/media-elements/event_loadedmetadata.html.ini
@@ -0,0 +1,6 @@
+[event_loadedmetadata.html]
+ type: testharness
+ expected: TIMEOUT
+ [setting src attribute on autoplay audio should trigger loadedmetadata event]
+ expected: NOTRUN
+
diff --git a/tests/wpt/metadata/html/semantics/embedded-content/media-elements/event_loadedmetadata_noautoplay.html.ini b/tests/wpt/metadata/html/semantics/embedded-content/media-elements/event_loadedmetadata_noautoplay.html.ini
new file mode 100644
index 00000000000..7d4abbe6b77
--- /dev/null
+++ b/tests/wpt/metadata/html/semantics/embedded-content/media-elements/event_loadedmetadata_noautoplay.html.ini
@@ -0,0 +1,6 @@
+[event_loadedmetadata_noautoplay.html]
+ type: testharness
+ expected: TIMEOUT
+ [setting src attribute on non-autoplay audio should trigger loadedmetadata event]
+ expected: NOTRUN
+
diff --git a/tests/wpt/metadata/html/semantics/embedded-content/media-elements/event_order_loadedmetadata_loadeddata.html.ini b/tests/wpt/metadata/html/semantics/embedded-content/media-elements/event_order_loadedmetadata_loadeddata.html.ini
new file mode 100644
index 00000000000..ef23353c3bc
--- /dev/null
+++ b/tests/wpt/metadata/html/semantics/embedded-content/media-elements/event_order_loadedmetadata_loadeddata.html.ini
@@ -0,0 +1,6 @@
+[event_order_loadedmetadata_loadeddata.html]
+ type: testharness
+ expected: TIMEOUT
+ [setting src attribute on autoplay audio should trigger loadedmetadata then loadeddata event]
+ expected: NOTRUN
+
diff --git a/tests/wpt/metadata/html/semantics/embedded-content/media-elements/readyState_during_loadeddata.html.ini b/tests/wpt/metadata/html/semantics/embedded-content/media-elements/readyState_during_loadeddata.html.ini
new file mode 100644
index 00000000000..f765e6bca1d
--- /dev/null
+++ b/tests/wpt/metadata/html/semantics/embedded-content/media-elements/readyState_during_loadeddata.html.ini
@@ -0,0 +1,6 @@
+[readyState_during_loadeddata.html]
+ type: testharness
+ expected: TIMEOUT
+ [audio.readyState should be >= HAVE_CURRENT_DATA during loadeddata event]
+ expected: NOTRUN
+
diff --git a/tests/wpt/metadata/html/semantics/embedded-content/media-elements/readyState_during_loadedmetadata.html.ini b/tests/wpt/metadata/html/semantics/embedded-content/media-elements/readyState_during_loadedmetadata.html.ini
new file mode 100644
index 00000000000..a3aaca7f389
--- /dev/null
+++ b/tests/wpt/metadata/html/semantics/embedded-content/media-elements/readyState_during_loadedmetadata.html.ini
@@ -0,0 +1,6 @@
+[readyState_during_loadedmetadata.html]
+ type: testharness
+ expected: TIMEOUT
+ [audio.readyState should be >= HAVE_METADATA during loadedmetadata event]
+ expected: NOTRUN
+
diff --git a/tests/wpt/metadata/html/semantics/grouping-content/the-li-element/grouping-li.html.ini b/tests/wpt/metadata/html/semantics/grouping-content/the-li-element/grouping-li.html.ini
index ea4e02e4cac..57509d09e74 100644
--- a/tests/wpt/metadata/html/semantics/grouping-content/the-li-element/grouping-li.html.ini
+++ b/tests/wpt/metadata/html/semantics/grouping-content/the-li-element/grouping-li.html.ini
@@ -3,33 +3,3 @@
[li should have a 'value' attribute]
expected: FAIL
- [Default (unspecified) value of value is 0.]
- expected: FAIL
-
- [.value property reflects content attribute - and both parse value of '2' correctly.]
- expected: FAIL
-
- [IDL and content attribute parse value of '-10' correctly.]
- expected: FAIL
-
- [IDL and content attribute parse value of '4.03' correctly.]
- expected: FAIL
-
- [IDL and content attribute parse value of '-4.03' correctly.]
- expected: FAIL
-
- [IDL and content attribute parse value of '4.9' correctly.]
- expected: FAIL
-
- [IDL and content attribute parse value of '-4.9' correctly.]
- expected: FAIL
-
- [IDL and content attribute parse value of '7e2' correctly.]
- expected: FAIL
-
- [IDL and content attribute parse value of '.5' correctly.]
- expected: FAIL
-
- [IDL and content attribute parse value of 'A' correctly.]
- expected: FAIL
-
diff --git a/tests/wpt/metadata/webgl/conformance-1.0.3/conformance/more/functions/readPixelsBadArgs.html.ini b/tests/wpt/metadata/webgl/conformance-1.0.3/conformance/more/functions/readPixelsBadArgs.html.ini
index 104168d037f..7f14a9449b1 100644
--- a/tests/wpt/metadata/webgl/conformance-1.0.3/conformance/more/functions/readPixelsBadArgs.html.ini
+++ b/tests/wpt/metadata/webgl/conformance-1.0.3/conformance/more/functions/readPixelsBadArgs.html.ini
@@ -1,6 +1,6 @@
[readPixelsBadArgs.html]
type: testharness
- expected: CRASH
+ expected: TIMEOUT
[WebGL test #0: testReadPixels]
expected: FAIL
diff --git a/tests/wpt/metadata/webgl/conformance-1.0.3/conformance/reading/read-pixels-pack-alignment.html.ini b/tests/wpt/metadata/webgl/conformance-1.0.3/conformance/reading/read-pixels-pack-alignment.html.ini
index d37219b0864..1b3d09229b9 100644
--- a/tests/wpt/metadata/webgl/conformance-1.0.3/conformance/reading/read-pixels-pack-alignment.html.ini
+++ b/tests/wpt/metadata/webgl/conformance-1.0.3/conformance/reading/read-pixels-pack-alignment.html.ini
@@ -1,6 +1,6 @@
[read-pixels-pack-alignment.html]
type: testharness
- expected: CRASH
+ expected: TIMEOUT
[WebGL test #3: successfullyParsed should be true (of type boolean). Was undefined (of type undefined).]
expected: FAIL
diff --git a/tests/wpt/metadata/webgl/conformance-1.0.3/conformance/rendering/draw-arrays-out-of-bounds.html.ini b/tests/wpt/metadata/webgl/conformance-1.0.3/conformance/rendering/draw-arrays-out-of-bounds.html.ini
index 1459ace05e4..64503c921e5 100644
--- a/tests/wpt/metadata/webgl/conformance-1.0.3/conformance/rendering/draw-arrays-out-of-bounds.html.ini
+++ b/tests/wpt/metadata/webgl/conformance-1.0.3/conformance/rendering/draw-arrays-out-of-bounds.html.ini
@@ -1,3 +1,3 @@
[draw-arrays-out-of-bounds.html]
type: testharness
- expected: CRASH
+ expected: TIMEOUT
diff --git a/tests/wpt/metadata/webgl/conformance-1.0.3/conformance/rendering/draw-elements-out-of-bounds.html.ini b/tests/wpt/metadata/webgl/conformance-1.0.3/conformance/rendering/draw-elements-out-of-bounds.html.ini
index 5c4701a6660..73287c519b5 100644
--- a/tests/wpt/metadata/webgl/conformance-1.0.3/conformance/rendering/draw-elements-out-of-bounds.html.ini
+++ b/tests/wpt/metadata/webgl/conformance-1.0.3/conformance/rendering/draw-elements-out-of-bounds.html.ini
@@ -1,3 +1,3 @@
[draw-elements-out-of-bounds.html]
type: testharness
- expected: CRASH
+ expected: TIMEOUT
diff --git a/tests/wpt/metadata/workers/WorkerGlobalScope_close.htm.ini b/tests/wpt/metadata/workers/WorkerGlobalScope_close.htm.ini
deleted file mode 100644
index 95efa590227..00000000000
--- a/tests/wpt/metadata/workers/WorkerGlobalScope_close.htm.ini
+++ /dev/null
@@ -1,5 +0,0 @@
-[WorkerGlobalScope_close.htm]
- type: testharness
- [ WorkerGlobalScope close(): clear events queue ]
- expected: FAIL
-
diff --git a/tests/wpt/metadata/workers/constructors/Worker/unexpected-self-properties.html.ini b/tests/wpt/metadata/workers/constructors/Worker/unexpected-self-properties.html.ini
deleted file mode 100644
index 9c2d5495179..00000000000
--- a/tests/wpt/metadata/workers/constructors/Worker/unexpected-self-properties.html.ini
+++ /dev/null
@@ -1,5 +0,0 @@
-[unexpected-self-properties.html]
- type: testharness
- [unexpected members/interface objects/constructors]
- expected: FAIL
-
diff --git a/tests/wpt/metadata/workers/interfaces.worker.js.ini b/tests/wpt/metadata/workers/interfaces.worker.js.ini
index cb9d2850693..3928e5f88e0 100644
--- a/tests/wpt/metadata/workers/interfaces.worker.js.ini
+++ b/tests/wpt/metadata/workers/interfaces.worker.js.ini
@@ -21,9 +21,6 @@
[DedicatedWorkerGlobalScope interface: attribute onmessage]
expected: FAIL
- [WorkerGlobalScope interface: self must inherit property "close" with the proper type (2)]
- expected: FAIL
-
[WorkerGlobalScope interface: self must inherit property "onerror" with the proper type (3)]
expected: FAIL
diff --git a/tests/wpt/mozilla/meta/MANIFEST.json b/tests/wpt/mozilla/meta/MANIFEST.json
index 3fedff120e5..20107d1e105 100644
--- a/tests/wpt/mozilla/meta/MANIFEST.json
+++ b/tests/wpt/mozilla/meta/MANIFEST.json
@@ -1032,6 +1032,18 @@
"url": "/_mozilla/css/box_shadow_blur_a.html"
}
],
+ "css/box_shadow_blur_fixed.html": [
+ {
+ "path": "css/box_shadow_blur_fixed.html",
+ "references": [
+ [
+ "/_mozilla/css/box_shadow_blur_fixed_ref.html",
+ "=="
+ ]
+ ],
+ "url": "/_mozilla/css/box_shadow_blur_fixed.html"
+ }
+ ],
"css/box_shadow_border_box_a.html": [
{
"path": "css/box_shadow_border_box_a.html",
@@ -5260,6 +5272,18 @@
"url": "/_mozilla/css/text_transform_uppercase_a.html"
}
],
+ "css/textarea_space_calculation.html": [
+ {
+ "path": "css/textarea_space_calculation.html",
+ "references": [
+ [
+ "/_mozilla/css/textarea_space_calculation-ref.html",
+ "=="
+ ]
+ ],
+ "url": "/_mozilla/css/textarea_space_calculation.html"
+ }
+ ],
"css/transform_3d.html": [
{
"path": "css/transform_3d.html",
@@ -5782,16 +5806,16 @@
"url": "/_mozilla/css/word_break_a.html"
}
],
- "mozilla/blob_url_upload.html": [
+ "mozilla/FileAPI/blob_url_upload.html": [
{
- "path": "mozilla/blob_url_upload.html",
+ "path": "mozilla/FileAPI/blob_url_upload.html",
"references": [
[
- "/_mozilla/mozilla/blob_url_upload_ref.html",
+ "/_mozilla/mozilla/FileAPI/blob_url_upload_ref.html",
"=="
]
],
- "url": "/_mozilla/mozilla/blob_url_upload.html"
+ "url": "/_mozilla/mozilla/FileAPI/blob_url_upload.html"
}
],
"mozilla/canvas/drawimage_html_image_1.html": [
@@ -6022,6 +6046,18 @@
"url": "/_mozilla/mozilla/table_valign_middle.html"
}
],
+ "mozilla/table_valign_uneven_height.html": [
+ {
+ "path": "mozilla/table_valign_uneven_height.html",
+ "references": [
+ [
+ "/_mozilla/mozilla/table_valign_uneven_height_ref.html",
+ "=="
+ ]
+ ],
+ "url": "/_mozilla/mozilla/table_valign_uneven_height.html"
+ }
+ ],
"mozilla/webgl/clearcolor.html": [
{
"path": "mozilla/webgl/clearcolor.html",
@@ -6126,6 +6162,12 @@
"url": "/_mozilla/css/animations/basic-linear-width.html"
}
],
+ "css/animations/basic-transition.html": [
+ {
+ "path": "css/animations/basic-transition.html",
+ "url": "/_mozilla/css/animations/basic-transition.html"
+ }
+ ],
"css/empty-keyframes.html": [
{
"path": "css/empty-keyframes.html",
@@ -6192,6 +6234,24 @@
"url": "/_mozilla/mozilla/Event.html"
}
],
+ "mozilla/FileAPI/blob.html": [
+ {
+ "path": "mozilla/FileAPI/blob.html",
+ "url": "/_mozilla/mozilla/FileAPI/blob.html"
+ }
+ ],
+ "mozilla/FileAPI/file-select.html": [
+ {
+ "path": "mozilla/FileAPI/file-select.html",
+ "url": "/_mozilla/mozilla/FileAPI/file-select.html"
+ }
+ ],
+ "mozilla/FileAPI/file-upload.html": [
+ {
+ "path": "mozilla/FileAPI/file-upload.html",
+ "url": "/_mozilla/mozilla/FileAPI/file-upload.html"
+ }
+ ],
"mozilla/FocusEvent.html": [
{
"path": "mozilla/FocusEvent.html",
@@ -6216,12 +6276,6 @@
"url": "/_mozilla/mozilla/binding_keyword.html"
}
],
- "mozilla/blob.html": [
- {
- "path": "mozilla/blob.html",
- "url": "/_mozilla/mozilla/blob.html"
- }
- ],
"mozilla/body_listener.html": [
{
"path": "mozilla/body_listener.html",
@@ -6498,12 +6552,6 @@
"url": "/_mozilla/mozilla/event_listener.html"
}
],
- "mozilla/file_upload.html": [
- {
- "path": "mozilla/file_upload.html",
- "url": "/_mozilla/mozilla/file_upload.html"
- }
- ],
"mozilla/focus_blur.html": [
{
"path": "mozilla/focus_blur.html",
@@ -10120,6 +10168,18 @@
"url": "/_mozilla/css/box_shadow_blur_a.html"
}
],
+ "css/box_shadow_blur_fixed.html": [
+ {
+ "path": "css/box_shadow_blur_fixed.html",
+ "references": [
+ [
+ "/_mozilla/css/box_shadow_blur_fixed_ref.html",
+ "=="
+ ]
+ ],
+ "url": "/_mozilla/css/box_shadow_blur_fixed.html"
+ }
+ ],
"css/box_shadow_border_box_a.html": [
{
"path": "css/box_shadow_border_box_a.html",
@@ -14348,6 +14408,18 @@
"url": "/_mozilla/css/text_transform_uppercase_a.html"
}
],
+ "css/textarea_space_calculation.html": [
+ {
+ "path": "css/textarea_space_calculation.html",
+ "references": [
+ [
+ "/_mozilla/css/textarea_space_calculation-ref.html",
+ "=="
+ ]
+ ],
+ "url": "/_mozilla/css/textarea_space_calculation.html"
+ }
+ ],
"css/transform_3d.html": [
{
"path": "css/transform_3d.html",
@@ -14870,16 +14942,16 @@
"url": "/_mozilla/css/word_break_a.html"
}
],
- "mozilla/blob_url_upload.html": [
+ "mozilla/FileAPI/blob_url_upload.html": [
{
- "path": "mozilla/blob_url_upload.html",
+ "path": "mozilla/FileAPI/blob_url_upload.html",
"references": [
[
- "/_mozilla/mozilla/blob_url_upload_ref.html",
+ "/_mozilla/mozilla/FileAPI/blob_url_upload_ref.html",
"=="
]
],
- "url": "/_mozilla/mozilla/blob_url_upload.html"
+ "url": "/_mozilla/mozilla/FileAPI/blob_url_upload.html"
}
],
"mozilla/canvas/drawimage_html_image_1.html": [
@@ -15110,6 +15182,18 @@
"url": "/_mozilla/mozilla/table_valign_middle.html"
}
],
+ "mozilla/table_valign_uneven_height.html": [
+ {
+ "path": "mozilla/table_valign_uneven_height.html",
+ "references": [
+ [
+ "/_mozilla/mozilla/table_valign_uneven_height_ref.html",
+ "=="
+ ]
+ ],
+ "url": "/_mozilla/mozilla/table_valign_uneven_height.html"
+ }
+ ],
"mozilla/webgl/clearcolor.html": [
{
"path": "mozilla/webgl/clearcolor.html",
diff --git a/tests/wpt/mozilla/meta/mozilla/blob_url_upload.html.ini b/tests/wpt/mozilla/meta/mozilla/FileAPI/blob_url_upload.html.ini
index 6ad257ede65..6ad257ede65 100644
--- a/tests/wpt/mozilla/meta/mozilla/blob_url_upload.html.ini
+++ b/tests/wpt/mozilla/meta/mozilla/FileAPI/blob_url_upload.html.ini
diff --git a/tests/wpt/mozilla/meta/mozilla/file_upload.html.ini b/tests/wpt/mozilla/meta/mozilla/FileAPI/file-select.html.ini
index 8c9a7d45d7d..b047e230d99 100644
--- a/tests/wpt/mozilla/meta/mozilla/file_upload.html.ini
+++ b/tests/wpt/mozilla/meta/mozilla/FileAPI/file-select.html.ini
@@ -1,3 +1,3 @@
-[file_upload.html]
+[file-select.html]
type: testharness
prefs: [dom.testing.htmlinputelement.select_files.enabled:true]
diff --git a/tests/wpt/mozilla/meta/mozilla/FileAPI/file-upload.html.ini b/tests/wpt/mozilla/meta/mozilla/FileAPI/file-upload.html.ini
new file mode 100644
index 00000000000..f3715f47bf9
--- /dev/null
+++ b/tests/wpt/mozilla/meta/mozilla/FileAPI/file-upload.html.ini
@@ -0,0 +1,3 @@
+[file-upload.html]
+ type: testharness
+ prefs: [dom.testing.htmlinputelement.select_files.enabled:true]
diff --git a/tests/wpt/mozilla/tests/css/animations/basic-transition.html b/tests/wpt/mozilla/tests/css/animations/basic-transition.html
new file mode 100644
index 00000000000..b80e8a666a6
--- /dev/null
+++ b/tests/wpt/mozilla/tests/css/animations/basic-transition.html
@@ -0,0 +1,34 @@
+<!doctype html>
+<meta charset="utf-8">
+<title>Transition test</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<style>
+#check-me, #check-me-2 {
+ background-color: #F00;
+ width: 10px;
+ height: 10px;
+ transition: background-color 1s linear;
+}
+#check-me-2 {
+ background-color: #000;
+}
+</style>
+<div id=check-me><span>a</span></div>
+<script>
+var div = document.getElementById('check-me');
+var span = div.childNodes[0];
+async_test(function(t) {
+ window.addEventListener('load', function() {
+ assert_equals(getComputedStyle(div).getPropertyValue('background-color'), 'rgb(255, 0, 0)');
+ div.id = "check-me-2";
+ requestAnimationFrame(function() {
+ var test = new window.TestBinding();
+ test.advanceClock(2000);
+ span.innerHTML = "a";
+ assert_equals(getComputedStyle(div).getPropertyValue('background-color'), 'rgb(0, 0, 0)');
+ t.done();
+ });
+ })
+})
+</script>
diff --git a/tests/wpt/mozilla/tests/css/box_shadow_blur_fixed.html b/tests/wpt/mozilla/tests/css/box_shadow_blur_fixed.html
new file mode 100644
index 00000000000..429a18dbc80
--- /dev/null
+++ b/tests/wpt/mozilla/tests/css/box_shadow_blur_fixed.html
@@ -0,0 +1,24 @@
+<head>
+ <link rel='match' href='box_shadow_blur_fixed_ref.html'>
+ <style>
+ #div_outer {
+ width: 100%;
+ position: fixed;
+ top: 100px;
+ left: 0;
+ }
+
+ #div_inner {
+ background: lightgrey;
+ height: 40px;
+ box-shadow: 0 0 30px 30px darkblue;
+ }
+ </style>
+</head>
+
+<body>
+ <div id="div_outer">
+ <div id="div_inner">
+ </div>
+ </div>
+</body> \ No newline at end of file
diff --git a/tests/wpt/mozilla/tests/css/box_shadow_blur_fixed_ref.html b/tests/wpt/mozilla/tests/css/box_shadow_blur_fixed_ref.html
new file mode 100644
index 00000000000..03e79789470
--- /dev/null
+++ b/tests/wpt/mozilla/tests/css/box_shadow_blur_fixed_ref.html
@@ -0,0 +1,23 @@
+<head>
+ <style>
+ #div_outer {
+ width: 100%;
+ position: absolute;
+ top: 100px;
+ left: 0;
+ }
+
+ #div_inner {
+ background: lightgrey;
+ height: 40px;
+ box-shadow: 0 0 30px 30px darkblue;
+ }
+ </style>
+</head>
+
+<body>
+ <div id="div_outer">
+ <div id="div_inner">
+ </div>
+ </div>
+</body> \ No newline at end of file
diff --git a/tests/wpt/mozilla/tests/css/textarea_space_calculation-ref.html b/tests/wpt/mozilla/tests/css/textarea_space_calculation-ref.html
new file mode 100644
index 00000000000..b777beb062b
--- /dev/null
+++ b/tests/wpt/mozilla/tests/css/textarea_space_calculation-ref.html
@@ -0,0 +1,19 @@
+<!doctype html>
+<title>REFERENCE: textarea does not take up more space than it takes up</title>
+<style>
+textarea{height:2em;width:2em}
+div{width:2em;font-size:12px;line-height:3px}
+</style>
+<h1>To pass, no red should be visible</h1>
+<div>
+<textarea>
+1
+2
+3
+4
+5
+6
+8
+9
+</textarea>
+</div>
diff --git a/tests/wpt/mozilla/tests/css/textarea_space_calculation.html b/tests/wpt/mozilla/tests/css/textarea_space_calculation.html
new file mode 100644
index 00000000000..20945e971b5
--- /dev/null
+++ b/tests/wpt/mozilla/tests/css/textarea_space_calculation.html
@@ -0,0 +1,21 @@
+<!doctype html>
+<meta charset="utf-8">
+<title>textarea does not take up more space than it takes up</title>
+<link rel="match" href="textarea_space_calculation-ref.html">
+<style>
+textarea{height:2em;width:2em}
+div{background:red;width:2em;font-size:12px;line-height:3px}
+</style>
+<h1>To pass, no red should be visible</h1>
+<div>
+<textarea>
+1
+2
+3
+4
+5
+6
+8
+9
+</textarea>
+</div>
diff --git a/tests/wpt/mozilla/tests/mozilla/blob.html b/tests/wpt/mozilla/tests/mozilla/FileAPI/blob.html
index 3f932083542..3f932083542 100644
--- a/tests/wpt/mozilla/tests/mozilla/blob.html
+++ b/tests/wpt/mozilla/tests/mozilla/FileAPI/blob.html
diff --git a/tests/wpt/mozilla/tests/mozilla/blob_url_upload.html b/tests/wpt/mozilla/tests/mozilla/FileAPI/blob_url_upload.html
index 17c8e3ad0b4..17c8e3ad0b4 100644
--- a/tests/wpt/mozilla/tests/mozilla/blob_url_upload.html
+++ b/tests/wpt/mozilla/tests/mozilla/FileAPI/blob_url_upload.html
diff --git a/tests/wpt/mozilla/tests/mozilla/blob_url_upload_ref.html b/tests/wpt/mozilla/tests/mozilla/FileAPI/blob_url_upload_ref.html
index 2ae08600b45..6f95c43ac32 100644
--- a/tests/wpt/mozilla/tests/mozilla/blob_url_upload_ref.html
+++ b/tests/wpt/mozilla/tests/mozilla/FileAPI/blob_url_upload_ref.html
@@ -2,6 +2,6 @@
<meta charset="utf-8">
<title>Reference: Blob URL with File Upload</title>
<body>
- <img src="test.jpg" id="image">
+ <img src="../test.jpg" id="image">
<input type="file" id="file-input"">
</body>
diff --git a/tests/wpt/mozilla/tests/mozilla/file_upload.html b/tests/wpt/mozilla/tests/mozilla/FileAPI/file-select.html
index ad911097f6c..06a5f30dd44 100644
--- a/tests/wpt/mozilla/tests/mozilla/file_upload.html
+++ b/tests/wpt/mozilla/tests/mozilla/FileAPI/file-select.html
@@ -1,6 +1,6 @@
<!doctype html>
<meta charset="utf-8">
-<title>Test of uploading a file through input element</title>
+<title>Test of selecting a file through input element</title>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
diff --git a/tests/wpt/mozilla/tests/mozilla/FileAPI/file-upload-frame.html b/tests/wpt/mozilla/tests/mozilla/FileAPI/file-upload-frame.html
new file mode 100644
index 00000000000..13951bb37d0
--- /dev/null
+++ b/tests/wpt/mozilla/tests/mozilla/FileAPI/file-upload-frame.html
@@ -0,0 +1,8 @@
+<form id="testform" enctype="multipart/form-data" action="resource/file-submission.py" method="post">
+<input type="file" name="file-input" id="file-input" />
+</form>
+
+<script type="text/javascript">
+ var e = document.getElementById("file-input");
+ e.selectFiles(["./tests/wpt/mozilla/tests/mozilla/FileAPI/resource/upload.txt"]);
+</script>
diff --git a/tests/wpt/mozilla/tests/mozilla/FileAPI/file-upload.html b/tests/wpt/mozilla/tests/mozilla/FileAPI/file-upload.html
new file mode 100644
index 00000000000..bff5fb1ee7a
--- /dev/null
+++ b/tests/wpt/mozilla/tests/mozilla/FileAPI/file-upload.html
@@ -0,0 +1,23 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script>
+
+function run_test() {
+ var t = async_test("form submission of uploaded file");
+
+ var testframe = document.getElementById("testframe");
+ var testdocument = testframe.contentWindow.document;
+
+ testframe.onload = function() {
+ t.step(function () {
+ var response = testframe.contentDocument.documentElement.textContent;
+ assert_equals(response, "OK");
+ });
+ t.done();
+ };
+ testdocument.getElementById("testform").submit();
+}
+</script>
+<iframe id=testframe src="file-upload-frame.html" onload="run_test();"></iframe>
diff --git a/tests/wpt/mozilla/tests/mozilla/FileAPI/resource/file-submission.py b/tests/wpt/mozilla/tests/mozilla/FileAPI/resource/file-submission.py
new file mode 100644
index 00000000000..aa278cb4c4d
--- /dev/null
+++ b/tests/wpt/mozilla/tests/mozilla/FileAPI/resource/file-submission.py
@@ -0,0 +1,29 @@
+#!/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/.
+
+
+def fail(msg):
+ return ([("Content-Type", "text/plain")], "FAIL: " + msg)
+
+
+def main(request, response):
+ content_type = request.headers.get('Content-Type').split("; ")
+
+ if len(content_type) != 2:
+ return fail("content type length is incorrect")
+
+ if content_type[0] != 'multipart/form-data':
+ return fail("content type first field is incorrect")
+
+ boundary = content_type[1].strip("boundary=")
+
+ body = "--" + boundary + "\r\nContent-Disposition: form-data; name=\"file-input\"; filename=\"upload.txt\""
+ body += "\r\n" + "text/plain\r\n\r\nHello\r\n--" + boundary + "--"
+
+ if body != request.body:
+ return fail("request body doesn't match: " + body + "+++++++" + request.body)
+
+ return ([("Content-Type", "text/plain")], "OK")
diff --git a/tests/wpt/mozilla/tests/mozilla/FileAPI/resource/upload.txt b/tests/wpt/mozilla/tests/mozilla/FileAPI/resource/upload.txt
new file mode 100644
index 00000000000..5ab2f8a4323
--- /dev/null
+++ b/tests/wpt/mozilla/tests/mozilla/FileAPI/resource/upload.txt
@@ -0,0 +1 @@
+Hello \ No newline at end of file
diff --git a/tests/wpt/mozilla/tests/mozilla/interfaces.html b/tests/wpt/mozilla/tests/mozilla/interfaces.html
index 95dfa65ad82..f037f9a879e 100644
--- a/tests/wpt/mozilla/tests/mozilla/interfaces.html
+++ b/tests/wpt/mozilla/tests/mozilla/interfaces.html
@@ -49,6 +49,7 @@ test_interfaces([
"FormData",
"HashChangeEvent",
"Headers",
+ "History",
"HTMLAnchorElement",
"HTMLAppletElement",
"HTMLAreaElement",
diff --git a/tests/wpt/mozilla/tests/mozilla/interfaces.worker.js b/tests/wpt/mozilla/tests/mozilla/interfaces.worker.js
index 79b99d4f1de..68d5cfbcedf 100644
--- a/tests/wpt/mozilla/tests/mozilla/interfaces.worker.js
+++ b/tests/wpt/mozilla/tests/mozilla/interfaces.worker.js
@@ -41,45 +41,18 @@ test_interfaces([
"File",
"FileList",
"FileReader",
+ "FileReaderSync",
"FocusEvent",
"FormData",
"HashChangeEvent",
- "Headers",
- "HTMLAnchorElement",
- "HTMLAppletElement",
- "HTMLAreaElement",
- "HTMLAudioElement",
- "HTMLBaseElement",
- "HTMLBodyElement",
- "HTMLBRElement",
- "HTMLButtonElement",
+ "Headers",
+ "History",
"HTMLCanvasElement",
"HTMLCollection",
- "HTMLDataElement",
- "HTMLDataListElement",
- "HTMLDetailsElement",
- "HTMLDialogElement",
- "HTMLDirectoryElement",
- "HTMLDivElement",
- "HTMLDListElement",
"HTMLElement",
- "HTMLEmbedElement",
- "HTMLFieldSetElement",
- "HTMLFontElement",
"HTMLFormControlsCollection",
"HTMLFormElement",
- "HTMLFrameElement",
- "HTMLFrameSetElement",
"HTMLHeadElement",
- "HTMLHeadingElement",
- "HTMLHRElement",
- "HTMLHtmlElement",
- "HTMLIFrameElement",
- "HTMLImageElement",
- "HTMLInputElement",
- "HTMLLabelElement",
- "HTMLLegendElement",
- "HTMLLIElement",
"HTMLLinkElement",
"HTMLMapElement",
"HTMLMediaElement",
@@ -91,34 +64,8 @@ test_interfaces([
"HTMLOptGroupElement",
"HTMLOptionElement",
"HTMLOutputElement",
- "HTMLParagraphElement",
- "HTMLParamElement",
- "HTMLPreElement",
- "HTMLProgressElement",
- "HTMLQuoteElement",
"HTMLScriptElement",
- "HTMLSelectElement",
- "HTMLSourceElement",
- "HTMLSpanElement",
- "HTMLStyleElement",
- "HTMLTableCaptionElement",
- "HTMLTableCellElement",
- "HTMLTableColElement",
- "HTMLTableDataCellElement",
- "HTMLTableElement",
- "HTMLTableHeaderCellElement",
- "HTMLTableRowElement",
- "HTMLTableSectionElement",
- "HTMLTemplateElement",
- "HTMLTextAreaElement",
- "HTMLTimeElement",
- "HTMLTitleElement",
- "HTMLTrackElement",
- "HTMLUListElement",
- "HTMLUnknownElement",
- "HTMLVideoElement",
"ImageData",
- "Image",
"KeyboardEvent",
"Location",
"MediaError",
diff --git a/tests/wpt/mozilla/tests/mozilla/table_valign_uneven_height.html b/tests/wpt/mozilla/tests/mozilla/table_valign_uneven_height.html
new file mode 100644
index 00000000000..6668070831a
--- /dev/null
+++ b/tests/wpt/mozilla/tests/mozilla/table_valign_uneven_height.html
@@ -0,0 +1,34 @@
+<!doctype html>
+<meta charset="utf-8">
+<title>Vertical Alignment for row with uneven height cells</title>
+<link rel="match" href="table_valign_uneven_height_ref.html">
+<style>
+ td {
+ border: 5px black solid;
+ border-spacing: 0;
+ padding: 0;
+ }
+ td {
+ vertical-align: middle;
+ background-color: green;
+ }
+ .b {
+ vertical-align: bottom;
+ }
+ div {
+ height: 50px;
+ width: 50px;
+ background-color: blue;
+ }
+ .c {
+ height: 100px !important;
+ background-color: red !important;
+ }
+</style>
+<table>
+ <tr>
+ <td><div class="c"></div></td>
+ <td><div></div></td>
+ <td class="b"><div></div></td>
+ </tr>
+</table>
diff --git a/tests/wpt/mozilla/tests/mozilla/table_valign_uneven_height_ref.html b/tests/wpt/mozilla/tests/mozilla/table_valign_uneven_height_ref.html
new file mode 100644
index 00000000000..321132b7e7e
--- /dev/null
+++ b/tests/wpt/mozilla/tests/mozilla/table_valign_uneven_height_ref.html
@@ -0,0 +1,34 @@
+<!doctype html>
+<meta charset="utf-8">
+<title>Reference: Vertical Alignment for row with uneven height cells</title>
+<style>
+ td {
+ background-color: green;
+ border: 5px black solid;
+ border-spacing: 0;
+ padding: 0;
+ }
+ div {
+ height: 50px;
+ width: 50px;
+ background-color: blue;
+ }
+ .c {
+ height: 100px !important;
+ background-color: #f00 !important;
+ }
+ .middle {
+ margin-top: 25px;
+ margin-bottom: 25px;
+ }
+ .bottom {
+ margin-top: 50px;
+ }
+</style>
+<table>
+ <tr>
+ <td class="a"><div class="c"></div></td>
+ <td class="a"><div class="middle"></div></td>
+ <td class="b"><div class="bottom"></div></td>
+ </tr>
+</table>
diff --git a/tests/wpt/web-platform-tests/FileAPI/idlharness.idl b/tests/wpt/web-platform-tests/FileAPI/idlharness.idl
index 62e6c5d9f21..d8f31b43a80 100644
--- a/tests/wpt/web-platform-tests/FileAPI/idlharness.idl
+++ b/tests/wpt/web-platform-tests/FileAPI/idlharness.idl
@@ -1,5 +1,7 @@
-[Constructor,
- Constructor(sequence<(ArrayBuffer or ArrayBufferView or Blob or DOMString)> blobParts, optional BlobPropertyBag options), Exposed=Window,Worker]
+// https://w3c.github.io/FileAPI/#idl-index
+
+[Constructor(optional sequence<BlobPart> blobParts, optional BlobPropertyBag options),
+Exposed=(Window,Worker)]
interface Blob {
readonly attribute unsigned long long size;
@@ -9,8 +11,8 @@ interface Blob {
//slice Blob into byte-ranged chunks
Blob slice([Clamp] optional long long start,
- [Clamp] optional long long end,
- optional DOMString contentType);
+ [Clamp] optional long long end,
+ optional DOMString contentType);
void close();
};
@@ -19,32 +21,33 @@ dictionary BlobPropertyBag {
DOMString type = "";
};
-[Constructor(sequence<(Blob or DOMString or ArrayBufferView or ArrayBuffer)> fileBits,
-[EnsureUTF16] DOMString fileName, optional FilePropertyBag options), Exposed=Window,Worker]
-interface File : Blob {
+typedef (BufferSource or Blob or USVString) BlobPart;
+[Constructor(sequence<BlobPart> fileBits,
+ [EnsureUTF16] DOMString fileName,
+ optional FilePropertyBag options),
+Exposed=(Window,Worker)]
+interface File : Blob {
readonly attribute DOMString name;
readonly attribute long long lastModified;
-
};
-dictionary FilePropertyBag {
-
- DOMString type = "";
+dictionary FilePropertyBag : BlobPropertyBag {
long long lastModified;
-
};
-[Exposed=Window,Worker] interface FileList {
+[Exposed=(Window,Worker)]
+interface FileList {
getter File? item(unsigned long index);
readonly attribute unsigned long length;
};
-[Constructor, Exposed=Window,Worker]
+[Constructor, Exposed=(Window,Worker)]
interface FileReader: EventTarget {
// async read methods
void readAsArrayBuffer(Blob blob);
+ void readAsBinaryString(Blob blob);
void readAsText(Blob blob, optional DOMString label);
void readAsDataURL(Blob blob);
@@ -55,6 +58,7 @@ interface FileReader: EventTarget {
const unsigned short LOADING = 1;
const unsigned short DONE = 2;
+
readonly attribute unsigned short readyState;
// File or Blob data
@@ -62,7 +66,7 @@ interface FileReader: EventTarget {
readonly attribute DOMError? error;
- // event handler attributes
+ // event handler content attributes
attribute EventHandler onloadstart;
attribute EventHandler onprogress;
attribute EventHandler onload;
@@ -72,20 +76,19 @@ interface FileReader: EventTarget {
};
-partial interface URL {
-
- static DOMString createObjectURL(Blob blob);
- static DOMString createFor(Blob blob);
- static void revokeObjectURL(DOMString url);
-
-};
-
[Constructor, Exposed=Worker]
interface FileReaderSync {
-
// Synchronously return strings
ArrayBuffer readAsArrayBuffer(Blob blob);
+ DOMString readAsBinaryString(Blob blob);
DOMString readAsText(Blob blob, optional DOMString label);
DOMString readAsDataURL(Blob blob);
};
+
+[Exposed=(Window,DedicatedWorker,SharedWorker)]
+partial interface URL {
+ static DOMString createObjectURL(Blob blob);
+ static DOMString createFor(Blob blob);
+ static void revokeObjectURL(DOMString url);
+};
diff --git a/tests/wpt/web-platform-tests/fetch/api/headers/headers-basic.html b/tests/wpt/web-platform-tests/fetch/api/headers/headers-basic.html
index 5c374ed1faf..26bbfe35935 100644
--- a/tests/wpt/web-platform-tests/fetch/api/headers/headers-basic.html
+++ b/tests/wpt/web-platform-tests/fetch/api/headers/headers-basic.html
@@ -66,7 +66,7 @@
assert_equals(headers2.get(name), String(headerDict[name]),
"name: " + name + " has value: " + headerDict[name]);
}
- }, "Create headers whith existing headers");
+ }, "Create headers with existing headers");
test(function() {
var headers = new Headers();
diff --git a/tests/wpt/web-platform-tests/html/semantics/interactive-elements/the-dialog-element/dialog-open.html b/tests/wpt/web-platform-tests/html/semantics/interactive-elements/the-dialog-element/dialog-open.html
new file mode 100644
index 00000000000..4719f63b853
--- /dev/null
+++ b/tests/wpt/web-platform-tests/html/semantics/interactive-elements/the-dialog-element/dialog-open.html
@@ -0,0 +1,30 @@
+<!doctype html>
+<meta charset="utf-8">
+<title>dialog element: open</title>
+<link rel=help href="https://html.spec.whatwg.org/multipage/forms.html#dom-dialog-open">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<dialog id="d1">
+ <p>foobar</p>
+ <button>OK</button>
+</dialog>
+<dialog id="d2" open>
+ <p>foobar</p>
+ <button>OK</button>
+</dialog>
+<script>
+ var d1 = document.getElementById('d1');
+ var d2 = document.getElementById('d2');
+
+ test(function(){
+ assert_false(d1.open);
+ assert_true(d2.open);
+ }, "On getting, the IDL open attribute must return true if the content open attribute is set, and false if it is absent.");
+
+ test(function(){
+ d1.open = true;
+ assert_true(d1.hasAttribute("open"));
+ d2.open = false;
+ assert_false(d2.hasAttribute("open"));
+ }, "On setting, the content open attribute must be removed if the IDL open attribute is set to false, and must be present if the IDL open attribute is set to true.");
+</script>
diff --git a/tests/wpt/web-platform-tests/html/semantics/tabular-data/the-table-element/remove-row.html b/tests/wpt/web-platform-tests/html/semantics/tabular-data/the-table-element/remove-row.html
new file mode 100644
index 00000000000..b0e529f91ec
--- /dev/null
+++ b/tests/wpt/web-platform-tests/html/semantics/tabular-data/the-table-element/remove-row.html
@@ -0,0 +1,50 @@
+<!doctype html>
+<meta charset="utf-8">
+<title>Delete Row tests</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+
+<table id="element">
+ <thead>
+ <th>First column</th>
+ <th>Second column</th>
+ </thead>
+ <tbody>
+ <tr>
+ <td>1.1</td>
+ <td>1.2</td>
+ </tr>
+ <tr>
+ <td>2.1</td>
+ <td>2.2</td>
+ </tr>
+ </tbody>
+</table>
+
+<script>
+var el = document.getElementById('element');
+
+test(function() {
+ assert_throws("IndexSizeError", function() {
+ el.deleteRow(-2)
+ })
+}, 'deleteRow function invalid argument');
+test(function() {
+ assert_throws("IndexSizeError", function() {
+ el.deleteRow(el.rows.length)
+ })
+}, 'deleteRow function invalid argument bis');
+
+test(function() {
+ var old_length = el.rows.length;
+ el.insertRow(-1);
+ el.deleteRow(-1);
+ assert_equals(old_length, el.rows.length);
+}, "check normal deleteRow");
+test(function() {
+ while (el.rows.length > 1) {
+ el.deleteRow(-1);
+ }
+ assert_equals(1, el.rows.length);
+}, "check normal deleteRow bis");
+</script>