diff --git a/browser/app/firefox.exe.manifest b/browser/app/firefox.exe.manifest index f27e149e3b43..1e1d6f651d27 100644 --- a/browser/app/firefox.exe.manifest +++ b/browser/app/firefox.exe.manifest @@ -19,6 +19,16 @@ /> + + + + + diff --git a/browser/config/mozconfigs/win32/mingwclang b/browser/config/mozconfigs/win32/mingwclang index 253ee951854b..29331cddeec2 100644 --- a/browser/config/mozconfigs/win32/mingwclang +++ b/browser/config/mozconfigs/win32/mingwclang @@ -30,6 +30,7 @@ ac_add_options --target=i686-w64-mingw32 ac_add_options --with-toolchain-prefix=i686-w64-mingw32- ac_add_options --disable-warnings-as-errors +MOZ_COPY_PDBS=1 # Temporary config settings until we get these working on mingw ac_add_options --disable-accessibility # https://sourceforge.net/p/mingw-w64/bugs/648/ diff --git a/browser/config/mozconfigs/win64/mingwclang b/browser/config/mozconfigs/win64/mingwclang index 305bc9e36f5b..5e9446e0acdc 100755 --- a/browser/config/mozconfigs/win64/mingwclang +++ b/browser/config/mozconfigs/win64/mingwclang @@ -30,6 +30,7 @@ ac_add_options --target=x86_64-w64-mingw32 ac_add_options --with-toolchain-prefix=x86_64-w64-mingw32- ac_add_options --disable-warnings-as-errors +MOZ_COPY_PDBS=1 # Temporary config settings until we get these working on mingw ac_add_options --disable-accessibility # https://sourceforge.net/p/mingw-w64/bugs/648/ diff --git a/browser/modules/Sanitizer.jsm b/browser/modules/Sanitizer.jsm index 6e0b7950ff07..e283c909450f 100644 --- a/browser/modules/Sanitizer.jsm +++ b/browser/modules/Sanitizer.jsm @@ -711,6 +711,14 @@ async function sanitizeSessionPrincipals() { return; } + // When PREF_COOKIE_LIFETIME is set to ACCEPT_SESSION, any new cookie will be + // marked as session only. But we don't touch the existing ones. For this + // reason, here we delete any existing cookie, at shutdown. + await new Promise(resolve => { + Services.clearData.deleteData(Ci.nsIClearDataService.CLEAR_COOKIES, + resolve); + }); + let principals = await new Promise(resolve => { quotaManagerService.getUsage(request => { if (request.resultCode != Cr.NS_OK) { diff --git a/build/moz.configure/toolchain.configure b/build/moz.configure/toolchain.configure index a8a4b9e7c8cf..118784bb0be0 100755 --- a/build/moz.configure/toolchain.configure +++ b/build/moz.configure/toolchain.configure @@ -1126,11 +1126,13 @@ def check_have_64_bit(have_64_bit, compiler_have_64_bit): 'about the target bitness.') -@depends(c_compiler) -def default_debug_flags(compiler_info): +@depends(c_compiler, target) +def default_debug_flags(compiler_info, target): # Debug info is ON by default. if compiler_info.type in ('msvc', 'clang-cl'): return '-Zi' + elif target.kernel == 'WINNT' and compiler_info.type == 'clang': + return '-g -gcodeview' return '-g' @@ -1992,11 +1994,16 @@ add_old_configure_assignment('LIBFUZZER_FLAGS', libfuzzer_flags.use_flags) @depends(target, c_compiler) def make_shared_library(target, compiler): if target.os == 'WINNT': - if compiler.type in ('gcc', 'clang'): + if compiler.type == 'gcc': return namespace( mkshlib=['$(CXX)', '$(DSO_LDOPTS)', '-o', '$@'], mkcshlib=['$(CC)', '$(DSO_LDOPTS)', '-o', '$@'], ) + elif compiler.type == 'clang': + return namespace( + mkshlib=['$(CXX)', '$(DSO_LDOPTS)', '-Wl,-pdb,$(LINK_PDBFILE)', '-o', '$@'], + mkcshlib=['$(CC)', '$(DSO_LDOPTS)', '-Wl,-pdb,$(LINK_PDBFILE)', '-o', '$@'], + ) else: linker = [ '$(LINKER)', diff --git a/build/win64/mozconfig.asan b/build/win64/mozconfig.asan index 0a7fd2b7a544..af6f1817e64e 100644 --- a/build/win64/mozconfig.asan +++ b/build/win64/mozconfig.asan @@ -7,6 +7,7 @@ if [ -d "$topsrcdir/clang" ]; then mk_export_correct_style LIB export LDFLAGS="clang_rt.asan_dynamic-x86_64.lib clang_rt.asan_dynamic_runtime_thunk-x86_64.lib" + export MOZ_COPY_PDBS=1 export LLVM_SYMBOLIZER="$topsrcdir/clang/bin/llvm-symbolizer.exe" export MOZ_CLANG_RT_ASAN_LIB_PATH="${CLANG_LIB_DIR}/clang_rt.asan_dynamic-x86_64.dll" fi diff --git a/config/rules.mk b/config/rules.mk index 65e5110786f4..45dc538c9fd3 100644 --- a/config/rules.mk +++ b/config/rules.mk @@ -126,6 +126,9 @@ endif # MKSHLIB endif # FORCE_SHARED_LIB ifeq ($(OS_ARCH),WINNT) + +LINK_PDBFILE ?= $(basename $(@F)).pdb + ifndef GNU_CC # @@ -147,7 +150,6 @@ endif COMPILE_CFLAGS += $(COMPILE_PDB_FLAG) COMPILE_CXXFLAGS += $(COMPILE_PDB_FLAG) -LINK_PDBFILE ?= $(basename $(@F)).pdb ifdef MOZ_DEBUG CODFILE=$(basename $(@F)).cod endif @@ -161,6 +163,12 @@ MOZ_PROGRAM_LDFLAGS += -Wl,-rpath -Wl,@executable_path/Frameworks endif endif +ifeq ($(OS_ARCH),WINNT) +ifeq ($(CC_TYPE),clang) +MOZ_PROGRAM_LDFLAGS += -Wl,-pdb,$(dir $@)/$(LINK_PDBFILE) +endif +endif + ifeq ($(HOST_OS_ARCH),WINNT) HOST_PDBFILE=$(basename $(@F)).pdb HOST_PDB_FLAG ?= -Fd$(HOST_PDBFILE) @@ -819,13 +827,13 @@ DUMP_SYMS_TARGETS := endif endif -ifdef MOZ_CRASHREPORTER -$(foreach file,$(DUMP_SYMS_TARGETS),$(eval $(call syms_template,$(file),$(notdir $(file))_syms.track))) -else ifneq (,$(and $(LLVM_SYMBOLIZER),$(filter WINNT,$(OS_ARCH)),$(MOZ_AUTOMATION))) +ifdef MOZ_COPY_PDBS PDB_FILES = $(addsuffix .pdb,$(basename $(DUMP_SYMS_TARGETS))) PDB_DEST ?= $(FINAL_TARGET) PDB_TARGET = syms INSTALL_TARGETS += PDB +else ifdef MOZ_CRASHREPORTER +$(foreach file,$(DUMP_SYMS_TARGETS),$(eval $(call syms_template,$(file),$(notdir $(file))_syms.track))) endif cargo_host_flag := --target=$(RUST_HOST_TARGET) diff --git a/config/version_win.pl b/config/version_win.pl index 47c7dfe30e4a..a2ac99b8f1a2 100755 --- a/config/version_win.pl +++ b/config/version_win.pl @@ -274,12 +274,14 @@ print RCFILE qq{ my $versionlevel=0; my $insideversion=0; +my $has_manifest=0; if (open(RCINCLUDE, "<$rcinclude")) { print RCFILE "// From included resource $rcinclude\n"; # my $mstring=""; while () { + $has_manifest = 1 if /^1 (24|RT_MANIFEST) "$binary.manifest"/; $_ =~ s/\@MOZ_APP_DISPLAYNAME\@/$displayname/g; print RCFILE $_; # my $instr=$_; @@ -330,6 +332,10 @@ if (open(RCINCLUDE, "<$rcinclude")) my $fileflags = join(' | ', @fileflags); +print RCFILE qq{ +1 RT_MANIFEST "$binary.manifest" +} if !$has_manifest && $binary =~ /\.exe$/ && -e "$objdir/$binary.manifest"; + print RCFILE qq{ diff --git a/devtools/client/inspector/inspector.js b/devtools/client/inspector/inspector.js index ba9c8f65fcba..44df7dc9b994 100644 --- a/devtools/client/inspector/inspector.js +++ b/devtools/client/inspector/inspector.js @@ -876,7 +876,7 @@ Inspector.prototype = { let defaultTab = Services.prefs.getCharPref("devtools.inspector.activeSidebar"); if (this.is3PaneModeEnabled && defaultTab === "ruleview") { - defaultTab = "computedview"; + defaultTab = "layoutview"; } // Append all side panels diff --git a/devtools/client/inspector/rules/test/browser.ini b/devtools/client/inspector/rules/test/browser.ini index 07d46b26e235..7bb3e6e30e53 100644 --- a/devtools/client/inspector/rules/test/browser.ini +++ b/devtools/client/inspector/rules/test/browser.ini @@ -181,6 +181,7 @@ skip-if = (os == "win" && debug) # bug 963492: win. [browser_rules_grid-toggle_02.js] [browser_rules_grid-toggle_03.js] [browser_rules_grid-toggle_04.js] +[browser_rules_grid-toggle_05.js] [browser_rules_gridline-names-autocomplete.js] [browser_rules_guessIndentation.js] [browser_rules_highlight-used-fonts.js] diff --git a/devtools/client/inspector/rules/test/browser_rules_grid-toggle_01.js b/devtools/client/inspector/rules/test/browser_rules_grid-toggle_01.js index 34f7fb55a6f0..12d90c8239a5 100644 --- a/devtools/client/inspector/rules/test/browser_rules_grid-toggle_01.js +++ b/devtools/client/inspector/rules/test/browser_rules_grid-toggle_01.js @@ -29,7 +29,7 @@ add_task(async function() { const gridToggle = container.querySelector(".ruleview-grid"); info("Checking the initial state of the CSS grid toggle in the rule-view."); - ok(gridToggle, "Grid highlighter toggle is visible."); + ok(!gridToggle.hasAttribute("disabled"), "Grid highlighter toggle is not disabled."); ok(!gridToggle.classList.contains("active"), "Grid highlighter toggle button is not active."); ok(!highlighters.gridHighlighters.size, "No CSS grid highlighter is shown."); @@ -41,6 +41,7 @@ add_task(async function() { info("Checking the CSS grid highlighter is created and toggle button is active in " + "the rule-view."); + ok(!gridToggle.hasAttribute("disabled"), "Grid highlighter toggle is not disabled."); ok(gridToggle.classList.contains("active"), "Grid highlighter toggle is active."); is(highlighters.gridHighlighters.size, 1, "CSS grid highlighter is shown."); @@ -52,6 +53,7 @@ add_task(async function() { info("Checking the CSS grid highlighter is not shown and toggle button is not active " + "in the rule-view."); + ok(!gridToggle.hasAttribute("disabled"), "Grid highlighter toggle is not disabled."); ok(!gridToggle.classList.contains("active"), "Grid highlighter toggle button is not active."); ok(!highlighters.gridHighlighters.size, "No CSS grid highlighter is shown."); diff --git a/devtools/client/inspector/rules/test/browser_rules_grid-toggle_01b.js b/devtools/client/inspector/rules/test/browser_rules_grid-toggle_01b.js index f0f7324f27d5..51ad0599cf45 100644 --- a/devtools/client/inspector/rules/test/browser_rules_grid-toggle_01b.js +++ b/devtools/client/inspector/rules/test/browser_rules_grid-toggle_01b.js @@ -29,7 +29,7 @@ add_task(async function() { const gridToggle = container.querySelector(".ruleview-grid"); info("Checking the initial state of the CSS grid toggle in the rule-view."); - ok(gridToggle, "Grid highlighter toggle is visible."); + ok(!gridToggle.hasAttribute("disabled"), "Grid highlighter toggle is not disabled."); ok(!gridToggle.classList.contains("active"), "Grid highlighter toggle button is not active."); ok(!highlighters.gridHighlighters.size, "No CSS grid highlighter is shown."); @@ -41,6 +41,7 @@ add_task(async function() { info("Checking the CSS grid highlighter is created and toggle button is active in " + "the rule-view."); + ok(!gridToggle.hasAttribute("disabled"), "Grid highlighter toggle is not disabled."); ok(gridToggle.classList.contains("active"), "Grid highlighter toggle is active."); is(highlighters.gridHighlighters.size, 1, "CSS grid highlighter is shown."); @@ -52,6 +53,7 @@ add_task(async function() { info("Checking the CSS grid highlighter is not shown and toggle button is not active " + "in the rule-view."); + ok(!gridToggle.hasAttribute("disabled"), "Grid highlighter toggle is not disabled."); ok(!gridToggle.classList.contains("active"), "Grid highlighter toggle button is not active."); ok(!highlighters.gridHighlighters.size, "No CSS grid highlighter is shown."); diff --git a/devtools/client/inspector/rules/test/browser_rules_grid-toggle_02.js b/devtools/client/inspector/rules/test/browser_rules_grid-toggle_02.js index 58c6e6b37782..1093169a0942 100644 --- a/devtools/client/inspector/rules/test/browser_rules_grid-toggle_02.js +++ b/devtools/client/inspector/rules/test/browser_rules_grid-toggle_02.js @@ -34,7 +34,9 @@ add_task(async function() { const overriddenGridToggle = overriddenContainer.querySelector(".ruleview-grid"); info("Checking the initial state of the CSS grid toggle in the rule-view."); - ok(gridToggle && overriddenGridToggle, "Grid highlighter toggles are visible."); + ok(!gridToggle.hasAttribute("disabled"), "Grid highlighter toggle is not disabled."); + ok(!overriddenGridToggle.hasAttribute("disabled"), + "Grid highlighter toggle is not disabled."); ok(!gridToggle.classList.contains("active") && !overriddenGridToggle.classList.contains("active"), "Grid highlighter toggle buttons are not active."); diff --git a/devtools/client/inspector/rules/test/browser_rules_grid-toggle_03.js b/devtools/client/inspector/rules/test/browser_rules_grid-toggle_03.js index df614c0ae3d3..1f1fabb6c10c 100644 --- a/devtools/client/inspector/rules/test/browser_rules_grid-toggle_03.js +++ b/devtools/client/inspector/rules/test/browser_rules_grid-toggle_03.js @@ -35,7 +35,7 @@ add_task(async function() { info("Checking the state of the CSS grid toggle for the first grid container in the " + "rule-view."); - ok(gridToggle, "Grid highlighter toggle is visible."); + ok(!gridToggle.hasAttribute("disabled"), "Grid highlighter toggle is not disabled."); ok(!gridToggle.classList.contains("active"), "Grid highlighter toggle button is not active."); ok(!highlighters.gridHighlighters.size, "No CSS grid highlighter is shown."); @@ -48,6 +48,7 @@ add_task(async function() { info("Checking the CSS grid highlighter is created and toggle button is active in " + "the rule-view."); + ok(!gridToggle.hasAttribute("disabled"), "Grid highlighter toggle is not disabled."); ok(gridToggle.classList.contains("active"), "Grid highlighter toggle is active."); is(highlighters.gridHighlighters.size, 1, "CSS grid highlighter is shown."); @@ -60,7 +61,7 @@ add_task(async function() { info("Checking the state of the CSS grid toggle for the second grid container in the " + "rule-view."); - ok(gridToggle, "Grid highlighter toggle is visible."); + ok(!gridToggle.hasAttribute("disabled"), "Grid highlighter toggle is not disabled."); ok(!gridToggle.classList.contains("active"), "Grid highlighter toggle button is not active."); is(highlighters.gridHighlighters.size, 1, "CSS grid highlighter is still shown."); @@ -85,7 +86,7 @@ add_task(async function() { info("Checking the state of the CSS grid toggle for the first grid container in the " + "rule-view."); - ok(gridToggle, "Grid highlighter toggle is visible."); + ok(!gridToggle.hasAttribute("disabled"), "Grid highlighter toggle is not disabled."); ok(!gridToggle.classList.contains("active"), "Grid highlighter toggle button is not active."); }); diff --git a/devtools/client/inspector/rules/test/browser_rules_grid-toggle_04.js b/devtools/client/inspector/rules/test/browser_rules_grid-toggle_04.js index 8f45bfbd0ccd..f3a09b12a317 100644 --- a/devtools/client/inspector/rules/test/browser_rules_grid-toggle_04.js +++ b/devtools/client/inspector/rules/test/browser_rules_grid-toggle_04.js @@ -29,7 +29,7 @@ add_task(async function() { const gridToggle = container.querySelector(".ruleview-grid"); info("Checking the initial state of the CSS grid toggle in the rule-view."); - ok(gridToggle, "Grid highlighter toggle is visible."); + ok(!gridToggle.hasAttribute("disabled"), "Grid highlighter toggle is not disabled."); ok(!gridToggle.classList.contains("active"), "Grid highlighter toggle button is not active."); ok(!highlighters.gridHighlighters.size, "No CSS grid highlighter is shown."); @@ -41,6 +41,7 @@ add_task(async function() { info("Checking the CSS grid highlighter is created and toggle button is active in " + "the rule-view."); + ok(!gridToggle.hasAttribute("disabled"), "Grid highlighter toggle is not disabled."); ok(gridToggle.classList.contains("active"), "Grid highlighter toggle is active."); is(highlighters.gridHighlighters.size, 1, "CSS grid highlighter is shown."); @@ -52,6 +53,7 @@ add_task(async function() { info("Checking the CSS grid highlighter is not shown and toggle button is not active " + "in the rule-view."); + ok(!gridToggle.hasAttribute("disabled"), "Grid highlighter toggle is not disabled."); ok(!gridToggle.classList.contains("active"), "Grid highlighter toggle button is not active."); ok(!highlighters.gridHighlighters.size, "No CSS grid highlighter is shown."); diff --git a/devtools/client/inspector/rules/test/browser_rules_grid-toggle_05.js b/devtools/client/inspector/rules/test/browser_rules_grid-toggle_05.js new file mode 100644 index 000000000000..6d1c5a80421d --- /dev/null +++ b/devtools/client/inspector/rules/test/browser_rules_grid-toggle_05.js @@ -0,0 +1,102 @@ +/* vim: set ft=javascript ts=2 et sw=2 tw=80: */ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ + +"use strict"; + +// Test that the grid toggle is hidden when the maximum number of grid highlighters +// have been reached. + +const TEST_URI = ` + + + cell1 + cell2 + + + cell1 + cell2 + + + cell1 + cell2 + +`; + +add_task(async function() { + await pushPref("devtools.gridinspector.maxHighlighters", 2); + await addTab("data:text/html;charset=utf-8," + encodeURIComponent(TEST_URI)); + const { inspector, gridInspector } = await openLayoutView(); + const ruleView = selectRuleView(inspector); + const { document: doc } = gridInspector; + const { highlighters } = inspector; + + await selectNode("#grid1", inspector); + const gridList = doc.getElementById("grid-list"); + const checkbox2 = gridList.children[1].querySelector("input"); + const checkbox3 = gridList.children[2].querySelector("input"); + const container = getRuleViewProperty(ruleView, ".grid", "display").valueSpan; + const gridToggle = container.querySelector(".ruleview-grid"); + + info("Checking the initial state of the CSS grid toggle in the rule-view."); + ok(!gridToggle.hasAttribute("disabled"), "Grid highlighter toggle is not disabled."); + ok(!gridToggle.classList.contains("active"), + "Grid highlighter toggle button is not active."); + ok(!highlighters.gridHighlighters.size, "No CSS grid highlighter is shown."); + + info("Toggling ON the CSS grid highlighter for #grid2."); + let onHighlighterShown = highlighters.once("grid-highlighter-shown"); + checkbox2.click(); + await onHighlighterShown; + + info("Checking the CSS grid toggle for #grid1 is not disabled and not active."); + ok(!gridToggle.hasAttribute("disabled"), "Grid highlighter toggle is not disabled."); + ok(!gridToggle.classList.contains("active"), + "Grid highlighter toggle button is not active."); + is(highlighters.gridHighlighters.size, 1, "CSS grid highlighter is shown."); + + info("Toggling ON the CSS grid highlighter for #grid3."); + onHighlighterShown = highlighters.once("grid-highlighter-shown"); + checkbox3.click(); + await onHighlighterShown; + + info("Checking the CSS grid toggle for #grid1 is disabled."); + ok(gridToggle.hasAttribute("disabled"), "Grid highlighter toggle is disabled."); + is(highlighters.gridHighlighters.size, 2, "CSS grid highlighters are shown."); + + info("Toggling OFF the CSS grid highlighter for #grid3."); + let onHighlighterHidden = highlighters.once("grid-highlighter-hidden"); + checkbox3.click(); + await onHighlighterHidden; + + info("Checking the CSS grid toggle for #grid1 is not disabled and not active."); + ok(!gridToggle.hasAttribute("disabled"), "Grid highlighter toggle is not disabled."); + ok(!gridToggle.classList.contains("active"), + "Grid highlighter toggle button is not active."); + is(highlighters.gridHighlighters.size, 1, "CSS grid highlighter is shown."); + + info("Toggling ON the CSS grid highlighter for #grid1 from the rule-view."); + onHighlighterShown = highlighters.once("grid-highlighter-shown"); + gridToggle.click(); + await onHighlighterShown; + + info("Checking the CSS grid toggle for #grid1 is not disabled."); + ok(!gridToggle.hasAttribute("disabled"), "Grid highlighter toggle is not disabled."); + ok(gridToggle.classList.contains("active"), "Grid highlighter toggle is active."); + is(highlighters.gridHighlighters.size, 2, "CSS grid highlighters are shown."); + + info("Toggling OFF the CSS grid highlighter for #grid1 from the rule-view."); + onHighlighterHidden = highlighters.once("grid-highlighter-hidden"); + gridToggle.click(); + await onHighlighterHidden; + + info("Checking the CSS grid toggle for #grid1 is not disabled and not active."); + ok(!gridToggle.hasAttribute("disabled"), "Grid highlighter toggle is not disabled."); + ok(!gridToggle.classList.contains("active"), + "Grid highlighter toggle button is not active."); + is(highlighters.gridHighlighters.size, 1, "CSS grid highlighter is shown."); +}); diff --git a/devtools/client/inspector/rules/views/text-property-editor.js b/devtools/client/inspector/rules/views/text-property-editor.js index ef5402067a31..d7ac2690cafb 100644 --- a/devtools/client/inspector/rules/views/text-property-editor.js +++ b/devtools/client/inspector/rules/views/text-property-editor.js @@ -76,6 +76,7 @@ function TextPropertyEditor(ruleEditor, property) { this.prop = property; this.prop.editor = this; this.browserWindow = this.doc.defaultView.top; + this._populatedComputed = false; this._hasPendingClick = false; this._clickedElementOptions = null; @@ -521,22 +522,22 @@ TextPropertyEditor.prototype = { } } + const nodeFront = this.ruleView.inspector.selection.nodeFront; + const flexToggle = this.valueSpan.querySelector(".ruleview-flex"); if (flexToggle) { flexToggle.setAttribute("title", l10n("rule.flexToggle.tooltip")); - if (this.ruleView.highlighters.flexboxHighlighterShown === - this.ruleView.inspector.selection.nodeFront) { - flexToggle.classList.add("active"); - } + flexToggle.classList.toggle("active", + this.ruleView.highlighters.flexboxHighlighterShown === nodeFront); } const gridToggle = this.valueSpan.querySelector(".ruleview-grid"); if (gridToggle) { gridToggle.setAttribute("title", l10n("rule.gridToggle.tooltip")); - if (this.ruleView.highlighters.gridHighlighters.has( - this.ruleView.inspector.selection.nodeFront)) { - gridToggle.classList.add("active"); - } + gridToggle.classList.toggle("active", + this.ruleView.highlighters.gridHighlighters.has(nodeFront)); + gridToggle.toggleAttribute("disabled", + !this.ruleView.highlighters.canGridHighlighterToggle(nodeFront)); } const shapeToggle = this.valueSpan.querySelector(".ruleview-shapeswatch"); diff --git a/devtools/client/inspector/shared/highlighters-overlay.js b/devtools/client/inspector/shared/highlighters-overlay.js index d6abca229821..3bc15cd6e9b9 100644 --- a/devtools/client/inspector/shared/highlighters-overlay.js +++ b/devtools/client/inspector/shared/highlighters-overlay.js @@ -28,6 +28,8 @@ class HighlightersOverlay { this.highlighterUtils = this.inspector.toolbox.highlighterUtils; this.store = this.inspector.store; this.telemetry = inspector.telemetry; + this.maxGridHighlighters = + Services.prefs.getIntPref("devtools.gridinspector.maxHighlighters"); // Collection of instantiated highlighter actors like FlexboxHighlighter, // ShapesHighlighter and GeometryEditorHighlighter. @@ -432,19 +434,16 @@ class HighlightersOverlay { * "rule" represents the rule view. */ async showGridHighlighter(node, options, trigger) { - const maxHighlighters = - Services.prefs.getIntPref("devtools.gridinspector.maxHighlighters"); - // When the grid highlighter has the given node, it is probably called with new // highlighting options, so skip any extra grid highlighter handling. if (!this.gridHighlighters.has(node)) { - if (maxHighlighters === 1) { + if (this.maxGridHighlighters === 1) { // Only one grid highlighter can be shown at a time. Hides any instantiated // grid highlighters. for (const nodeFront of this.gridHighlighters.keys()) { await this.hideGridHighlighter(nodeFront); } - } else if (this.gridHighlighters.size === maxHighlighters) { + } else if (this.gridHighlighters.size === this.maxGridHighlighters) { // The maximum number of grid highlighters shown have been reached. Don't show // any additional grid highlighters. return; @@ -496,8 +495,6 @@ class HighlightersOverlay { return; } - this._toggleRuleViewIcon(node, false, ".ruleview-grid"); - // Hide the highlighter and put it in the pool of extra grid highlighters // so that it can be reused. const highlighter = this.gridHighlighters.get(node); @@ -507,6 +504,8 @@ class HighlightersOverlay { this.state.grids.delete(node); this.gridHighlighters.delete(node); + this._toggleRuleViewIcon(node, false, ".ruleview-grid"); + // Emit the NodeFront of the grid container element that the grid highlighter was // hidden for. this.emit("grid-highlighter-hidden", node); @@ -790,12 +789,22 @@ class HighlightersOverlay { * The selector of the rule view icon to toggle. */ _toggleRuleViewIcon(node, active, selector) { - if (this.inspector.selection.nodeFront != node) { + const ruleViewEl = this.inspector.getPanel("ruleview").view.element; + + if (this.inspector.selection.nodeFront !== node) { + if (selector === ".ruleview-grid") { + for (const icon of ruleViewEl.querySelectorAll(selector)) { + if (this.canGridHighlighterToggle(this.inspector.selection.nodeFront)) { + icon.removeAttribute("disabled"); + } else { + icon.setAttribute("disabled", true); + } + } + } + return; } - const ruleViewEl = this.inspector.getPanel("ruleview").view.element; - for (const icon of ruleViewEl.querySelectorAll(selector)) { icon.classList.toggle("active", active); } diff --git a/devtools/client/inspector/test/browser_inspector_sidebarstate.js b/devtools/client/inspector/test/browser_inspector_sidebarstate.js index ab9657173848..ec7108275ac5 100644 --- a/devtools/client/inspector/test/browser_inspector_sidebarstate.js +++ b/devtools/client/inspector/test/browser_inspector_sidebarstate.js @@ -8,16 +8,6 @@ const TEST_URI = "data:text/html;charset=UTF-8," + const OPTOUT = Ci.nsITelemetry.DATASET_RELEASE_CHANNEL_OPTOUT; const TELEMETRY_DATA = [ - { - timestamp: null, - category: "devtools.main", - method: "tool_timer", - object: "computedview", - value: null, - extra: { - time_open: "" - } - }, { timestamp: null, category: "devtools.main", @@ -32,7 +22,17 @@ const TELEMETRY_DATA = [ timestamp: null, category: "devtools.main", method: "tool_timer", - object: "ruleview", + object: "fontinspector", + value: null, + extra: { + time_open: "" + } + }, + { + timestamp: null, + category: "devtools.main", + method: "tool_timer", + object: "computedview", value: null, extra: { time_open: "" @@ -50,18 +50,18 @@ add_task(async function() { let { inspector, toolbox } = await openInspectorForURL(TEST_URI); + info("Selecting font inspector."); + inspector.sidebar.select("fontinspector"); + + is(inspector.sidebar.getCurrentTabID(), "fontinspector", + "Font Inspector is selected"); + info("Selecting computed view."); inspector.sidebar.select("computedview"); is(inspector.sidebar.getCurrentTabID(), "computedview", "Computed View is selected"); - info("Selecting layout view."); - inspector.sidebar.select("layoutview"); - - is(inspector.sidebar.getCurrentTabID(), "layoutview", - "Layout View is selected"); - info("Closing inspector."); await toolbox.destroy(); @@ -73,8 +73,8 @@ add_task(async function() { await inspector.sidebar.once("select"); } - is(inspector.sidebar.getCurrentTabID(), "layoutview", - "Layout view is selected by default."); + is(inspector.sidebar.getCurrentTabID(), "computedview", + "Computed view is selected by default."); checkTelemetryResults(); }); diff --git a/devtools/client/preferences/devtools-client.js b/devtools/client/preferences/devtools-client.js index e437d22c207d..f3c322b82ec8 100644 --- a/devtools/client/preferences/devtools-client.js +++ b/devtools/client/preferences/devtools-client.js @@ -33,7 +33,7 @@ pref("devtools.command-button-noautohide.enabled", false); // Enable the Inspector pref("devtools.inspector.enabled", true); // What was the last active sidebar in the inspector -pref("devtools.inspector.activeSidebar", "ruleview"); +pref("devtools.inspector.activeSidebar", "layoutview"); pref("devtools.inspector.remote", false); // Enable the 3 pane mode in the inspector diff --git a/devtools/client/shared/test/browser_telemetry_sidebar.js b/devtools/client/shared/test/browser_telemetry_sidebar.js index 9041ea576d56..275dfec94038 100644 --- a/devtools/client/shared/test/browser_telemetry_sidebar.js +++ b/devtools/client/shared/test/browser_telemetry_sidebar.js @@ -19,7 +19,7 @@ const DATA = [ object: "inspector", value: null, extra: { - oldpanel: "computedview", + oldpanel: "layoutview", newpanel: "animationinspector" } }, @@ -156,8 +156,8 @@ function checkResults() { // here. checkTelemetry("DEVTOOLS_INSPECTOR_OPENED_COUNT", "", [1, 0, 0], "array"); checkTelemetry("DEVTOOLS_RULEVIEW_OPENED_COUNT", "", [1, 0, 0], "array"); - checkTelemetry("DEVTOOLS_COMPUTEDVIEW_OPENED_COUNT", "", [3, 0, 0], "array"); - checkTelemetry("DEVTOOLS_LAYOUTVIEW_OPENED_COUNT", "", [2, 0, 0], "array"); + checkTelemetry("DEVTOOLS_COMPUTEDVIEW_OPENED_COUNT", "", [2, 0, 0], "array"); + checkTelemetry("DEVTOOLS_LAYOUTVIEW_OPENED_COUNT", "", [3, 0, 0], "array"); checkTelemetry("DEVTOOLS_FONTINSPECTOR_OPENED_COUNT", "", [2, 0, 0], "array"); checkTelemetry("DEVTOOLS_COMPUTEDVIEW_TIME_ACTIVE_SECONDS", "", null, "hasentries"); checkTelemetry("DEVTOOLS_LAYOUTVIEW_TIME_ACTIVE_SECONDS", "", null, "hasentries"); diff --git a/devtools/client/themes/rules.css b/devtools/client/themes/rules.css index 64f2e6189d9d..1051a4509ebd 100644 --- a/devtools/client/themes/rules.css +++ b/devtools/client/themes/rules.css @@ -440,6 +440,11 @@ border-radius: 0; } +.ruleview-grid[disabled] { + cursor: default; + opacity: 0.5; +} + .ruleview-shape-point.active, .ruleview-shapeswatch.active + .ruleview-shape > .ruleview-shape-point:hover { background-color: var(--rule-highlight-background-color); diff --git a/dom/base/TimeoutExecutor.cpp b/dom/base/TimeoutExecutor.cpp index 036460251558..ee60094bb68d 100644 --- a/dom/base/TimeoutExecutor.cpp +++ b/dom/base/TimeoutExecutor.cpp @@ -56,22 +56,18 @@ TimeoutExecutor::ScheduleDelayed(const TimeStamp& aDeadline, nsresult rv = NS_OK; if (!mTimer) { - mTimer = NS_NewTimer(); + mTimer = NS_NewTimer(mOwner->EventTarget()); NS_ENSURE_TRUE(mTimer, NS_ERROR_OUT_OF_MEMORY); uint32_t earlyMicros = 0; MOZ_ALWAYS_SUCCEEDS(mTimer->GetAllowedEarlyFiringMicroseconds(&earlyMicros)); mAllowedEarlyFiringTime = TimeDuration::FromMicroseconds(earlyMicros); + } else { + // Always call Cancel() in case we are re-using a timer. + rv = mTimer->Cancel(); + NS_ENSURE_SUCCESS(rv, rv); } - // Always call Cancel() in case we are re-using a timer. Otherwise - // the subsequent SetTarget() may fail. - rv = mTimer->Cancel(); - NS_ENSURE_SUCCESS(rv, rv); - - rv = mTimer->SetTarget(mOwner->EventTarget()); - NS_ENSURE_SUCCESS(rv, rv); - // Calculate the delay based on the deadline and current time. If we have // a minimum delay set then clamp to that value. // diff --git a/dom/file/FileReader.cpp b/dom/file/FileReader.cpp index e6451bb48c74..a8d5b472078a 100644 --- a/dom/file/FileReader.cpp +++ b/dom/file/FileReader.cpp @@ -531,14 +531,13 @@ void FileReader::StartProgressEventTimer() { if (!mProgressNotifier) { - mProgressNotifier = NS_NewTimer(); + mProgressNotifier = NS_NewTimer(mTarget); } if (mProgressNotifier) { mProgressEventWasDelayed = false; mTimerIsActive = true; mProgressNotifier->Cancel(); - mProgressNotifier->SetTarget(mTarget); mProgressNotifier->InitWithCallback(this, NS_PROGRESS_EVENT_INTERVAL, nsITimer::TYPE_ONE_SHOT); } diff --git a/dom/ipc/ContentParent.cpp b/dom/ipc/ContentParent.cpp index ca4a7f204172..4396f1170296 100644 --- a/dom/ipc/ContentParent.cpp +++ b/dom/ipc/ContentParent.cpp @@ -1592,7 +1592,7 @@ ContentParent::MarkAsDead() void ContentParent::OnChannelError() { - RefPtr content(this); + RefPtr kungFuDeathGrip(this); PContentParent::OnChannelError(); } @@ -1738,14 +1738,14 @@ struct DelayedDeleteContentParentTask : public Runnable { explicit DelayedDeleteContentParentTask(ContentParent* aObj) : Runnable("dom::DelayedDeleteContentParentTask") - , mObj(aObj) + , mKungFuDeathGrip(aObj) { } // No-op NS_IMETHOD Run() override { return NS_OK; } - RefPtr mObj; + RefPtr mKungFuDeathGrip; }; } // namespace diff --git a/dom/security/featurepolicy/FeaturePolicyUtils.cpp b/dom/security/featurepolicy/FeaturePolicyUtils.cpp index 27a3b18788c4..7c94600e4763 100644 --- a/dom/security/featurepolicy/FeaturePolicyUtils.cpp +++ b/dom/security/featurepolicy/FeaturePolicyUtils.cpp @@ -23,16 +23,16 @@ struct FeatureMap { */ static FeatureMap sSupportedFeatures[] = { { "autoplay", FeaturePolicyUtils::FeaturePolicyValue::eAll }, - { "camera", FeaturePolicyUtils::FeaturePolicyValue::eAll }, - { "encrypted-media", FeaturePolicyUtils::FeaturePolicyValue::eAll }, - { "fullscreen", FeaturePolicyUtils::FeaturePolicyValue::eAll }, - { "geolocation", FeaturePolicyUtils::FeaturePolicyValue::eAll }, - { "microphone", FeaturePolicyUtils::FeaturePolicyValue::eAll }, - { "midi", FeaturePolicyUtils::FeaturePolicyValue::eAll }, - { "payment", FeaturePolicyUtils::FeaturePolicyValue::eAll }, + { "camera", FeaturePolicyUtils::FeaturePolicyValue::eAll }, + { "encrypted-media", FeaturePolicyUtils::FeaturePolicyValue::eAll }, + { "fullscreen", FeaturePolicyUtils::FeaturePolicyValue::eAll }, + { "geolocation", FeaturePolicyUtils::FeaturePolicyValue::eAll }, + { "microphone", FeaturePolicyUtils::FeaturePolicyValue::eAll }, + { "midi", FeaturePolicyUtils::FeaturePolicyValue::eAll }, + { "payment", FeaturePolicyUtils::FeaturePolicyValue::eAll }, // TODO: not supported yet!!! - { "speaker", FeaturePolicyUtils::FeaturePolicyValue::eAll }, - { "vr", FeaturePolicyUtils::FeaturePolicyValue::eAll }, + { "speaker", FeaturePolicyUtils::FeaturePolicyValue::eAll }, + { "vr", FeaturePolicyUtils::FeaturePolicyValue::eAll }, }; /* static */ bool diff --git a/dom/xhr/XMLHttpRequestMainThread.cpp b/dom/xhr/XMLHttpRequestMainThread.cpp index 7cdd4ca86aae..556e180b1fed 100644 --- a/dom/xhr/XMLHttpRequestMainThread.cpp +++ b/dom/xhr/XMLHttpRequestMainThread.cpp @@ -3142,13 +3142,13 @@ XMLHttpRequestMainThread::SetTimeout(uint32_t aTimeout, ErrorResult& aRv) } } -void -XMLHttpRequestMainThread::SetTimerEventTarget(nsITimer* aTimer) +nsIEventTarget* +XMLHttpRequestMainThread::GetTimerEventTarget() { if (nsCOMPtr global = GetOwnerGlobal()) { - nsCOMPtr target = global->EventTargetFor(TaskCategory::Other); - aTimer->SetTarget(target); + return global->EventTargetFor(TaskCategory::Other); } + return nullptr; } nsresult @@ -3183,8 +3183,7 @@ XMLHttpRequestMainThread::StartTimeoutTimer() } if (!mTimeoutTimer) { - mTimeoutTimer = NS_NewTimer(); - SetTimerEventTarget(mTimeoutTimer); + mTimeoutTimer = NS_NewTimer(GetTimerEventTarget()); } uint32_t elapsed = (uint32_t)((PR_Now() - mRequestSentTime) / PR_USEC_PER_MSEC); @@ -3601,8 +3600,7 @@ void XMLHttpRequestMainThread::StartProgressEventTimer() { if (!mProgressNotifier) { - mProgressNotifier = NS_NewTimer(); - SetTimerEventTarget(mProgressNotifier); + mProgressNotifier = NS_NewTimer(GetTimerEventTarget()); } if (mProgressNotifier) { mProgressTimerIsActive = true; @@ -3628,8 +3626,7 @@ XMLHttpRequestMainThread::MaybeStartSyncTimeoutTimer() return eErrorOrExpired; } - mSyncTimeoutTimer = NS_NewTimer(); - SetTimerEventTarget(mSyncTimeoutTimer); + mSyncTimeoutTimer = NS_NewTimer(GetTimerEventTarget()); if (!mSyncTimeoutTimer) { return eErrorOrExpired; } diff --git a/dom/xhr/XMLHttpRequestMainThread.h b/dom/xhr/XMLHttpRequestMainThread.h index 1db9c353ae66..b8fb689ed646 100644 --- a/dom/xhr/XMLHttpRequestMainThread.h +++ b/dom/xhr/XMLHttpRequestMainThread.h @@ -514,7 +514,7 @@ protected: nsresult OnRedirectVerifyCallback(nsresult result); - void SetTimerEventTarget(nsITimer* aTimer); + nsIEventTarget* GetTimerEventTarget(); nsresult DispatchToMainThread(already_AddRefed aRunnable); diff --git a/gfx/thebes/gfxPlatform.cpp b/gfx/thebes/gfxPlatform.cpp index d51732a78d7b..eae46bebd0c6 100644 --- a/gfx/thebes/gfxPlatform.cpp +++ b/gfx/thebes/gfxPlatform.cpp @@ -737,6 +737,7 @@ WebRenderMemoryReporter::CollectReports(nsIHandleReportCallback* aHandleReport, helper.ReportTexture(aReport.vertex_data_textures, "vertex-data"); helper.ReportTexture(aReport.render_target_textures, "render-targets"); helper.ReportTexture(aReport.texture_cache_textures, "texture-cache"); + helper.ReportTexture(aReport.depth_target_textures, "depth-targets"); FinishAsyncMemoryReport(); }, diff --git a/gfx/webrender/res/brush.glsl b/gfx/webrender/res/brush.glsl index f8c7c387e373..d55e21c77351 100644 --- a/gfx/webrender/res/brush.glsl +++ b/gfx/webrender/res/brush.glsl @@ -22,6 +22,7 @@ void brush_vs( #define BRUSH_FLAG_SEGMENT_RELATIVE 2 #define BRUSH_FLAG_SEGMENT_REPEAT_X 4 #define BRUSH_FLAG_SEGMENT_REPEAT_Y 8 +#define BRUSH_FLAG_TEXEL_RECT 16 void main(void) { // Load the brush instance from vertex attributes. diff --git a/gfx/webrender/res/brush_image.glsl b/gfx/webrender/res/brush_image.glsl index 140c89b97204..768c6e10c9af 100644 --- a/gfx/webrender/res/brush_image.glsl +++ b/gfx/webrender/res/brush_image.glsl @@ -51,7 +51,7 @@ void brush_vs( mat4 transform, PictureTask pic_task, int brush_flags, - vec4 texel_rect + vec4 segment_data ) { ImageBrushData image_data = fetch_image_data(prim_address); @@ -76,19 +76,18 @@ void brush_vs( local_rect = segment_rect; stretch_size = local_rect.size; - // Note: Here we can assume that texels in device - // space map to local space, due to how border-image - // works. That assumption may not hold if this - // is used for other purposes in the future. if ((brush_flags & BRUSH_FLAG_SEGMENT_REPEAT_X) != 0) { - stretch_size.x = (texel_rect.z - texel_rect.x) / pic_task.common_data.device_pixel_scale; + stretch_size.x = (segment_data.z - segment_data.x); } if ((brush_flags & BRUSH_FLAG_SEGMENT_REPEAT_Y) != 0) { - stretch_size.y = (texel_rect.w - texel_rect.y) / pic_task.common_data.device_pixel_scale; + stretch_size.y = (segment_data.w - segment_data.y); } - uv0 = res.uv_rect.p0 + texel_rect.xy; - uv1 = res.uv_rect.p0 + texel_rect.zw; + // If the extra data is a texel rect, modify the UVs. + if ((brush_flags & BRUSH_FLAG_TEXEL_RECT) != 0) { + uv0 = res.uv_rect.p0 + segment_data.xy; + uv1 = res.uv_rect.p0 + segment_data.zw; + } } vUv.z = res.layer; diff --git a/gfx/webrender/res/ps_split_composite.glsl b/gfx/webrender/res/ps_split_composite.glsl index 6ed1f926c0f2..d3db7e9713a8 100644 --- a/gfx/webrender/res/ps_split_composite.glsl +++ b/gfx/webrender/res/ps_split_composite.glsl @@ -10,7 +10,6 @@ flat varying vec4 vUvSampleBounds; #ifdef WR_VERTEX_SHADER struct SplitGeometry { vec2 local[4]; - RectWithSize local_rect; }; SplitGeometry fetch_split_geometry(int address) { @@ -18,7 +17,6 @@ SplitGeometry fetch_split_geometry(int address) { vec4 data0 = TEXEL_FETCH(sGpuCache, uv, 0, ivec2(0, 0)); vec4 data1 = TEXEL_FETCH(sGpuCache, uv, 0, ivec2(1, 0)); - vec4 data2 = TEXEL_FETCH(sGpuCache, uv, 0, ivec2(2, 0)); SplitGeometry geo; geo.local = vec2[4]( @@ -27,7 +25,6 @@ SplitGeometry fetch_split_geometry(int address) { data1.xy, data1.zw ); - geo.local_rect = RectWithSize(data2.xy, data2.zw); return geo; } @@ -98,7 +95,7 @@ void main(void) { max_uv - vec2(0.5) ) / texture_size.xyxy; - vec2 f = (local_pos - geometry.local_rect.p0) / geometry.local_rect.size; + vec2 f = (local_pos - ph.local_rect.p0) / ph.local_rect.size; f = bilerp( extra_data.st_tl, extra_data.st_tr, diff --git a/gfx/webrender/src/batch.rs b/gfx/webrender/src/batch.rs index 231fc43191a9..61066fa0a0f0 100644 --- a/gfx/webrender/src/batch.rs +++ b/gfx/webrender/src/batch.rs @@ -20,12 +20,13 @@ use plane_split::{BspSplitter, Clipper, Polygon, Splitter}; use prim_store::{BrushKind, BrushPrimitive, BrushSegmentTaskId, DeferredResolve}; use prim_store::{EdgeAaSegmentMask, ImageSource, PrimitiveIndex}; use prim_store::{VisibleGradientTile, PrimitiveInstance}; -use prim_store::{BorderSource, Primitive, PrimitiveDetails}; +use prim_store::{BrushSegment, BorderSource, Primitive, PrimitiveDetails}; use render_task::{RenderTaskAddress, RenderTaskId, RenderTaskTree}; use renderer::{BlendMode, ImageBufferKind, ShaderColorMode}; use renderer::BLOCKS_PER_UV_RECT; use resource_cache::{CacheItem, GlyphFetchResult, ImageRequest, ResourceCache, ImageProperties}; use scene::FilterOpHelpers; +use smallvec::SmallVec; use std::{f32, i32, usize}; use tiling::{RenderTargetContext}; use util::{MatrixHelpers, TransformedRectKind}; @@ -419,6 +420,15 @@ impl AlphaBatchContainer { } } +/// Each segment can optionally specify a per-segment +/// texture set and one user data field. +#[derive(Debug, Copy, Clone)] +struct SegmentInstanceData { + textures: BatchTextures, + user_data: i32, + is_opaque_override: Option, +} + /// Encapsulates the logic of building batches for items that are blended. pub struct AlphaBatchBuilder { pub batch_list: BatchList, @@ -551,7 +561,6 @@ impl AlphaBatchBuilder { let gpu_blocks = [ [local_points[0].x, local_points[0].y, local_points[1].x, local_points[1].y].into(), [local_points[2].x, local_points[2].y, local_points[3].x, local_points[3].y].into(), - pic_metadata.local_rect.into(), ]; let gpu_handle = gpu_cache.push_per_frame_blocks(&gpu_blocks); @@ -1103,37 +1112,29 @@ impl AlphaBatchBuilder { ); } _ => { - // TODO(gw): As an interim step, just return one value for the - // per-segment user data. In the future, this method - // will be expanded to optionally return a list of - // (BatchTextures, user_data) per segment, which will - // allow a different texture / render task to be used - // per segment. - if let Some((batch_kind, textures, user_data, segment_user_data)) = brush.get_batch_params( - ctx.resource_cache, - gpu_cache, - deferred_resolves, - ctx.prim_store.chase_id == Some(prim_instance.prim_index), + if let Some(params) = brush.get_batch_params( + ctx.resource_cache, + gpu_cache, + deferred_resolves, + ctx.prim_store.chase_id == Some(prim_instance.prim_index), ) { - let prim_header_index = prim_headers.push(&prim_header, user_data); + let prim_header_index = prim_headers.push(&prim_header, params.prim_user_data); if cfg!(debug_assertions) && ctx.prim_store.chase_id == Some(prim_instance.prim_index) { println!("\t{:?} {:?}, task relative bounds {:?}", - batch_kind, prim_header_index, bounding_rect); + params.batch_kind, prim_header_index, bounding_rect); } self.add_brush_to_batch( brush, + ¶ms, prim_instance, - batch_kind, specified_blend_mode, non_segmented_blend_mode, - textures, prim_header_index, clip_task_address, bounding_rect, transform_kind, render_tasks, - segment_user_data, ); } } @@ -1270,80 +1271,147 @@ impl AlphaBatchBuilder { ); } + /// Add a single segment instance to a batch. + fn add_segment_to_batch( + &mut self, + segment: &BrushSegment, + segment_data: &SegmentInstanceData, + segment_index: i32, + batch_kind: BrushBatchKind, + prim_instance: &PrimitiveInstance, + prim_header_index: PrimitiveHeaderIndex, + alpha_blend_mode: BlendMode, + bounding_rect: &WorldRect, + transform_kind: TransformedRectKind, + render_tasks: &RenderTaskTree, + ) { + let clip_task_address = match segment.clip_task_id { + BrushSegmentTaskId::RenderTaskId(id) => + render_tasks.get_task_address(id), + BrushSegmentTaskId::Opaque => OPAQUE_TASK_ADDRESS, + BrushSegmentTaskId::Empty => return, + }; + + // If the segment instance data specifies opacity for that + // segment, use it. Otherwise, assume opacity for the segment + // from the overall primitive opacity. + let is_segment_opaque = match segment_data.is_opaque_override { + Some(is_opaque) => is_opaque, + None => prim_instance.opacity.is_opaque, + }; + + let is_inner = segment.edge_flags.is_empty(); + let needs_blending = !is_segment_opaque || + segment.clip_task_id.needs_blending() || + (!is_inner && transform_kind == TransformedRectKind::Complex); + + let instance = PrimitiveInstanceData::from(BrushInstance { + segment_index, + edge_flags: segment.edge_flags, + clip_task_address, + brush_flags: BrushFlags::PERSPECTIVE_INTERPOLATION | segment.brush_flags, + prim_header_index, + user_data: segment_data.user_data, + }); + + let batch_key = BatchKey { + blend_mode: if needs_blending { alpha_blend_mode } else { BlendMode::None }, + kind: BatchKind::Brush(batch_kind), + textures: segment_data.textures, + }; + + self.batch_list.push_single_instance( + batch_key, + bounding_rect, + prim_instance.prim_index, + instance, + ); + } + + /// Add any segment(s) from a brush to batches. fn add_brush_to_batch( &mut self, brush: &BrushPrimitive, + params: &BrushBatchParameters, prim_instance: &PrimitiveInstance, - batch_kind: BrushBatchKind, alpha_blend_mode: BlendMode, non_segmented_blend_mode: BlendMode, - textures: BatchTextures, prim_header_index: PrimitiveHeaderIndex, clip_task_address: RenderTaskAddress, bounding_rect: &WorldRect, transform_kind: TransformedRectKind, render_tasks: &RenderTaskTree, - user_data: i32, ) { - let base_instance = BrushInstance { - prim_header_index, - clip_task_address, - segment_index: 0, - edge_flags: EdgeAaSegmentMask::all(), - brush_flags: BrushFlags::PERSPECTIVE_INTERPOLATION, - user_data, - }; - - match brush.segment_desc { - Some(ref segment_desc) => { - for (i, segment) in segment_desc.segments.iter().enumerate() { - let is_inner = segment.edge_flags.is_empty(); - let needs_blending = !prim_instance.opacity.is_opaque || - segment.clip_task_id.needs_blending() || - (!is_inner && transform_kind == TransformedRectKind::Complex); - - let clip_task_address = match segment.clip_task_id { - BrushSegmentTaskId::RenderTaskId(id) => - render_tasks.get_task_address(id), - BrushSegmentTaskId::Opaque => OPAQUE_TASK_ADDRESS, - BrushSegmentTaskId::Empty => continue, - }; - - let instance = PrimitiveInstanceData::from(BrushInstance { - segment_index: i as i32, - edge_flags: segment.edge_flags, - clip_task_address, - brush_flags: base_instance.brush_flags | segment.brush_flags, - ..base_instance - }); - - let batch_key = BatchKey { - blend_mode: if needs_blending { alpha_blend_mode } else { BlendMode::None }, - kind: BatchKind::Brush(batch_kind), - textures, - }; - - self.batch_list.push_single_instance( - batch_key, + match (&brush.segment_desc, ¶ms.segment_data) { + (Some(ref segment_desc), SegmentDataKind::Instanced(ref segment_data)) => { + // In this case, we have both a list of segments, and a list of + // per-segment instance data. Zip them together to build batches. + debug_assert_eq!(segment_desc.segments.len(), segment_data.len()); + for (segment_index, (segment, segment_data)) in segment_desc.segments + .iter() + .zip(segment_data.iter()) + .enumerate() { + self.add_segment_to_batch( + segment, + segment_data, + segment_index as i32, + params.batch_kind, + prim_instance, + prim_header_index, + alpha_blend_mode, bounding_rect, - prim_instance.prim_index, - instance, + transform_kind, + render_tasks, ); } } - None => { + (Some(ref segment_desc), SegmentDataKind::Shared(ref segment_data)) => { + // A list of segments, but the per-segment data is common + // between all segments. + for (segment_index, segment) in segment_desc.segments + .iter() + .enumerate() { + self.add_segment_to_batch( + segment, + segment_data, + segment_index as i32, + params.batch_kind, + prim_instance, + prim_header_index, + alpha_blend_mode, + bounding_rect, + transform_kind, + render_tasks, + ); + } + } + (None, SegmentDataKind::Shared(ref segment_data)) => { + // No segments, and thus no per-segment instance data. let batch_key = BatchKey { blend_mode: non_segmented_blend_mode, - kind: BatchKind::Brush(batch_kind), - textures, + kind: BatchKind::Brush(params.batch_kind), + textures: segment_data.textures, }; + let instance = PrimitiveInstanceData::from(BrushInstance { + segment_index: 0, + edge_flags: EdgeAaSegmentMask::all(), + clip_task_address, + brush_flags: BrushFlags::PERSPECTIVE_INTERPOLATION, + prim_header_index, + user_data: segment_data.user_data, + }); self.batch_list.push_single_instance( batch_key, bounding_rect, prim_instance.prim_index, - PrimitiveInstanceData::from(base_instance), + PrimitiveInstanceData::from(instance), ); } + (None, SegmentDataKind::Instanced(..)) => { + // We should never hit the case where there are no segments, + // but a list of segment instance data. + unreachable!(); + } } } } @@ -1426,6 +1494,58 @@ fn get_image_tile_params( } } +/// Either a single texture / user data for all segments, +/// or a list of one per segment. +enum SegmentDataKind { + Shared(SegmentInstanceData), + Instanced(SmallVec<[SegmentInstanceData; 8]>), +} + +/// The parameters that are specific to a kind of brush, +/// used by the common method to add a brush to batches. +struct BrushBatchParameters { + batch_kind: BrushBatchKind, + prim_user_data: [i32; 3], + segment_data: SegmentDataKind, +} + +impl BrushBatchParameters { + /// This brush instance has a list of per-segment + /// instance data. + fn instanced( + batch_kind: BrushBatchKind, + prim_user_data: [i32; 3], + segment_data: SmallVec<[SegmentInstanceData; 8]>, + ) -> Self { + BrushBatchParameters { + batch_kind, + prim_user_data, + segment_data: SegmentDataKind::Instanced(segment_data), + } + } + + /// This brush instance shares the per-segment data + /// across all segments. + fn shared( + batch_kind: BrushBatchKind, + textures: BatchTextures, + prim_user_data: [i32; 3], + segment_user_data: i32, + ) -> Self { + BrushBatchParameters { + batch_kind, + prim_user_data, + segment_data: SegmentDataKind::Shared( + SegmentInstanceData { + textures, + user_data: segment_user_data, + is_opaque_override: None, + } + ), + } + } +} + impl BrushPrimitive { fn get_batch_params( &self, @@ -1433,7 +1553,7 @@ impl BrushPrimitive { gpu_cache: &mut GpuCache, deferred_resolves: &mut Vec, is_chased: bool, - ) -> Option<(BrushBatchKind, BatchTextures, [i32; 3], i32)> { + ) -> Option { match self.kind { BrushKind::Image { request, ref source, .. } => { let cache_item = match *source { @@ -1463,7 +1583,7 @@ impl BrushPrimitive { } else { let textures = BatchTextures::color(cache_item.texture_id); - Some(( + Some(BrushBatchParameters::shared( BrushBatchKind::Image(get_buffer_kind(cache_item.texture_id)), textures, [ @@ -1478,7 +1598,7 @@ impl BrushPrimitive { BrushKind::LineDecoration { ref handle, style, .. } => { match style { LineStyle::Solid => { - Some(( + Some(BrushBatchParameters::shared( BrushBatchKind::Solid, BatchTextures::no_texture(), [0; 3], @@ -1492,7 +1612,7 @@ impl BrushPrimitive { .get_cached_render_task(handle.as_ref().unwrap()); let cache_item = resource_cache.get_texture_cache_item(&rt_cache_entry.handle); let textures = BatchTextures::color(cache_item.texture_id); - Some(( + Some(BrushBatchParameters::shared( BrushBatchKind::Image(get_buffer_kind(cache_item.texture_id)), textures, [ @@ -1506,48 +1626,69 @@ impl BrushPrimitive { } } BrushKind::Border { ref source, .. } => { - let cache_item = match *source { + match *source { BorderSource::Image(request) => { - resolve_image( + let cache_item = resolve_image( request, resource_cache, gpu_cache, deferred_resolves, - ) - } - BorderSource::Border { ref handle, .. } => { - let rt_handle = match *handle { - Some(ref handle) => handle, - None => return None, - }; - let rt_cache_entry = resource_cache - .get_cached_render_task(rt_handle); - resource_cache.get_texture_cache_item(&rt_cache_entry.handle) - } - }; + ); - if cache_item.texture_id == TextureSource::Invalid { - None - } else { - let textures = BatchTextures::color(cache_item.texture_id); + if cache_item.texture_id == TextureSource::Invalid { + return None; + } - Some(( - BrushBatchKind::Image(get_buffer_kind(cache_item.texture_id)), - textures, - [ - ShaderColorMode::Image as i32, - RasterizationSpace::Local as i32, - 0, - ], - cache_item.uv_rect_handle.as_int(gpu_cache), - )) + let textures = BatchTextures::color(cache_item.texture_id); + + Some(BrushBatchParameters::shared( + BrushBatchKind::Image(get_buffer_kind(cache_item.texture_id)), + textures, + [ + ShaderColorMode::Image as i32, + RasterizationSpace::Local as i32, + 0, + ], + cache_item.uv_rect_handle.as_int(gpu_cache), + )) + } + BorderSource::Border { ref segments, .. } => { + let mut segment_data = SmallVec::new(); + + // Collect the segment instance data from each render + // task for each valid edge / corner of the border. + + for segment in segments { + let rt_cache_entry = resource_cache + .get_cached_render_task(segment.handle.as_ref().unwrap()); + let cache_item = resource_cache + .get_texture_cache_item(&rt_cache_entry.handle); + segment_data.push( + SegmentInstanceData { + textures: BatchTextures::color(cache_item.texture_id), + user_data: cache_item.uv_rect_handle.as_int(gpu_cache), + is_opaque_override: Some(segment.is_opaque), + } + ); + } + + Some(BrushBatchParameters::instanced( + BrushBatchKind::Image(ImageBufferKind::Texture2DArray), + [ + ShaderColorMode::Image as i32, + RasterizationSpace::Local as i32, + 0, + ], + segment_data, + )) + } } } BrushKind::Picture { .. } => { panic!("bug: get_batch_key is handled at higher level for pictures"); } BrushKind::Solid { .. } => { - Some(( + Some(BrushBatchParameters::shared( BrushBatchKind::Solid, BatchTextures::no_texture(), [0; 3], @@ -1555,7 +1696,7 @@ impl BrushPrimitive { )) } BrushKind::Clear => { - Some(( + Some(BrushBatchParameters::shared( BrushBatchKind::Solid, BatchTextures::no_texture(), [0; 3], @@ -1563,7 +1704,7 @@ impl BrushPrimitive { )) } BrushKind::RadialGradient { ref stops_handle, .. } => { - Some(( + Some(BrushBatchParameters::shared( BrushBatchKind::RadialGradient, BatchTextures::no_texture(), [ @@ -1575,7 +1716,7 @@ impl BrushPrimitive { )) } BrushKind::LinearGradient { ref stops_handle, .. } => { - Some(( + Some(BrushBatchParameters::shared( BrushBatchKind::LinearGradient, BatchTextures::no_texture(), [ @@ -1631,7 +1772,7 @@ impl BrushPrimitive { color_space, ); - Some(( + Some(BrushBatchParameters::shared( kind, textures, [ diff --git a/gfx/webrender/src/border.rs b/gfx/webrender/src/border.rs index 62eaf8bb9aa4..0733100439ad 100644 --- a/gfx/webrender/src/border.rs +++ b/gfx/webrender/src/border.rs @@ -4,15 +4,15 @@ use api::{BorderRadius, BorderSide, BorderStyle, ColorF, ColorU, DeviceRect, DeviceSize}; use api::{LayoutSideOffsets, LayoutSizeAu, LayoutPrimitiveInfo, LayoutToDeviceScale}; -use api::{DeviceVector2D, DevicePoint, DeviceIntSize, LayoutRect, LayoutSize, NormalBorder}; +use api::{DeviceVector2D, DevicePoint, LayoutRect, LayoutSize, NormalBorder, DeviceIntSize}; use api::{AuHelpers}; -use app_units::Au; use ellipse::Ellipse; -use euclid::SideOffsets2D; use display_list_flattener::DisplayListFlattener; use gpu_types::{BorderInstance, BorderSegment, BrushFlags}; -use prim_store::{BrushKind, BrushPrimitive, BrushSegment, BrushSegmentVec}; -use prim_store::{EdgeAaSegmentMask, PrimitiveContainer, ScrollNodeAndClipChain}; +use prim_store::{BorderSegmentInfo, BrushKind, BrushPrimitive, BrushSegment, BrushSegmentVec}; +use prim_store::{EdgeAaSegmentMask, PrimitiveContainer, ScrollNodeAndClipChain, BrushSegmentDescriptor}; +use render_task::{RenderTaskCacheKey, RenderTaskCacheKeyKind}; +use smallvec::SmallVec; use util::{lerp, RectHelpers}; // Using 2048 as the maximum radius in device space before which we @@ -93,38 +93,30 @@ impl From for BorderSideAu { } } +/// Cache key that uniquely identifies a border +/// edge in the render task cache. #[derive(Clone, Debug, Hash, PartialEq, Eq)] #[cfg_attr(feature = "capture", derive(Serialize))] #[cfg_attr(feature = "replay", derive(Deserialize))] -pub struct BorderCacheKey { - pub left: BorderSideAu, - pub right: BorderSideAu, - pub top: BorderSideAu, - pub bottom: BorderSideAu, - pub radius: BorderRadiusAu, - pub widths: SideOffsets2D, +pub struct BorderEdgeCacheKey { + pub side: BorderSideAu, + pub size: LayoutSizeAu, pub do_aa: bool, - pub scale: Au, + pub segment: BorderSegment, } -impl BorderCacheKey { - pub fn new(border: &NormalBorder, widths: &LayoutSideOffsets) -> Self { - BorderCacheKey { - left: border.left.into(), - top: border.top.into(), - right: border.right.into(), - bottom: border.bottom.into(), - widths: SideOffsets2D::new( - Au::from_f32_px(widths.top), - Au::from_f32_px(widths.right), - Au::from_f32_px(widths.bottom), - Au::from_f32_px(widths.left), - ), - radius: border.radius.into(), - do_aa: border.do_aa, - scale: Au(0), - } - } +/// Cache key that uniquely identifies a border +/// corner in the render task cache. +#[derive(Clone, Debug, Hash, PartialEq, Eq)] +#[cfg_attr(feature = "capture", derive(Serialize))] +#[cfg_attr(feature = "replay", derive(Deserialize))] +pub struct BorderCornerCacheKey { + pub widths: LayoutSizeAu, + pub radius: LayoutSizeAu, + pub side0: BorderSideAu, + pub side1: BorderSideAu, + pub segment: BorderSegment, + pub do_aa: bool, } pub fn ensure_no_corner_overlap( @@ -177,15 +169,16 @@ impl<'a> DisplayListFlattener<'a> { &mut self, info: &LayoutPrimitiveInfo, border: &NormalBorder, - widths: &LayoutSideOffsets, + widths: LayoutSideOffsets, clip_and_scroll: ScrollNodeAndClipChain, ) { let mut border = *border; ensure_no_corner_overlap(&mut border.radius, &info.rect); - let prim = BrushPrimitive::new( - BrushKind::new_border(border, *widths), - None, + let prim = create_normal_border_prim( + &info.rect, + border, + widths, ); self.add_primitive( @@ -199,6 +192,7 @@ impl<'a> DisplayListFlattener<'a> { pub trait BorderSideHelpers { fn border_color(&self, is_inner_border: bool) -> ColorF; + fn is_opaque(&self) -> bool; } impl BorderSideHelpers for BorderSide { @@ -227,6 +221,11 @@ impl BorderSideHelpers for BorderSide { let black = if lighter { 0.7 } else { 0.3 }; ColorF::new(black, black, black, self.color.a) } + + /// Returns true if all pixels in this border style are opaque. + fn is_opaque(&self) -> bool { + self.color.a >= 1.0 && self.style.is_opaque() + } } /// The kind of border corner clip. @@ -517,74 +516,6 @@ impl DotInfo { } } -#[derive(Debug)] -pub struct BorderSegmentInfo { - task_rect: DeviceRect, - segment: BorderSegment, - radius: DeviceSize, - widths: DeviceSize, -} - -bitflags! { - /// Whether we depend on the available size for the border (effectively in - /// the local rect of the primitive), and in which direction. - /// - /// Note that this relies on the corners being only dependent on the border - /// widths and radius. - /// - /// This is not just a single boolean to allow instance caching for border - /// boxes where one of the directions differ but not the one on the affected - /// border is. - /// - /// This allows sharing instances for stuff like paragraphs of different - /// heights separated by horizontal borders. - pub struct AvailableSizeDependence : u8 { - /// There's a dependence on the vertical direction, that is, at least - /// one of the right or left edges is dashed or dotted. - const VERTICAL = 1 << 0; - /// Same but for the horizontal direction. - const HORIZONTAL = 1 << 1; - } -} - -/// This is the data that describes a single border with (up to) four sides and -/// four corners. -/// -/// This object gets created for each border primitive at least once. Note, -/// however, that the instances this produces via `build_instances()` can and -/// will be shared by multiple borders, as long as they share the same cache -/// key. -/// -/// Segments, however, also get build once per primitive. -/// -/// So the important invariant to preserve when going through this code is that -/// the result of `build_instances()` would remain invariant for a given cache -/// key. -/// -/// That means, then, that `border_segments` can't depend at all on something -/// that isn't on the key like the available_size, while the brush segments can -/// (and will, since we skip painting empty segments caused by things like edges -/// getting constrained by huge border-radius). -/// -/// Note that the cache key is not only `BorderCacheKey`, but also a -/// `size` from `RenderTaskCacheKey`, which will always be zero unless -/// `available_size_dependence` is non-empty, which is effectively just dashed -/// and dotted borders for now, since the spacing between the dash and dots -/// changes depending on that size. -#[derive(Debug)] -pub struct BorderRenderTaskInfo { - pub border_segments: Vec, - pub size: DeviceIntSize, - pub available_size_dependence: AvailableSizeDependence, - do_aa: bool, -} - -#[derive(PartialEq, Eq)] -enum DependsOnAvailableSize { - No, - Yes, -} - /// Information needed to place and draw a border edge. #[derive(Debug)] struct EdgeInfo { @@ -592,24 +523,20 @@ struct EdgeInfo { local_offset: f32, /// Size of the edge in local space. local_size: f32, - /// Size in device pixels needed in the render task. - device_size: f32, - /// Whether this edge depends on the available size. - depends_on_available_size: bool, + /// Local stretch size for this edge (repeat past this). + stretch_size: f32, } impl EdgeInfo { fn new( local_offset: f32, local_size: f32, - device_size: f32, - depends_on_avail_size: DependsOnAvailableSize, + stretch_size: f32, ) -> Self { Self { local_offset, local_size, - device_size, - depends_on_available_size: depends_on_avail_size == DependsOnAvailableSize::Yes, + stretch_size, } } } @@ -645,11 +572,10 @@ fn get_edge_info( style: BorderStyle, side_width: f32, avail_size: f32, - scale: f32, ) -> EdgeInfo { // To avoid division by zero below. - if side_width <= 0.0 { - return EdgeInfo::new(0.0, 0.0, 0.0, DependsOnAvailableSize::No); + if side_width <= 0.0 || avail_size <= 0.0 { + return EdgeInfo::new(0.0, 0.0, 0.0); } match style { @@ -657,436 +583,233 @@ fn get_edge_info( // Basically, two times the dash size. let (half_dash, _num_half_dashes) = compute_half_dash(side_width, avail_size); - let device_size = (2.0 * 2.0 * half_dash * scale).round(); - EdgeInfo::new(0., avail_size, device_size, DependsOnAvailableSize::Yes) + let stretch_size = 2.0 * 2.0 * half_dash; + EdgeInfo::new(0., avail_size, stretch_size) } BorderStyle::Dotted => { let dot_and_space_size = 2.0 * side_width; if avail_size < dot_and_space_size * 0.75 { - return EdgeInfo::new(0.0, 0.0, 0.0, DependsOnAvailableSize::Yes); + return EdgeInfo::new(0.0, 0.0, 0.0); } let approx_dot_count = avail_size / dot_and_space_size; let dot_count = approx_dot_count.floor().max(1.0); let used_size = dot_count * dot_and_space_size; let extra_space = avail_size - used_size; - let device_size = dot_and_space_size * scale; + let stretch_size = dot_and_space_size; let offset = (extra_space * 0.5).round(); - EdgeInfo::new(offset, used_size, device_size, DependsOnAvailableSize::Yes) + EdgeInfo::new(offset, used_size, stretch_size) } _ => { - EdgeInfo::new(0.0, avail_size, 8.0, DependsOnAvailableSize::No) + EdgeInfo::new(0.0, avail_size, 8.0) } } } -impl BorderRenderTaskInfo { - pub fn new( - rect: &LayoutRect, - border: &NormalBorder, - widths: &LayoutSideOffsets, - scale: LayoutToDeviceScale, - brush_segments: &mut BrushSegmentVec, - ) -> Option { - let mut border_segments = Vec::new(); - - let dp_width_top = (widths.top * scale.0).ceil(); - let dp_width_bottom = (widths.bottom * scale.0).ceil(); - let dp_width_left = (widths.left * scale.0).ceil(); - let dp_width_right = (widths.right * scale.0).ceil(); - - let dp_corner_tl = (border.radius.top_left * scale).ceil(); - let dp_corner_tr = (border.radius.top_right * scale).ceil(); - let dp_corner_bl = (border.radius.bottom_left * scale).ceil(); - let dp_corner_br = (border.radius.bottom_right * scale).ceil(); - - let dp_size_tl = DeviceSize::new( - dp_corner_tl.width.max(dp_width_left), - dp_corner_tl.height.max(dp_width_top), - ); - let dp_size_tr = DeviceSize::new( - dp_corner_tr.width.max(dp_width_right), - dp_corner_tr.height.max(dp_width_top), - ); - let dp_size_br = DeviceSize::new( - dp_corner_br.width.max(dp_width_right), - dp_corner_br.height.max(dp_width_bottom), - ); - let dp_size_bl = DeviceSize::new( - dp_corner_bl.width.max(dp_width_left), - dp_corner_bl.height.max(dp_width_bottom), - ); - - let local_size_tl = LayoutSize::new( - border.radius.top_left.width.max(widths.left), - border.radius.top_left.height.max(widths.top), - ); - let local_size_tr = LayoutSize::new( - border.radius.top_right.width.max(widths.right), - border.radius.top_right.height.max(widths.top), - ); - let local_size_br = LayoutSize::new( - border.radius.bottom_right.width.max(widths.right), - border.radius.bottom_right.height.max(widths.bottom), - ); - let local_size_bl = LayoutSize::new( - border.radius.bottom_left.width.max(widths.left), - border.radius.bottom_left.height.max(widths.bottom), - ); - - let top_edge_info = get_edge_info( - border.top.style, - widths.top, - rect.size.width - local_size_tl.width - local_size_tr.width, - scale.0, - ); - let bottom_edge_info = get_edge_info( - border.bottom.style, - widths.bottom, - rect.size.width - local_size_bl.width - local_size_br.width, - scale.0, - ); - let inner_width = top_edge_info.device_size.max(bottom_edge_info.device_size).ceil(); - - let left_edge_info = get_edge_info( - border.left.style, - widths.left, - rect.size.height - local_size_tl.height - local_size_bl.height, - scale.0, - ); - let right_edge_info = get_edge_info( - border.right.style, - widths.right, - rect.size.height - local_size_tr.height - local_size_br.height, - scale.0, - ); - - let inner_height = left_edge_info.device_size.max(right_edge_info.device_size).ceil(); - - let size = DeviceSize::new( - dp_size_tl.width.max(dp_size_bl.width) + inner_width + dp_size_tr.width.max(dp_size_br.width), - dp_size_tl.height.max(dp_size_tr.height) + inner_height + dp_size_bl.height.max(dp_size_br.height), - ); - - if size.width == 0.0 || size.height == 0.0 { - return None; - } - - let mut size_dependence = AvailableSizeDependence::empty(); - if top_edge_info.depends_on_available_size || - bottom_edge_info.depends_on_available_size - { - size_dependence.insert(AvailableSizeDependence::HORIZONTAL); - } - - if left_edge_info.depends_on_available_size || - right_edge_info.depends_on_available_size - { - size_dependence.insert(AvailableSizeDependence::VERTICAL); - } - - add_edge_segment( - LayoutRect::from_floats( - rect.origin.x, - rect.origin.y + local_size_tl.height + left_edge_info.local_offset, - rect.origin.x + widths.left, - rect.origin.y + local_size_tl.height + left_edge_info.local_offset + left_edge_info.local_size, - ), - DeviceRect::from_floats( - 0.0, - dp_size_tl.height, - dp_width_left, - dp_size_tl.height + left_edge_info.device_size, - ), - &border.left, - BorderSegment::Left, - EdgeAaSegmentMask::LEFT | EdgeAaSegmentMask::RIGHT, - &mut border_segments, - BrushFlags::SEGMENT_RELATIVE | BrushFlags::SEGMENT_REPEAT_Y, - brush_segments, - ); - - add_edge_segment( - LayoutRect::from_floats( - rect.origin.x + local_size_tl.width + top_edge_info.local_offset, - rect.origin.y, - rect.origin.x + local_size_tl.width + top_edge_info.local_offset + top_edge_info.local_size, - rect.origin.y + widths.top, - ), - DeviceRect::from_floats( - dp_size_tl.width, - 0.0, - dp_size_tl.width + top_edge_info.device_size, - dp_width_top, - ), - &border.top, - BorderSegment::Top, - EdgeAaSegmentMask::TOP | EdgeAaSegmentMask::BOTTOM, - &mut border_segments, - BrushFlags::SEGMENT_RELATIVE | BrushFlags::SEGMENT_REPEAT_X, - brush_segments, - ); - - add_edge_segment( - LayoutRect::from_floats( - rect.origin.x + rect.size.width - widths.right, - rect.origin.y + local_size_tr.height + right_edge_info.local_offset, - rect.origin.x + rect.size.width, - rect.origin.y + local_size_tr.height + right_edge_info.local_offset + right_edge_info.local_size, - ), - DeviceRect::from_floats( - size.width - dp_width_right, - dp_size_tr.height, - size.width, - dp_size_tr.height + right_edge_info.device_size, - ), - &border.right, - BorderSegment::Right, - EdgeAaSegmentMask::RIGHT | EdgeAaSegmentMask::LEFT, - &mut border_segments, - BrushFlags::SEGMENT_RELATIVE | BrushFlags::SEGMENT_REPEAT_Y, - brush_segments, - ); - - add_edge_segment( - LayoutRect::from_floats( - rect.origin.x + local_size_bl.width + bottom_edge_info.local_offset, - rect.origin.y + rect.size.height - widths.bottom, - rect.origin.x + local_size_bl.width + bottom_edge_info.local_offset + bottom_edge_info.local_size, - rect.origin.y + rect.size.height, - ), - DeviceRect::from_floats( - dp_size_bl.width, - size.height - dp_width_bottom, - dp_size_bl.width + bottom_edge_info.device_size, - size.height, - ), - &border.bottom, - BorderSegment::Bottom, - EdgeAaSegmentMask::BOTTOM | EdgeAaSegmentMask::TOP, - &mut border_segments, - BrushFlags::SEGMENT_RELATIVE | BrushFlags::SEGMENT_REPEAT_X, - brush_segments, - ); - - add_corner_segment( - LayoutRect::from_floats( - rect.origin.x, - rect.origin.y, - rect.origin.x + local_size_tl.width, - rect.origin.y + local_size_tl.height, - ), - DeviceRect::from_floats( - 0.0, - 0.0, - dp_size_tl.width, - dp_size_tl.height, - ), - &border.left, - &border.top, - DeviceSize::new(dp_width_left, dp_width_top), - dp_corner_tl, - BorderSegment::TopLeft, - EdgeAaSegmentMask::TOP | EdgeAaSegmentMask::LEFT, - &mut border_segments, - brush_segments, - ); - - add_corner_segment( - LayoutRect::from_floats( - rect.origin.x + rect.size.width - local_size_tr.width, - rect.origin.y, - rect.origin.x + rect.size.width, - rect.origin.y + local_size_tr.height, - ), - DeviceRect::from_floats( - size.width - dp_size_tr.width, - 0.0, - size.width, - dp_size_tr.height, - ), - &border.top, - &border.right, - DeviceSize::new(dp_width_right, dp_width_top), - dp_corner_tr, - BorderSegment::TopRight, - EdgeAaSegmentMask::TOP | EdgeAaSegmentMask::RIGHT, - &mut border_segments, - brush_segments, - ); - - add_corner_segment( - LayoutRect::from_floats( - rect.origin.x + rect.size.width - local_size_br.width, - rect.origin.y + rect.size.height - local_size_br.height, - rect.origin.x + rect.size.width, - rect.origin.y + rect.size.height, - ), - DeviceRect::from_floats( - size.width - dp_size_br.width, - size.height - dp_size_br.height, - size.width, - size.height, - ), - &border.right, - &border.bottom, - DeviceSize::new(dp_width_right, dp_width_bottom), - dp_corner_br, - BorderSegment::BottomRight, - EdgeAaSegmentMask::BOTTOM | EdgeAaSegmentMask::RIGHT, - &mut border_segments, - brush_segments, - ); - - add_corner_segment( - LayoutRect::from_floats( - rect.origin.x, - rect.origin.y + rect.size.height - local_size_bl.height, - rect.origin.x + local_size_bl.width, - rect.origin.y + rect.size.height, - ), - DeviceRect::from_floats( - 0.0, - size.height - dp_size_bl.height, - dp_size_bl.width, - size.height, - ), - &border.bottom, - &border.left, - DeviceSize::new(dp_width_left, dp_width_bottom), - dp_corner_bl, - BorderSegment::BottomLeft, - EdgeAaSegmentMask::BOTTOM | EdgeAaSegmentMask::LEFT, - &mut border_segments, - brush_segments, - ); - - Some(BorderRenderTaskInfo { - border_segments, - size: size.to_i32(), - available_size_dependence: size_dependence, - do_aa: border.do_aa, - }) - } - - /// Returns the cache key size for this task, based on our available size - /// dependence computed earlier. - #[inline] - pub fn cache_key_size( - &self, - local_size: &LayoutSize, - scale: LayoutToDeviceScale, - ) -> DeviceIntSize { - let mut size = DeviceIntSize::zero(); - if self.available_size_dependence.is_empty() { - return size; - } - - let device_size = (*local_size * scale).to_i32(); - if self.available_size_dependence.contains(AvailableSizeDependence::VERTICAL) { - size.height = device_size.height; - } - if self.available_size_dependence.contains(AvailableSizeDependence::HORIZONTAL) { - size.width = device_size.width; - } - size - } - - pub fn build_instances(&self, border: &NormalBorder) -> Vec { - let mut instances = Vec::new(); - - for info in &self.border_segments { - let (side0, side1, flip0, flip1) = match info.segment { - BorderSegment::Left => (&border.left, &border.left, false, false), - BorderSegment::Top => (&border.top, &border.top, false, false), - BorderSegment::Right => (&border.right, &border.right, true, true), - BorderSegment::Bottom => (&border.bottom, &border.bottom, true, true), - BorderSegment::TopLeft => (&border.left, &border.top, false, false), - BorderSegment::TopRight => (&border.top, &border.right, false, true), - BorderSegment::BottomRight => (&border.right, &border.bottom, true, true), - BorderSegment::BottomLeft => (&border.bottom, &border.left, true, false), - }; - - let style0 = if side0.style.is_hidden() { - side1.style - } else { - side0.style - }; - let style1 = if side1.style.is_hidden() { - side0.style - } else { - side1.style - }; - - let color0 = side0.border_color(flip0); - let color1 = side1.border_color(flip1); - - add_segment( - info.task_rect, - style0, - style1, - color0, - color1, - info.segment, - &mut instances, - info.widths, - info.radius, - self.do_aa, - ); - } - - instances - } - - /// Computes the maximum scale that we allow for this set of border parameters. - /// capping the scale will result in rendering very large corners at a lower - /// resolution and stretching them, so they will have the right shape, but - /// blurrier. - pub fn get_max_scale( - radii: &BorderRadius, - widths: &LayoutSideOffsets - ) -> LayoutToDeviceScale { - let r = radii.top_left.width - .max(radii.top_left.height) - .max(radii.top_right.width) - .max(radii.top_right.height) - .max(radii.bottom_left.width) - .max(radii.bottom_left.height) - .max(radii.bottom_right.width) - .max(radii.bottom_right.height) - .max(widths.top) - .max(widths.bottom) - .max(widths.left) - .max(widths.right); - - LayoutToDeviceScale::new(MAX_BORDER_RESOLUTION as f32 / r) - } -} - -fn add_brush_segment( - image_rect: LayoutRect, - task_rect: DeviceRect, - brush_flags: BrushFlags, - edge_flags: EdgeAaSegmentMask, +/// Create the set of border segments and render task +/// cache keys for a given CSS border. +fn create_border_segments( + rect: &LayoutRect, + border: &NormalBorder, + widths: &LayoutSideOffsets, + border_segments: &mut SmallVec<[BorderSegmentInfo; 8]>, brush_segments: &mut BrushSegmentVec, ) { - if image_rect.size.width <= 0. || image_rect.size.width <= 0. { - return; - } - - brush_segments.push( - BrushSegment::new( - image_rect, - /* may_need_clip_mask = */ true, - edge_flags, - [ - task_rect.origin.x, - task_rect.origin.y, - task_rect.origin.x + task_rect.size.width, - task_rect.origin.y + task_rect.size.height, - ], - brush_flags, - ) + let local_size_tl = LayoutSize::new( + border.radius.top_left.width.max(widths.left), + border.radius.top_left.height.max(widths.top), ); + let local_size_tr = LayoutSize::new( + border.radius.top_right.width.max(widths.right), + border.radius.top_right.height.max(widths.top), + ); + let local_size_br = LayoutSize::new( + border.radius.bottom_right.width.max(widths.right), + border.radius.bottom_right.height.max(widths.bottom), + ); + let local_size_bl = LayoutSize::new( + border.radius.bottom_left.width.max(widths.left), + border.radius.bottom_left.height.max(widths.bottom), + ); + + let top_edge_info = get_edge_info( + border.top.style, + widths.top, + rect.size.width - local_size_tl.width - local_size_tr.width, + ); + let bottom_edge_info = get_edge_info( + border.bottom.style, + widths.bottom, + rect.size.width - local_size_bl.width - local_size_br.width, + ); + + let left_edge_info = get_edge_info( + border.left.style, + widths.left, + rect.size.height - local_size_tl.height - local_size_bl.height, + ); + let right_edge_info = get_edge_info( + border.right.style, + widths.right, + rect.size.height - local_size_tr.height - local_size_br.height, + ); + + add_edge_segment( + LayoutRect::from_floats( + rect.origin.x, + rect.origin.y + local_size_tl.height + left_edge_info.local_offset, + rect.origin.x + widths.left, + rect.origin.y + local_size_tl.height + left_edge_info.local_offset + left_edge_info.local_size, + ), + &left_edge_info, + border.left, + widths.left, + BorderSegment::Left, + EdgeAaSegmentMask::LEFT | EdgeAaSegmentMask::RIGHT, + brush_segments, + border_segments, + border.do_aa, + ); + add_edge_segment( + LayoutRect::from_floats( + rect.origin.x + local_size_tl.width + top_edge_info.local_offset, + rect.origin.y, + rect.origin.x + local_size_tl.width + top_edge_info.local_offset + top_edge_info.local_size, + rect.origin.y + widths.top, + ), + &top_edge_info, + border.top, + widths.top, + BorderSegment::Top, + EdgeAaSegmentMask::TOP | EdgeAaSegmentMask::BOTTOM, + brush_segments, + border_segments, + border.do_aa, + ); + add_edge_segment( + LayoutRect::from_floats( + rect.origin.x + rect.size.width - widths.right, + rect.origin.y + local_size_tr.height + right_edge_info.local_offset, + rect.origin.x + rect.size.width, + rect.origin.y + local_size_tr.height + right_edge_info.local_offset + right_edge_info.local_size, + ), + &right_edge_info, + border.right, + widths.right, + BorderSegment::Right, + EdgeAaSegmentMask::RIGHT | EdgeAaSegmentMask::LEFT, + brush_segments, + border_segments, + border.do_aa, + ); + add_edge_segment( + LayoutRect::from_floats( + rect.origin.x + local_size_bl.width + bottom_edge_info.local_offset, + rect.origin.y + rect.size.height - widths.bottom, + rect.origin.x + local_size_bl.width + bottom_edge_info.local_offset + bottom_edge_info.local_size, + rect.origin.y + rect.size.height, + ), + &bottom_edge_info, + border.bottom, + widths.bottom, + BorderSegment::Bottom, + EdgeAaSegmentMask::BOTTOM | EdgeAaSegmentMask::TOP, + brush_segments, + border_segments, + border.do_aa, + ); + + add_corner_segment( + LayoutRect::from_floats( + rect.origin.x, + rect.origin.y, + rect.origin.x + local_size_tl.width, + rect.origin.y + local_size_tl.height, + ), + border.left, + border.top, + LayoutSize::new(widths.left, widths.top), + border.radius.top_left, + BorderSegment::TopLeft, + EdgeAaSegmentMask::TOP | EdgeAaSegmentMask::LEFT, + brush_segments, + border_segments, + border.do_aa, + ); + add_corner_segment( + LayoutRect::from_floats( + rect.origin.x + rect.size.width - local_size_tr.width, + rect.origin.y, + rect.origin.x + rect.size.width, + rect.origin.y + local_size_tr.height, + ), + border.top, + border.right, + LayoutSize::new(widths.right, widths.top), + border.radius.top_right, + BorderSegment::TopRight, + EdgeAaSegmentMask::TOP | EdgeAaSegmentMask::RIGHT, + brush_segments, + border_segments, + border.do_aa, + ); + add_corner_segment( + LayoutRect::from_floats( + rect.origin.x + rect.size.width - local_size_br.width, + rect.origin.y + rect.size.height - local_size_br.height, + rect.origin.x + rect.size.width, + rect.origin.y + rect.size.height, + ), + border.right, + border.bottom, + LayoutSize::new(widths.right, widths.bottom), + border.radius.bottom_right, + BorderSegment::BottomRight, + EdgeAaSegmentMask::BOTTOM | EdgeAaSegmentMask::RIGHT, + brush_segments, + border_segments, + border.do_aa, + ); + add_corner_segment( + LayoutRect::from_floats( + rect.origin.x, + rect.origin.y + rect.size.height - local_size_bl.height, + rect.origin.x + local_size_bl.width, + rect.origin.y + rect.size.height, + ), + border.bottom, + border.left, + LayoutSize::new(widths.left, widths.bottom), + border.radius.bottom_left, + BorderSegment::BottomLeft, + EdgeAaSegmentMask::BOTTOM | EdgeAaSegmentMask::LEFT, + brush_segments, + border_segments, + border.do_aa, + ); +} + +/// Computes the maximum scale that we allow for this set of border parameters. +/// capping the scale will result in rendering very large corners at a lower +/// resolution and stretching them, so they will have the right shape, but +/// blurrier. +pub fn get_max_scale_for_border( + radii: &BorderRadius, + widths: &LayoutSideOffsets +) -> LayoutToDeviceScale { + let r = radii.top_left.width + .max(radii.top_left.height) + .max(radii.top_right.width) + .max(radii.top_right.height) + .max(radii.bottom_left.width) + .max(radii.bottom_left.height) + .max(radii.bottom_right.width) + .max(radii.bottom_right.height) + .max(widths.top) + .max(widths.bottom) + .max(widths.left) + .max(widths.right); + + LayoutToDeviceScale::new(MAX_BORDER_RESOLUTION as f32 / r) } fn add_segment( @@ -1209,17 +932,19 @@ fn add_segment( } } +/// Add a corner segment (if valid) to the list of +/// border segments for this primitive. fn add_corner_segment( image_rect: LayoutRect, - task_rect: DeviceRect, - side0: &BorderSide, - side1: &BorderSide, - widths: DeviceSize, - radius: DeviceSize, + side0: BorderSide, + side1: BorderSide, + widths: LayoutSize, + radius: LayoutSize, segment: BorderSegment, edge_flags: EdgeAaSegmentMask, - border_segments: &mut Vec, brush_segments: &mut BrushSegmentVec, + border_segments: &mut SmallVec<[BorderSegmentInfo; 8]>, + do_aa: bool, ) { if side0.color.a <= 0.0 && side1.color.a <= 0.0 { return; @@ -1233,31 +958,58 @@ fn add_corner_segment( return; } - border_segments.push(BorderSegmentInfo { - task_rect, - segment, - radius, - widths, - }); + if image_rect.size.width <= 0. || image_rect.size.height <= 0. { + return; + } - add_brush_segment( - image_rect, - task_rect, - BrushFlags::SEGMENT_RELATIVE, - edge_flags, - brush_segments, + let is_opaque = + side0.is_opaque() && + side1.is_opaque() && + radius.width <= 0.0 && + radius.height <= 0.0; + + brush_segments.push( + BrushSegment::new( + image_rect, + /* may_need_clip_mask = */ true, + edge_flags, + [0.0; 4], + BrushFlags::SEGMENT_RELATIVE, + ) ); + + border_segments.push(BorderSegmentInfo { + handle: None, + local_task_size: image_rect.size, + is_opaque, + cache_key: RenderTaskCacheKey { + size: DeviceIntSize::zero(), + kind: RenderTaskCacheKeyKind::BorderCorner( + BorderCornerCacheKey { + do_aa, + side0: side0.into(), + side1: side1.into(), + segment, + radius: radius.to_au(), + widths: widths.to_au(), + } + ), + }, + }); } +/// Add an edge segment (if valid) to the list of +/// border segments for this primitive. fn add_edge_segment( image_rect: LayoutRect, - task_rect: DeviceRect, - side: &BorderSide, + edge_info: &EdgeInfo, + side: BorderSide, + width: f32, segment: BorderSegment, edge_flags: EdgeAaSegmentMask, - border_segments: &mut Vec, - brush_flags: BrushFlags, brush_segments: &mut BrushSegmentVec, + border_segments: &mut SmallVec<[BorderSegmentInfo; 8]>, + do_aa: bool, ) { if side.color.a <= 0.0 { return; @@ -1267,18 +1019,141 @@ fn add_edge_segment( return; } - border_segments.push(BorderSegmentInfo { - task_rect, - segment, - radius: DeviceSize::zero(), - widths: task_rect.size, - }); + let (size, brush_flags) = match segment { + BorderSegment::Left | BorderSegment::Right => { + (LayoutSize::new(width, edge_info.stretch_size), BrushFlags::SEGMENT_REPEAT_Y) + } + BorderSegment::Top | BorderSegment::Bottom => { + (LayoutSize::new(edge_info.stretch_size, width), BrushFlags::SEGMENT_REPEAT_X) + } + _ => { + unreachable!(); + } + }; - add_brush_segment( - image_rect, - task_rect, - brush_flags, - edge_flags, - brush_segments, + if image_rect.size.width <= 0. || image_rect.size.height <= 0. { + return; + } + + let is_opaque = side.is_opaque(); + + brush_segments.push( + BrushSegment::new( + image_rect, + /* may_need_clip_mask = */ true, + edge_flags, + [0.0, 0.0, size.width, size.height], + BrushFlags::SEGMENT_RELATIVE | brush_flags, + ) ); + + border_segments.push(BorderSegmentInfo { + handle: None, + local_task_size: size, + is_opaque, + cache_key: RenderTaskCacheKey { + size: DeviceIntSize::zero(), + kind: RenderTaskCacheKeyKind::BorderEdge( + BorderEdgeCacheKey { + do_aa, + side: side.into(), + size: size.to_au(), + segment, + }, + ), + }, + }); +} + +/// Build the set of border instances needed to draw a border +/// segment into the render task cache. +pub fn build_border_instances( + cache_key: &RenderTaskCacheKey, + border: &NormalBorder, + scale: LayoutToDeviceScale, +) -> Vec { + let mut instances = Vec::new(); + + let (segment, widths, radius) = match cache_key.kind { + RenderTaskCacheKeyKind::BorderEdge(ref key) => { + (key.segment, LayoutSize::from_au(key.size), LayoutSize::zero()) + } + RenderTaskCacheKeyKind::BorderCorner(ref key) => { + (key.segment, LayoutSize::from_au(key.widths), LayoutSize::from_au(key.radius)) + } + _ => { + unreachable!(); + } + }; + + let (side0, side1, flip0, flip1) = match segment { + BorderSegment::Left => (&border.left, &border.left, false, false), + BorderSegment::Top => (&border.top, &border.top, false, false), + BorderSegment::Right => (&border.right, &border.right, true, true), + BorderSegment::Bottom => (&border.bottom, &border.bottom, true, true), + BorderSegment::TopLeft => (&border.left, &border.top, false, false), + BorderSegment::TopRight => (&border.top, &border.right, false, true), + BorderSegment::BottomRight => (&border.right, &border.bottom, true, true), + BorderSegment::BottomLeft => (&border.bottom, &border.left, true, false), + }; + + let style0 = if side0.style.is_hidden() { + side1.style + } else { + side0.style + }; + let style1 = if side1.style.is_hidden() { + side0.style + } else { + side1.style + }; + + let color0 = side0.border_color(flip0); + let color1 = side1.border_color(flip1); + + let widths = (widths * scale).ceil(); + let radius = (radius * scale).ceil(); + + add_segment( + DeviceRect::new(DevicePoint::zero(), cache_key.size.to_f32()), + style0, + style1, + color0, + color1, + segment, + &mut instances, + widths, + radius, + border.do_aa, + ); + + instances +} + +pub fn create_normal_border_prim( + local_rect: &LayoutRect, + border: NormalBorder, + widths: LayoutSideOffsets, +) -> BrushPrimitive { + let mut brush_segments = BrushSegmentVec::new(); + let mut border_segments = SmallVec::new(); + + create_border_segments( + local_rect, + &border, + &widths, + &mut border_segments, + &mut brush_segments, + ); + + BrushPrimitive::new( + BrushKind::new_border( + border, + widths, + border_segments, + ), + Some(BrushSegmentDescriptor { + segments: brush_segments, + }), + ) } diff --git a/gfx/webrender/src/clip_scroll_tree.rs b/gfx/webrender/src/clip_scroll_tree.rs index d105beb31200..1f4b9f3b1909 100644 --- a/gfx/webrender/src/clip_scroll_tree.rs +++ b/gfx/webrender/src/clip_scroll_tree.rs @@ -405,8 +405,8 @@ impl ClipScrollTree { pt.add_item(format!("scrollable_size: {:?}", scrolling_info.scrollable_size)); pt.add_item(format!("scroll offset: {:?}", scrolling_info.offset)); } - SpatialNodeType::ReferenceFrame(ref info) => { - pt.new_level(format!("ReferenceFrame {:?}", info.resolved_transform)); + SpatialNodeType::ReferenceFrame(ref _info) => { + pt.new_level(format!("ReferenceFrame")); pt.add_item(format!("index: {:?}", index)); } } diff --git a/gfx/webrender/src/device/gl.rs b/gfx/webrender/src/device/gl.rs index e87ae7b87325..5399eff1b56f 100644 --- a/gfx/webrender/src/device/gl.rs +++ b/gfx/webrender/src/device/gl.rs @@ -3,18 +3,19 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ use super::super::shader_source; -use api::{ColorF, ImageFormat}; +use api::{ColorF, ImageFormat, MemoryReport}; use api::{DeviceIntPoint, DeviceIntRect, DeviceUintRect, DeviceUintSize}; use api::TextureTarget; #[cfg(any(feature = "debug_renderer", feature="capture"))] use api::ImageDescriptor; use euclid::Transform3D; use gleam::gl; -use internal_types::{FastHashMap, RenderTargetInfo}; +use internal_types::{FastHashMap, LayerIndex, RenderTargetInfo}; use log::Level; use smallvec::SmallVec; use std::cell::RefCell; use std::cmp; +use std::collections::hash_map::Entry; use std::fs::File; use std::io::Read; use std::marker::PhantomData; @@ -442,9 +443,28 @@ pub struct Texture { width: u32, height: u32, filter: TextureFilter, - render_target: Option, - fbo_ids: Vec, - depth_rb: Option, + /// Framebuffer Objects, one for each layer of the texture, allowing this + /// texture to be rendered to. Empty if this texture is not used as a render + /// target. + fbos: Vec, + /// Same as the above, but with a depth buffer attached. + /// + /// FBOs are cheap to create but expensive to reconfigure (since doing so + /// invalidates framebuffer completeness caching). Moreover, rendering with + /// a depth buffer attached but the depth write+test disabled relies on the + /// driver to optimize it out of the rendering pass, which most drivers + /// probably do but, according to jgilbert, is best not to rely on. + /// + /// So we lazily generate a second list of FBOs with depth. This list is + /// empty if this texture is not used as a render target _or_ if it is, but + /// the depth buffer has never been requested. + /// + /// Note that we always fill fbos, and then lazily create fbos_with_depth + /// when needed. We could make both lazy (i.e. render targets would have one + /// or the other, but not both, unless they were actually used in both + /// configurations). But that would complicate a lot of logic in this module, + /// and FBOs are cheap enough to create. + fbos_with_depth: Vec, last_frame_used: FrameId, } @@ -453,10 +473,6 @@ impl Texture { DeviceUintSize::new(self.width, self.height) } - pub fn get_render_target_layer_count(&self) -> usize { - self.fbo_ids.len() - } - pub fn get_layer_count(&self) -> i32 { self.layer_count } @@ -470,17 +486,8 @@ impl Texture { self.filter } - #[cfg(any(feature = "debug_renderer", feature = "capture"))] - pub fn get_render_target(&self) -> Option { - self.render_target.clone() - } - - pub fn has_depth(&self) -> bool { - self.depth_rb.is_some() - } - - pub fn get_rt_info(&self) -> Option<&RenderTargetInfo> { - self.render_target.as_ref() + pub fn supports_depth(&self) -> bool { + !self.fbos_with_depth.is_empty() } pub fn used_in_frame(&self, frame_id: FrameId) -> bool { @@ -713,6 +720,22 @@ pub enum ShaderError { Link(String, String), // name, error message } +/// A refcounted depth target, which may be shared by multiple textures across +/// the device. +struct SharedDepthTarget { + /// The Render Buffer Object representing the depth target. + rbo_id: RBOId, + /// Reference count. When this drops to zero, the RBO is deleted. + refcount: usize, +} + +#[cfg(feature = "debug")] +impl Drop for SharedDepthTarget { + fn drop(&mut self) { + debug_assert!(thread::panicking() || self.refcount == 0); + } +} + pub struct Device { gl: Rc, // device state @@ -735,6 +758,12 @@ pub struct Device { bgra_format_internal: gl::GLuint, bgra_format_external: gl::GLuint, + /// Map from texture dimensions to shared depth buffers for render targets. + /// + /// Render targets often have the same width/height, so we can save memory + /// by sharing these across targets. + depth_targets: FastHashMap, + // debug inside_frame: bool, @@ -759,6 +788,35 @@ pub struct Device { extensions: Vec, } +/// Contains the parameters necessary to bind a texture-backed draw target. +#[derive(Clone, Copy)] +pub struct TextureDrawTarget<'a> { + /// The target texture. + pub texture: &'a Texture, + /// The slice within the texture array to draw to. + pub layer: LayerIndex, + /// Whether to draw with the texture's associated depth target. + pub with_depth: bool, +} + +/// Contains the parameters necessary to bind a texture-backed read target. +#[derive(Clone, Copy)] +pub struct TextureReadTarget<'a> { + /// The source texture. + pub texture: &'a Texture, + /// The slice within the texture array to read from. + pub layer: LayerIndex, +} + +impl<'a> From> for TextureReadTarget<'a> { + fn from(t: TextureDrawTarget<'a>) -> Self { + TextureReadTarget { + texture: t.texture, + layer: t.layer, + } + } +} + impl Device { pub fn new( gl: Rc, @@ -829,6 +887,8 @@ impl Device { bgra_format_internal, bgra_format_external, + depth_targets: FastHashMap::default(), + bound_textures: [0; 16], bound_program: 0, bound_vao: 0, @@ -1006,9 +1066,9 @@ impl Device { } } - pub fn bind_read_target(&mut self, texture_and_layer: Option<(&Texture, i32)>) { - let fbo_id = texture_and_layer.map_or(FBOId(self.default_read_fbo), |texture_and_layer| { - texture_and_layer.0.fbo_ids[texture_and_layer.1 as usize] + pub fn bind_read_target(&mut self, texture_target: Option) { + let fbo_id = texture_target.map_or(FBOId(self.default_read_fbo), |target| { + target.texture.fbos[target.layer] }); self.bind_read_target_impl(fbo_id) @@ -1025,11 +1085,15 @@ impl Device { pub fn bind_draw_target( &mut self, - texture_and_layer: Option<(&Texture, i32)>, + texture_target: Option, dimensions: Option, ) { - let fbo_id = texture_and_layer.map_or(FBOId(self.default_draw_fbo), |texture_and_layer| { - texture_and_layer.0.fbo_ids[texture_and_layer.1 as usize] + let fbo_id = texture_target.map_or(FBOId(self.default_draw_fbo), |target| { + if target.with_depth { + target.texture.fbos_with_depth[target.layer] + } else { + target.texture.fbos[target.layer] + } }); self.bind_draw_target_impl(fbo_id); @@ -1232,9 +1296,8 @@ impl Device { layer_count, format, filter, - render_target, - fbo_ids: vec![], - depth_rb: None, + fbos: vec![], + fbos_with_depth: vec![], last_frame_used: self.frame_id, }; self.bind_texture(DEFAULT_TEXTURE, &texture); @@ -1309,7 +1372,10 @@ impl Device { // Set up FBOs, if required. if let Some(rt_info) = render_target { - self.init_fbos(&mut texture, rt_info); + self.init_fbos(&mut texture, false); + if rt_info.has_depth { + self.init_fbos(&mut texture, true); + } } texture @@ -1349,7 +1415,7 @@ impl Device { debug_assert!(dst.height >= src.height); let rect = DeviceIntRect::new(DeviceIntPoint::zero(), src.get_dimensions().to_i32()); - for (read_fbo, draw_fbo) in src.fbo_ids.iter().zip(&dst.fbo_ids) { + for (read_fbo, draw_fbo) in src.fbos.iter().zip(&dst.fbos) { self.bind_read_target_impl(*read_fbo); self.bind_draw_target_impl(*draw_fbo); self.blit_render_target(rect, rect); @@ -1359,15 +1425,19 @@ impl Device { /// Notifies the device that the contents of a render target are no longer /// needed. + /// + /// FIXME(bholley): We could/should invalidate the depth targets earlier + /// than the color targets, i.e. immediately after each pass. pub fn invalidate_render_target(&mut self, texture: &Texture) { - let attachments: &[gl::GLenum] = if texture.has_depth() { - &[gl::COLOR_ATTACHMENT0, gl::DEPTH_ATTACHMENT] + let (fbos, attachments) = if texture.supports_depth() { + (&texture.fbos_with_depth, + &[gl::COLOR_ATTACHMENT0, gl::DEPTH_ATTACHMENT] as &[gl::GLenum]) } else { - &[gl::COLOR_ATTACHMENT0] + (&texture.fbos, &[gl::COLOR_ATTACHMENT0] as &[gl::GLenum]) }; let original_bound_fbo = self.bound_draw_fbo; - for fbo_id in texture.fbo_ids.iter() { + for fbo_id in fbos.iter() { // Note: The invalidate extension may not be supported, in which // case this is a no-op. That's ok though, because it's just a // hint. @@ -1386,42 +1456,28 @@ impl Device { rt_info: RenderTargetInfo, ) { texture.last_frame_used = self.frame_id; - texture.render_target = Some(rt_info); - // If the depth target requirements changed, just drop the FBOs and - // reinitialize. - // - // FIXME(bholley): I have a patch to do this better. - if rt_info.has_depth != texture.has_depth() { - self.deinit_fbos(texture); - self.init_fbos(texture, rt_info); + // Add depth support if needed. + if rt_info.has_depth && !texture.supports_depth() { + self.init_fbos(texture, true); } } - fn init_fbos(&mut self, texture: &mut Texture, rt_info: RenderTargetInfo) { - // Generate the FBOs. - assert!(texture.fbo_ids.is_empty()); - texture.fbo_ids.extend( - self.gl.gen_framebuffers(texture.layer_count).into_iter().map(FBOId) - ); + fn init_fbos(&mut self, texture: &mut Texture, with_depth: bool) { + let (fbos, depth_rb) = if with_depth { + let depth_target = self.acquire_depth_target(texture.get_dimensions()); + (&mut texture.fbos_with_depth, Some(depth_target)) + } else { + (&mut texture.fbos, None) + }; - // Optionally generate a depth target. - if rt_info.has_depth { - let renderbuffer_ids = self.gl.gen_renderbuffers(1); - let depth_rb = renderbuffer_ids[0]; - texture.depth_rb = Some(RBOId(depth_rb)); - self.gl.bind_renderbuffer(gl::RENDERBUFFER, depth_rb); - self.gl.renderbuffer_storage( - gl::RENDERBUFFER, - gl::DEPTH_COMPONENT24, - texture.width as _, - texture.height as _, - ); - } + // Generate the FBOs. + assert!(fbos.is_empty()); + fbos.extend(self.gl.gen_framebuffers(texture.layer_count).into_iter().map(FBOId)); // Bind the FBOs. let original_bound_fbo = self.bound_draw_fbo; - for (fbo_index, &fbo_id) in texture.fbo_ids.iter().enumerate() { + for (fbo_index, &fbo_id) in fbos.iter().enumerate() { self.bind_external_draw_target(fbo_id); match texture.target { gl::TEXTURE_2D_ARRAY => { @@ -1445,7 +1501,7 @@ impl Device { } } - if let Some(depth_rb) = texture.depth_rb { + if let Some(depth_rb) = depth_rb { self.gl.framebuffer_renderbuffer( gl::DRAW_FRAMEBUFFER, gl::DEPTH_ATTACHMENT, @@ -1457,15 +1513,9 @@ impl Device { self.bind_external_draw_target(original_bound_fbo); } - fn deinit_fbos(&mut self, texture: &mut Texture) { - if let Some(RBOId(depth_rb)) = texture.depth_rb.take() { - self.gl.delete_renderbuffers(&[depth_rb]); - texture.depth_rb = None; - } - - if !texture.fbo_ids.is_empty() { - let fbo_ids: Vec<_> = texture - .fbo_ids + fn deinit_fbos(&mut self, fbos: &mut Vec) { + if !fbos.is_empty() { + let fbo_ids: SmallVec<[gl::GLuint; 8]> = fbos .drain(..) .map(|FBOId(fbo_id)| fbo_id) .collect(); @@ -1473,6 +1523,40 @@ impl Device { } } + fn acquire_depth_target(&mut self, dimensions: DeviceUintSize) -> RBOId { + let gl = &self.gl; + let target = self.depth_targets.entry(dimensions).or_insert_with(|| { + let renderbuffer_ids = gl.gen_renderbuffers(1); + let depth_rb = renderbuffer_ids[0]; + gl.bind_renderbuffer(gl::RENDERBUFFER, depth_rb); + gl.renderbuffer_storage( + gl::RENDERBUFFER, + gl::DEPTH_COMPONENT24, + dimensions.width as _, + dimensions.height as _, + ); + SharedDepthTarget { + rbo_id: RBOId(depth_rb), + refcount: 0, + } + }); + target.refcount += 1; + target.rbo_id + } + + fn release_depth_target(&mut self, dimensions: DeviceUintSize) { + let mut entry = match self.depth_targets.entry(dimensions) { + Entry::Occupied(x) => x, + Entry::Vacant(..) => panic!("Releasing unknown depth target"), + }; + debug_assert!(entry.get().refcount != 0); + entry.get_mut().refcount -= 1; + if entry.get().refcount == 0 { + let t = entry.remove(); + self.gl.delete_renderbuffers(&[t.rbo_id.0]); + } + } + pub fn blit_render_target(&mut self, src_rect: DeviceIntRect, dest_rect: DeviceIntRect) { debug_assert!(self.inside_frame); @@ -1492,7 +1576,13 @@ impl Device { pub fn delete_texture(&mut self, mut texture: Texture) { debug_assert!(self.inside_frame); - self.deinit_fbos(&mut texture); + let had_depth = texture.supports_depth(); + self.deinit_fbos(&mut texture.fbos); + self.deinit_fbos(&mut texture.fbos_with_depth); + if had_depth { + self.release_depth_target(texture.get_dimensions()); + } + self.gl.delete_textures(&[texture.id]); for bound_texture in &mut self.bound_textures { @@ -2317,6 +2407,18 @@ impl Device { }, } } + + /// Generates a memory report for the resources managed by the device layer. + pub fn report_memory(&self) -> MemoryReport { + let mut report = MemoryReport::default(); + for dim in self.depth_targets.keys() { + // DEPTH24 textures generally reserve 3 bytes for depth and 1 byte + // for stencil, so we measure them as 32 bytes. + let pixels: u32 = dim.width * dim.height; + report.depth_target_textures += (pixels as usize) * 4; + } + report + } } struct FormatDesc { diff --git a/gfx/webrender/src/display_list_flattener.rs b/gfx/webrender/src/display_list_flattener.rs index 1f0aabc3ca84..7866cb879fa2 100644 --- a/gfx/webrender/src/display_list_flattener.rs +++ b/gfx/webrender/src/display_list_flattener.rs @@ -5,7 +5,7 @@ use api::{AlphaType, BorderDetails, BorderDisplayItem, BuiltDisplayListIter, ClipAndScrollInfo}; use api::{ClipId, ColorF, ComplexClipRegion, DeviceIntPoint, DeviceIntRect, DeviceIntSize}; -use api::{DevicePixelScale, DeviceUintRect, DisplayItemRef, ExtendMode, ExternalScrollId}; +use api::{DisplayItemRef, ExtendMode, ExternalScrollId}; use api::{FilterOp, FontInstanceKey, GlyphInstance, GlyphOptions, RasterSpace, GradientStop}; use api::{IframeDisplayItem, ImageKey, ImageRendering, ItemRange, LayoutPoint, ColorDepth}; use api::{LayoutPrimitiveInfo, LayoutRect, LayoutSize, LayoutTransform, LayoutVector2D}; @@ -32,7 +32,7 @@ use render_backend::{DocumentView}; use resource_cache::{FontInstanceMap, ImageRequest}; use scene::{Scene, ScenePipeline, StackingContextHelpers}; use scene_builder::DocumentResources; -use spatial_node::{SpatialNodeType, StickyFrameInfo}; +use spatial_node::{StickyFrameInfo}; use std::{f32, mem}; use std::collections::vec_deque::VecDeque; use tiling::{CompositeOps}; @@ -209,7 +209,6 @@ impl<'a> DisplayListFlattener<'a> { &root_pipeline.viewport_size, &root_pipeline.content_size, ); - flattener.setup_viewport_offset(view.inner_rect, view.accumulated_scale_factor()); flattener.flatten_root(root_pipeline, &root_pipeline.viewport_size); debug_assert!(flattener.sc_stack.is_empty()); @@ -1257,20 +1256,6 @@ impl<'a> DisplayListFlattener<'a> { index } - pub fn setup_viewport_offset( - &mut self, - inner_rect: DeviceUintRect, - device_pixel_scale: DevicePixelScale, - ) { - let viewport_offset = (inner_rect.origin.to_vector().to_f32() / device_pixel_scale).round(); - let root_id = self.clip_scroll_tree.root_reference_frame_index(); - let root_node = &mut self.clip_scroll_tree.spatial_nodes[root_id.0]; - if let SpatialNodeType::ReferenceFrame(ref mut info) = root_node.node_type { - info.resolved_transform = - LayoutVector2D::new(viewport_offset.x, viewport_offset.y).into(); - } - } - pub fn push_root( &mut self, pipeline_id: PipelineId, @@ -1484,7 +1469,10 @@ impl<'a> DisplayListFlattener<'a> { &info, pending_primitive.clip_and_scroll.clip_chain_id, pending_primitive.clip_and_scroll.spatial_node_index, - pending_primitive.container.create_shadow(&pending_shadow.shadow), + pending_primitive.container.create_shadow( + &pending_shadow.shadow, + &info.rect, + ), ); // Add the new primitive to the shadow picture. @@ -1687,7 +1675,9 @@ impl<'a> DisplayListFlattener<'a> { // Use segment relative interpolation for all // instances in this primitive. - let mut brush_flags = BrushFlags::SEGMENT_RELATIVE; + let mut brush_flags = + BrushFlags::SEGMENT_RELATIVE | + BrushFlags::SEGMENT_TEXEL_RECT; // Enable repeat modes on the segment. if repeat_horizontal == RepeatMode::Repeat { @@ -1845,7 +1835,12 @@ impl<'a> DisplayListFlattener<'a> { self.add_primitive(clip_and_scroll, info, Vec::new(), prim); } BorderDetails::Normal(ref border) => { - self.add_normal_border(info, border, &border_item.widths, clip_and_scroll); + self.add_normal_border( + info, + border, + border_item.widths, + clip_and_scroll, + ); } } } diff --git a/gfx/webrender/src/gpu_glyph_renderer.rs b/gfx/webrender/src/gpu_glyph_renderer.rs index 20d80093c16e..93697f06a2bc 100644 --- a/gfx/webrender/src/gpu_glyph_renderer.rs +++ b/gfx/webrender/src/gpu_glyph_renderer.rs @@ -7,7 +7,7 @@ use api::{DeviceIntPoint, DeviceIntRect, DeviceUintSize, FontRenderMode}; use api::{ImageFormat, TextureTarget}; use debug_colors; -use device::{Device, Texture, TextureFilter, VAO}; +use device::{Device, Texture, TextureDrawTarget, TextureFilter, VAO}; use euclid::{Point2D, Size2D, Transform3D, TypedVector2D, Vector2D}; use internal_types::RenderTargetInfo; use pathfinder_gfx_utils::ShelfBinPacker; @@ -194,7 +194,11 @@ impl Renderer { projection, &mut self.renderer_errors); - self.device.bind_draw_target(Some((¤t_page.texture, 0)), Some(*target_size)); + self.device.bind_draw_target(Some(TextureDrawTarget { + texture: ¤t_page.texture, + layer: 0, + with_depth: false, + }), Some(*target_size)); self.device.clear_target(Some([0.0, 0.0, 0.0, 0.0]), None, None); self.device.set_blend(true); diff --git a/gfx/webrender/src/gpu_types.rs b/gfx/webrender/src/gpu_types.rs index 2ab663c539c9..59c8690ed44a 100644 --- a/gfx/webrender/src/gpu_types.rs +++ b/gfx/webrender/src/gpu_types.rs @@ -89,7 +89,7 @@ pub struct ScalingInstance { pub src_task_address: RenderTaskAddress, } -#[derive(Debug, Copy, Clone, PartialEq)] +#[derive(Copy, Clone, Debug, Hash, PartialEq, Eq)] #[repr(C)] #[cfg_attr(feature = "capture", derive(Serialize))] #[cfg_attr(feature = "replay", derive(Deserialize))] @@ -318,6 +318,8 @@ bitflags! { const SEGMENT_REPEAT_X = 0x4; /// Repeat UVs vertically. const SEGMENT_REPEAT_Y = 0x8; + /// The extra segment data is a texel rect. + const SEGMENT_TEXEL_RECT = 0x10; } } diff --git a/gfx/webrender/src/internal_types.rs b/gfx/webrender/src/internal_types.rs index 176332cff45d..579763081291 100644 --- a/gfx/webrender/src/internal_types.rs +++ b/gfx/webrender/src/internal_types.rs @@ -38,6 +38,19 @@ pub type FastHashSet = HashSet>; #[cfg_attr(feature = "replay", derive(Deserialize))] pub struct CacheTextureId(pub u64); +/// Canonical type for texture layer indices. +/// +/// WebRender is currently not very consistent about layer index types. Some +/// places use i32 (since that's the type used in various OpenGL APIs), some +/// places use u32 (since having it be signed is non-sensical, but the +/// underlying graphics APIs generally operate on 32-bit integers) and some +/// places use usize (since that's most natural in Rust). +/// +/// Going forward, we aim to us usize throughout the codebase, since that allows +/// operations like indexing without a cast, and convert to the required type in +/// the device module when making calls into the platform layer. +pub type LayerIndex = usize; + /// Identifies a render pass target that is persisted until the end of the frame. /// /// By default, only the targets of the immediately-preceding pass are bound as diff --git a/gfx/webrender/src/platform/windows/font.rs b/gfx/webrender/src/platform/windows/font.rs index a476947762c6..ac90e0d5c234 100644 --- a/gfx/webrender/src/platform/windows/font.rs +++ b/gfx/webrender/src/platform/windows/font.rs @@ -131,9 +131,20 @@ impl FontContext { } let system_fc = dwrote::FontCollection::system(); - let font = match system_fc.get_font_from_descriptor(&font_handle) { - Some(font) => font, - None => { panic!("missing descriptor {:?}", font_handle) } + // A version of get_font_from_descriptor() that panics early to help with bug 1455848 + let font = if let Some(family) = system_fc.get_font_family_by_name(&font_handle.family_name) { + let font = family.get_first_matching_font(font_handle.weight, font_handle.stretch, font_handle.style); + // Exact matches only here + if font.weight() == font_handle.weight && + font.stretch() == font_handle.stretch && + font.style() == font_handle.style + { + font + } else { + panic!("font mismatch for descriptor {:?} {:?}", font_handle, font.to_descriptor()) + } + } else { + panic!("missing font family for descriptor {:?}", font_handle) }; let face = font.create_font_face(); self.fonts.insert(*font_key, face); diff --git a/gfx/webrender/src/prim_store.rs b/gfx/webrender/src/prim_store.rs index 5f3bbe3203ea..cbe3b9b4cc75 100644 --- a/gfx/webrender/src/prim_store.rs +++ b/gfx/webrender/src/prim_store.rs @@ -7,10 +7,10 @@ use api::{DeviceIntRect, DeviceIntSize, DevicePixelScale, ExtendMode, DeviceRect use api::{FilterOp, GlyphInstance, GradientStop, ImageKey, ImageRendering, ItemRange, TileOffset}; use api::{RasterSpace, LayoutPoint, LayoutRect, LayoutSideOffsets, LayoutSize, LayoutToWorldTransform}; use api::{LayoutVector2D, PremultipliedColorF, PropertyBinding, Shadow, YuvColorSpace, YuvFormat}; -use api::{DeviceIntSideOffsets, WorldPixel, BoxShadowClipMode, LayoutToWorldScale, NormalBorder, WorldRect}; +use api::{DeviceIntSideOffsets, WorldPixel, BoxShadowClipMode, NormalBorder, WorldRect, LayoutToWorldScale}; use api::{PicturePixel, RasterPixel, ColorDepth, LineStyle, LineOrientation, LayoutSizeAu, AuHelpers}; use app_units::Au; -use border::{BorderCacheKey, BorderRenderTaskInfo}; +use border::{get_max_scale_for_border, build_border_instances, create_normal_border_prim}; use clip_scroll_tree::{ClipScrollTree, CoordinateSystemId, SpatialNodeIndex}; use clip::{ClipNodeFlags, ClipChainId, ClipChainInstance, ClipItem, ClipNodeCollector}; use euclid::{TypedTransform3D, TypedRect, TypedScale}; @@ -25,7 +25,7 @@ use intern; use picture::{PictureCompositeMode, PicturePrimitive}; #[cfg(debug_assertions)] use render_backend::FrameId; -use render_task::{BlitSource, RenderTask, RenderTaskCacheKey}; +use render_task::{BlitSource, RenderTask, RenderTaskCacheKey, to_cache_size}; use render_task::{RenderTaskCacheKeyKind, RenderTaskId, RenderTaskCacheEntryHandle}; use renderer::{MAX_VERTEX_TEXTURE_WIDTH}; use resource_cache::{ImageProperties, ImageRequest, ResourceCache}; @@ -345,13 +345,21 @@ pub struct VisibleGradientTile { pub local_clip_rect: LayoutRect, } +/// Information about how to cache a border segment, +/// along with the current render task cache entry. +#[derive(Debug)] +pub struct BorderSegmentInfo { + pub handle: Option, + pub local_task_size: LayoutSize, + pub cache_key: RenderTaskCacheKey, + pub is_opaque: bool, +} + #[derive(Debug)] pub enum BorderSource { Image(ImageRequest), Border { - handle: Option, - cache_key: BorderCacheKey, - task_info: Option, + segments: SmallVec<[BorderSegmentInfo; 8]>, border: NormalBorder, widths: LayoutSideOffsets, }, @@ -456,18 +464,19 @@ impl BrushKind { // Construct a brush that is a border with `border` style and `widths` // dimensions. - pub fn new_border(mut border: NormalBorder, widths: LayoutSideOffsets) -> BrushKind { + pub fn new_border( + mut border: NormalBorder, + widths: LayoutSideOffsets, + segments: SmallVec<[BorderSegmentInfo; 8]>, + ) -> BrushKind { // FIXME(emilio): Is this the best place to do this? border.normalize(&widths); - let cache_key = BorderCacheKey::new(&border, &widths); BrushKind::Border { source: BorderSource::Border { border, widths, - cache_key, - task_info: None, - handle: None, + segments, } } } @@ -1412,7 +1421,11 @@ impl PrimitiveContainer { // Create a clone of this PrimitiveContainer, applying whatever // changes are necessary to the primitive to support rendering // it as part of the supplied shadow. - pub fn create_shadow(&self, shadow: &Shadow) -> PrimitiveContainer { + pub fn create_shadow( + &self, + shadow: &Shadow, + prim_rect: &LayoutRect, + ) -> PrimitiveContainer { match *self { PrimitiveContainer::TextRun(ref info) => { let mut font = FontInstance { @@ -1440,22 +1453,25 @@ impl PrimitiveContainer { )) } BrushKind::Border { ref source } => { - let source = match *source { + let prim = match *source { BorderSource::Image(request) => { - BrushKind::Border { - source: BorderSource::Image(request) - } - }, + BrushPrimitive::new( + BrushKind::Border { + source: BorderSource::Image(request) + }, + None, + ) + } BorderSource::Border { border, widths, .. } => { let border = border.with_color(shadow.color); - BrushKind::new_border(border, widths) - + create_normal_border_prim( + prim_rect, + border, + widths, + ) } }; - PrimitiveContainer::Brush(BrushPrimitive::new( - source, - None, - )) + PrimitiveContainer::Brush(prim) } BrushKind::LineDecoration { style, orientation, wavy_line_thickness, .. } => { PrimitiveContainer::Brush(BrushPrimitive::new_line_decoration( @@ -1960,13 +1976,6 @@ impl PrimitiveStore { prim_instance.clipped_world_rect = Some(clipped_world_rect); - prim.build_prim_segments_if_needed( - prim_instance, - pic_state, - frame_state, - frame_context, - ); - prim.update_clip_task( prim_instance, prim_context, @@ -2839,9 +2848,46 @@ impl Primitive { ); } } - BorderSource::Border { .. } => { - // Handled earlier since we need to update the segment - // descriptor *before* update_clip_task() is called. + BorderSource::Border { ref border, ref widths, ref mut segments, .. } => { + // TODO(gw): When drawing in screen raster mode, we should also incorporate a + // scale factor from the world transform to get an appropriately + // sized border task. + let world_scale = LayoutToWorldScale::new(1.0); + let mut scale = world_scale * frame_context.device_pixel_scale; + let max_scale = get_max_scale_for_border(&border.radius, widths); + scale.0 = scale.0.min(max_scale.0); + + // For each edge and corner, request the render task by content key + // from the render task cache. This ensures that the render task for + // this segment will be available for batching later in the frame. + for segment in segments { + // Update the cache key device size based on requested scale. + segment.cache_key.size = to_cache_size(segment.local_task_size * scale); + + segment.handle = Some(frame_state.resource_cache.request_render_task( + segment.cache_key.clone(), + frame_state.gpu_cache, + frame_state.render_tasks, + None, + segment.is_opaque, + |render_tasks| { + let task = RenderTask::new_border_segment( + segment.cache_key.size, + build_border_instances( + &segment.cache_key, + border, + scale, + ), + ); + + let task_id = render_tasks.add(task); + + pic_state.tasks.push(task_id); + + task_id + } + )); + } } } } @@ -3092,95 +3138,6 @@ impl Primitive { } } } - - fn build_prim_segments_if_needed( - &mut self, - prim_instance: &mut PrimitiveInstance, - pic_state: &mut PictureState, - frame_state: &mut FrameBuildingState, - frame_context: &FrameBuildingContext, - ) { - let brush = match self.details { - PrimitiveDetails::Brush(ref mut brush) => brush, - PrimitiveDetails::TextRun(..) => return, - }; - - if let BrushKind::Border { - source: BorderSource::Border { - ref border, - ref mut cache_key, - ref widths, - ref mut handle, - ref mut task_info, - .. - } - } = brush.kind { - // TODO(gw): When drawing in screen raster mode, we should also incorporate a - // scale factor from the world transform to get an appropriately - // sized border task. - let world_scale = LayoutToWorldScale::new(1.0); - let mut scale = world_scale * frame_context.device_pixel_scale; - let max_scale = BorderRenderTaskInfo::get_max_scale(&border.radius, &widths); - scale.0 = scale.0.min(max_scale.0); - let scale_au = Au::from_f32_px(scale.0); - - // NOTE(emilio): This `needs_update` relies on the local rect for a - // given primitive being immutable. If that changes, this code - // should probably handle changes to it as well, retaining the old - // size in cache_key. - let needs_update = scale_au != cache_key.scale; - - let mut new_segments = BrushSegmentVec::new(); - - let local_rect = &self.metadata.local_rect; - if needs_update { - cache_key.scale = scale_au; - - *task_info = BorderRenderTaskInfo::new( - local_rect, - border, - widths, - scale, - &mut new_segments, - ); - } - - *handle = task_info.as_ref().map(|task_info| { - frame_state.resource_cache.request_render_task( - RenderTaskCacheKey { - size: task_info.cache_key_size(&local_rect.size, scale), - kind: RenderTaskCacheKeyKind::Border(cache_key.clone()), - }, - frame_state.gpu_cache, - frame_state.render_tasks, - None, - false, // todo - |render_tasks| { - let task = RenderTask::new_border( - task_info.size, - task_info.build_instances(border), - ); - - let task_id = render_tasks.add(task); - - pic_state.tasks.push(task_id); - - task_id - } - ) - }); - - if needs_update { - brush.segment_desc = Some(BrushSegmentDescriptor { - segments: new_segments, - }); - - // The segments have changed, so force the GPU cache to - // re-upload the primitive information. - frame_state.gpu_cache.invalidate(&mut prim_instance.gpu_location); - } - } - } } pub fn get_raster_rects( diff --git a/gfx/webrender/src/render_backend.rs b/gfx/webrender/src/render_backend.rs index 8211fa91edd0..7af23bdc008c 100644 --- a/gfx/webrender/src/render_backend.rs +++ b/gfx/webrender/src/render_backend.rs @@ -277,6 +277,12 @@ impl Document { FrameMsg::AppendDynamicProperties(property_bindings) => { self.dynamic_properties.add_properties(property_bindings); } + FrameMsg::SetPinchZoom(factor) => { + if self.view.pinch_zoom_factor != factor.get() { + self.view.pinch_zoom_factor = factor.get(); + self.frame_is_valid = false; + } + } } DocumentOps::nop() @@ -508,9 +514,6 @@ impl RenderBackend { SceneMsg::SetPageZoom(factor) => { doc.view.page_zoom_factor = factor.get(); } - SceneMsg::SetPinchZoom(factor) => { - doc.view.pinch_zoom_factor = factor.get(); - } SceneMsg::SetWindowParameters { window_size, inner_rect, diff --git a/gfx/webrender/src/render_task.rs b/gfx/webrender/src/render_task.rs index f2c679e7b3a6..fbf3f2b7475e 100644 --- a/gfx/webrender/src/render_task.rs +++ b/gfx/webrender/src/render_task.rs @@ -7,7 +7,7 @@ use api::{DevicePixelScale, ImageDescriptor, ImageFormat}; use api::{LineStyle, LineOrientation, LayoutSize}; #[cfg(feature = "pathfinder")] use api::FontRenderMode; -use border::BorderCacheKey; +use border::{BorderCornerCacheKey, BorderEdgeCacheKey}; use box_shadow::{BoxShadowCacheKey}; use clip::{ClipDataStore, ClipItem, ClipStore, ClipNodeRange}; use clip_scroll_tree::SpatialNodeIndex; @@ -18,7 +18,7 @@ use freelist::{FreeList, FreeListHandle, WeakFreeListHandle}; use glyph_rasterizer::GpuGlyphCacheKey; use gpu_cache::{GpuCache, GpuCacheAddress, GpuCacheHandle}; use gpu_types::{BorderInstance, ImageSource, UvRectKind}; -use internal_types::{CacheTextureId, FastHashMap, SavedTargetIndex}; +use internal_types::{CacheTextureId, FastHashMap, LayerIndex, SavedTargetIndex}; #[cfg(feature = "pathfinder")] use pathfinder_partitioner::mesh::Mesh; use picture::PictureCacheKey; @@ -113,7 +113,7 @@ impl RenderTaskTree { debug_assert!(pass_index == passes.len() - 1); } RenderTaskLocation::Dynamic(..) | - RenderTaskLocation::TextureCache(..) => { + RenderTaskLocation::TextureCache { .. } => { debug_assert!(pass_index < passes.len() - 1); } } @@ -192,7 +192,14 @@ pub enum RenderTaskLocation { Dynamic(Option<(DeviceIntPoint, RenderTargetIndex)>, DeviceIntSize), /// The output of the `RenderTask` will be persisted beyond this frame, and /// thus should be drawn into the `TextureCache`. - TextureCache(CacheTextureId, i32, DeviceIntRect), + TextureCache { + /// Which texture in the texture cache should be drawn into. + texture: CacheTextureId, + /// The target layer in the above texture. + layer: LayerIndex, + /// The target region within the above layer. + rect: DeviceIntRect, + }, } #[derive(Debug)] @@ -386,7 +393,7 @@ impl RenderTask { let size = match location { RenderTaskLocation::Dynamic(_, size) => size, RenderTaskLocation::Fixed(rect) => rect.size, - RenderTaskLocation::TextureCache(_, _, rect) => rect.size, + RenderTaskLocation::TextureCache { rect, .. } => rect.size, }; render_task_sanity_check(&size); @@ -655,7 +662,7 @@ impl RenderTask { ) } - pub fn new_border( + pub fn new_border_segment( size: DeviceIntSize, instances: Vec, ) -> Self { @@ -839,7 +846,7 @@ impl RenderTask { match self.location { RenderTaskLocation::Fixed(..) => DeviceIntSize::zero(), RenderTaskLocation::Dynamic(_, size) => size, - RenderTaskLocation::TextureCache(_, _, rect) => rect.size, + RenderTaskLocation::TextureCache { rect, .. } => rect.size, } } @@ -868,7 +875,7 @@ impl RenderTask { RenderTaskLocation::Dynamic(None, _) => { (DeviceIntRect::zero(), RenderTargetIndex(0)) } - RenderTaskLocation::TextureCache(_, layer, rect) => { + RenderTaskLocation::TextureCache {layer, rect, .. } => { (rect, RenderTargetIndex(layer as usize)) } } @@ -1044,7 +1051,7 @@ impl RenderTask { RenderTaskLocation::Dynamic(..) => { self.saved_index = Some(SavedTargetIndex::PENDING); } - RenderTaskLocation::TextureCache(..) => { + RenderTaskLocation::TextureCache { .. } => { panic!("Unable to mark a permanently cached task for saving!"); } } @@ -1060,7 +1067,8 @@ pub enum RenderTaskCacheKeyKind { #[allow(dead_code)] Glyph(GpuGlyphCacheKey), Picture(PictureCacheKey), - Border(BorderCacheKey), + BorderEdge(BorderEdgeCacheKey), + BorderCorner(BorderCornerCacheKey), LineDecoration(LineDecorationCacheKey), } @@ -1161,7 +1169,7 @@ impl RenderTaskCache { // Find out what size to alloc in the texture cache. let size = match render_task.location { RenderTaskLocation::Fixed(..) | - RenderTaskLocation::TextureCache(..) => { + RenderTaskLocation::TextureCache { .. } => { panic!("BUG: dynamic task was expected"); } RenderTaskLocation::Dynamic(_, size) => size, @@ -1203,11 +1211,11 @@ impl RenderTaskCache { let (texture_id, texture_layer, uv_rect) = texture_cache.get_cache_location(&entry.handle); - render_task.location = RenderTaskLocation::TextureCache( - texture_id, - texture_layer, - uv_rect.to_i32() - ); + render_task.location = RenderTaskLocation::TextureCache { + texture: texture_id, + layer: texture_layer, + rect: uv_rect.to_i32(), + }; } } } diff --git a/gfx/webrender/src/renderer.rs b/gfx/webrender/src/renderer.rs index 94e9fe0829bc..66bec87ef77e 100644 --- a/gfx/webrender/src/renderer.rs +++ b/gfx/webrender/src/renderer.rs @@ -36,7 +36,7 @@ use batch::{BatchKind, BatchTextures, BrushBatchKind}; use capture::{CaptureConfig, ExternalCaptureImage, PlainExternalImage}; use debug_colors; use device::{DepthFunction, Device, FrameId, Program, UploadMethod, Texture, PBO}; -use device::{ExternalTexture, FBOId, TextureSlot}; +use device::{ExternalTexture, FBOId, TextureDrawTarget, TextureReadTarget, TextureSlot}; use device::{ShaderError, TextureFilter, VertexUsageHint, VAO, VBO, CustomVAO}; use device::{ProgramCache, ReadPixelsFormat}; @@ -54,7 +54,7 @@ use gpu_glyph_renderer::GpuGlyphRenderer; use gpu_types::ScalingInstance; use internal_types::{TextureSource, ORTHO_FAR_PLANE, ORTHO_NEAR_PLANE, ResourceCacheError}; use internal_types::{CacheTextureId, DebugOutput, FastHashMap, RenderedDocument, ResultMsg}; -use internal_types::{TextureUpdateList, TextureUpdateOp, TextureUpdateSource}; +use internal_types::{LayerIndex, TextureUpdateList, TextureUpdateOp, TextureUpdateSource}; use internal_types::{RenderTargetInfo, SavedTargetIndex}; use prim_store::DeferredResolve; use profiler::{BackendProfileCounters, FrameProfileCounters, @@ -1337,7 +1337,11 @@ impl GpuCacheTexture { device.bind_program(program); device.bind_custom_vao(vao); device.bind_draw_target( - Some((texture, 0)), + Some(TextureDrawTarget { + texture, + layer: 0, + with_depth: false, + }), Some(texture.get_dimensions()), ); device.draw_nonindexed_points(0, count as _); @@ -2918,7 +2922,7 @@ impl Renderer { fn handle_readback_composite( &mut self, - render_target: Option<(&Texture, i32)>, + render_target: Option, framebuffer_size: DeviceUintSize, scissor_rect: Option, source: &RenderTask, @@ -2951,7 +2955,11 @@ impl Renderer { // Called per-instance in case the layer (and therefore FBO) // changes. The device will skip the GL call if the requested // target is already bound. - let cache_draw_target = (cache_texture, readback_layer.0 as i32); + let cache_draw_target = TextureDrawTarget { + texture: cache_texture, + layer: readback_layer.0 as usize, + with_depth: false, + }; self.device.bind_draw_target(Some(cache_draw_target), None); let mut src = DeviceIntRect::new( @@ -2968,7 +2976,7 @@ impl Renderer { dest.size.height = -dest.size.height; } - self.device.bind_read_target(render_target); + self.device.bind_read_target(render_target.map(|r| r.into())); self.device.blit_render_target(src, dest); // Restore draw target to current pass render target + layer. @@ -2997,22 +3005,22 @@ impl Renderer { let source_rect = match blit.source { BlitJobSource::Texture(texture_id, layer, source_rect) => { // A blit from a texture into this target. - let src_texture = self.texture_resolver + let texture = self.texture_resolver .resolve(&texture_id) .expect("BUG: invalid source texture"); - self.device.bind_read_target(Some((src_texture, layer))); + self.device.bind_read_target(Some(TextureReadTarget { texture, layer: layer as usize })); source_rect } BlitJobSource::RenderTask(task_id) => { // A blit from the child render task into this target. // TODO(gw): Support R8 format here once we start // creating mips for alpha masks. - let src_texture = self.texture_resolver + let texture = self.texture_resolver .resolve(&TextureSource::PrevPassColor) .expect("BUG: invalid source texture"); let source = &render_tasks[task_id]; let (source_rect, layer) = source.get_target_rect(); - self.device.bind_read_target(Some((src_texture, layer.0 as i32))); + self.device.bind_read_target(Some(TextureReadTarget { texture, layer: layer.0 })); source_rect } }; @@ -3059,7 +3067,7 @@ impl Renderer { fn draw_color_target( &mut self, - render_target: Option<(&Texture, i32)>, + render_target: Option, target: &ColorRenderTarget, framebuffer_target_rect: DeviceUintRect, target_size: DeviceUintSize, @@ -3074,8 +3082,8 @@ impl Renderer { let _gm = self.gpu_profile.start_marker("color target"); // sanity check for the depth buffer - if let Some((texture, _)) = render_target { - assert!(texture.has_depth() >= target.needs_depth()); + if let Some(t) = render_target { + assert!(t.texture.supports_depth() >= target.needs_depth()); } let framebuffer_kind = if render_target.is_none() { @@ -3372,7 +3380,7 @@ impl Renderer { dest_rect.origin.y += dest_rect.size.height; dest_rect.size.height *= -1; - self.device.bind_read_target(render_target); + self.device.bind_read_target(render_target.map(|r| r.into())); self.device.bind_external_draw_target(fbo_id); self.device.blit_render_target(src_rect, dest_rect); handler.unlock(output.pipeline_id); @@ -3382,7 +3390,7 @@ impl Renderer { fn draw_alpha_target( &mut self, - render_target: (&Texture, i32), + render_target: TextureDrawTarget, target: &AlphaRenderTarget, target_size: DeviceUintSize, projection: &Transform3D, @@ -3527,7 +3535,7 @@ impl Renderer { fn draw_texture_cache_target( &mut self, texture: &CacheTextureId, - layer: i32, + layer: LayerIndex, target: &TextureCacheRenderTarget, render_tasks: &RenderTaskTree, stats: &mut RendererStats, @@ -3561,8 +3569,11 @@ impl Renderer { let texture = self.texture_resolver .resolve(&texture_source) .expect("BUG: invalid target texture"); - self.device - .bind_draw_target(Some((texture, layer)), Some(target_size)); + self.device.bind_draw_target(Some(TextureDrawTarget { + texture, + layer, + with_depth: false, + }), Some(target_size)); } self.device.disable_depth(); @@ -3801,7 +3812,7 @@ impl Renderer { // create a new texture. let selector = TargetSelector { size: list.max_size, - num_layers: list.targets.len() as _, + num_layers: list.targets.len(), format: list.format, }; let index = self.texture_resolver.render_target_pool @@ -3809,7 +3820,7 @@ impl Renderer { .position(|texture| { selector == TargetSelector { size: texture.get_dimensions(), - num_layers: texture.get_render_target_layer_count(), + num_layers: texture.get_layer_count() as usize, format: texture.get_format(), } }); @@ -3980,7 +3991,11 @@ impl Renderer { ); self.draw_alpha_target( - (&alpha_tex.as_ref().unwrap().texture, target_index as i32), + TextureDrawTarget { + texture: &alpha_tex.as_ref().unwrap().texture, + layer: target_index, + with_depth: false, + }, target, alpha.max_size, &projection, @@ -4002,7 +4017,11 @@ impl Renderer { ); self.draw_color_target( - Some((&color_tex.as_ref().unwrap().texture, target_index as i32)), + Some(TextureDrawTarget { + texture: &color_tex.as_ref().unwrap().texture, + layer: target_index, + with_depth: target.needs_depth(), + }), target, frame.inner_rect, color.max_size, @@ -4106,7 +4125,7 @@ impl Renderer { let fb_width = framebuffer_size.width as i32; let num_layers: i32 = self.texture_resolver.render_target_pool .iter() - .map(|texture| texture.get_render_target_layer_count() as i32) + .map(|texture| texture.get_layer_count() as i32) .sum(); if num_layers * (size + spacing) > fb_width { @@ -4120,10 +4139,9 @@ impl Renderer { let dimensions = texture.get_dimensions(); let src_rect = DeviceIntRect::new(DeviceIntPoint::zero(), dimensions.to_i32()); - let layer_count = texture.get_render_target_layer_count(); - for layer_index in 0 .. layer_count { - self.device - .bind_read_target(Some((texture, layer_index as i32))); + let layer_count = texture.get_layer_count() as usize; + for layer in 0 .. layer_count { + self.device.bind_read_target(Some(TextureReadTarget { texture, layer })); let x = fb_width - (spacing + size) * (target_index + 1); let y = spacing; @@ -4168,9 +4186,9 @@ impl Renderer { DeviceIntSize::new(dimensions.width as i32, dimensions.height as i32), ); - let layer_count = texture.get_layer_count(); - for layer_index in 0 .. layer_count { - self.device.bind_read_target(Some((texture, layer_index))); + let layer_count = texture.get_layer_count() as usize; + for layer in 0 .. layer_count { + self.device.bind_read_target(Some(TextureReadTarget { texture, layer})); let x = fb_width - (spacing + size) * (i as i32 + 1); @@ -4277,7 +4295,7 @@ impl Renderer { let size = texture.get_dimensions(); let mut texels = vec![0; (size.width * size.height * 16) as usize]; self.device.begin_frame(); - self.device.bind_read_target(Some((texture, 0))); + self.device.bind_read_target(Some(TextureReadTarget { texture, layer: 0 })); self.device.read_pixels_into( DeviceUintRect::new(DeviceUintPoint::zero(), size), ReadPixelsFormat::Standard(ImageFormat::RGBAF32), @@ -4362,6 +4380,9 @@ impl Renderer { // Texture cache and render target GPU memory. report += self.texture_resolver.report_memory(); + // Textures held internally within the device layer. + report += self.device.report_memory(); + report } @@ -4631,7 +4652,6 @@ struct PlainTexture { size: (u32, u32, i32), format: ImageFormat, filter: TextureFilter, - render_target: Option, } @@ -4741,7 +4761,6 @@ impl Renderer { size: (rect.size.width, rect.size.height, texture.get_layer_count()), format: texture.get_format(), filter: texture.get_filter(), - render_target: texture.get_render_target(), } } @@ -4749,6 +4768,7 @@ impl Renderer { fn load_texture( target: TextureTarget, plain: &PlainTexture, + rt_info: Option, root: &PathBuf, device: &mut Device ) -> (Texture, Vec) @@ -4768,7 +4788,7 @@ impl Renderer { plain.size.0, plain.size.1, plain.filter, - plain.render_target, + rt_info, plain.size.2, ); device.upload_texture_immediate(&texture, &texels); @@ -4939,6 +4959,7 @@ impl Renderer { let t = Self::load_texture( TextureTarget::Array, &texture, + Some(RenderTargetInfo { has_depth: false }), &root, &mut self.device ); @@ -4952,6 +4973,7 @@ impl Renderer { let (t, gpu_cache_data) = Self::load_texture( TextureTarget::Default, &renderer.gpu_cache, + Some(RenderTargetInfo { has_depth: false }), &root, &mut self.device, ); @@ -4996,11 +5018,11 @@ impl Renderer { size: (descriptor.size.width, descriptor.size.height, layer_count), format: descriptor.format, filter, - render_target: None, }; let t = Self::load_texture( target, &plain_tex, + None, &root, &mut self.device ); diff --git a/gfx/webrender/src/spatial_node.rs b/gfx/webrender/src/spatial_node.rs index bccbf90d4167..debe4ec60fa9 100644 --- a/gfx/webrender/src/spatial_node.rs +++ b/gfx/webrender/src/spatial_node.rs @@ -122,7 +122,6 @@ impl SpatialNode { let source_perspective = source_perspective.map_or_else( LayoutFastTransform::identity, |perspective| perspective.into()); let info = ReferenceFrameInfo { - resolved_transform: LayoutFastTransform::identity(), source_transform: source_transform.unwrap_or(PropertyBinding::Value(identity)), source_perspective, origin_in_parent_reference_frame, @@ -256,7 +255,7 @@ impl SpatialNode { let scrolled_perspective = info.source_perspective .pre_translate(&state.parent_accumulated_scroll_offset) .post_translate(-state.parent_accumulated_scroll_offset); - info.resolved_transform = + let resolved_transform = LayoutFastTransform::with_vector(info.origin_in_parent_reference_frame) .pre_mul(&source_transform.into()) .pre_mul(&scrolled_perspective); @@ -265,7 +264,7 @@ impl SpatialNode { // our parent reference frame, plus any accumulated scrolling offsets from nodes // between our reference frame and this node. Finally, we also include // whatever local transformation this reference frame provides. - let relative_transform = info.resolved_transform + let relative_transform = resolved_transform .post_translate(state.parent_accumulated_scroll_offset) .to_transform() .with_destination::(); @@ -622,10 +621,6 @@ impl ScrollFrameInfo { /// Contains information about reference frames. #[derive(Copy, Clone, Debug)] pub struct ReferenceFrameInfo { - /// The transformation that establishes this reference frame, relative to the parent - /// reference frame. The origin of the reference frame is included in the transformation. - pub resolved_transform: LayoutFastTransform, - /// The source transform and perspective matrices provided by the stacking context /// that forms this reference frame. We maintain the property binding information /// here so that we can resolve the animated transform and update the tree each diff --git a/gfx/webrender/src/texture_cache.rs b/gfx/webrender/src/texture_cache.rs index fae9e5e274a4..3a53c944d774 100644 --- a/gfx/webrender/src/texture_cache.rs +++ b/gfx/webrender/src/texture_cache.rs @@ -9,7 +9,7 @@ use device::TextureFilter; use freelist::{FreeList, FreeListHandle, UpsertResult, WeakFreeListHandle}; use gpu_cache::{GpuCache, GpuCacheHandle}; use gpu_types::{ImageSource, UvRectKind}; -use internal_types::{CacheTextureId, TextureUpdateList, TextureUpdateSource}; +use internal_types::{CacheTextureId, LayerIndex, TextureUpdateList, TextureUpdateSource}; use internal_types::{RenderTargetInfo, TextureSource, TextureUpdate, TextureUpdateOp}; use profiler::{ResourceProfileCounter, TextureCacheProfileCounters}; use render_backend::FrameId; @@ -541,12 +541,14 @@ impl TextureCache { } } - // A more detailed version of get(). This allows access to the actual - // device rect of the cache allocation. + /// A more detailed version of get(). This allows access to the actual + /// device rect of the cache allocation. + /// + /// Returns a tuple identifying the texture, the layer, and the region. pub fn get_cache_location( &self, handle: &TextureCacheHandle, - ) -> (CacheTextureId, i32, DeviceUintRect) { + ) -> (CacheTextureId, LayerIndex, DeviceUintRect) { let handle = handle .entry .as_ref() @@ -567,7 +569,7 @@ impl TextureCache { } => (layer_index, origin), }; (entry.texture_id, - layer_index as i32, + layer_index as usize, DeviceUintRect::new(origin, entry.size)) } diff --git a/gfx/webrender/src/tiling.rs b/gfx/webrender/src/tiling.rs index f7cc3c6c5aca..1b011d10f7ea 100644 --- a/gfx/webrender/src/tiling.rs +++ b/gfx/webrender/src/tiling.rs @@ -285,10 +285,8 @@ impl RenderTargetList { pub fn check_ready(&self, t: &Texture) { assert_eq!(t.get_dimensions(), self.max_size); assert_eq!(t.get_format(), self.format); - assert_eq!(t.get_render_target_layer_count(), self.targets.len()); assert_eq!(t.get_layer_count() as usize, self.targets.len()); - assert_eq!(t.has_depth(), t.get_rt_info().unwrap().has_depth); - assert_eq!(t.has_depth(), self.needs_depth()); + assert!(t.supports_depth() >= self.needs_depth()); } } @@ -821,7 +819,7 @@ pub enum RenderPassKind { OffScreen { alpha: RenderTargetList, color: RenderTargetList, - texture_cache: FastHashMap<(CacheTextureId, i32), TextureCacheRenderTarget>, + texture_cache: FastHashMap<(CacheTextureId, usize), TextureCacheRenderTarget>, }, } @@ -950,8 +948,8 @@ impl RenderPass { // Find a target to assign this task to, or create a new // one if required. let texture_target = match task.location { - RenderTaskLocation::TextureCache(texture_id, layer, _) => { - Some((texture_id, layer)) + RenderTaskLocation::TextureCache { texture, layer, .. } => { + Some((texture, layer)) } RenderTaskLocation::Fixed(..) => { None diff --git a/gfx/webrender_api/src/api.rs b/gfx/webrender_api/src/api.rs index a0dc049420dc..9baa9bae6a38 100644 --- a/gfx/webrender_api/src/api.rs +++ b/gfx/webrender_api/src/api.rs @@ -232,7 +232,7 @@ impl Transaction { } pub fn set_pinch_zoom(&mut self, pinch_zoom: ZoomFactor) { - self.scene_ops.push(SceneMsg::SetPinchZoom(pinch_zoom)); + self.frame_ops.push(FrameMsg::SetPinchZoom(pinch_zoom)); } pub fn set_pan(&mut self, pan: DeviceIntPoint) { @@ -523,7 +523,6 @@ pub struct AddFontInstance { pub enum SceneMsg { UpdateEpoch(PipelineId, Epoch), SetPageZoom(ZoomFactor), - SetPinchZoom(ZoomFactor), SetRootPipeline(PipelineId), RemovePipeline(PipelineId), SetDisplayList { @@ -554,6 +553,7 @@ pub enum FrameMsg { GetScrollNodeState(MsgSender>), UpdateDynamicProperties(DynamicProperties), AppendDynamicProperties(DynamicProperties), + SetPinchZoom(ZoomFactor), } impl fmt::Debug for SceneMsg { @@ -562,7 +562,6 @@ impl fmt::Debug for SceneMsg { SceneMsg::UpdateEpoch(..) => "SceneMsg::UpdateEpoch", SceneMsg::SetDisplayList { .. } => "SceneMsg::SetDisplayList", SceneMsg::SetPageZoom(..) => "SceneMsg::SetPageZoom", - SceneMsg::SetPinchZoom(..) => "SceneMsg::SetPinchZoom", SceneMsg::RemovePipeline(..) => "SceneMsg::RemovePipeline", SceneMsg::SetWindowParameters { .. } => "SceneMsg::SetWindowParameters", SceneMsg::SetRootPipeline(..) => "SceneMsg::SetRootPipeline", @@ -582,6 +581,7 @@ impl fmt::Debug for FrameMsg { FrameMsg::EnableFrameOutput(..) => "FrameMsg::EnableFrameOutput", FrameMsg::UpdateDynamicProperties(..) => "FrameMsg::UpdateDynamicProperties", FrameMsg::AppendDynamicProperties(..) => "FrameMsg::AppendDynamicProperties", + FrameMsg::SetPinchZoom(..) => "FrameMsg::SetPinchZoom", }) } } @@ -791,6 +791,7 @@ pub struct MemoryReport { pub vertex_data_textures: usize, pub render_target_textures: usize, pub texture_cache_textures: usize, + pub depth_target_textures: usize, } impl ::std::ops::AddAssign for MemoryReport { @@ -808,6 +809,7 @@ impl ::std::ops::AddAssign for MemoryReport { self.vertex_data_textures += other.vertex_data_textures; self.render_target_textures += other.render_target_textures; self.texture_cache_textures += other.texture_cache_textures; + self.depth_target_textures += other.depth_target_textures; } } diff --git a/gfx/webrender_api/src/display_item.rs b/gfx/webrender_api/src/display_item.rs index 47474ace98e6..b543c69270a6 100644 --- a/gfx/webrender_api/src/display_item.rs +++ b/gfx/webrender_api/src/display_item.rs @@ -435,6 +435,29 @@ impl BorderStyle { pub fn is_hidden(&self) -> bool { *self == BorderStyle::Hidden || *self == BorderStyle::None } + + /// Returns true if the border style itself is opaque. Other + /// factors (such as color, or border radii) may mean that + /// the border segment isn't opaque regardless of this. + pub fn is_opaque(&self) -> bool { + match *self { + BorderStyle::None | + BorderStyle::Double | + BorderStyle::Dotted | + BorderStyle::Dashed | + BorderStyle::Hidden => { + false + } + + BorderStyle::Solid | + BorderStyle::Groove | + BorderStyle::Ridge | + BorderStyle::Inset | + BorderStyle::Outset => { + true + } + } + } } #[repr(u32)] diff --git a/gfx/webrender_bindings/revision.txt b/gfx/webrender_bindings/revision.txt index 829f83699f83..b04fb7b84fd0 100644 --- a/gfx/webrender_bindings/revision.txt +++ b/gfx/webrender_bindings/revision.txt @@ -1 +1 @@ -98d507003c07c003ef0e0297dc4d29ee896a5868 +74f265e447d2927c27d4320c676779956d39eaf0 diff --git a/gfx/webrender_bindings/webrender_ffi_generated.h b/gfx/webrender_bindings/webrender_ffi_generated.h index 9fe1f27cd7dc..96a1c7de649e 100644 --- a/gfx/webrender_bindings/webrender_ffi_generated.h +++ b/gfx/webrender_bindings/webrender_ffi_generated.h @@ -542,6 +542,7 @@ struct MemoryReport { uintptr_t vertex_data_textures; uintptr_t render_target_textures; uintptr_t texture_cache_textures; + uintptr_t depth_target_textures; bool operator==(const MemoryReport& aOther) const { return primitive_stores == aOther.primitive_stores && @@ -556,7 +557,8 @@ struct MemoryReport { gpu_cache_textures == aOther.gpu_cache_textures && vertex_data_textures == aOther.vertex_data_textures && render_target_textures == aOther.render_target_textures && - texture_cache_textures == aOther.texture_cache_textures; + texture_cache_textures == aOther.texture_cache_textures && + depth_target_textures == aOther.depth_target_textures; } }; diff --git a/ipc/app/plugin-container.exe.manifest b/ipc/app/plugin-container.exe.manifest index e3bdc56b0818..3ccedc20c267 100644 --- a/ipc/app/plugin-container.exe.manifest +++ b/ipc/app/plugin-container.exe.manifest @@ -18,6 +18,16 @@ language="*" /> + + + + + diff --git a/ipc/glue/BackgroundChild.h b/ipc/glue/BackgroundChild.h index 8f2e1dea0550..34590c23c75c 100644 --- a/ipc/glue/BackgroundChild.h +++ b/ipc/glue/BackgroundChild.h @@ -7,7 +7,6 @@ #ifndef mozilla_ipc_backgroundchild_h__ #define mozilla_ipc_backgroundchild_h__ -#include "base/process.h" #include "mozilla/Attributes.h" #include "mozilla/ipc/Transport.h" @@ -47,7 +46,6 @@ class BackgroundChild final friend class mozilla::dom::ContentChild; friend class mozilla::dom::ContentParent; - typedef base::ProcessId ProcessId; typedef mozilla::ipc::Transport Transport; public: diff --git a/js/src/builtin/Array.cpp b/js/src/builtin/Array.cpp index ad4fbd98ed85..c643252921aa 100644 --- a/js/src/builtin/Array.cpp +++ b/js/src/builtin/Array.cpp @@ -412,9 +412,6 @@ js::GetElementsWithAdder(JSContext* cx, HandleObject obj, HandleObject receiver, return true; } -static bool -ObjectMayHaveExtraIndexedProperties(JSObject* obj); - static inline bool IsPackedArrayOrNoExtraIndexedProperties(JSObject* obj, uint64_t length) { @@ -1050,8 +1047,8 @@ ObjectMayHaveExtraIndexedOwnProperties(JSObject* obj) * elements. This includes other indexed properties in its shape hierarchy, and * indexed properties or elements along its prototype chain. */ -static bool -ObjectMayHaveExtraIndexedProperties(JSObject* obj) +bool +js::ObjectMayHaveExtraIndexedProperties(JSObject* obj) { MOZ_ASSERT_IF(obj->hasDynamicPrototype(), !obj->isNative()); diff --git a/js/src/builtin/Array.h b/js/src/builtin/Array.h index 977c68ff3d30..8df5611c5155 100644 --- a/js/src/builtin/Array.h +++ b/js/src/builtin/Array.h @@ -196,6 +196,9 @@ array_construct(JSContext* cx, unsigned argc, Value* vp); extern bool IsCrossRealmArrayConstructor(JSContext* cx, const Value& v, bool* result); +extern bool +ObjectMayHaveExtraIndexedProperties(JSObject* obj); + class MOZ_NON_TEMPORARY_CLASS ArraySpeciesLookup final { /* diff --git a/js/src/jit-test/tests/cacheir/bug1494537.js b/js/src/jit-test/tests/cacheir/bug1494537.js new file mode 100644 index 000000000000..7bf139819c40 --- /dev/null +++ b/js/src/jit-test/tests/cacheir/bug1494537.js @@ -0,0 +1,125 @@ +setJitCompilerOption("ion.forceinlineCaches", 1); + +let offsets = [213, 559, 255, 515, 30, 507, 252, 329, 487, 7]; + +function update_index(i, j) { + var offset = offsets[j % offsets.length]; + return i + offset; +} + +function compute_index(initial, count) { + for (var i = 0; i < count; i++) { + initial = update_index(initial, i); + } + return initial; +} + +// This is written so that the IC added in the bug activates. +function mutate_array(array, count, epsilon = 0) { + var index = 0; + for (var i = 0; i < count; i++) { + index = update_index(index, i); + array[index] = i + epsilon; + } + return array[offsets[0]+offsets[1]] === (1 + epsilon) && + array[10] === undefined; +} + +// Monomorphizing mutate_array to ensure we get the IC chains we want +function create_variant(variant) { + var source = mutate_array.toString().replace("mutate_array", "mutate_array_"+variant); + return source; +} + +function test_basic() { + eval(create_variant("basic")); + var x = []; + + var count = 100; + assertEq(mutate_array_basic(x, count), true); + var end = compute_index(0, count); + assertEq(x[end], count - 1); + assertEq(x[end - 1], undefined); +} + +// Ensure the IC respects frozen. +function test_frozen() { + eval(create_variant("frozen")); + var x = []; + Object.freeze(x); + + var count = 100; + assertEq(mutate_array_frozen(x, count), false); + assertEq(x.length, 0); + + var end = compute_index(0, count); + + var y = []; + assertEq(mutate_array_frozen(y, count), true); + assertEq(y[end], count - 1); + Object.freeze(y); + + // After a mutated array is frozen, can't subsequently modify elements + assertEq(mutate_array_frozen(x, count, 10), false); + assertEq(y[end], count - 1); +} + +// Let's make sure updates to the array happen as expected. +function test_update() { + eval(create_variant("update")); + + var x = []; + var count = 100; + assertEq(mutate_array_update(x, count), true); + var end = compute_index(0, count); + assertEq(x[end], count - 1); + assertEq(x[end - 1], undefined); + + var epsilon = 2; + mutate_array_update(x, 200, epsilon); + assertEq(x[end], count -1 + epsilon) +} + +// Elements may be non-writable, let us not write them. +function test_nonwritable() { + eval(create_variant("nonwritable")); + var x = []; + var count = 100; + var index = compute_index(0, 10); + Object.defineProperty(x, index, {value: -10, writable: false}); + mutate_array_nonwritable(x, count); + assertEq(x[index], -10); +} + +// Random indices can get setters, let's make sure we honour those. +function test_setter() { + eval(create_variant("setter")); + var x = []; + var count = 100; + var index = compute_index(0, 80); + var sigil = 0; + Object.defineProperty(x, index, {set(newVal) {sigil++; }}); + mutate_array_setter(x, count); + assertEq(sigil, 1); + assertEq(x[index], undefined); +} + +// Ensure indexes on the prototype don't break things; +// +function test_proto_indices() { + eval(create_variant("proto_indices")); + var x = []; + var count = 100; + var index = compute_index(0, 80); + x.__proto__[index] = "hello"; + mutate_array_proto_indices(x, count); + assertEq(x.__proto__[index], "hello"); + assertEq(x[index], 79); +} + +test_basic(); +test_frozen(); +test_update(); +test_nonwritable(); +test_setter(); +test_proto_indices(); diff --git a/js/src/jit/BaselineCacheIRCompiler.cpp b/js/src/jit/BaselineCacheIRCompiler.cpp index abef641ffacb..7330137dc03f 100644 --- a/js/src/jit/BaselineCacheIRCompiler.cpp +++ b/js/src/jit/BaselineCacheIRCompiler.cpp @@ -1879,6 +1879,33 @@ BaselineCacheIRCompiler::emitCallProxySetByValue() return true; } +bool +BaselineCacheIRCompiler::emitCallAddOrUpdateSparseElementHelper() +{ + Register obj = allocator.useRegister(masm, reader.objOperandId()); + Register id = allocator.useRegister(masm, reader.int32OperandId()); + ValueOperand val = allocator.useValueRegister(masm, reader.valOperandId()); + bool strict = reader.readBool(); + AutoScratchRegister scratch(allocator, masm); + + allocator.discardStack(masm); + + AutoStubFrame stubFrame(*this); + stubFrame.enter(masm, scratch); + + masm.Push(Imm32(strict)); + masm.Push(val); + masm.Push(id); + masm.Push(obj); + + if (!callVM(masm, AddOrUpdateSparseElementHelperInfo)) { + return false; + } + stubFrame.leave(masm); + return true; +} + + bool BaselineCacheIRCompiler::emitMegamorphicSetElement() { diff --git a/js/src/jit/CacheIR.cpp b/js/src/jit/CacheIR.cpp index 4b342dd54bce..5f7ad849abef 100644 --- a/js/src/jit/CacheIR.cpp +++ b/js/src/jit/CacheIR.cpp @@ -3450,6 +3450,9 @@ SetPropIRGenerator::tryAttachStub() if (tryAttachSetTypedElement(obj, objId, index, indexId, rhsValId)) { return true; } + if (tryAttachAddOrUpdateSparseElement(obj, objId, index, indexId, rhsValId)) { + return true; + } return false; } return false; @@ -4066,6 +4069,89 @@ SetPropIRGenerator::tryAttachSetDenseElementHole(HandleObject obj, ObjOperandId return true; } +// Add an IC for adding or updating a sparse array element. +bool +SetPropIRGenerator::tryAttachAddOrUpdateSparseElement(HandleObject obj, ObjOperandId objId, + uint32_t index, Int32OperandId indexId, + ValOperandId rhsId) +{ + JSOp op = JSOp(*pc_); + MOZ_ASSERT(IsPropertySetOp(op) || IsPropertyInitOp(op)); + + if (op != JSOP_SETELEM && op != JSOP_STRICTSETELEM) { + return false; + } + + if (!obj->isNative()) { + return false; + } + RootedNativeObject nobj(cx_, &obj->as()); + + // We cannot attach a stub to a non-extensible object + if (!nobj->isExtensible()) { + return false; + } + + // Stub doesn't handle negative indices. + if (index > INT_MAX) { + return false; + } + + // We also need to be past the end of the dense capacity, to ensure sparse. + if (index < nobj->getDenseInitializedLength()) { + return false; + } + + // Only handle Array objects in this stub. + if (!nobj->is()) { + return false; + } + RootedArrayObject aobj(cx_, &obj->as()); + + // Don't attach if we're adding to an array with non-writable length. + bool isAdd = (index >= aobj->length()); + if (isAdd && !aobj->lengthIsWritable()) { + return false; + } + + // Indexed properties on the prototype chain aren't handled by the helper. + if (ObjectMayHaveExtraIndexedProperties(aobj->staticPrototype())) { + return false; + } + + // Ensure we are still talking about an array class. + writer.guardClass(objId, GuardClassKind::Array); + + // The helper we are going to call only applies to non-dense elements. + writer.guardIndexGreaterThanDenseInitLength(objId, indexId); + + // Guard extensible: We may be trying to add a new element, and so we'd best + // be able to do so safely. + writer.guardIsExtensible(objId); + + // Ensures we are able to efficiently able to map to an integral jsid. + writer.guardIndexIsNonNegative(indexId); + + // Shape guard the prototype chain to avoid shadowing indexes from appearing. + // Dense elements may appear on the prototype chain (and prototypes may + // have a different notion of which elements are dense), but they can + // only be data properties, so our specialized Set handler is ok to bind + // to them. + ShapeGuardProtoChain(writer, obj, objId); + + // Ensure that if we're adding an element to the object, the object's + // length is writable. + writer.guardIndexIsValidUpdateOrAdd(objId, indexId); + + writer.callAddOrUpdateSparseElementHelper(objId, indexId, rhsId, + /* strict = */op == JSOP_STRICTSETELEM); + writer.returnFromIC(); + + trackAttached("AddOrUpdateSparseElement"); + return true; +} + + bool SetPropIRGenerator::tryAttachSetTypedElement(HandleObject obj, ObjOperandId objId, uint32_t index, Int32OperandId indexId, diff --git a/js/src/jit/CacheIR.h b/js/src/jit/CacheIR.h index cb52deec033a..b5e034052bef 100644 --- a/js/src/jit/CacheIR.h +++ b/js/src/jit/CacheIR.h @@ -201,6 +201,7 @@ extern const char* const CacheKindNames[]; _(GuardClass) /* Guard an object class, per GuardClassKind */ \ _(GuardAnyClass) /* Guard an arbitrary class for an object */ \ _(GuardCompartment) \ + _(GuardIsExtensible) \ _(GuardIsNativeFunction) \ _(GuardIsNativeObject) \ _(GuardIsProxy) \ @@ -222,6 +223,9 @@ extern const char* const CacheKindNames[]; _(GuardHasGetterSetter) \ _(GuardGroupHasUnanalyzedNewScript) \ _(GuardIndexIsNonNegative) \ + _(GuardIndexGreaterThanDenseCapacity) \ + _(GuardIndexGreaterThanArrayLength) \ + _(GuardIndexIsValidUpdateOrAdd) \ _(GuardIndexGreaterThanDenseInitLength) \ _(GuardTagNotEqual) \ _(GuardXrayExpandoShapeAndDefaultProto) \ @@ -267,6 +271,7 @@ extern const char* const CacheKindNames[]; _(CallSetArrayLength) \ _(CallProxySet) \ _(CallProxySetByValue) \ + _(CallAddOrUpdateSparseElementHelper) \ _(CallInt32ToString) \ _(CallNumberToString) \ \ @@ -765,6 +770,9 @@ class MOZ_RAII CacheIRWriter : public JS::CustomAutoRooter // Use RawWord, because compartments never move and it can't be GCed. addStubField(uintptr_t(compartment), StubField::Type::RawWord); } + void guardIsExtensible(ObjOperandId obj) { + writeOpWithOperandId(CacheOp::GuardIsExtensible, obj); + } void guardNoDetachedTypedObjects() { writeOp(CacheOp::GuardNoDetachedTypedObjects); } @@ -811,6 +819,18 @@ class MOZ_RAII CacheIRWriter : public JS::CustomAutoRooter writeOpWithOperandId(CacheOp::GuardIndexGreaterThanDenseInitLength, obj); writeOperandId(index); } + void guardIndexGreaterThanDenseCapacity(ObjOperandId obj, Int32OperandId index) { + writeOpWithOperandId(CacheOp::GuardIndexGreaterThanDenseCapacity, obj); + writeOperandId(index); + } + void guardIndexGreaterThanArrayLength(ObjOperandId obj, Int32OperandId index) { + writeOpWithOperandId(CacheOp::GuardIndexGreaterThanArrayLength, obj); + writeOperandId(index); + } + void guardIndexIsValidUpdateOrAdd(ObjOperandId obj, Int32OperandId index) { + writeOpWithOperandId(CacheOp::GuardIndexIsValidUpdateOrAdd, obj); + writeOperandId(index); + } void guardTagNotEqual(ValueTagOperandId lhs, ValueTagOperandId rhs) { writeOpWithOperandId(CacheOp::GuardTagNotEqual, lhs); writeOperandId(rhs); @@ -1041,6 +1061,12 @@ class MOZ_RAII CacheIRWriter : public JS::CustomAutoRooter writeOperandId(rhs); buffer_.writeByte(uint32_t(strict)); } + void callAddOrUpdateSparseElementHelper(ObjOperandId obj, Int32OperandId id, ValOperandId rhs, bool strict) { + writeOpWithOperandId(CacheOp::CallAddOrUpdateSparseElementHelper, obj); + writeOperandId(id); + writeOperandId(rhs); + buffer_.writeByte(uint32_t(strict)); + } StringOperandId callInt32ToString(Int32OperandId id) { StringOperandId res(nextOperandId_++); writeOpWithOperandId(CacheOp::CallInt32ToString, id); @@ -1753,6 +1779,10 @@ class MOZ_RAII SetPropIRGenerator : public IRGenerator bool tryAttachSetDenseElementHole(HandleObject obj, ObjOperandId objId, uint32_t index, Int32OperandId indexId, ValOperandId rhsId); + bool tryAttachAddOrUpdateSparseElement(HandleObject obj, ObjOperandId objId, uint32_t index, + Int32OperandId indexId, ValOperandId rhsId); + + bool tryAttachGenericProxy(HandleObject obj, ObjOperandId objId, HandleId id, ValOperandId rhsId, bool handleDOMProxies); bool tryAttachDOMProxyShadowed(HandleObject obj, ObjOperandId objId, HandleId id, diff --git a/js/src/jit/CacheIRCompiler.cpp b/js/src/jit/CacheIRCompiler.cpp index f440167e666b..407b71b0593e 100644 --- a/js/src/jit/CacheIRCompiler.cpp +++ b/js/src/jit/CacheIRCompiler.cpp @@ -1734,6 +1734,35 @@ CacheIRCompiler::emitGuardClass() return true; } +bool +CacheIRCompiler::emitGuardIsExtensible() +{ + Register obj = allocator.useRegister(masm, reader.objOperandId()); + AutoScratchRegister scratch(allocator, masm); + + FailurePath* failure; + if (!addFailurePath(&failure)) { + return false; + } + + Address shape(obj, ShapedObject::offsetOfShape()); + masm.loadPtr(shape, scratch); + + Address baseShape(scratch, Shape::offsetOfBaseShape()); + masm.loadPtr(baseShape, scratch); + + Address baseShapeFlags(scratch, BaseShape::offsetOfFlags()); + masm.loadPtr(baseShapeFlags, scratch); + + masm.and32(Imm32(js::BaseShape::NOT_EXTENSIBLE), scratch); + + // Spectre-style checks are not needed here because we do not + // interpret data based on this check. + masm.branch32(Assembler::Equal, scratch, Imm32(js::BaseShape::NOT_EXTENSIBLE), + failure->label()); + return true; +} + bool CacheIRCompiler::emitGuardIsNativeFunction() { @@ -2836,7 +2865,7 @@ CacheIRCompiler::emitGuardIndexGreaterThanDenseInitLength() // Load obj->elements. masm.loadPtr(Address(obj, NativeObject::offsetOfElements()), scratch); - // Ensure index >= capacity. + // Ensure index >= initLength. Label outOfBounds; Address capacity(scratch, ObjectElements::offsetOfInitializedLength()); masm.spectreBoundsCheck32(index, capacity, scratch2, &outOfBounds); @@ -2846,6 +2875,89 @@ CacheIRCompiler::emitGuardIndexGreaterThanDenseInitLength() return true; } +bool +CacheIRCompiler::emitGuardIndexGreaterThanDenseCapacity() +{ + Register obj = allocator.useRegister(masm, reader.objOperandId()); + Register index = allocator.useRegister(masm, reader.int32OperandId()); + AutoScratchRegister scratch(allocator, masm); + AutoScratchRegister scratch2(allocator, masm); + + FailurePath* failure; + if (!addFailurePath(&failure)) { + return false; + } + + // Load obj->elements. + masm.loadPtr(Address(obj, NativeObject::offsetOfElements()), scratch); + + // Ensure index >= capacity. + Label outOfBounds; + Address capacity(scratch, ObjectElements::offsetOfCapacity()); + masm.spectreBoundsCheck32(index, capacity, scratch2, &outOfBounds); + masm.jump(failure->label()); + masm.bind(&outOfBounds); + + return true; +} + +bool +CacheIRCompiler::emitGuardIndexGreaterThanArrayLength() +{ + Register obj = allocator.useRegister(masm, reader.objOperandId()); + Register index = allocator.useRegister(masm, reader.int32OperandId()); + AutoScratchRegister scratch(allocator, masm); + AutoScratchRegister scratch2(allocator, masm); + + FailurePath* failure; + if (!addFailurePath(&failure)) { + return false; + } + + // Load obj->elements. + masm.loadPtr(Address(obj, NativeObject::offsetOfElements()), scratch); + + // Ensure index >= length; + Label outOfBounds; + Address length(scratch, ObjectElements::offsetOfLength()); + masm.spectreBoundsCheck32(index, length, scratch2, &outOfBounds); + masm.jump(failure->label()); + masm.bind(&outOfBounds); + return true; +} + +bool +CacheIRCompiler::emitGuardIndexIsValidUpdateOrAdd() +{ + Register obj = allocator.useRegister(masm, reader.objOperandId()); + Register index = allocator.useRegister(masm, reader.int32OperandId()); + AutoScratchRegister scratch(allocator, masm); + AutoScratchRegister scratch2(allocator, masm); + + FailurePath* failure; + if (!addFailurePath(&failure)) { + return false; + } + + // Load obj->elements. + masm.loadPtr(Address(obj, NativeObject::offsetOfElements()), scratch); + + Label success; + + // If length is writable, branch to &success. All indices are writable. + Address flags(scratch, ObjectElements::offsetOfFlags()); + masm.branchTest32(Assembler::Zero, flags, + Imm32(ObjectElements::Flags::NONWRITABLE_ARRAY_LENGTH), + &success); + + // Otherwise, ensure index is in bounds. + Address length(scratch, ObjectElements::offsetOfLength()); + masm.spectreBoundsCheck32(index, length, scratch2, + /* failure = */ failure->label()); + masm.bind(&success); + return true; +} + bool CacheIRCompiler::emitGuardTagNotEqual() { diff --git a/js/src/jit/CacheIRCompiler.h b/js/src/jit/CacheIRCompiler.h index 2614e66eaed9..07304488b800 100644 --- a/js/src/jit/CacheIRCompiler.h +++ b/js/src/jit/CacheIRCompiler.h @@ -32,6 +32,7 @@ namespace jit { _(GuardType) \ _(GuardClass) \ _(GuardGroupHasUnanalyzedNewScript) \ + _(GuardIsExtensible) \ _(GuardIsNativeFunction) \ _(GuardFunctionPrototype) \ _(GuardIsNativeObject) \ @@ -46,6 +47,9 @@ namespace jit { _(GuardAndGetNumberFromString) \ _(GuardAndGetIndexFromString) \ _(GuardIndexIsNonNegative) \ + _(GuardIndexGreaterThanDenseCapacity) \ + _(GuardIndexGreaterThanArrayLength) \ + _(GuardIndexIsValidUpdateOrAdd) \ _(GuardIndexGreaterThanDenseInitLength) \ _(GuardTagNotEqual) \ _(GuardXrayExpandoShapeAndDefaultProto)\ diff --git a/js/src/jit/IonCacheIRCompiler.cpp b/js/src/jit/IonCacheIRCompiler.cpp index 6140f72de870..4a928278c434 100644 --- a/js/src/jit/IonCacheIRCompiler.cpp +++ b/js/src/jit/IonCacheIRCompiler.cpp @@ -2265,6 +2265,28 @@ IonCacheIRCompiler::emitCallProxySetByValue() return callVM(masm, ProxySetPropertyByValueInfo); } +bool +IonCacheIRCompiler::emitCallAddOrUpdateSparseElementHelper() +{ + AutoSaveLiveRegisters save(*this); + + Register obj = allocator.useRegister(masm, reader.objOperandId()); + Register id = allocator.useRegister(masm, reader.int32OperandId()); + ValueOperand val = allocator.useValueRegister(masm, reader.valOperandId()); + bool strict = reader.readBool(); + + Label done; + prepareVMCall(masm, save); + + masm.Push(Imm32(strict)); + masm.Push(val); + masm.Push(id); + masm.Push(obj); + + return callVM(masm, AddOrUpdateSparseElementHelperInfo); +} + + bool IonCacheIRCompiler::emitMegamorphicSetElement() { diff --git a/js/src/jit/VMFunctions.cpp b/js/src/jit/VMFunctions.cpp index b6db6526c4ad..5a3b0e60b6a2 100644 --- a/js/src/jit/VMFunctions.cpp +++ b/js/src/jit/VMFunctions.cpp @@ -2072,5 +2072,10 @@ typedef bool (*NativeGetElementFn)(JSContext*, HandleNativeObject, HandleValue, const VMFunction NativeGetElementInfo = FunctionInfo(NativeGetElement, "NativeGetProperty"); +typedef bool (*AddOrUpdateSparseElementHelperFn)(JSContext* cx, HandleArrayObject obj, + int32_t int_id, HandleValue v, bool strict); +const VMFunction AddOrUpdateSparseElementHelperInfo = + FunctionInfo(AddOrUpdateSparseElementHelper, "AddOrUpdateSparseElementHelper"); + } // namespace jit } // namespace js diff --git a/js/src/jit/VMFunctions.h b/js/src/jit/VMFunctions.h index 6dd045750d0d..da27a134af9b 100644 --- a/js/src/jit/VMFunctions.h +++ b/js/src/jit/VMFunctions.h @@ -982,6 +982,8 @@ extern const VMFunction ProxyHasOwnInfo; extern const VMFunction NativeGetElementInfo; +extern const VMFunction AddOrUpdateSparseElementHelperInfo; + // TailCall VMFunctions extern const VMFunction DoConcatStringObjectInfo; diff --git a/js/src/jit/x86/Assembler-x86.h b/js/src/jit/x86/Assembler-x86.h index 12faf71d0ee9..58c817c2bd5e 100644 --- a/js/src/jit/x86/Assembler-x86.h +++ b/js/src/jit/x86/Assembler-x86.h @@ -459,20 +459,11 @@ class Assembler : public AssemblerX86Shared MOZ_ASSERT(dest.size() == 16); masm.vhaddpd_rr(src.encoding(), dest.encoding()); } - void vsubpd(const Operand& src1, FloatRegister src0, FloatRegister dest) { + void vsubpd(FloatRegister src1, FloatRegister src0, FloatRegister dest) { MOZ_ASSERT(HasSSE2()); MOZ_ASSERT(src0.size() == 16); MOZ_ASSERT(dest.size() == 16); - switch (src1.kind()) { - case Operand::MEM_REG_DISP: - masm.vsubpd_mr(src1.disp(), src1.base(), src0.encoding(), dest.encoding()); - break; - case Operand::MEM_ADDRESS32: - masm.vsubpd_mr(src1.address(), src0.encoding(), dest.encoding()); - break; - default: - MOZ_CRASH("unexpected operand kind"); - } + masm.vsubpd_rr(src1.encoding(), src0.encoding(), dest.encoding()); } void vpunpckldq(FloatRegister src1, FloatRegister src0, FloatRegister dest) { diff --git a/js/src/jit/x86/BaseAssembler-x86.h b/js/src/jit/x86/BaseAssembler-x86.h index 17fa8ce02c62..55bb2c52d0b7 100644 --- a/js/src/jit/x86/BaseAssembler-x86.h +++ b/js/src/jit/x86/BaseAssembler-x86.h @@ -176,14 +176,6 @@ class BaseAssemblerX86 : public BaseAssembler { twoByteOpSimd("vsubpd", VEX_PD, OP2_SUBPS_VpsWps, src1, src0, dst); } - void vsubpd_mr(int32_t offset, RegisterID base, XMMRegisterID src0, XMMRegisterID dst) - { - twoByteOpSimd("vsubpd", VEX_PD, OP2_SUBPS_VpsWps, offset, base, src0, dst); - } - void vsubpd_mr(const void* address, XMMRegisterID src0, XMMRegisterID dst) - { - twoByteOpSimd("vsubpd", VEX_PD, OP2_SUBPS_VpsWps, address, src0, dst); - } void vpunpckldq_rr(XMMRegisterID src1, XMMRegisterID src0, XMMRegisterID dst) { twoByteOpSimd("vpunpckldq", VEX_PD, OP2_PUNPCKLDQ, src1, src0, dst); diff --git a/js/src/jit/x86/MacroAssembler-x86.cpp b/js/src/jit/x86/MacroAssembler-x86.cpp index 876af6c6e72f..e62eb48870a0 100644 --- a/js/src/jit/x86/MacroAssembler-x86.cpp +++ b/js/src/jit/x86/MacroAssembler-x86.cpp @@ -1120,15 +1120,6 @@ MacroAssembler::wasmTruncateFloat32ToUInt64(FloatRegister input, Register64 outp // ======================================================================== // Convert floating point. -// vpunpckldq requires 16-byte boundary for memory operand. -// See convertUInt64ToDouble for the details. -MOZ_ALIGNED_DECL(static const uint64_t, 16) TO_DOUBLE[4] = { - 0x4530000043300000LL, - 0x0LL, - 0x4330000000000000LL, - 0x4530000000000000LL -}; - bool MacroAssembler::convertUInt64ToDoubleNeedsTemp() { @@ -1187,8 +1178,16 @@ MacroAssembler::convertUInt64ToDouble(Register64 src, FloatRegister dest, Regist // here, each 64-bit part of dest represents following double: // HI(dest) = 0x 1.00000HHHHHHHH * 2**84 == 2**84 + 0x HHHHHHHH 00000000 // LO(dest) = 0x 1.00000LLLLLLLL * 2**52 == 2**52 + 0x 00000000 LLLLLLLL - movePtr(ImmWord((uintptr_t)TO_DOUBLE), temp); - vpunpckldq(Operand(temp, 0), dest128, dest128); + // See convertUInt64ToDouble for the details. + static const int32_t CST1[4] = { + 0x43300000, + 0x45300000, + 0x0, + 0x0, + }; + + loadConstantSimd128Int(SimdConstant::CreateX4(CST1), ScratchSimd128Reg); + vpunpckldq(ScratchSimd128Reg, dest128, dest128); // Subtract a constant C2 from dest, for each 64-bit part: // C2 = 0x 45300000 00000000 43300000 00000000 @@ -1198,7 +1197,15 @@ MacroAssembler::convertUInt64ToDouble(Register64 src, FloatRegister dest, Regist // after the operation each 64-bit part of dest represents following: // HI(dest) = double(0x HHHHHHHH 00000000) // LO(dest) = double(0x 00000000 LLLLLLLL) - vsubpd(Operand(temp, sizeof(uint64_t) * 2), dest128, dest128); + static const int32_t CST2[4] = { + 0x0, + 0x43300000, + 0x0, + 0x45300000, + }; + + loadConstantSimd128Int(SimdConstant::CreateX4(CST2), ScratchSimd128Reg); + vsubpd(ScratchSimd128Reg, dest128, dest128); // Add HI(dest) and LO(dest) in double and store it into LO(dest), // LO(dest) = double(0x HHHHHHHH 00000000) + double(0x 00000000 LLLLLLLL) diff --git a/js/src/vm/NativeObject.cpp b/js/src/vm/NativeObject.cpp index 52c69afd12d0..188695b5c681 100644 --- a/js/src/vm/NativeObject.cpp +++ b/js/src/vm/NativeObject.cpp @@ -2107,6 +2107,48 @@ DefineNonexistentProperty(JSContext* cx, HandleNativeObject obj, HandleId id, return result.succeed(); } +bool +js::AddOrUpdateSparseElementHelper(JSContext* cx, HandleArrayObject obj, int32_t int_id, + HandleValue v, bool strict) +{ + MOZ_ASSERT(INT_FITS_IN_JSID(int_id)); + RootedId id(cx, INT_TO_JSID(int_id)); + + // This helper doesn't handle the case where the index may be in the dense elements + MOZ_ASSERT(int_id >= 0); + MOZ_ASSERT(uint32_t(int_id) >= obj->getDenseInitializedLength()); + + // First decide if this is an add or an update. Because the IC guards have + // already ensured this exists exterior to the dense array range, and the + // prototype checks have ensured there are no indexes on the prototype, we + // can use the shape lineage to find the element if it exists: + RootedShape shape(cx, obj->lastProperty()->search(cx, id)); + + // If we didn't find the shape, we're on the add path: delegate to + // AddSparseElement: + if (shape == nullptr) { + Rooted desc(cx); + desc.setDataDescriptor(v, JSPROP_ENUMERATE); + desc.assertComplete(); + + return AddOrChangeProperty(cx, obj, id, desc); + } + + // At this point we're updating a property: See SetExistingProperty + if (shape->writable() && shape->isDataProperty()) { + // While all JSID_INT properties use a single TI entry, + // nothing yet has inspected the updated value so we *must* use setSlotWithType(). + obj->setSlotWithType(cx, shape, v, /* overwriting = */ true); + return true; + } + + // We don't know exactly what this object looks like, hit the slowpath. + RootedValue receiver(cx, ObjectValue(*obj)); + JS::ObjectOpResult result; + return SetProperty(cx, obj, id, v, receiver, result) && + result.checkStrictErrorOrWarning(cx, obj, id, strict); +} + /*** [[HasProperty]] *****************************************************************************/ diff --git a/js/src/vm/NativeObject.h b/js/src/vm/NativeObject.h index 0a6cfac8cb32..b3b51723b8cf 100644 --- a/js/src/vm/NativeObject.h +++ b/js/src/vm/NativeObject.h @@ -1622,6 +1622,10 @@ bool SetPropertyOnProto(JSContext* cx, HandleObject obj, HandleId id, HandleValue v, HandleValue receiver, ObjectOpResult& result); +bool +AddOrUpdateSparseElementHelper(JSContext* cx, HandleArrayObject obj, int32_t int_id, + HandleValue v, bool strict); + /* * Indicates whether an assignment operation is qualified (`x.y = 0`) or * unqualified (`y = 0`). In strict mode, the latter is an error if no such diff --git a/js/src/vm/Shape.h b/js/src/vm/Shape.h index 7af4390bf5e3..df0baefd17a6 100644 --- a/js/src/vm/Shape.h +++ b/js/src/vm/Shape.h @@ -1159,8 +1159,10 @@ class Shape : public gc::TenuredCell void fixupGetterSetterForBarrier(JSTracer* trc); void updateBaseShapeAfterMovingGC(); -#ifdef DEBUG // For JIT usage. + static inline size_t offsetOfBaseShape() { return offsetof(Shape, base_); } + +#ifdef DEBUG static inline size_t offsetOfImmutableFlags() { return offsetof(Shape, immutableFlags); } static inline uint32_t fixedSlotsMask() { return FIXED_SLOTS_MASK; } #endif diff --git a/js/src/vm/ShapedObject.h b/js/src/vm/ShapedObject.h index da5687350e49..b6f3f8fb4e4e 100644 --- a/js/src/vm/ShapedObject.h +++ b/js/src/vm/ShapedObject.h @@ -11,6 +11,8 @@ namespace js { +namespace jit { class CacheIRCompiler; } + /* * Shaped objects are a variant of JSObject that use a GCPtrShape for their * |shapeOrExpando_| field. All objects that point to a js::Shape as their @@ -58,6 +60,8 @@ class ShapedObject : public JSObject // See JSObject::offsetOfGroup() comment. friend class js::jit::MacroAssembler; + friend class js::jit::CacheIRCompiler; + static constexpr size_t offsetOfShape() { static_assert(offsetOfShapeOrExpando() == offsetof(shadow::Object, shape), "shadow shape must match actual shape"); diff --git a/js/src/vm/StructuredClone.cpp b/js/src/vm/StructuredClone.cpp index 6dbaeb563695..dc358e798c4b 100644 --- a/js/src/vm/StructuredClone.cpp +++ b/js/src/vm/StructuredClone.cpp @@ -366,7 +366,6 @@ class SCInput { static void getPair(uint64_t data, uint32_t* tagp, uint32_t* datap); MOZ_MUST_USE bool read(uint64_t* p); - MOZ_MUST_USE bool readNativeEndian(uint64_t* p); MOZ_MUST_USE bool readPair(uint32_t* tagp, uint32_t* datap); MOZ_MUST_USE bool readDouble(double* p); MOZ_MUST_USE bool readBytes(void* p, size_t nbytes); @@ -702,18 +701,6 @@ SCInput::read(uint64_t* p) return true; } -bool -SCInput::readNativeEndian(uint64_t* p) -{ - if (!point.canPeek()) { - *p = 0; // initialize to shut GCC up - return reportTruncated(); - } - *p = point.peek(); - point.next(); - return true; -} - bool SCInput::readPair(uint32_t* tagp, uint32_t* datap) { @@ -854,7 +841,7 @@ bool SCInput::readPtr(void** p) { uint64_t u; - if (!readNativeEndian(&u)) { + if (!read(&u)) { return false; } *p = reinterpret_cast(u); diff --git a/js/xpconnect/shell/xpcshell.exe.manifest b/js/xpconnect/shell/xpcshell.exe.manifest index c35b77af4360..1c671f14ef98 100644 --- a/js/xpconnect/shell/xpcshell.exe.manifest +++ b/js/xpconnect/shell/xpcshell.exe.manifest @@ -12,6 +12,16 @@ type="win32" /> XPConnect Shell + + + + + diff --git a/moz.configure b/moz.configure index 2bd815ad5711..c52bd1616258 100755 --- a/moz.configure +++ b/moz.configure @@ -39,6 +39,12 @@ def imply_disable_compile_environment(value): if value: return False +option(env='MOZ_COPY_PDBS', + help='For builds that do not support symbols in the normal fashion,' + ' generate and copy them into the resulting build archive.') + +set_config('MOZ_COPY_PDBS', depends_if('MOZ_COPY_PDBS')(lambda _: True)) + imply_option('--enable-compile-environment', imply_disable_compile_environment) option('--disable-compile-environment', diff --git a/mozglue/build/Makefile.in b/mozglue/build/Makefile.in index 0a86b3c15d73..35d101d5fe2d 100644 --- a/mozglue/build/Makefile.in +++ b/mozglue/build/Makefile.in @@ -11,6 +11,12 @@ mozglue.def: mozglue.def.in $(GLOBAL_DEPS) $(call py_action,preprocessor,$(if $(MOZ_REPLACE_MALLOC),-DMOZ_REPLACE_MALLOC) $(ACDEFINES) $< -o $@) GARBAGE += mozglue.def + +# Rebuild mozglue.dll if the manifest changes - it's included by mozglue.rc. +# (this dependency should really be just for mozglue.dll, not other targets) +# Note the manifest file exists in the tree, so we use the explicit filename +# here. +EXTRA_DEPS += mozglue.dll.manifest endif include $(topsrcdir)/mozglue/build/replace_malloc.mk diff --git a/mozglue/build/moz.build b/mozglue/build/moz.build index dacfa1a2e226..bf086fb154f7 100644 --- a/mozglue/build/moz.build +++ b/mozglue/build/moz.build @@ -35,6 +35,7 @@ if CONFIG['OS_TARGET'] == 'WINNT': DELAYLOAD_DLLS += [ 'user32.dll', ] + RCINCLUDE = 'mozglue.rc' if CONFIG['MOZ_PGO'] and CONFIG['CC_TYPE'] == 'clang-cl': SOURCES += ['cygprofile.cpp'] diff --git a/mozglue/build/mozglue.dll.manifest b/mozglue/build/mozglue.dll.manifest new file mode 100644 index 000000000000..037eae4f77fe --- /dev/null +++ b/mozglue/build/mozglue.dll.manifest @@ -0,0 +1,9 @@ + + + + + diff --git a/mozglue/build/mozglue.rc b/mozglue/build/mozglue.rc new file mode 100644 index 000000000000..a678fa3b3d4f --- /dev/null +++ b/mozglue/build/mozglue.rc @@ -0,0 +1,6 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* 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/. */ + +1 RT_MANIFEST "mozglue.dll.manifest" diff --git a/parser/html/nsHtml5StreamParser.cpp b/parser/html/nsHtml5StreamParser.cpp index 81e522b97b72..9a6a777d29cc 100644 --- a/parser/html/nsHtml5StreamParser.cpp +++ b/parser/html/nsHtml5StreamParser.cpp @@ -177,14 +177,13 @@ nsHtml5StreamParser::nsHtml5StreamParser(nsHtml5TreeOpExecutor* aExecutor, , mFeedChardet(false) , mInitialEncodingWasFromParentFrame(false) , mHasHadErrors(false) - , mFlushTimer(NS_NewTimer()) + , mFlushTimer(NS_NewTimer(mEventTarget)) , mFlushTimerMutex("nsHtml5StreamParser mFlushTimerMutex") , mFlushTimerArmed(false) , mFlushTimerEverFired(false) , mMode(aMode) { NS_ASSERTION(NS_IsMainThread(), "Wrong thread!"); - mFlushTimer->SetTarget(mEventTarget); #ifdef DEBUG mAtomTable.SetPermittedLookupEventTarget(mEventTarget); #endif diff --git a/python/mozbuild/mozbuild/action/check_binary.py b/python/mozbuild/mozbuild/action/check_binary.py index e34211fa38b7..aea4d36d3e25 100644 --- a/python/mozbuild/mozbuild/action/check_binary.py +++ b/python/mozbuild/mozbuild/action/check_binary.py @@ -39,6 +39,7 @@ TARGET = { 'readelf': '{}readelf'.format( buildconfig.substs.get('TOOLCHAIN_PREFIX', '')), 'nm': '{}nm'.format(buildconfig.substs.get('TOOLCHAIN_PREFIX', '')), + 'readobj': '{}readobj'.format(buildconfig.substs.get('TOOLCHAIN_PREFIX', '')), } if buildconfig.substs.get('HAVE_64BIT_BUILD'): @@ -190,7 +191,24 @@ def check_nsmodules(target, binary): symbols.append((int(data[2], 16), GUESSED_NSMODULE_SIZE, name)) else: - for line in get_output(target['nm'], '-P', binary): + # MinGW-Clang, when building pdbs, doesn't include the symbol table into + # the final module. To get the NSModule info, we can look at the exported + # symbols. (#1475562) + if buildconfig.substs['OS_ARCH'] == 'WINNT' and \ + buildconfig.substs['HOST_OS_ARCH'] != 'WINNT': + readobj_output = get_output(target['readobj'], '-coff-exports', binary) + # Transform the output of readobj into nm-like output + output = [] + for line in readobj_output: + if "Name" in line: + name = line.replace("Name:", "").strip() + elif "RVA" in line: + rva = line.replace("RVA:", "").strip() + output.append("%s r %s" % (name, rva)) + else: + output = get_output(target['nm'], '-P', binary) + + for line in output: data = line.split() # Some symbols may not have a size listed at all. if len(data) == 3: diff --git a/taskcluster/scripts/misc/build-clang-7-mingw.sh b/taskcluster/scripts/misc/build-clang-7-mingw.sh index d21ec25868f4..014e880c5893 100755 --- a/taskcluster/scripts/misc/build-clang-7-mingw.sh +++ b/taskcluster/scripts/misc/build-clang-7-mingw.sh @@ -275,6 +275,11 @@ build_windres() { # Manually install only nm and windres cp binutils/windres $INSTALL_DIR/bin/$machine-w64-mingw32-windres cp binutils/nm-new $INSTALL_DIR/bin/$machine-w64-mingw32-nm + + pushd $INSTALL_DIR/bin/ + ln -s llvm-readobj $machine-w64-mingw32-readobj + popd + popd } diff --git a/testing/marionette/reftest.js b/testing/marionette/reftest.js index 45d2d0f2684f..898d52abab39 100644 --- a/testing/marionette/reftest.js +++ b/testing/marionette/reftest.js @@ -97,7 +97,7 @@ reftest.Runner = class { let reftestWin = this.parentWindow.open( "chrome://marionette/content/reftest.xul", "reftest", - "chrome,dialog,height=600,width=600"); + "chrome,height=600,width=600"); await new Promise(resolve => { reftestWin.addEventListener("load", resolve, {once: true}); diff --git a/testing/marionette/reftest.xul b/testing/marionette/reftest.xul index fe2d1cfb4848..2c7b96e0d1dc 100644 --- a/testing/marionette/reftest.xul +++ b/testing/marionette/reftest.xul @@ -1,2 +1,5 @@ - + \ No newline at end of file diff --git a/testing/mozbase/mozdevice/tests/manifest.ini b/testing/mozbase/mozdevice/tests/manifest.ini index aac8b424b6a0..c078c87e7349 100644 --- a/testing/mozbase/mozdevice/tests/manifest.ini +++ b/testing/mozbase/mozdevice/tests/manifest.ini @@ -4,3 +4,4 @@ skip-if = python == 3 [test_socket_connection.py] [test_is_app_installed.py] [test_chown.py] +[test_escape_command_line.py] diff --git a/testing/mozbase/mozdevice/tests/test_escape_command_line.py b/testing/mozbase/mozdevice/tests/test_escape_command_line.py new file mode 100644 index 000000000000..23056ceab0d6 --- /dev/null +++ b/testing/mozbase/mozdevice/tests/test_escape_command_line.py @@ -0,0 +1,23 @@ +#!/usr/bin/env python + +from __future__ import absolute_import + +import mozunit + + +def test_escape_command_line(mock_adb_object, redirect_stdout_and_assert): + """Test _escape_command_line.""" + cases = { + # expected output : test input + 'adb shell ls -l': ['adb', 'shell', 'ls', '-l'], + 'adb shell "ls -l"': ['adb', 'shell', 'ls -l'], + '-e "if (true)"': ['-e', 'if (true)'], + '-e "if (x === \\"hello\\")"': ['-e', 'if (x === "hello")'], + '-e "if (x === \'hello\')"': ['-e', "if (x === 'hello')"], + } + for expected, input in cases.items(): + assert mock_adb_object._escape_command_line(input) == expected + + +if __name__ == '__main__': + mozunit.main() diff --git a/testing/web-platform/meta/background-fetch/abort.https.window.js.ini b/testing/web-platform/meta/background-fetch/abort.https.window.js.ini new file mode 100644 index 000000000000..6bb44762d35d --- /dev/null +++ b/testing/web-platform/meta/background-fetch/abort.https.window.js.ini @@ -0,0 +1,7 @@ +[abort.https.window.html] + [Calling BackgroundFetchRegistration.abort sets the correct fields and responses are still available] + expected: FAIL + + [Aborting the same registration twice fails] + expected: FAIL + diff --git a/testing/web-platform/meta/background-fetch/fetch.https.window.js.ini b/testing/web-platform/meta/background-fetch/fetch.https.window.js.ini index 21136acc61c6..ebd1f8da01c4 100644 --- a/testing/web-platform/meta/background-fetch/fetch.https.window.js.ini +++ b/testing/web-platform/meta/background-fetch/fetch.https.window.js.ini @@ -38,3 +38,6 @@ [Requests with PUT method require CORS Preflight and succeed.] expected: FAIL + [Registration object gets updated values when a background fetch completes.] + expected: FAIL + diff --git a/testing/web-platform/meta/css/compositing/mix-blend-mode/mix-blend-mode-parent-element-overflow-scroll.html.ini b/testing/web-platform/meta/css/compositing/mix-blend-mode/mix-blend-mode-parent-element-overflow-scroll.html.ini new file mode 100644 index 000000000000..ac02f42f1ccf --- /dev/null +++ b/testing/web-platform/meta/css/compositing/mix-blend-mode/mix-blend-mode-parent-element-overflow-scroll.html.ini @@ -0,0 +1,3 @@ +[mix-blend-mode-parent-element-overflow-scroll.html] + disabled: + if os == "linux": https://bugzilla.mozilla.org/show_bug.cgi?id=1499779 diff --git a/testing/web-platform/meta/css/css-properties-values-api/self-utils.html.ini b/testing/web-platform/meta/css/css-properties-values-api/self-utils.html.ini new file mode 100644 index 000000000000..46ebce691a64 --- /dev/null +++ b/testing/web-platform/meta/css/css-properties-values-api/self-utils.html.ini @@ -0,0 +1,7 @@ +[self-utils.html] + [Default initial values of generated properties are valid (self-test).] + expected: FAIL + + [Generated properties respect inherits flag] + expected: FAIL + diff --git a/testing/web-platform/meta/dom/interfaces.html.ini b/testing/web-platform/meta/dom/interfaces.html.ini index 9e9921690b3e..87edc3378456 100644 --- a/testing/web-platform/meta/dom/interfaces.html.ini +++ b/testing/web-platform/meta/dom/interfaces.html.ini @@ -88,7 +88,6 @@ expected: FAIL - [interfaces.html?1-1000] [Test driver] expected: FAIL @@ -103,7 +102,6 @@ [Test driver] expected: FAIL - [Document interface: attribute origin] expected: FAIL @@ -175,7 +173,6 @@ [interfaces.html?exclude=Node] prefs: [dom.window.event.enabled:true] - [Document interface: attribute origin] expected: FAIL @@ -242,3 +239,6 @@ [Range interface: existence and properties of interface prototype object] expected: FAIL + [Document interface: existence and properties of interface prototype object's @@unscopables property] + expected: FAIL + diff --git a/testing/web-platform/meta/feature-policy/experimental-features/lazyload/lazyload-image-attribute-on-sanity-check-tentative.sub.html.ini b/testing/web-platform/meta/feature-policy/experimental-features/lazyload/lazyload-image-attribute-on-sanity-check-tentative.sub.html.ini new file mode 100644 index 000000000000..7682fec0085d --- /dev/null +++ b/testing/web-platform/meta/feature-policy/experimental-features/lazyload/lazyload-image-attribute-on-sanity-check-tentative.sub.html.ini @@ -0,0 +1,4 @@ +[lazyload-image-attribute-on-sanity-check-tentative.sub.html] + [Verify 'lazyload' attribute state 'on' works as expected: image loads only when in viewport.] + expected: FAIL + diff --git a/testing/web-platform/meta/feature-policy/picture-in-picture-allowed-by-feature-policy-attribute-redirect-on-load.https.sub.html.ini b/testing/web-platform/meta/feature-policy/picture-in-picture-allowed-by-feature-policy-attribute-redirect-on-load.https.sub.html.ini index 036a9f0405a5..908332d10faf 100644 --- a/testing/web-platform/meta/feature-policy/picture-in-picture-allowed-by-feature-policy-attribute-redirect-on-load.https.sub.html.ini +++ b/testing/web-platform/meta/feature-policy/picture-in-picture-allowed-by-feature-policy-attribute-redirect-on-load.https.sub.html.ini @@ -5,3 +5,6 @@ [Untitled] expected: FAIL + [Feature-Policy allow="picture-in-picture" disallows cross-origin navigation in an iframe.] + expected: FAIL + diff --git a/testing/web-platform/meta/feature-policy/picture-in-picture-disabled-by-feature-policy.https.sub.html.ini b/testing/web-platform/meta/feature-policy/picture-in-picture-disabled-by-feature-policy.https.sub.html.ini index ae3bb4405ef4..a9760fa5eadb 100644 --- a/testing/web-platform/meta/feature-policy/picture-in-picture-disabled-by-feature-policy.https.sub.html.ini +++ b/testing/web-platform/meta/feature-policy/picture-in-picture-disabled-by-feature-policy.https.sub.html.ini @@ -2,3 +2,12 @@ [Untitled] expected: FAIL + [Feature-Policy header: picture-in-picture "none" disallows cross-origin iframes.] + expected: FAIL + + [Feature-Policy header: picture-in-picture "none" disallows same-origin iframes.] + expected: FAIL + + [Feature-Policy header: picture-in-picture "none" disallows the top-level document.] + expected: FAIL + diff --git a/testing/web-platform/meta/feature-policy/reporting/generic-sensor-reporting.https.html.ini b/testing/web-platform/meta/feature-policy/reporting/generic-sensor-reporting.https.html.ini new file mode 100644 index 000000000000..907c9c908c30 --- /dev/null +++ b/testing/web-platform/meta/feature-policy/reporting/generic-sensor-reporting.https.html.ini @@ -0,0 +1,4 @@ +[generic-sensor-reporting.https.html] + [Generic Sensor Report Format] + expected: FAIL + diff --git a/testing/web-platform/meta/fetch/api/request/destination/fetch-destination.https.html.ini b/testing/web-platform/meta/fetch/api/request/destination/fetch-destination.https.html.ini new file mode 100644 index 000000000000..40a1c2e68e65 --- /dev/null +++ b/testing/web-platform/meta/fetch/api/request/destination/fetch-destination.https.html.ini @@ -0,0 +1,5 @@ +[fetch-destination.https.html] + [HTMLLinkElement with rel=preload and as=audio fetches with a "audio" Request.destination] + expected: + if not debug and webrender and e10s and (os == "linux") and (version == "Ubuntu 16.04") and (processor == "x86_64") and (bits == 64): FAIL + diff --git a/testing/web-platform/meta/html/rendering/bindings/the-textarea-element-0/cols-zero.html.ini b/testing/web-platform/meta/html/rendering/bindings/the-textarea-element-0/cols-zero.html.ini index fb6ef36fe347..2ccf5e494d24 100644 --- a/testing/web-platform/meta/html/rendering/bindings/the-textarea-element-0/cols-zero.html.ini +++ b/testing/web-platform/meta/html/rendering/bindings/the-textarea-element-0/cols-zero.html.ini @@ -1,5 +1,3 @@ [cols-zero.html] disabled: if verify and (os == "mac"): fails in verify mode - expected: - if os == "mac": FAIL diff --git a/testing/web-platform/meta/html/rendering/bindings/the-textarea-element-0/rows-zero.html.ini b/testing/web-platform/meta/html/rendering/bindings/the-textarea-element-0/rows-zero.html.ini index 409250047613..0e6281d964c2 100644 --- a/testing/web-platform/meta/html/rendering/bindings/the-textarea-element-0/rows-zero.html.ini +++ b/testing/web-platform/meta/html/rendering/bindings/the-textarea-element-0/rows-zero.html.ini @@ -1,5 +1,3 @@ [rows-zero.html] disabled: if verify and (os == "mac"): fails in verify mode - expected: - if e10s and (os == "mac") and (version == "OS X 10.10.5") and (processor == "x86_64") and (bits == 64): FAIL diff --git a/testing/web-platform/meta/html/rendering/non-replaced-elements/lists/ol-type-unsupported-invalid.html.ini b/testing/web-platform/meta/html/rendering/non-replaced-elements/lists/ol-type-unsupported-invalid.html.ini index 4975c6c24664..3afd30fda2ac 100644 --- a/testing/web-platform/meta/html/rendering/non-replaced-elements/lists/ol-type-unsupported-invalid.html.ini +++ b/testing/web-platform/meta/html/rendering/non-replaced-elements/lists/ol-type-unsupported-invalid.html.ini @@ -1,5 +1,3 @@ [ol-type-unsupported-invalid.html] disabled: if verify and (os == "mac"): fails in verify mode - expected: - if e10s and (os == "mac") and (version == "OS X 10.10.5") and (processor == "x86_64") and (bits == 64): FAIL diff --git a/testing/web-platform/meta/html/rendering/non-replaced-elements/lists/ul-type-supported-xhtml.xhtml.ini b/testing/web-platform/meta/html/rendering/non-replaced-elements/lists/ul-type-supported-xhtml.xhtml.ini index f82b88e94c53..e15855d0f1d4 100644 --- a/testing/web-platform/meta/html/rendering/non-replaced-elements/lists/ul-type-supported-xhtml.xhtml.ini +++ b/testing/web-platform/meta/html/rendering/non-replaced-elements/lists/ul-type-supported-xhtml.xhtml.ini @@ -1,5 +1,3 @@ [ul-type-supported-xhtml.xhtml] disabled: if verify and (os == "mac"): fails in verify mode - expected: - if e10s and (os == "mac") and (version == "OS X 10.10.5") and (processor == "x86_64") and (bits == 64): FAIL diff --git a/testing/web-platform/meta/html/rendering/non-replaced-elements/lists/ul-type-supported.html.ini b/testing/web-platform/meta/html/rendering/non-replaced-elements/lists/ul-type-supported.html.ini index 35e5f4595262..40d269eb4ed2 100644 --- a/testing/web-platform/meta/html/rendering/non-replaced-elements/lists/ul-type-supported.html.ini +++ b/testing/web-platform/meta/html/rendering/non-replaced-elements/lists/ul-type-supported.html.ini @@ -1,5 +1,3 @@ [ul-type-supported.html] disabled: if verify and (os == "mac"): fails in verify mode - expected: - if e10s and (os == "mac") and (version == "OS X 10.10.5") and (processor == "x86_64") and (bits == 64): FAIL diff --git a/testing/web-platform/meta/html/rendering/non-replaced-elements/lists/ul-type-unsupported-invalid.html.ini b/testing/web-platform/meta/html/rendering/non-replaced-elements/lists/ul-type-unsupported-invalid.html.ini index b48f1a7d9ebd..2adaba70cb7b 100644 --- a/testing/web-platform/meta/html/rendering/non-replaced-elements/lists/ul-type-unsupported-invalid.html.ini +++ b/testing/web-platform/meta/html/rendering/non-replaced-elements/lists/ul-type-unsupported-invalid.html.ini @@ -1,5 +1,3 @@ [ul-type-unsupported-invalid.html] disabled: if verify and (os == "mac"): fails in verify mode - expected: - if e10s and (os == "mac") and (version == "OS X 10.10.5") and (processor == "x86_64") and (bits == 64): FAIL diff --git a/testing/web-platform/meta/html/rendering/the-details-element/details-before.html.ini b/testing/web-platform/meta/html/rendering/the-details-element/details-before.html.ini index 2628da449120..005bc0987324 100644 --- a/testing/web-platform/meta/html/rendering/the-details-element/details-before.html.ini +++ b/testing/web-platform/meta/html/rendering/the-details-element/details-before.html.ini @@ -1,7 +1,4 @@ [details-before.html] disabled: if verify and (os == "mac"): fails in verify mode - expected: - if debug and not webrender and e10s and (os == "mac") and (version == "OS X 10.10.5") and (processor == "x86_64") and (bits == 64): PASS - if not debug and not webrender and e10s and (os == "mac") and (version == "OS X 10.10.5") and (processor == "x86_64") and (bits == 64): PASS - FAIL + expected: FAIL diff --git a/testing/web-platform/meta/html/semantics/embedded-content/the-iframe-element/iframe-with-base.html.ini b/testing/web-platform/meta/html/semantics/embedded-content/the-iframe-element/iframe-with-base.html.ini index ca83f9719065..5f41542e78db 100644 --- a/testing/web-platform/meta/html/semantics/embedded-content/the-iframe-element/iframe-with-base.html.ini +++ b/testing/web-platform/meta/html/semantics/embedded-content/the-iframe-element/iframe-with-base.html.ini @@ -1,5 +1,3 @@ [iframe-with-base.html] disabled: if verify and (os == "mac"): fails in verify mode - expected: - if e10s and (os == "mac") and (version == "OS X 10.10.5") and (processor == "x86_64") and (bits == 64): FAIL diff --git a/testing/web-platform/meta/html/semantics/embedded-content/the-img-element/document-adopt-base-url.html.ini b/testing/web-platform/meta/html/semantics/embedded-content/the-img-element/document-adopt-base-url.html.ini index e81bfea400b9..f8624a345539 100644 --- a/testing/web-platform/meta/html/semantics/embedded-content/the-img-element/document-adopt-base-url.html.ini +++ b/testing/web-platform/meta/html/semantics/embedded-content/the-img-element/document-adopt-base-url.html.ini @@ -1,5 +1,3 @@ [document-adopt-base-url.html] disabled: if verify and (os == "mac"): fails in verify mode - expected: - if os == "mac": FAIL diff --git a/testing/web-platform/meta/infrastructure/reftest/reftest_or_0.html.ini b/testing/web-platform/meta/infrastructure/reftest/reftest_or_0.html.ini deleted file mode 100644 index 3884f268904f..000000000000 --- a/testing/web-platform/meta/infrastructure/reftest/reftest_or_0.html.ini +++ /dev/null @@ -1,4 +0,0 @@ -[reftest_or_0.html] - expected: - if debug and not webrender and e10s and (os == "mac") and (version == "OS X 10.10.5") and (processor == "x86_64") and (bits == 64): FAIL - if not debug and not webrender and e10s and (os == "mac") and (version == "OS X 10.10.5") and (processor == "x86_64") and (bits == 64): FAIL diff --git a/testing/web-platform/meta/mozilla-sync b/testing/web-platform/meta/mozilla-sync index 0e96d052ad04..f90975d70d99 100644 --- a/testing/web-platform/meta/mozilla-sync +++ b/testing/web-platform/meta/mozilla-sync @@ -1,2 +1,2 @@ -local: 05a38ce912d57ee269bd0af8f0b3ced1bb5f068b -upstream: 9f2daa2a5d08d0d44f680501af2b62292f6264f0 +local: db5952ad2f9586639fd0aeea8a5cd2d9967c101e +upstream: 37d83def16bacfa66abac065f8f5adc8f7e7a4fc diff --git a/testing/web-platform/meta/picture-in-picture/idlharness.window.js.ini b/testing/web-platform/meta/picture-in-picture/idlharness.window.js.ini index 766dd1669017..3dfb3609d11a 100644 --- a/testing/web-platform/meta/picture-in-picture/idlharness.window.js.ini +++ b/testing/web-platform/meta/picture-in-picture/idlharness.window.js.ini @@ -110,3 +110,9 @@ [EnterPictureInPictureEvent interface: existence and properties of interface object] expected: FAIL + [HTMLVideoElement interface: operation requestPictureInPicture()] + expected: FAIL + + [HTMLVideoElement interface: video must inherit property "requestPictureInPicture()" with the proper type] + expected: FAIL + diff --git a/testing/web-platform/meta/service-workers/service-worker/service-worker-header.https.html.ini b/testing/web-platform/meta/service-workers/service-worker/service-worker-header.https.html.ini new file mode 100644 index 000000000000..c1d9879f95c7 --- /dev/null +++ b/testing/web-platform/meta/service-workers/service-worker/service-worker-header.https.html.ini @@ -0,0 +1,4 @@ +[service-worker-header.https.html] + [A request to fetch service worker importScripts() resources during the update should not have Service-Worker header] + expected: TIMEOUT + diff --git a/testing/web-platform/meta/svg/shapes/ellipse-04.svg.ini b/testing/web-platform/meta/svg/shapes/ellipse-04.svg.ini deleted file mode 100644 index 7d468f97d86d..000000000000 --- a/testing/web-platform/meta/svg/shapes/ellipse-04.svg.ini +++ /dev/null @@ -1,3 +0,0 @@ -[ellipse-04.svg] - expected: - if os == "mac": FAIL diff --git a/testing/web-platform/meta/svg/shapes/line-dasharray.svg.ini b/testing/web-platform/meta/svg/shapes/line-dasharray.svg.ini index 6c723c282ee9..fb16519844a6 100644 --- a/testing/web-platform/meta/svg/shapes/line-dasharray.svg.ini +++ b/testing/web-platform/meta/svg/shapes/line-dasharray.svg.ini @@ -1,4 +1,2 @@ [line-dasharray.svg] - expected: - if os == "mac": FAIL restart-after: true diff --git a/testing/web-platform/meta/trusted-types/Document-write.tentative.html.ini b/testing/web-platform/meta/trusted-types/Document-write.tentative.html.ini index fcff1ec25784..5d2f777d21c2 100644 --- a/testing/web-platform/meta/trusted-types/Document-write.tentative.html.ini +++ b/testing/web-platform/meta/trusted-types/Document-write.tentative.html.ini @@ -2,3 +2,6 @@ [document.write with html assigned via policy (successful URL transformation).] expected: FAIL + [document.write with html assigned via policy (successful transformation).] + expected: FAIL + diff --git a/testing/web-platform/meta/url/failure.html.ini b/testing/web-platform/meta/url/failure.html.ini index d72cadfc7a1b..025471036ebe 100644 --- a/testing/web-platform/meta/url/failure.html.ini +++ b/testing/web-platform/meta/url/failure.html.ini @@ -482,3 +482,39 @@ [window.open(): a// should throw] expected: FAIL + [sendBeacon(): https://� should throw] + expected: FAIL + + [window.open(): https://� should throw] + expected: FAIL + + [Location's href: https://� should throw] + expected: FAIL + + [XHR: https://� should throw] + expected: FAIL + + [URL's constructor's base argument: https://� should throw] + expected: FAIL + + [URL's href: https://� should throw] + expected: FAIL + + [sendBeacon(): https://� should throw] + expected: FAIL + + [window.open(): https://� should throw] + expected: FAIL + + [Location's href: https://� should throw] + expected: FAIL + + [XHR: https://� should throw] + expected: FAIL + + [URL's constructor's base argument: https://� should throw] + expected: FAIL + + [URL's href: https://� should throw] + expected: FAIL + diff --git a/testing/web-platform/meta/wasm/idlharness.any.js.ini b/testing/web-platform/meta/wasm/idlharness.any.js.ini deleted file mode 100644 index c5ad27c3c545..000000000000 --- a/testing/web-platform/meta/wasm/idlharness.any.js.ini +++ /dev/null @@ -1,368 +0,0 @@ -[idlharness.any.html] - [Module interface: existence and properties of interface object] - expected: FAIL - - [Module interface object length] - expected: FAIL - - [Module interface object name] - expected: FAIL - - [Module interface: existence and properties of interface prototype object] - expected: FAIL - - [Module interface: existence and properties of interface prototype object's "constructor" property] - expected: FAIL - - [Module interface: existence and properties of interface prototype object's @@unscopables property] - expected: FAIL - - [Module interface: operation exports(Module)] - expected: FAIL - - [Module interface: operation imports(Module)] - expected: FAIL - - [Module interface: operation customSections(Module, USVString)] - expected: FAIL - - [Module must be primary interface of mod] - expected: FAIL - - [Stringification of mod] - expected: FAIL - - [Instance interface: existence and properties of interface object] - expected: FAIL - - [Instance interface object length] - expected: FAIL - - [Instance interface object name] - expected: FAIL - - [Instance interface: existence and properties of interface prototype object] - expected: FAIL - - [Instance interface: existence and properties of interface prototype object's "constructor" property] - expected: FAIL - - [Instance interface: existence and properties of interface prototype object's @@unscopables property] - expected: FAIL - - [Instance interface: attribute exports] - expected: FAIL - - [Instance must be primary interface of instance] - expected: FAIL - - [Stringification of instance] - expected: FAIL - - [Instance interface: instance must inherit property "exports" with the proper type] - expected: FAIL - - [Memory interface: existence and properties of interface object] - expected: FAIL - - [Memory interface object length] - expected: FAIL - - [Memory interface object name] - expected: FAIL - - [Memory interface: existence and properties of interface prototype object] - expected: FAIL - - [Memory interface: existence and properties of interface prototype object's "constructor" property] - expected: FAIL - - [Memory interface: existence and properties of interface prototype object's @@unscopables property] - expected: FAIL - - [Memory interface: operation grow(unsigned long)] - expected: FAIL - - [Memory interface: attribute buffer] - expected: FAIL - - [Memory must be primary interface of memory] - expected: FAIL - - [Stringification of memory] - expected: FAIL - - [Memory interface: memory must inherit property "grow(unsigned long)" with the proper type] - expected: FAIL - - [Memory interface: calling grow(unsigned long) on memory with too few arguments must throw TypeError] - expected: FAIL - - [Memory interface: memory must inherit property "buffer" with the proper type] - expected: FAIL - - [Table interface: existence and properties of interface object] - expected: FAIL - - [Table interface object length] - expected: FAIL - - [Table interface object name] - expected: FAIL - - [Table interface: existence and properties of interface prototype object] - expected: FAIL - - [Table interface: existence and properties of interface prototype object's "constructor" property] - expected: FAIL - - [Table interface: existence and properties of interface prototype object's @@unscopables property] - expected: FAIL - - [Table interface: operation grow(unsigned long)] - expected: FAIL - - [Table interface: operation get(unsigned long)] - expected: FAIL - - [Table interface: operation set(unsigned long, Function)] - expected: FAIL - - [Table interface: attribute length] - expected: FAIL - - [Global interface: existence and properties of interface object] - expected: FAIL - - [Global interface object length] - expected: FAIL - - [Global interface object name] - expected: FAIL - - [Global interface: existence and properties of interface prototype object] - expected: FAIL - - [Global interface: existence and properties of interface prototype object's "constructor" property] - expected: FAIL - - [Global interface: existence and properties of interface prototype object's @@unscopables property] - expected: FAIL - - [Global interface: operation valueOf()] - expected: FAIL - - [Global interface: attribute value] - expected: FAIL - - [CompileError interface: existence and properties of interface object] - expected: FAIL - - [CompileError interface object length] - expected: FAIL - - [CompileError interface object name] - expected: FAIL - - [CompileError interface: existence and properties of interface prototype object] - expected: FAIL - - [CompileError interface: existence and properties of interface prototype object's "constructor" property] - expected: FAIL - - [CompileError interface: existence and properties of interface prototype object's @@unscopables property] - expected: FAIL - - [LinkError interface: existence and properties of interface object] - expected: FAIL - - [LinkError interface object length] - expected: FAIL - - [LinkError interface object name] - expected: FAIL - - [LinkError interface: existence and properties of interface prototype object] - expected: FAIL - - [LinkError interface: existence and properties of interface prototype object's "constructor" property] - expected: FAIL - - [LinkError interface: existence and properties of interface prototype object's @@unscopables property] - expected: FAIL - - [RuntimeError interface: existence and properties of interface object] - expected: FAIL - - [RuntimeError interface object length] - expected: FAIL - - [RuntimeError interface object name] - expected: FAIL - - [RuntimeError interface: existence and properties of interface prototype object] - expected: FAIL - - [RuntimeError interface: existence and properties of interface prototype object's "constructor" property] - expected: FAIL - - [RuntimeError interface: existence and properties of interface prototype object's @@unscopables property] - expected: FAIL - - -[idlharness.any.worker.html] - [Module interface: existence and properties of interface object] - expected: FAIL - - [Module interface object length] - expected: FAIL - - [Module interface object name] - expected: FAIL - - [Module interface: existence and properties of interface prototype object] - expected: FAIL - - [Module interface: existence and properties of interface prototype object's "constructor" property] - expected: FAIL - - [Module interface: existence and properties of interface prototype object's @@unscopables property] - expected: FAIL - - [Module interface: operation exports(Module)] - expected: FAIL - - [Module interface: operation imports(Module)] - expected: FAIL - - [Module interface: operation customSections(Module, USVString)] - expected: FAIL - - [Module must be primary interface of mod] - expected: FAIL - - [Stringification of mod] - expected: FAIL - - [Instance interface: existence and properties of interface object] - expected: FAIL - - [Instance interface object length] - expected: FAIL - - [Instance interface object name] - expected: FAIL - - [Instance interface: existence and properties of interface prototype object] - expected: FAIL - - [Instance interface: existence and properties of interface prototype object's "constructor" property] - expected: FAIL - - [Instance interface: existence and properties of interface prototype object's @@unscopables property] - expected: FAIL - - [Instance interface: attribute exports] - expected: FAIL - - [Instance must be primary interface of instance] - expected: FAIL - - [Stringification of instance] - expected: FAIL - - [Instance interface: instance must inherit property "exports" with the proper type] - expected: FAIL - - [Memory interface: existence and properties of interface object] - expected: FAIL - - [Memory interface object length] - expected: FAIL - - [Memory interface object name] - expected: FAIL - - [Memory interface: existence and properties of interface prototype object] - expected: FAIL - - [Memory interface: existence and properties of interface prototype object's "constructor" property] - expected: FAIL - - [Memory interface: existence and properties of interface prototype object's @@unscopables property] - expected: FAIL - - [Memory interface: operation grow(unsigned long)] - expected: FAIL - - [Memory interface: attribute buffer] - expected: FAIL - - [Memory must be primary interface of memory] - expected: FAIL - - [Stringification of memory] - expected: FAIL - - [Memory interface: memory must inherit property "grow(unsigned long)" with the proper type] - expected: FAIL - - [Memory interface: calling grow(unsigned long) on memory with too few arguments must throw TypeError] - expected: FAIL - - [Memory interface: memory must inherit property "buffer" with the proper type] - expected: FAIL - - [Table interface: existence and properties of interface object] - expected: FAIL - - [Table interface object length] - expected: FAIL - - [Table interface object name] - expected: FAIL - - [Table interface: existence and properties of interface prototype object] - expected: FAIL - - [Table interface: existence and properties of interface prototype object's "constructor" property] - expected: FAIL - - [Table interface: existence and properties of interface prototype object's @@unscopables property] - expected: FAIL - - [Table interface: operation grow(unsigned long)] - expected: FAIL - - [Table interface: operation get(unsigned long)] - expected: FAIL - - [Table interface: operation set(unsigned long, Function)] - expected: FAIL - - [Table interface: attribute length] - expected: FAIL - - [Global interface: existence and properties of interface object] - expected: FAIL - - [Global interface object length] - expected: FAIL - - [Global interface object name] - expected: FAIL - - [Global interface: existence and properties of interface prototype object] - expected: FAIL - - [Global interface: existence and properties of interface prototype object's "constructor" property] - expected: FAIL - - [Global interface: existence and properties of interface prototype object's @@unscopables property] - expected: FAIL - - [Global interface: operation valueOf()] - expected: FAIL - - [Global interface: attribute value] - expected: FAIL diff --git a/testing/web-platform/meta/webrtc/RTCDTMFSender-ontonechange-long.https.html.ini b/testing/web-platform/meta/webrtc/RTCDTMFSender-ontonechange-long.https.html.ini new file mode 100644 index 000000000000..c899f2930290 --- /dev/null +++ b/testing/web-platform/meta/webrtc/RTCDTMFSender-ontonechange-long.https.html.ini @@ -0,0 +1,9 @@ +[RTCDTMFSender-ontonechange-long.https.html] + [insertDTMF with duration greater than 6000 should be clamped to 6000] + disabled: https://bugzilla.mozilla.org/show_bug.cgi?id=1420640 + expected: + if debug and not webrender and e10s and (os == "linux") and (version == "Ubuntu 16.04") and (processor == "x86_64") and (bits == 64): FAIL + if debug and not webrender and e10s and (os == "linux") and (version == "Ubuntu 16.04") and (processor == "x86") and (bits == 32): FAIL + if not debug and not webrender and e10s and (os == "linux") and (version == "Ubuntu 16.04") and (processor == "x86_64") and (bits == 64): FAIL + if not debug and webrender and e10s and (os == "linux") and (version == "Ubuntu 16.04") and (processor == "x86_64") and (bits == 64): FAIL + diff --git a/testing/web-platform/meta/webvtt/rendering/cues-with-video/processing-model/selectors/default_styles/italic_object_default_font-style.html.ini b/testing/web-platform/meta/webvtt/rendering/cues-with-video/processing-model/selectors/default_styles/italic_object_default_font-style.html.ini index 10a644945906..92e3c95b2b3f 100644 --- a/testing/web-platform/meta/webvtt/rendering/cues-with-video/processing-model/selectors/default_styles/italic_object_default_font-style.html.ini +++ b/testing/web-platform/meta/webvtt/rendering/cues-with-video/processing-model/selectors/default_styles/italic_object_default_font-style.html.ini @@ -1,5 +1,3 @@ [italic_object_default_font-style.html] disabled: if verify and (os == "mac"): fails in verify mode - expected: - if os == "mac": FAIL diff --git a/testing/web-platform/meta/webvtt/rendering/cues-with-video/processing-model/selectors/default_styles/underline_object_default_font-style.html.ini b/testing/web-platform/meta/webvtt/rendering/cues-with-video/processing-model/selectors/default_styles/underline_object_default_font-style.html.ini index c02446d9f650..2ccbb0a37bbc 100644 --- a/testing/web-platform/meta/webvtt/rendering/cues-with-video/processing-model/selectors/default_styles/underline_object_default_font-style.html.ini +++ b/testing/web-platform/meta/webvtt/rendering/cues-with-video/processing-model/selectors/default_styles/underline_object_default_font-style.html.ini @@ -1,5 +1,3 @@ [underline_object_default_font-style.html] disabled: if verify and (os == "mac"): fails in verify mode - expected: - if os == "mac": FAIL diff --git a/testing/web-platform/meta/webvtt/rendering/cues-with-video/processing-model/too_many_cues.html.ini b/testing/web-platform/meta/webvtt/rendering/cues-with-video/processing-model/too_many_cues.html.ini index 9bb2b2c25c78..d2a63ceb2880 100644 --- a/testing/web-platform/meta/webvtt/rendering/cues-with-video/processing-model/too_many_cues.html.ini +++ b/testing/web-platform/meta/webvtt/rendering/cues-with-video/processing-model/too_many_cues.html.ini @@ -1,2 +1,5 @@ [too_many_cues.html] - expected: FAIL + expected: + if debug and not webrender and e10s and (os == "mac") and (version == "OS X 10.10.5") and (processor == "x86_64") and (bits == 64): PASS + if not debug and not webrender and e10s and (os == "mac") and (version == "OS X 10.10.5") and (processor == "x86_64") and (bits == 64): PASS + FAIL diff --git a/testing/web-platform/tests/background-fetch/abort.https.window.js b/testing/web-platform/tests/background-fetch/abort.https.window.js new file mode 100644 index 000000000000..db01bf94b85f --- /dev/null +++ b/testing/web-platform/tests/background-fetch/abort.https.window.js @@ -0,0 +1,59 @@ +// META: script=/service-workers/service-worker/resources/test-helpers.sub.js +// META: script=resources/utils.js +'use strict'; + +// Covers basic functionality provided by BackgroundFetchManager.abort(). +// https://wicg.github.io/background-fetch/#background-fetch-registration-abort + +backgroundFetchTest(async (test, backgroundFetch) => { + const registration = await backgroundFetch.fetch( + uniqueId(), + ['resources/feature-name.txt', '/serviceworker/resources/slow-response.php']); + + assert_true(await registration.abort()); + assert_false(await registration.abort()); + +}, 'Aborting the same registration twice fails'); + +backgroundFetchTest(async (test, backgroundFetch) => { + const registration = await backgroundFetch.fetch( + uniqueId(), + ['resources/feature-name.txt', '/serviceworker/resources/slow-response.php']); + + await new Promise(resolve => { + let aborted = false; + const expectedResultText = 'Background Fetch'; + + registration.onprogress = async event => { + if (event.target.downloaded < expectedResultText.length) + return; + + if (aborted) + return; + + // Abort after the first file has been downloaded and check the results. + + aborted = true; + assert_true(await registration.abort()); + + const {type, eventRegistration, results} = await getMessageFromServiceWorker(); + + assert_equals(eventRegistration.result, 'failure'); + assert_equals(eventRegistration.failureReason, 'aborted'); + assert_equals(registration.result, 'failure'); + assert_equals(registration.failureReason, 'aborted'); + + assert_equals(type, 'backgroundfetchabort'); + + // The abort might have gone through before the first result was persisted. + if (results.length === 1) { + assert_true(results[0].url.includes('resources/feature-name.txt')); + assert_equals(results[0].status, 200); + assert_equals(results[0].text, expectedResultText); + } + + resolve(); + }; + }); + +}, 'Calling BackgroundFetchRegistration.abort sets the correct fields and responses are still available'); \ No newline at end of file diff --git a/testing/web-platform/tests/background-fetch/fetch.https.window.js b/testing/web-platform/tests/background-fetch/fetch.https.window.js index 77297186ca45..9ed7e94da3bf 100644 --- a/testing/web-platform/tests/background-fetch/fetch.https.window.js +++ b/testing/web-platform/tests/background-fetch/fetch.https.window.js @@ -145,6 +145,24 @@ backgroundFetchTest(async (test, backgroundFetch) => { }, 'Using Background Fetch to successfully fetch a single resource'); +backgroundFetchTest(async (test, backgroundFetch) => { + const registrationId = uniqueId(); + const registration = + await backgroundFetch.fetch(registrationId, 'resources/feature-name.txt'); + + assert_equals(registration.result, ''); + assert_equals(registration.failureReason, ''); + + const {type, eventRegistration, results} = + await getMessageFromServiceWorker(); + assert_equals('backgroundfetchsuccess', type); + + assert_equals(eventRegistration.id, registration.id); + assert_equals(registration.result, 'success'); + assert_equals(registration.failureReason, ''); + +}, 'Registration object gets updated values when a background fetch completes.'); + backgroundFetchTest(async (test, backgroundFetch) => { const registrationId = uniqueId(); @@ -240,6 +258,9 @@ backgroundFetchTest(async (test, backgroundFetch) => { assert_equals(eventRegistration.result, 'failure'); assert_equals(eventRegistration.failureReason, 'bad-status'); + assert_equals(registration.result, 'failure'); + assert_equals(registration.failureReason, 'bad-status'); + }, 'Using Background Fetch to fetch a non-existent resource should fail.'); backgroundFetchTest(async (test, backgroundFetch) => { diff --git a/testing/web-platform/tests/background-fetch/service_workers/sw.js b/testing/web-platform/tests/background-fetch/service_workers/sw.js index af4655dbad4e..2e3fbfff1a83 100644 --- a/testing/web-platform/tests/background-fetch/service_workers/sw.js +++ b/testing/web-platform/tests/background-fetch/service_workers/sw.js @@ -27,3 +27,4 @@ function handleBackgroundFetchUpdateEvent(event) { self.addEventListener('backgroundfetchsuccess', handleBackgroundFetchUpdateEvent); self.addEventListener('backgroundfetchfail', handleBackgroundFetchUpdateEvent); +self.addEventListener('backgroundfetchabort', handleBackgroundFetchUpdateEvent); diff --git a/testing/web-platform/tests/css/css-properties-values-api/registered-property-computation.html b/testing/web-platform/tests/css/css-properties-values-api/registered-property-computation.html index 30d6b4bd609b..cbcc0bea64d4 100644 --- a/testing/web-platform/tests/css/css-properties-values-api/registered-property-computation.html +++ b/testing/web-platform/tests/css/css-properties-values-api/registered-property-computation.html @@ -1,117 +1,115 @@ - + + + diff --git a/testing/web-platform/tests/css/css-properties-values-api/resources/utils.js b/testing/web-platform/tests/css/css-properties-values-api/resources/utils.js new file mode 100644 index 000000000000..c4dc3fd5a8d9 --- /dev/null +++ b/testing/web-platform/tests/css/css-properties-values-api/resources/utils.js @@ -0,0 +1,86 @@ +let next_property_id = 1; + +// Generate a unique property name on the form --prop-N. +function generate_name() { + return `--prop-${next_property_id++}`; +} + +// Produce a compatible initial value for the specified syntax. +function any_initial_value(syntax) { + let components = syntax.split('|').map(x => x.trim()) + let first_component = components[0]; + + if (first_component.endsWith('+') || first_component.endsWith('#')) + first_component = first_component.slice(0, -1); + + switch (first_component) { + case '*': + case '': + return 'NULL'; + case '': + return '0deg'; + case '': + return 'rgb(0, 0, 0)'; + case '': + case '': + return 'url(0)'; + case '': + case '': + case '': + case '': + return '0'; + case '': + return '0%'; + case '': + return '0dpi'; + case '': + return '0s'; + case '': + case '': + return 'matrix(0, 0, 0, 0, 0, 0)'; + default: + // We assume syntax is a specific custom ident. + return first_component; + } +} + +// Registers a unique property on the form '--prop-N' and returns the name. +// Any value except 'syntax' may be omitted, in which case the property will +// not inherit, and some undefined (but compatible) initial value will be +// generated. If a single string is used as the argument, it is assumed to be +// the syntax. +function generate_property(reg) { + let syntax = typeof(reg) === 'string' ? reg : reg.syntax; + let initial = typeof(reg.initialValue) === 'undefined' ? any_initial_value(syntax) + : reg.initialValue; + let inherits = typeof(reg.inherits) === 'undefined' ? false : reg.inherits; + + let name = generate_name(); + CSS.registerProperty({ + name: name, + syntax: syntax, + initialValue: initial, + inherits: inherits + }); + return name; +} + +function all_syntaxes() { + return [ + '*', + '', + '', + '', + '', + '', + '', + '', + '', + '', + '', + '', + '', + '', + '' + ] +} diff --git a/testing/web-platform/tests/css/css-properties-values-api/self-utils.html b/testing/web-platform/tests/css/css-properties-values-api/self-utils.html new file mode 100644 index 000000000000..530c5f677ad2 --- /dev/null +++ b/testing/web-platform/tests/css/css-properties-values-api/self-utils.html @@ -0,0 +1,35 @@ + +Self-test for utils.js + + + + + + diff --git a/testing/web-platform/tests/css/css-properties-values-api/typedom.tentative.html b/testing/web-platform/tests/css/css-properties-values-api/typedom.tentative.html index 6d0623bba420..0255b8f7a2d2 100644 --- a/testing/web-platform/tests/css/css-properties-values-api/typedom.tentative.html +++ b/testing/web-platform/tests/css/css-properties-values-api/typedom.tentative.html @@ -221,86 +221,86 @@ test_style_property_map_get(function(styleDecl, propertyMap){ let name2 = gen_prop('', '0px'); styleDecl.setProperty(name2, `var(${name1})`); assert_true(propertyMap.get(name2) instanceof CSSUnparsedValue); -}, name => `${name}.get returns CSSUnparsedValue for value with var references`); +}, name => `StylePropertyMap.get returns CSSUnparsedValue for value with var references (${name})`); test_style_property_map_get(function(styleDecl, propertyMap){ let name1 = gen_prop('', '100px'); let name2 = gen_prop('#', '0px'); styleDecl.setProperty(name2, `1px, var(${name1}), 3px`); assert_true(propertyMap.get(name2) instanceof CSSUnparsedValue); -}, name => `${name}.get returns CSSUnparsedValue for value with var references in list`); +}, name => `StylePropertyMap.get returns CSSUnparsedValue for value with var references in list (${name})`); test_style_property_map_get(function(styleDecl, propertyMap){ assert_attribute_get_type(styleDecl, propertyMap, '*', 'if(){}', CSSUnparsedValue); -}, name => `${name}.get returns CSSUnparsedValue for *`); +}, name => `StylePropertyMap.get returns CSSUnparsedValue for * (${name})`); test_style_property_map_get(function(styleDecl, propertyMap){ assert_attribute_get_type(styleDecl, propertyMap, '', '42deg', CSSUnitValue); -}, name => `${name}.get returns CSSUnitValue for `); +}, name => `StylePropertyMap.get returns CSSUnitValue for (${name})`); test_style_property_map_get(function(styleDecl, propertyMap){ assert_attribute_get_type(styleDecl, propertyMap, '', '#fefefe', CSSStyleValue); -}, name => `${name}.get returns CSSStyleValue for `); +}, name => `StylePropertyMap.get returns CSSStyleValue for (${name})`); test_style_property_map_get(function(styleDecl, propertyMap){ assert_attribute_get_type(styleDecl, propertyMap, '', 'none', CSSKeywordValue); -}, name => `${name}.get returns CSSKeywordValue for `); +}, name => `StylePropertyMap.get returns CSSKeywordValue for (${name})`); test_style_property_map_get(function(styleDecl, propertyMap){ assert_attribute_get_type(styleDecl, propertyMap, '', 'url(thing.png)', CSSImageValue); -}, name => `${name}.get returns CSSImageValue for `); +}, name => `StylePropertyMap.get returns CSSImageValue for (${name})`); test_style_property_map_get(function(styleDecl, propertyMap){ assert_attribute_get_type(styleDecl, propertyMap, '', '100', CSSUnitValue); -}, name => `${name}.get returns CSSUnitValue for `); +}, name => `StylePropertyMap.get returns CSSUnitValue for (${name})`); test_style_property_map_get(function(styleDecl, propertyMap){ assert_attribute_get_type(styleDecl, propertyMap, '', '10%', CSSUnitValue); -}, name => `${name}.get returns CSSUnitValue for [10%]`); +}, name => `StylePropertyMap.get returns CSSUnitValue for [10%] (${name})`); test_style_property_map_get(function(styleDecl, propertyMap){ assert_attribute_get_type(styleDecl, propertyMap, '', '10px', CSSUnitValue); -}, name => `${name}.get returns CSSUnitValue for [10px]`); +}, name => `StylePropertyMap.get returns CSSUnitValue for [10px] (${name})`); test_style_property_map_get(function(styleDecl, propertyMap){ assert_attribute_get_type(styleDecl, propertyMap, '', 'calc(10px + 10%)', CSSMathSum); -}, name => `${name}.get returns CSSMathSum for [calc(10px + 10%)]`); +}, name => `StylePropertyMap.get returns CSSMathSum for [calc(10px + 10%)] (${name})`); test_style_property_map_get(function(styleDecl, propertyMap){ assert_attribute_get_type(styleDecl, propertyMap, '', '10px', CSSUnitValue); -}, name => `${name}.get returns CSSUnitValue for `); +}, name => `StylePropertyMap.get returns CSSUnitValue for (${name})`); test_style_property_map_get(function(styleDecl, propertyMap){ assert_attribute_get_type(styleDecl, propertyMap, '', '42', CSSUnitValue); -}, name => `${name}.get returns CSSUnitValue for `); +}, name => `StylePropertyMap.get returns CSSUnitValue for (${name})`); test_style_property_map_get(function(styleDecl, propertyMap){ assert_attribute_get_type(styleDecl, propertyMap, '', '10%', CSSUnitValue); -}, name => `${name}.get returns CSSUnitValue for `); +}, name => `StylePropertyMap.get returns CSSUnitValue for (${name})`); test_style_property_map_get(function(styleDecl, propertyMap){ assert_attribute_get_type(styleDecl, propertyMap, '', '300dpi', CSSUnitValue); -}, name => `${name}.get returns CSSUnitValue for `); +}, name => `StylePropertyMap.get returns CSSUnitValue for (${name})`); test_style_property_map_get(function(styleDecl, propertyMap){ assert_attribute_get_type(styleDecl, propertyMap, '', '42s', CSSUnitValue); -}, name => `${name}.get returns CSSUnitValue for `); +}, name => `StylePropertyMap.get returns CSSUnitValue for (${name})`); test_style_property_map_get(function(styleDecl, propertyMap){ assert_attribute_get_type(styleDecl, propertyMap, '', 'url(a)', CSSStyleValue); -}, name => `${name}.get returns CSSStyleValue for `); +}, name => `StylePropertyMap.get returns CSSStyleValue for (${name})`); test_style_property_map_get(function(styleDecl, propertyMap){ assert_attribute_get_type(styleDecl, propertyMap, 'thing1 | THING2', 'thing1', CSSKeywordValue); -}, name => `${name}.get returns CSSKeywordValue for thing1 | THING2`); +}, name => `StylePropertyMap.get returns CSSKeywordValue for thing1 | THING2 (${name})`); test_style_property_map_get(function(styleDecl, propertyMap){ assert_attribute_get_type(styleDecl, propertyMap, '+', '10px 20px', CSSUnitValue); -}, name => `${name}.get returns CSSUnitValue for +`); +}, name => `StylePropertyMap.get returns CSSUnitValue for + (${name})`); test_style_property_map_get(function(styleDecl, propertyMap){ assert_attribute_get_type(styleDecl, propertyMap, '#', '10px 20px', CSSUnitValue); -}, name => `${name}.get returns CSSUnitValue for #`); +}, name => `StylePropertyMap.get returns CSSUnitValue for # (${name})`); // attributeStyleMap.getAll @@ -309,14 +309,14 @@ test_style_property_map_get(function(styleDecl, propertyMap){ styleDecl.setProperty(name, '10px 20px 30px'); assert_equals(propertyMap.getAll(name).length, 3); assert_true(propertyMap.getAll(name).every(x => x instanceof CSSUnitValue)); -}, name => `${name}.getAll returns a list of CSSUnitValues for +`); +}, name => `StylePropertyMap.getAll returns a list of CSSUnitValues for + (${name})`); test_style_property_map_get(function(styleDecl, propertyMap){ let name = gen_prop('#', '0px'); styleDecl.setProperty(name, '10px, 20px, 30px'); assert_equals(propertyMap.getAll(name).length, 3); assert_true(propertyMap.getAll(name).every(x => x instanceof CSSUnitValue)); -}, name => `${name}.getAll returns a list of CSSUnitValues for #`); +}, name => `StylePropertyMap.getAll returns a list of CSSUnitValues for # (${name})`); // StylePropertyMap.set @@ -325,13 +325,15 @@ function test_style_property_map_set_using_property_map(propertyMapName, propert let name = gen_prop(options.syntax, options.initialValue); propertyMap.clear(); + let ensureArray = v => v.constructor === Array ? v : [v]; + for (let value of options.shouldAccept) - propertyMap.set(name, value); + propertyMap.set(name, ...ensureArray(value)); for (let value of options.shouldReject) { - assert_throws(new TypeError(), () => propertyMap.set(name, value)); + assert_throws(new TypeError(), () => propertyMap.set(name, ...ensureArray(value))); } - }, `${propertyMapName}.set accepts correct CSSUnitValues for ${options.syntax}`); + }, `StylePropertyMap.set accepts correct CSSStyleValues for ${options.syntax} (${propertyMapName})`); } // Verify that the correct CSSStyleValues are accepted/rejected for a registered @@ -360,77 +362,77 @@ test_style_property_map_set({ syntax: '', initialValue: '0deg', shouldAccept: [CSS.deg(42), CSS.turn(2), '42deg'], - shouldReject: [unparsed('42deg'), CSS.px(15), '50px'], + shouldReject: [unparsed('42deg'), CSS.px(15), '50px', [CSS.deg(15), '10deg']], }); test_style_property_map_set({ syntax: '', initialValue: 'none', shouldAccept: [keyword('foo'), 'foo'], - shouldReject: [unparsed('foo'), CSS.px(15), '15px'], + shouldReject: [unparsed('foo'), CSS.px(15), '15px', [keyword('foo'), 'foo']], }); test_style_property_map_set({ syntax: '', initialValue: 'url(a)', shouldAccept: [url_image('url(b)'), 'url(b)'], - shouldReject: [unparsed('url(b)'), CSS.px(100), '50px'], + shouldReject: [unparsed('url(b)'), CSS.px(100), '50px', [url_image('url(1)'), 'url(2)']], }); test_style_property_map_set({ syntax: '', initialValue: '0', shouldAccept: [CSS.number(1), CSS.number(-42), '1', '-42'], - shouldReject: [unparsed('42'), CSS.px(100), '50px'], + shouldReject: [unparsed('42'), CSS.px(100), '50px', [CSS.number(42), '42']], }); test_style_property_map_set({ syntax: '', initialValue: '0px', shouldAccept: [CSS.percent(10), CSS.px(1), CSS.em(1), '10px', '10%'], - shouldReject: [unparsed('10%'), unparsed('10px'), CSS.dpi(1), 'url(b)'], + shouldReject: [unparsed('10%'), unparsed('10px'), CSS.dpi(1), 'url(b)', [CSS.percent(10), '10%']], }); test_style_property_map_set({ syntax: '', initialValue: '0px', shouldAccept: [CSS.px(10), CSS.em(10), CSS.vh(200), sum(CSS.px(10), CSS.em(20)), '10em', 'calc(10px + 10em)'], - shouldReject: [unparsed('10px'), CSS.percent(1), 'url(b)'], + shouldReject: [unparsed('10px'), CSS.percent(1), 'url(b)', [CSS.em(10), '10px']], }); test_style_property_map_set({ syntax: '', initialValue: '0', shouldAccept: [CSS.number(1337), CSS.number(-42.5), '1337', '-42.5'], - shouldReject: [unparsed('42'), CSS.px(15), '#fef'], + shouldReject: [unparsed('42'), CSS.px(15), '#fef', [CSS.number(-42.5), '42.5']], }); test_style_property_map_set({ syntax: '', initialValue: '0%', shouldAccept: [CSS.percent(10), '10%'], - shouldReject: [unparsed('10%'), CSS.px(1), '#fef'], + shouldReject: [unparsed('10%'), CSS.px(1), '#fef', [CSS.percent(10), '1%']], }); test_style_property_map_set({ syntax: '', initialValue: '0dpi', shouldAccept: [CSS.dpi(100), CSS.dpcm(10), CSS.dppx(50), '100dpi'], - shouldReject: [unparsed('42'), CSS.px(15), '#fef'], + shouldReject: [unparsed('42'), CSS.px(15), '#fef', [CSS.dpi(1), '2dpi']], }); test_style_property_map_set({ syntax: '', initialValue: '0s', shouldAccept: [CSS.s(42), CSS.ms(16), '16ms'], - shouldReject: [unparsed('42s'), CSS.px(15), '#fef'], + shouldReject: [unparsed('42s'), CSS.px(15), '#fef', [CSS.s(5), '6s']], }); test_style_property_map_set({ syntax: '', initialValue: 'url(a)', shouldAccept: [url_image('url(b)')], - shouldReject: [unparsed('url(b)'), CSS.px(100), '#fef'], + shouldReject: [unparsed('url(b)'), CSS.px(100), '#fef', [url_image('url(1)'), 'url(2)']], }); test_style_property_map_set({ @@ -444,14 +446,308 @@ test_style_property_map_set({ syntax: 'none | thing | THING', initialValue: 'none', shouldAccept: [keyword('thing'), keyword('THING'), 'thing'], - shouldReject: [unparsed('thing'), CSS.px(15), keyword('notathing'), 'notathing'], + shouldReject: [unparsed('thing'), CSS.px(15), keyword('notathing'), 'notathing', [keyword('thing'), keyword('thing')]], }); test_style_property_map_set({ syntax: ' | ', initialValue: '0deg', shouldAccept: [CSS.deg(42), CSS.turn(2), CSS.px(10), CSS.em(10), '10deg', '10px'], - shouldReject: [unparsed('42deg'), unparsed('20px'), CSS.s(1), '#fef'], + shouldReject: [unparsed('42deg'), unparsed('20px'), CSS.s(1), '#fef', [CSS.deg(42), '21deg']], +}); + +// StylePropertyMap.set for list-valued properties: + +test_style_property_map_set({ + syntax: '+', + initialValue: '0deg', + shouldAccept: [CSS.deg(15), [CSS.deg(15), '10deg'], '15deg 10deg'], + shouldReject: [[CSS.deg(15), CSS.px(10)], '15deg 10px'], +}); + +test_style_property_map_set({ + syntax: '+', + initialValue: 'none', + shouldAccept: [keyword('foo'), [keyword('foo'), 'bar'], 'foo bar'], + shouldReject: [[keyword('foo'), CSS.px(10)], 'foo 10px'], +}); + +test_style_property_map_set({ + syntax: '+', + initialValue: 'url(a)', + shouldAccept: [url_image('url(1)'), [url_image('url(1)'), 'url(2)'], 'url(1) url(2)'], + shouldReject: [[url_image('url(1)'), CSS.px(10)], 'url(1) 10px'], +}); + +test_style_property_map_set({ + syntax: '+', + initialValue: '0', + shouldAccept: [CSS.number(42), [CSS.number(42), '42'], '42 42'], + shouldReject: [[CSS.number(42), keyword('noint')], '42 noint'], +}); + +test_style_property_map_set({ + syntax: '+', + initialValue: '0px', + shouldAccept: [CSS.percent(10), [CSS.percent(10), '10%']], + shouldReject: [[CSS.percent(10), keyword('nolength')], '10% nolength'], +}); + +test_style_property_map_set({ + syntax: '+', + initialValue: '0px', + shouldAccept: [CSS.em(10), [CSS.em(10), '10px']], + shouldReject: [[CSS.em(10), keyword('nolength'), '10em nolength']], +}); + +test_style_property_map_set({ + syntax: '+', + initialValue: '0', + shouldAccept: [CSS.number(-42.5), [CSS.number(-42.5), '42.5'], '-42.5 42.5'], + shouldReject: [[CSS.number(-42.5), CSS.px(10)], '-42.5 10px'], +}); + +test_style_property_map_set({ + syntax: '+', + initialValue: '0%', + shouldAccept: [CSS.percent(10), [CSS.percent(10), '1%'], '10% 1%'], + shouldReject: [[CSS.percent(10), keyword('foo')], '10% foo'], +}); + +test_style_property_map_set({ + syntax: '+', + initialValue: '0dpi', + shouldAccept: [CSS.dpi(1), [CSS.dpi(1), '2dpi'], '1dpi 2dpi'], + shouldReject: [[CSS.dpi(1), keyword('foo')], '1dpi foo'], +}); + +test_style_property_map_set({ + syntax: '+', + initialValue: '0s', + shouldAccept: [CSS.s(5), [CSS.s(5), '6s'], '5s 6s'], + shouldReject: [[CSS.s(5), keyword('foo')], '5s foo'], +}); + +test_style_property_map_set({ + syntax: '+', + initialValue: 'url(a)', + shouldAccept: [url_image('url(1)'), [url_image('url(1)'), 'url(2)'], 'url(1) url(2)'], + shouldReject: [[url_image('url(1)'), CSS.px(10)], 'url(1) 10px'], +}); + +test_style_property_map_set({ + syntax: 'thing+', + initialValue: 'thing', + shouldAccept: [keyword('thing'), [keyword('thing'), 'thing'], 'thing thing'], + shouldReject: [[keyword('thing'), CSS.px(10)], 'thing 10px'], +}); + +test_style_property_map_set({ + syntax: '#', + initialValue: '0px', + shouldAccept: [CSS.em(10), [CSS.em(10), '10px']], + shouldReject: [[CSS.em(10), keyword('nolength'), '10em nolength']], +}); + +function test_append_for_property_map(propertyMapName, propertyMap, options) { + test(function(){ + let name = gen_prop(options.syntax, options.initialValue); + + let ensureArray = v => v.constructor === Array ? v : [v]; + + for (let value of options.values) { + propertyMap.clear(); + + if (value.base !== null) + propertyMap.set(name, ...ensureArray(value.base)); + + // If 'null' is expected, it means we expect the append to fail. + if (value.expect !== null) { + propertyMap.append(name, ...ensureArray(value.append)); + let actual = Array.from(propertyMap.getAll(name)).join(' '); + assert_equals(actual, value.expect); + } else { + assert_throws(new TypeError(), () => propertyMap.append(name, ...ensureArray(value.append))); + } + } + }, `StylePropertyMap.append accepts correct CSSStyleValues for ${options.syntax} (${propertyMapName})`); +} + +// Verify that the correct CSSStyleValues are accepted/rejected when +// appending values to list-valued properties. +// +// The same test is performed twice: once for attributeStyleMap, and once +// for styleMap. +function test_append(options) { + test_append_for_property_map('attributeStyleMap', target.attributeStyleMap, options); + test_append_for_property_map('styleMap', style.sheet.rules[0].styleMap, options); +} + +test_append({ + syntax: '+', + initialValue: '0deg', + values: [ + { base: [CSS.deg(1)], append: [CSS.px(1)], expect: null }, + { base: [CSS.deg(1)], append: [CSS.deg(2), CSS.px(1)], expect: null }, + { base: [CSS.deg(1)], append: [CSS.deg(2), '1px'], expect: null }, + { base: [CSS.deg(1)], append: [CSS.turn(2), CSS.deg(3)], expect: '1deg 2turn 3deg' }, + { base: [CSS.deg(1), CSS.deg(2)], append: [CSS.deg(3)], expect: '1deg 2deg 3deg' }, + { base: [CSS.deg(1)], append: [CSS.deg(2), '3deg'], expect: '1deg 2deg 3deg' }, + { base: [CSS.deg(1)], append: [CSS.deg(2), '3turn 4deg'], expect: '1deg 2deg 3turn 4deg' }, + { base: null, append: [CSS.deg(1), '2deg'], expect: '1deg 2deg' }, + ], +}); + +test_append({ + syntax: '+', + initialValue: 'none', + values: [ + { base: [keyword('foo')], append: [CSS.px(1)], expect: null }, + { base: [keyword('foo')], append: [keyword('bar'), CSS.px(1)], expect: null }, + { base: [keyword('foo')], append: [keyword('bar'), '1px'], expect: null }, + { base: [keyword('foo')], append: [keyword('bar'), keyword('baz')], expect: 'foo bar baz' }, + { base: [keyword('foo'), keyword('bar')], append: [keyword('baz')], expect: 'foo bar baz' }, + { base: [keyword('foo')], append: [keyword('bar'), 'baz'], expect: 'foo bar baz' }, + { base: [keyword('foo')], append: [keyword('bar'), 'baz zim'], expect: 'foo bar baz zim' }, + { base: null, append: [keyword('foo'), 'bar'], expect: 'foo bar' }, + ], +}); + +['+', '+'].forEach((syntax) => { + test_append({ + syntax: syntax, + initialValue: 'url(0)', + values: [ + { base: [url_image('url("1")')], append: [CSS.px(1)], expect: null }, + { base: [url_image('url("1")')], append: [url_image('url("2")'), CSS.px(1)], expect: null }, + { base: [url_image('url("1")')], append: [url_image('url("2")'), '1px'], expect: null }, + { base: [url_image('url("1")')], append: [url_image('url("2")'), url_image('url("3")')], expect: 'url("1") url("2") url("3")' }, + { base: [url_image('url("1")'), url_image('url("2")')], append: [url_image('url("3")')], expect: 'url("1") url("2") url("3")' }, + { base: [url_image('url("1")')], append: [url_image('url("2")'), 'url("3")'], expect: 'url("1") url("2") url("3")' }, + { base: [url_image('url("1")')], append: [url_image('url("2")'), 'url("3") url("4")'], expect: 'url("1") url("2") url("3") url("4")' }, + { base: null, append: [url_image('url("1")'), 'url("2")'], expect: 'url("1") url("2")' }, + ], + }); +}); + +test_append({ + syntax: '+', + initialValue: '0', + values: [ + { base: [CSS.number(1)], append: [CSS.px(1)], expect: null }, + { base: [CSS.number(1)], append: [CSS.number(2), CSS.px(1)], expect: null }, + { base: [CSS.number(1)], append: [CSS.number(2), 'noint'], expect: null }, + { base: [CSS.number(1)], append: [CSS.number(2), CSS.number(3)], expect: '1 2 3' }, + { base: [CSS.number(1), CSS.number(2)], append: [CSS.number(3)], expect: '1 2 3' }, + { base: [CSS.number(1)], append: [CSS.number(2), '3'], expect: '1 2 3' }, + { base: [CSS.number(1)], append: [CSS.number(2), '3 4'], expect: '1 2 3 4' }, + { base: null, append: [CSS.number(1), '2'], expect: '1 2' }, + ], +}); + +test_append({ + syntax: '+', + initialValue: '0px', + values: [ + { base: [CSS.px(1)], append: [keyword('nolength')], expect: null }, + { base: [CSS.px(1)], append: [CSS.px(2), keyword('nolength')], expect: null }, + { base: [CSS.px(1)], append: [CSS.px(2), 'nolength'], expect: null }, + { base: [CSS.px(1)], append: [CSS.px(2), CSS.percent(3)], expect: '1px 2px 3%' }, + { base: [CSS.px(1), CSS.px(2)], append: [CSS.percent(3)], expect: '1px 2px 3%' }, + { base: [CSS.px(1)], append: [CSS.percent(2), '3px'], expect: '1px 2% 3px' }, + { base: [CSS.px(1)], append: [CSS.px(2), '3% 4px'], expect: '1px 2px 3% 4px' }, + { base: null, append: [CSS.px(1), '2%'], expect: '1px 2%' }, + ], +}); + +test_append({ + syntax: '+', + initialValue: '0', + values: [ + { base: [CSS.px(1)], append: [keyword('nolength')], expect: null }, + { base: [CSS.px(1)], append: [CSS.px(2), keyword('nolength')], expect: null }, + { base: [CSS.px(1)], append: [CSS.px(2), 'nolength'], expect: null }, + { base: [CSS.px(1)], append: [CSS.em(2), CSS.px(3)], expect: '1px 2em 3px' }, + { base: [CSS.px(1), CSS.em(2)], append: [CSS.vh(3)], expect: '1px 2em 3vh' }, + { base: [CSS.px(1)], append: [CSS.em(2), '3px'], expect: '1px 2em 3px' }, + { base: [CSS.px(1)], append: [CSS.px(2), '3em 4cm'], expect: '1px 2px 3em 4cm' }, + { base: null, append: [CSS.vh(1), '2px'], expect: '1vh 2px' }, + ], +}); + +test_append({ + syntax: '+', + initialValue: '0', + values: [ + { base: [CSS.number(-1)], append: [keyword('NaN')], expect: null }, + { base: [CSS.number(-1)], append: [CSS.number(2.5), keyword('NaN')], expect: null }, + { base: [CSS.number(-1)], append: [CSS.number(2.5), '1px'], expect: null }, + { base: [CSS.number(-1)], append: [CSS.number(2.5), CSS.number(3.2)], expect: '-1 2.5 3.2' }, + { base: [CSS.number(-1), CSS.number(2.5)], append: [CSS.number(3.2)], expect: '-1 2.5 3.2' }, + { base: [CSS.number(-1)], append: [CSS.number(2.5), '3.2'], expect: '-1 2.5 3.2' }, + { base: [CSS.number(-1)], append: [CSS.number(2.5), '3.2 4'], expect: '-1 2.5 3.2 4' }, + { base: null, append: [CSS.number(-1), '2.5'], expect: '-1 2.5' }, + ], +}); + +test_append({ + syntax: '+', + initialValue: '0%', + values: [ + { base: [CSS.percent(1)], append: [CSS.px(1)], expect: null }, + { base: [CSS.percent(1)], append: [CSS.percent(2), CSS.px(1)], expect: null }, + { base: [CSS.percent(1)], append: [CSS.percent(2), '1px'], expect: null }, + { base: [CSS.percent(1)], append: [CSS.percent(2), CSS.percent(3)], expect: '1% 2% 3%' }, + { base: [CSS.percent(1), CSS.percent(2)], append: [CSS.percent(3)], expect: '1% 2% 3%' }, + { base: [CSS.percent(1)], append: [CSS.percent(2), '3%'], expect: '1% 2% 3%' }, + { base: [CSS.percent(1)], append: [CSS.percent(2), '3% 4%'], expect: '1% 2% 3% 4%' }, + { base: null, append: [CSS.percent(1), '2%'], expect: '1% 2%' }, + ], +}); + +test_append({ + syntax: '+', + initialValue: '0dpi', + values: [ + { base: [CSS.dpi(1)], append: [CSS.px(1)], expect: null }, + { base: [CSS.dpi(1)], append: [CSS.dpi(2), CSS.px(1)], expect: null }, + { base: [CSS.dpi(1)], append: [CSS.dpi(2), '1px'], expect: null }, + { base: [CSS.dpi(1)], append: [CSS.dpi(2), CSS.dpi(3)], expect: '1dpi 2dpi 3dpi' }, + { base: [CSS.dpi(1), CSS.dpi(2)], append: [CSS.dpi(3)], expect: '1dpi 2dpi 3dpi' }, + { base: [CSS.dpi(1)], append: [CSS.dpi(2), '3dpi'], expect: '1dpi 2dpi 3dpi' }, + { base: [CSS.dpi(1)], append: [CSS.dpi(2), '3dpi 4dpi'], expect: '1dpi 2dpi 3dpi 4dpi' }, + { base: null, append: [CSS.dpi(1), '2dpi'], expect: '1dpi 2dpi' }, + ], +}); + +test_append({ + syntax: '+', + initialValue: '0s', + values: [ + { base: [CSS.s(1)], append: [CSS.px(1)], expect: null }, + { base: [CSS.s(1)], append: [CSS.s(2), CSS.px(1)], expect: null }, + { base: [CSS.s(1)], append: [CSS.ms(2), '1px'], expect: null }, + { base: [CSS.s(1)], append: [CSS.ms(2), CSS.s(3)], expect: '1s 2ms 3s' }, + { base: [CSS.s(1), CSS.s(2)], append: [CSS.s(3)], expect: '1s 2s 3s' }, + { base: [CSS.s(1)], append: [CSS.s(2), '3s'], expect: '1s 2s 3s' }, + { base: [CSS.s(1)], append: [CSS.s(2), '3ms 4s'], expect: '1s 2s 3ms 4s' }, + { base: null, append: [CSS.s(1), '2s'], expect: '1s 2s' }, + ], +}); + +test_append({ + syntax: 'foo+', + initialValue: 'foo', + values: [ + { base: [keyword('foo')], append: [CSS.px(1)], expect: null }, + { base: [keyword('foo')], append: [keyword('foo'), CSS.px(1)], expect: null }, + { base: [keyword('foo')], append: [keyword('foo'), '1px'], expect: null }, + { base: [keyword('foo')], append: [keyword('foo'), keyword('foo')], expect: 'foo foo foo' }, + { base: [keyword('foo'), keyword('foo')], append: [keyword('foo')], expect: 'foo foo foo' }, + { base: [keyword('foo')], append: [keyword('foo'), 'foo'], expect: 'foo foo foo' }, + { base: [keyword('foo')], append: [keyword('foo'), 'foo foo'], expect: 'foo foo foo foo' }, + { base: null, append: [keyword('foo'), keyword('foo')], expect: 'foo foo' }, + ], }); // CSSStyleValue.parse/parseAll diff --git a/testing/web-platform/tests/css/css-text/text-transform/reference/text-transform-capitalize-001-ref.html b/testing/web-platform/tests/css/css-text/text-transform/reference/text-transform-capitalize-001-ref.html index afb8ba02abc2..855ec1e87a94 100644 --- a/testing/web-platform/tests/css/css-text/text-transform/reference/text-transform-capitalize-001-ref.html +++ b/testing/web-platform/tests/css/css-text/text-transform/reference/text-transform-capitalize-001-ref.html @@ -1,5 +1,5 @@ - + CSS3 Text, text transform: capitalize, Latin Basic and Latin-1 @@ -19,8 +19,5 @@ The text is arranged in pairs of three-letter 'words'. Test passes if the words in each pair match If you are missing a font glyph for a character, ignore that pair, but report which characters were ignored. Aaa Aaa Bbb Bbb Ccc Ccc Ddd Ddd Eee Eee Fff Fff Ggg Ggg Hhh Hhh Iii Iii Jjj Jjj Kkk Kkk Lll Lll Mmm Mmm Nnn Nnn Ooo Ooo Ppp Ppp Qqq Qqq Rrr Rrr Sss Sss Ttt Ttt Uuu Uuu Vvv Vvv Www Www Xxx Xxx Yyy Yyy Zzz Zzz Μµµ Μµµ Ààà Ààà Ááá Ááá Âââ Âââ Ããã Ããã Äää Äää Ååå Ååå Æææ Æææ Ççç Ççç Èèè Èèè Ééé Ééé Êêê Êêê Ëëë Ëëë Ììì Ììì Ííí Ííí Îîî Îîî Ïïï Ïïï Ððð Ððð Ñññ Ñññ Òòò Òòò Óóó Óóó Ôôô Ôôô Õõõ Õõõ Ööö Ööö Øøø Øøø Ùùù Ùùù Úúú Úúú Ûûû Ûûû Üüü Üüü Ýýý Ýýý Þþþ Þþþ Ÿÿÿ Ÿÿÿ - - \ No newline at end of file + diff --git a/testing/web-platform/tests/css/css-text/text-transform/reference/text-transform-capitalize-003-ref.html b/testing/web-platform/tests/css/css-text/text-transform/reference/text-transform-capitalize-003-ref.html index 72c023f55929..8ef0497f50f2 100644 --- a/testing/web-platform/tests/css/css-text/text-transform/reference/text-transform-capitalize-003-ref.html +++ b/testing/web-platform/tests/css/css-text/text-transform/reference/text-transform-capitalize-003-ref.html @@ -1,5 +1,5 @@ - + CSS3 Text, text transform: capitalize, Latin Extended Additional @@ -19,8 +19,5 @@ The text is arranged in pairs of three-letter 'words'. Test passes if the words in each pair match If you are missing a font glyph for a character, ignore that pair, but report which characters were ignored. Ḁḁḁ Ḁḁḁ Ḃḃḃ Ḃḃḃ Ḅḅḅ Ḅḅḅ Ḇḇḇ Ḇḇḇ Ḉḉḉ Ḉḉḉ Ḋḋḋ Ḋḋḋ Ḍḍḍ Ḍḍḍ Ḏḏḏ Ḏḏḏ Ḑḑḑ Ḑḑḑ Ḓḓḓ Ḓḓḓ Ḕḕḕ Ḕḕḕ Ḗḗḗ Ḗḗḗ Ḙḙḙ Ḙḙḙ Ḛḛḛ Ḛḛḛ Ḝḝḝ Ḝḝḝ Ḟḟḟ Ḟḟḟ Ḡḡḡ Ḡḡḡ Ḣḣḣ Ḣḣḣ Ḥḥḥ Ḥḥḥ Ḧḧḧ Ḧḧḧ Ḩḩḩ Ḩḩḩ Ḫḫḫ Ḫḫḫ Ḭḭḭ Ḭḭḭ Ḯḯḯ Ḯḯḯ Ḱḱḱ Ḱḱḱ Ḳḳḳ Ḳḳḳ Ḵḵḵ Ḵḵḵ Ḷḷḷ Ḷḷḷ Ḹḹḹ Ḹḹḹ Ḻḻḻ Ḻḻḻ Ḽḽḽ Ḽḽḽ Ḿḿḿ Ḿḿḿ Ṁṁṁ Ṁṁṁ Ṃṃṃ Ṃṃṃ Ṅṅṅ Ṅṅṅ Ṇṇṇ Ṇṇṇ Ṉṉṉ Ṉṉṉ Ṋṋṋ Ṋṋṋ Ṍṍṍ Ṍṍṍ Ṏṏṏ Ṏṏṏ Ṑṑṑ Ṑṑṑ Ṓṓṓ Ṓṓṓ Ṕṕṕ Ṕṕṕ Ṗṗṗ Ṗṗṗ Ṙṙṙ Ṙṙṙ Ṛṛṛ Ṛṛṛ Ṝṝṝ Ṝṝṝ Ṟṟṟ Ṟṟṟ Ṡṡṡ Ṡṡṡ Ṣṣṣ Ṣṣṣ Ṥṥṥ Ṥṥṥ Ṧṧṧ Ṧṧṧ Ṩṩṩ Ṩṩṩ Ṫṫṫ Ṫṫṫ Ṭṭṭ Ṭṭṭ Ṯṯṯ Ṯṯṯ Ṱṱṱ Ṱṱṱ Ṳṳṳ Ṳṳṳ Ṵṵṵ Ṵṵṵ Ṷṷṷ Ṷṷṷ Ṹṹṹ Ṹṹṹ Ṻṻṻ Ṻṻṻ Ṽṽṽ Ṽṽṽ Ṿṿṿ Ṿṿṿ Ẁẁẁ Ẁẁẁ Ẃẃẃ Ẃẃẃ Ẅẅẅ Ẅẅẅ Ẇẇẇ Ẇẇẇ Ẉẉẉ Ẉẉẉ Ẋẋẋ Ẋẋẋ Ẍẍẍ Ẍẍẍ Ẏẏẏ Ẏẏẏ Ẑẑẑ Ẑẑẑ Ẓẓẓ Ẓẓẓ Ẕẕẕ Ẕẕẕ Ṡẛẛ Ṡẛẛ Ạạạ Ạạạ Ảảả Ảảả Ấấấ Ấấấ Ầầầ Ầầầ Ẩẩẩ Ẩẩẩ Ẫẫẫ Ẫẫẫ Ậậậ Ậậậ Ắắắ Ắắắ Ằằằ Ằằằ Ẳẳẳ Ẳẳẳ Ẵẵẵ Ẵẵẵ Ặặặ Ặặặ Ẹẹẹ Ẹẹẹ Ẻẻẻ Ẻẻẻ Ẽẽẽ Ẽẽẽ Ếếế Ếếế Ềềề Ềềề Ểểể Ểểể Ễễễ Ễễễ Ệệệ Ệệệ Ỉỉỉ Ỉỉỉ Ịịị Ịịị Ọọọ Ọọọ Ỏỏỏ Ỏỏỏ Ốốố Ốốố Ồồồ Ồồồ Ổổổ Ổổổ Ỗỗỗ Ỗỗỗ Ộộộ Ộộộ Ớớớ Ớớớ Ờờờ Ờờờ Ởởở Ởởở Ỡỡỡ Ỡỡỡ Ợợợ Ợợợ Ụụụ Ụụụ Ủủủ Ủủủ Ứứứ Ứứứ Ừừừ Ừừừ Ửửử Ửửử Ữữữ Ữữữ Ựựự Ựựự Ỳỳỳ Ỳỳỳ Ỵỵỵ Ỵỵỵ Ỷỷỷ Ỷỷỷ Ỹỹỹ Ỹỹỹ Ỻỻỻ Ỻỻỻ Ỽỽỽ Ỽỽỽ Ỿỿỿ Ỿỿỿ - - \ No newline at end of file + diff --git a/testing/web-platform/tests/css/css-text/text-transform/reference/text-transform-capitalize-005-ref.html b/testing/web-platform/tests/css/css-text/text-transform/reference/text-transform-capitalize-005-ref.html index 2d4e5909a10f..b7ac094cc293 100644 --- a/testing/web-platform/tests/css/css-text/text-transform/reference/text-transform-capitalize-005-ref.html +++ b/testing/web-platform/tests/css/css-text/text-transform/reference/text-transform-capitalize-005-ref.html @@ -1,5 +1,5 @@ - + CSS3 Text, text transform: capitalize, Latin Extended-A @@ -19,8 +19,5 @@ The text is arranged in pairs of three-letter 'words'. Test passes if the words in each pair match If you are missing a font glyph for a character, ignore that pair, but report which characters were ignored. Āāā Āāā Ăăă Ăăă Ąąą Ąąą Ććć Ććć Ĉĉĉ Ĉĉĉ Ċċċ Ċċċ Ččč Ččč Ďďď Ďďď Đđđ Đđđ Ēēē Ēēē Ĕĕĕ Ĕĕĕ Ėėė Ėėė Ęęę Ęęę Ěěě Ěěě Ĝĝĝ Ĝĝĝ Ğğğ Ğğğ Ġġġ Ġġġ Ģģģ Ģģģ Ĥĥĥ Ĥĥĥ Ħħħ Ħħħ Ĩĩĩ Ĩĩĩ Īīī Īīī Ĭĭĭ Ĭĭĭ Įįį Įįį Iıı Iıı IJijij IJijij Ĵĵĵ Ĵĵĵ Ķķķ Ķķķ Ĺĺĺ Ĺĺĺ Ļļļ Ļļļ Ľľľ Ľľľ Ŀŀŀ Ŀŀŀ Łłł Łłł Ńńń Ńńń Ņņņ Ņņņ Ňňň Ňňň Ŋŋŋ Ŋŋŋ Ōōō Ōōō Ŏŏŏ Ŏŏŏ Őőő Őőő Œœœ Œœœ Ŕŕŕ Ŕŕŕ Ŗŗŗ Ŗŗŗ Řřř Řřř Śśś Śśś Ŝŝŝ Ŝŝŝ Şşş Şşş Ššš Ššš Ţţţ Ţţţ Ťťť Ťťť Ŧŧŧ Ŧŧŧ Ũũũ Ũũũ Ūūū Ūūū Ŭŭŭ Ŭŭŭ Ůůů Ůůů Űűű Űűű Ųųų Ųųų Ŵŵŵ Ŵŵŵ Ŷŷŷ Ŷŷŷ Źźź Źźź Żżż Żżż Žžž Žžž Sſſ Sſſ - - \ No newline at end of file + diff --git a/testing/web-platform/tests/css/css-text/text-transform/reference/text-transform-capitalize-007-ref.html b/testing/web-platform/tests/css/css-text/text-transform/reference/text-transform-capitalize-007-ref.html index 18d644a71c53..d68fac13de6f 100644 --- a/testing/web-platform/tests/css/css-text/text-transform/reference/text-transform-capitalize-007-ref.html +++ b/testing/web-platform/tests/css/css-text/text-transform/reference/text-transform-capitalize-007-ref.html @@ -1,5 +1,5 @@ - + CSS3 Text, text transform: capitalize, Latin Extended-B @@ -19,8 +19,5 @@ The text is arranged in pairs of three-letter 'words'. Test passes if the words in each pair match If you are missing a font glyph for a character, ignore that pair, but report which characters were ignored. Ƀƀƀ Ƀƀƀ Ƃƃƃ Ƃƃƃ Ƅƅƅ Ƅƅƅ Ƈƈƈ Ƈƈƈ Ƌƌƌ Ƌƌƌ Ƒƒƒ Ƒƒƒ Ƕƕƕ Ƕƕƕ Ƙƙƙ Ƙƙƙ Ƚƚƚ Ƚƚƚ Ƞƞƞ Ƞƞƞ Ơơơ Ơơơ Ƣƣƣ Ƣƣƣ Ƥƥƥ Ƥƥƥ Ƨƨƨ Ƨƨƨ Ƭƭƭ Ƭƭƭ Ưưư Ưưư Ƴƴƴ Ƴƴƴ Ƶƶƶ Ƶƶƶ Ƹƹƹ Ƹƹƹ Ƽƽƽ Ƽƽƽ Ƿƿƿ Ƿƿƿ Dždždž Dždždž Dždždž Dždždž Ljljlj Ljljlj Ljljlj Ljljlj Njnjnj Njnjnj Njnjnj Njnjnj Ǎǎǎ Ǎǎǎ Ǐǐǐ Ǐǐǐ Ǒǒǒ Ǒǒǒ Ǔǔǔ Ǔǔǔ Ǖǖǖ Ǖǖǖ Ǘǘǘ Ǘǘǘ Ǚǚǚ Ǚǚǚ Ǜǜǜ Ǜǜǜ Ǝǝǝ Ǝǝǝ Ǟǟǟ Ǟǟǟ Ǡǡǡ Ǡǡǡ Ǣǣǣ Ǣǣǣ Ǥǥǥ Ǥǥǥ Ǧǧǧ Ǧǧǧ Ǩǩǩ Ǩǩǩ Ǫǫǫ Ǫǫǫ Ǭǭǭ Ǭǭǭ Ǯǯǯ Ǯǯǯ Dzdzdz Dzdzdz Dzdzdz Dzdzdz Ǵǵǵ Ǵǵǵ Ǹǹǹ Ǹǹǹ Ǻǻǻ Ǻǻǻ Ǽǽǽ Ǽǽǽ Ǿǿǿ Ǿǿǿ Ȁȁȁ Ȁȁȁ Ȃȃȃ Ȃȃȃ Ȅȅȅ Ȅȅȅ Ȇȇȇ Ȇȇȇ Ȉȉȉ Ȉȉȉ Ȋȋȋ Ȋȋȋ Ȍȍȍ Ȍȍȍ Ȏȏȏ Ȏȏȏ Ȑȑȑ Ȑȑȑ Ȓȓȓ Ȓȓȓ Ȕȕȕ Ȕȕȕ Ȗȗȗ Ȗȗȗ Șșș Șșș Țțț Țțț Ȝȝȝ Ȝȝȝ Ȟȟȟ Ȟȟȟ Ȣȣȣ Ȣȣȣ Ȥȥȥ Ȥȥȥ Ȧȧȧ Ȧȧȧ Ȩȩȩ Ȩȩȩ Ȫȫȫ Ȫȫȫ Ȭȭȭ Ȭȭȭ Ȯȯȯ Ȯȯȯ Ȱȱȱ Ȱȱȱ Ȳȳȳ Ȳȳȳ Ȼȼȼ Ȼȼȼ Ȿȿȿ Ȿȿȿ Ɀɀɀ Ɀɀɀ Ɂɂɂ Ɂɂɂ Ɇɇɇ Ɇɇɇ Ɉɉɉ Ɉɉɉ Ɋɋɋ Ɋɋɋ Ɍɍɍ Ɍɍɍ Ɏɏɏ Ɏɏɏ - - \ No newline at end of file + diff --git a/testing/web-platform/tests/css/css-text/text-transform/reference/text-transform-capitalize-009-ref.html b/testing/web-platform/tests/css/css-text/text-transform/reference/text-transform-capitalize-009-ref.html index fcfcd337ac98..859e033ae766 100644 --- a/testing/web-platform/tests/css/css-text/text-transform/reference/text-transform-capitalize-009-ref.html +++ b/testing/web-platform/tests/css/css-text/text-transform/reference/text-transform-capitalize-009-ref.html @@ -1,5 +1,5 @@ - + CSS3 Text, text transform: capitalize, Latin Extended-C @@ -19,8 +19,5 @@ The text is arranged in pairs of three-letter 'words'. Test passes if the words in each pair match If you are missing a font glyph for a character, ignore that pair, but report which characters were ignored. Ⱡⱡⱡ Ⱡⱡⱡ Ⱥⱥⱥ Ⱥⱥⱥ Ⱦⱦⱦ Ⱦⱦⱦ Ⱨⱨⱨ Ⱨⱨⱨ Ⱪⱪⱪ Ⱪⱪⱪ Ⱬⱬⱬ Ⱬⱬⱬ Ⱳⱳⱳ Ⱳⱳⱳ Ⱶⱶⱶ Ⱶⱶⱶ - - \ No newline at end of file + diff --git a/testing/web-platform/tests/css/css-text/text-transform/reference/text-transform-capitalize-010-ref.html b/testing/web-platform/tests/css/css-text/text-transform/reference/text-transform-capitalize-010-ref.html index 19f0c3783719..9c5e4e6f97e9 100644 --- a/testing/web-platform/tests/css/css-text/text-transform/reference/text-transform-capitalize-010-ref.html +++ b/testing/web-platform/tests/css/css-text/text-transform/reference/text-transform-capitalize-010-ref.html @@ -1,5 +1,5 @@ - + CSS3 Text, text transform: capitalize, Latin Extended-D @@ -19,8 +19,5 @@ The text is arranged in pairs of three-letter 'words'. Test passes if the words in each pair match If you are missing a font glyph for a character, ignore that pair, but report which characters were ignored. Ꜣꜣꜣ Ꜣꜣꜣ Ꜥꜥꜥ Ꜥꜥꜥ Ꜧꜧꜧ Ꜧꜧꜧ Ꜩꜩꜩ Ꜩꜩꜩ Ꜫꜫꜫ Ꜫꜫꜫ Ꜭꜭꜭ Ꜭꜭꜭ Ꜯꜯꜯ Ꜯꜯꜯ Ꜳꜳꜳ Ꜳꜳꜳ Ꜵꜵꜵ Ꜵꜵꜵ Ꜷꜷꜷ Ꜷꜷꜷ Ꜹꜹꜹ Ꜹꜹꜹ Ꜻꜻꜻ Ꜻꜻꜻ Ꜽꜽꜽ Ꜽꜽꜽ Ꜿꜿꜿ Ꜿꜿꜿ Ꝁꝁꝁ Ꝁꝁꝁ Ꝃꝃꝃ Ꝃꝃꝃ Ꝅꝅꝅ Ꝅꝅꝅ Ꝇꝇꝇ Ꝇꝇꝇ Ꝉꝉꝉ Ꝉꝉꝉ Ꝋꝋꝋ Ꝋꝋꝋ Ꝍꝍꝍ Ꝍꝍꝍ Ꝏꝏꝏ Ꝏꝏꝏ Ꝑꝑꝑ Ꝑꝑꝑ Ꝓꝓꝓ Ꝓꝓꝓ Ꝕꝕꝕ Ꝕꝕꝕ Ꝗꝗꝗ Ꝗꝗꝗ Ꝙꝙꝙ Ꝙꝙꝙ Ꝛꝛꝛ Ꝛꝛꝛ Ꝝꝝꝝ Ꝝꝝꝝ Ꝟꝟꝟ Ꝟꝟꝟ Ꝡꝡꝡ Ꝡꝡꝡ Ꝣꝣꝣ Ꝣꝣꝣ Ꝥꝥꝥ Ꝥꝥꝥ Ꝧꝧꝧ Ꝧꝧꝧ Ꝩꝩꝩ Ꝩꝩꝩ Ꝫꝫꝫ Ꝫꝫꝫ Ꝭꝭꝭ Ꝭꝭꝭ Ꝯꝯꝯ Ꝯꝯꝯ Ꝺꝺꝺ Ꝺꝺꝺ Ꝼꝼꝼ Ꝼꝼꝼ Ꝿꝿꝿ Ꝿꝿꝿ Ꞁꞁꞁ Ꞁꞁꞁ Ꞃꞃꞃ Ꞃꞃꞃ Ꞅꞅꞅ Ꞅꞅꞅ Ꞇꞇꞇ Ꞇꞇꞇ Ꞌꞌꞌ Ꞌꞌꞌ Ꞑꞑꞑ Ꞑꞑꞑ Ꞓꞓꞓ Ꞓꞓꞓ Ꞗꞗꞗ Ꞗꞗꞗ Ꞙꞙꞙ Ꞙꞙꞙ Ꞛꞛꞛ Ꞛꞛꞛ Ꞝꞝꞝ Ꞝꞝꞝ Ꞟꞟꞟ Ꞟꞟꞟ Ꞡꞡꞡ Ꞡꞡꞡ Ꞣꞣꞣ Ꞣꞣꞣ Ꞥꞥꞥ Ꞥꞥꞥ Ꞧꞧꞧ Ꞧꞧꞧ Ꞩꞩꞩ Ꞩꞩꞩ - - \ No newline at end of file + diff --git a/testing/web-platform/tests/css/css-text/text-transform/reference/text-transform-capitalize-011-ref.html b/testing/web-platform/tests/css/css-text/text-transform/reference/text-transform-capitalize-011-ref.html index abd595d55fa0..65496f1019d8 100644 --- a/testing/web-platform/tests/css/css-text/text-transform/reference/text-transform-capitalize-011-ref.html +++ b/testing/web-platform/tests/css/css-text/text-transform/reference/text-transform-capitalize-011-ref.html @@ -1,5 +1,5 @@ - + CSS3 Text, text transform: capitalize, Full-width Latin @@ -19,8 +19,5 @@ The text is arranged in pairs of three-letter 'words'. Test passes if the words in each pair match If you are missing a font glyph for a character, ignore that pair, but report which characters were ignored. Aaa Aaa Bbb Bbb Ccc Ccc Ddd Ddd Eee Eee Fff Fff Ggg Ggg Hhh Hhh Iii Iii Jjj Jjj Kkk Kkk Lll Lll Mmm Mmm Nnn Nnn Ooo Ooo Ppp Ppp Qqq Qqq Rrr Rrr Sss Sss Ttt Ttt Uuu Uuu Vvv Vvv Www Www Xxx Xxx Yyy Yyy Zzz Zzz - - \ No newline at end of file + diff --git a/testing/web-platform/tests/css/css-text/text-transform/reference/text-transform-capitalize-014-ref.html b/testing/web-platform/tests/css/css-text/text-transform/reference/text-transform-capitalize-014-ref.html index d97eeec201e1..606a463874f5 100644 --- a/testing/web-platform/tests/css/css-text/text-transform/reference/text-transform-capitalize-014-ref.html +++ b/testing/web-platform/tests/css/css-text/text-transform/reference/text-transform-capitalize-014-ref.html @@ -1,5 +1,5 @@ - + CSS3 Text, text transform: capitalize, Greek and Coptic @@ -19,8 +19,5 @@ The text is arranged in pairs of three-letter 'words'. Test passes if the words in each pair match If you are missing a font glyph for a character, ignore that pair, but report which characters were ignored. Ͱͱͱ Ͱͱͱ Ͳͳͳ Ͳͳͳ Ͷͷͷ Ͷͷͷ Ͻͻͻ Ͻͻͻ Ͼͼͼ Ͼͼͼ Ͽͽͽ Ͽͽͽ Άάά Άάά Έέέ Έέέ Ήήή Ήήή Ίίί Ίίί Ααα Ααα Βββ Βββ Γγγ Γγγ Δδδ Δδδ Εεε Εεε Ζζζ Ζζζ Ηηη Ηηη Θθθ Θθθ Ιιι Ιιι Κκκ Κκκ Λλλ Λλλ Μμμ Μμμ Ννν Ννν Ξξξ Ξξξ Οοο Οοο Πππ Πππ Ρρρ Ρρρ Σςς Σςς Σσσ Σσσ Τττ Τττ Υυυ Υυυ Φφφ Φφφ Χχχ Χχχ Ψψψ Ψψψ Ωωω Ωωω Ϊϊϊ Ϊϊϊ Ϋϋϋ Ϋϋϋ Όόό Όόό Ύύύ Ύύύ Ώώώ Ώώώ Βϐϐ Βϐϐ Θϑϑ Θϑϑ Φϕϕ Φϕϕ Πϖϖ Πϖϖ Ϗϗϗ Ϗϗϗ Ϙϙϙ Ϙϙϙ Ϛϛϛ Ϛϛϛ Ϝϝϝ Ϝϝϝ Ϟϟϟ Ϟϟϟ Ϡϡϡ Ϡϡϡ Ϣϣϣ Ϣϣϣ Ϥϥϥ Ϥϥϥ Ϧϧϧ Ϧϧϧ Ϩϩϩ Ϩϩϩ Ϫϫϫ Ϫϫϫ Ϭϭϭ Ϭϭϭ Ϯϯϯ Ϯϯϯ Κϰϰ Κϰϰ Ρϱϱ Ρϱϱ Ϲϲϲ Ϲϲϲ Ϳϳϳ Ϳϳϳ Εϵϵ Εϵϵ Ϸϸϸ Ϸϸϸ Ϻϻϻ Ϻϻϻ - - \ No newline at end of file + diff --git a/testing/web-platform/tests/css/css-text/text-transform/reference/text-transform-capitalize-016-ref.html b/testing/web-platform/tests/css/css-text/text-transform/reference/text-transform-capitalize-016-ref.html index ac84d5f3755a..1e3e331ca543 100644 --- a/testing/web-platform/tests/css/css-text/text-transform/reference/text-transform-capitalize-016-ref.html +++ b/testing/web-platform/tests/css/css-text/text-transform/reference/text-transform-capitalize-016-ref.html @@ -1,5 +1,5 @@ - + CSS3 Text, text transform: capitalize, Greek Extended @@ -20,8 +20,5 @@ The text is arranged in pairs of three-letter 'words'. Test passes if the words in each pair match If you are missing a font glyph for a character, ignore that pair, but report which characters were ignored. Ἀἀἀ Ἀἀἀ Ἁἁἁ Ἁἁἁ Ἂἂἂ Ἂἂἂ Ἃἃἃ Ἃἃἃ Ἄἄἄ Ἄἄἄ Ἅἅἅ Ἅἅἅ Ἆἆἆ Ἆἆἆ Ἇἇἇ Ἇἇἇ Ἐἐἐ Ἐἐἐ Ἑἑἑ Ἑἑἑ Ἒἒἒ Ἒἒἒ Ἓἓἓ Ἓἓἓ Ἔἔἔ Ἔἔἔ Ἕἕἕ Ἕἕἕ Ἠἠἠ Ἠἠἠ Ἡἡἡ Ἡἡἡ Ἢἢἢ Ἢἢἢ Ἣἣἣ Ἣἣἣ Ἤἤἤ Ἤἤἤ Ἥἥἥ Ἥἥἥ Ἦἦἦ Ἦἦἦ Ἧἧἧ Ἧἧἧ Ἰἰἰ Ἰἰἰ Ἱἱἱ Ἱἱἱ Ἲἲἲ Ἲἲἲ Ἳἳἳ Ἳἳἳ Ἴἴἴ Ἴἴἴ Ἵἵἵ Ἵἵἵ Ἶἶἶ Ἶἶἶ Ἷἷἷ Ἷἷἷ Ὀὀὀ Ὀὀὀ Ὁὁὁ Ὁὁὁ Ὂὂὂ Ὂὂὂ Ὃὃὃ Ὃὃὃ Ὄὄὄ Ὄὄὄ Ὅὅὅ Ὅὅὅ Ὑὑὑ Ὑὑὑ Ὓὓὓ Ὓὓὓ Ὕὕὕ Ὕὕὕ Ὗὗὗ Ὗὗὗ Ὠὠὠ Ὠὠὠ Ὡὡὡ Ὡὡὡ Ὢὢὢ Ὢὢὢ Ὣὣὣ Ὣὣὣ Ὤὤὤ Ὤὤὤ Ὥὥὥ Ὥὥὥ Ὦὦὦ Ὦὦὦ Ὧὧὧ Ὧὧὧ Ὰὰὰ Ὰὰὰ Άάά Άάά Ὲὲὲ Ὲὲὲ Έέέ Έέέ Ὴὴὴ Ὴὴὴ Ήήή Ήήή Ὶὶὶ Ὶὶὶ Ίίί Ίίί Ὸὸὸ Ὸὸὸ Όόό Όόό Ὺὺὺ Ὺὺὺ Ύύύ Ύύύ Ὼὼὼ Ὼὼὼ Ώώώ Ώώώ ᾈᾀᾀ ᾈᾀᾀ ᾉᾁᾁ ᾉᾁᾁ ᾊᾂᾂ ᾊᾂᾂ ᾋᾃᾃ ᾋᾃᾃ ᾌᾄᾄ ᾌᾄᾄ ᾍᾅᾅ ᾍᾅᾅ ᾎᾆᾆ ᾎᾆᾆ ᾏᾇᾇ ᾏᾇᾇ ᾘᾐᾐ ᾘᾐᾐ ᾙᾑᾑ ᾙᾑᾑ ᾚᾒᾒ ᾚᾒᾒ ᾛᾓᾓ ᾛᾓᾓ ᾜᾔᾔ ᾜᾔᾔ ᾝᾕᾕ ᾝᾕᾕ ᾞᾖᾖ ᾞᾖᾖ ᾟᾗᾗ ᾟᾗᾗ ᾨᾠᾠ ᾨᾠᾠ ᾩᾡᾡ ᾩᾡᾡ ᾪᾢᾢ ᾪᾢᾢ ᾫᾣᾣ ᾫᾣᾣ ᾬᾤᾤ ᾬᾤᾤ ᾭᾥᾥ ᾭᾥᾥ ᾮᾦᾦ ᾮᾦᾦ ᾯᾧᾧ ᾯᾧᾧ Ᾰᾰᾰ Ᾰᾰᾰ Ᾱᾱᾱ Ᾱᾱᾱ ᾼᾳᾳ ᾼᾳᾳ Ιιι Ιιι ῌῃῃ ῌῃῃ Ῐῐῐ Ῐῐῐ Ῑῑῑ Ῑῑῑ Ῠῠῠ Ῠῠῠ Ῡῡῡ Ῡῡῡ Ῥῥῥ Ῥῥῥ ῼῳῳ ῼῳῳ - - \ No newline at end of file + diff --git a/testing/web-platform/tests/css/css-text/text-transform/reference/text-transform-capitalize-018-ref.html b/testing/web-platform/tests/css/css-text/text-transform/reference/text-transform-capitalize-018-ref.html index 6d4e35aaeeb5..90dbfd73bbc4 100644 --- a/testing/web-platform/tests/css/css-text/text-transform/reference/text-transform-capitalize-018-ref.html +++ b/testing/web-platform/tests/css/css-text/text-transform/reference/text-transform-capitalize-018-ref.html @@ -1,5 +1,5 @@ - + CSS3 Text, text transform: capitalize, Cyrillic @@ -21,8 +21,5 @@ The text is arranged in pairs of three-letter 'words'. Test passes if the words in each pair match If you are missing a font glyph for a character, ignore that pair, but report which characters were ignored. Ааа Ааа Ббб Ббб Ввв Ввв Ггг Ггг Ддд Ддд Еее Еее Жжж Жжж Ззз Ззз Иии Иии Ййй Ййй Ккк Ккк Ллл Ллл Ммм Ммм Ннн Ннн Ооо Ооо Ппп Ппп Ррр Ррр Ссс Ссс Ттт Ттт Ууу Ууу Ффф Ффф Ххх Ххх Ццц Ццц Ччч Ччч Шшш Шшш Щщщ Щщщ Ъъъ Ъъъ Ыыы Ыыы Ььь Ььь Эээ Эээ Ююю Ююю Яяя Яяя Ѐѐѐ Ѐѐѐ Ёёё Ёёё Ђђђ Ђђђ Ѓѓѓ Ѓѓѓ Єєє Єєє Ѕѕѕ Ѕѕѕ Ііі Ііі Їїї Їїї Јјј Јјј Љљљ Љљљ Њњњ Њњњ Ћћћ Ћћћ Ќќќ Ќќќ Ѝѝѝ Ѝѝѝ Ўўў Ўўў Џџџ Џџџ Ѡѡѡ Ѡѡѡ Ѣѣѣ Ѣѣѣ Ѥѥѥ Ѥѥѥ Ѧѧѧ Ѧѧѧ Ѩѩѩ Ѩѩѩ Ѫѫѫ Ѫѫѫ Ѭѭѭ Ѭѭѭ Ѯѯѯ Ѯѯѯ Ѱѱѱ Ѱѱѱ Ѳѳѳ Ѳѳѳ Ѵѵѵ Ѵѵѵ Ѷѷѷ Ѷѷѷ Ѹѹѹ Ѹѹѹ Ѻѻѻ Ѻѻѻ Ѽѽѽ Ѽѽѽ Ѿѿѿ Ѿѿѿ Ҁҁҁ Ҁҁҁ Ҋҋҋ Ҋҋҋ Ҍҍҍ Ҍҍҍ Ҏҏҏ Ҏҏҏ Ґґґ Ґґґ Ғғғ Ғғғ Ҕҕҕ Ҕҕҕ Җҗҗ Җҗҗ Ҙҙҙ Ҙҙҙ Қққ Қққ Ҝҝҝ Ҝҝҝ Ҟҟҟ Ҟҟҟ Ҡҡҡ Ҡҡҡ Ңңң Ңңң Ҥҥҥ Ҥҥҥ Ҧҧҧ Ҧҧҧ Ҩҩҩ Ҩҩҩ Ҫҫҫ Ҫҫҫ Ҭҭҭ Ҭҭҭ Үүү Үүү Ұұұ Ұұұ Ҳҳҳ Ҳҳҳ Ҵҵҵ Ҵҵҵ Ҷҷҷ Ҷҷҷ Ҹҹҹ Ҹҹҹ Һһһ Һһһ Ҽҽҽ Ҽҽҽ Ҿҿҿ Ҿҿҿ Ӂӂӂ Ӂӂӂ Ӄӄӄ Ӄӄӄ Ӆӆӆ Ӆӆӆ Ӈӈӈ Ӈӈӈ Ӊӊӊ Ӊӊӊ Ӌӌӌ Ӌӌӌ Ӎӎӎ Ӎӎӎ Ӏӏӏ Ӏӏӏ Ӑӑӑ Ӑӑӑ Ӓӓӓ Ӓӓӓ Ӕӕӕ Ӕӕӕ Ӗӗӗ Ӗӗӗ Әәә Әәә Ӛӛӛ Ӛӛӛ Ӝӝӝ Ӝӝӝ Ӟӟӟ Ӟӟӟ Ӡӡӡ Ӡӡӡ Ӣӣӣ Ӣӣӣ Ӥӥӥ Ӥӥӥ Ӧӧӧ Ӧӧӧ Өөө Өөө Ӫӫӫ Ӫӫӫ Ӭӭӭ Ӭӭӭ Ӯӯӯ Ӯӯӯ Ӱӱӱ Ӱӱӱ Ӳӳӳ Ӳӳӳ Ӵӵӵ Ӵӵӵ Ӷӷӷ Ӷӷӷ Ӹӹӹ Ӹӹӹ Ӻӻӻ Ӻӻӻ Ӽӽӽ Ӽӽӽ Ӿӿӿ Ӿӿӿ - - \ No newline at end of file + diff --git a/testing/web-platform/tests/css/css-text/text-transform/reference/text-transform-capitalize-020-ref.html b/testing/web-platform/tests/css/css-text/text-transform/reference/text-transform-capitalize-020-ref.html index 30cb39c28833..075aca4a57d7 100644 --- a/testing/web-platform/tests/css/css-text/text-transform/reference/text-transform-capitalize-020-ref.html +++ b/testing/web-platform/tests/css/css-text/text-transform/reference/text-transform-capitalize-020-ref.html @@ -1,5 +1,5 @@ - + CSS3 Text, text transform: capitalize, Cyrillic Supplement @@ -20,8 +20,5 @@ The text is arranged in pairs of three-letter 'words'. Test passes if the words in each pair match If you are missing a font glyph for a character, ignore that pair, but report which characters were ignored. Ԁԁԁ Ԁԁԁ Ԃԃԃ Ԃԃԃ Ԅԅԅ Ԅԅԅ Ԇԇԇ Ԇԇԇ Ԉԉԉ Ԉԉԉ Ԋԋԋ Ԋԋԋ Ԍԍԍ Ԍԍԍ Ԏԏԏ Ԏԏԏ Ԑԑԑ Ԑԑԑ Ԓԓԓ Ԓԓԓ Ԕԕԕ Ԕԕԕ Ԗԗԗ Ԗԗԗ Ԙԙԙ Ԙԙԙ Ԛԛԛ Ԛԛԛ Ԝԝԝ Ԝԝԝ Ԟԟԟ Ԟԟԟ Ԡԡԡ Ԡԡԡ Ԣԣԣ Ԣԣԣ Ԥԥԥ Ԥԥԥ Ԧԧԧ Ԧԧԧ Ԩԩԩ Ԩԩԩ Ԫԫԫ Ԫԫԫ Ԭԭԭ Ԭԭԭ Ԯԯԯ Ԯԯԯ - - \ No newline at end of file + diff --git a/testing/web-platform/tests/css/css-text/text-transform/reference/text-transform-capitalize-022-ref.html b/testing/web-platform/tests/css/css-text/text-transform/reference/text-transform-capitalize-022-ref.html index a8885631a4e2..984e703a5c49 100644 --- a/testing/web-platform/tests/css/css-text/text-transform/reference/text-transform-capitalize-022-ref.html +++ b/testing/web-platform/tests/css/css-text/text-transform/reference/text-transform-capitalize-022-ref.html @@ -1,5 +1,5 @@ - + CSS3 Text, text transform: capitalize, Armenian @@ -19,8 +19,5 @@ The text is arranged in pairs of three-letter 'words'. Test passes if the words in each pair match If you are missing a font glyph for a character, ignore that pair, but report which characters were ignored. Աաա Աաա Բբբ Բբբ Գգգ Գգգ Դդդ Դդդ Եեե Եեե Զզզ Զզզ Էէէ Էէէ Ըըը Ըըը Թթթ Թթթ Ժժժ Ժժժ Իիի Իիի Լլլ Լլլ Խխխ Խխխ Ծծծ Ծծծ Կկկ Կկկ Հհհ Հհհ Ձձձ Ձձձ Ղղղ Ղղղ Ճճճ Ճճճ Մմմ Մմմ Յյյ Յյյ Ննն Ննն Շշշ Շշշ Ոոո Ոոո Չչչ Չչչ Պպպ Պպպ Ջջջ Ջջջ Ռռռ Ռռռ Սսս Սսս Վվվ Վվվ Տտտ Տտտ Րրր Րրր Ցցց Ցցց Ւււ Ւււ Փփփ Փփփ Քքք Քքք Օօօ Օօօ Ֆֆֆ Ֆֆֆ - diff --git a/testing/web-platform/tests/css/css-text/text-transform/reference/text-transform-capitalize-024-ref.html b/testing/web-platform/tests/css/css-text/text-transform/reference/text-transform-capitalize-024-ref.html index 20bc68d33fea..3754845856b3 100644 --- a/testing/web-platform/tests/css/css-text/text-transform/reference/text-transform-capitalize-024-ref.html +++ b/testing/web-platform/tests/css/css-text/text-transform/reference/text-transform-capitalize-024-ref.html @@ -1,5 +1,5 @@ - + CSS3 Text, text transform: capitalize, Number Forms @@ -19,8 +19,5 @@ The text is arranged in pairs of three-letter 'words'. Test passes if the words in each pair match If you are missing a font glyph for a character, ignore that pair, but report which characters were ignored. Ⅰⅰⅰ Ⅰⅰⅰ Ⅱⅱⅱ Ⅱⅱⅱ Ⅲⅲⅲ Ⅲⅲⅲ Ⅳⅳⅳ Ⅳⅳⅳ Ⅴⅴⅴ Ⅴⅴⅴ Ⅵⅵⅵ Ⅵⅵⅵ Ⅶⅶⅶ Ⅶⅶⅶ Ⅷⅷⅷ Ⅷⅷⅷ Ⅸⅸⅸ Ⅸⅸⅸ Ⅹⅹⅹ Ⅹⅹⅹ Ⅺⅺⅺ Ⅺⅺⅺ Ⅻⅻⅻ Ⅻⅻⅻ Ⅼⅼⅼ Ⅼⅼⅼ Ⅽⅽⅽ Ⅽⅽⅽ Ⅾⅾⅾ Ⅾⅾⅾ Ⅿⅿⅿ Ⅿⅿⅿ Ↄↄↄ Ↄↄↄ - diff --git a/testing/web-platform/tests/css/css-text/text-transform/reference/text-transform-capitalize-026-ref.html b/testing/web-platform/tests/css/css-text/text-transform/reference/text-transform-capitalize-026-ref.html index 6a0cb139f4c4..2c43f5f45f8c 100644 --- a/testing/web-platform/tests/css/css-text/text-transform/reference/text-transform-capitalize-026-ref.html +++ b/testing/web-platform/tests/css/css-text/text-transform/reference/text-transform-capitalize-026-ref.html @@ -1,5 +1,5 @@ - + CSS3 Text, text transform: capitalize, Enclosed Alphanumerics @@ -19,9 +19,5 @@ The text is arranged in pairs of three-letter 'words'. Test passes if there are NO uppercase letters. If you are missing a font glyph for a character, ignore that pair, but report which characters were ignored. ⓐⓐⓐ ⓑⓑⓑ ⓒⓒⓒ ⓓⓓⓓ ⓔⓔⓔ ⓕⓕⓕ ⓖⓖⓖ ⓗⓗⓗ ⓘⓘⓘ ⓙⓙⓙ ⓚⓚⓚ ⓛⓛⓛ ⓜⓜⓜ ⓝⓝⓝ ⓞⓞⓞ ⓟⓟⓟ ⓠⓠⓠ ⓡⓡⓡ ⓢⓢⓢ ⓣⓣⓣ ⓤⓤⓤ ⓥⓥⓥ ⓦⓦⓦ ⓧⓧⓧ ⓨⓨⓨ ⓩⓩⓩ - diff --git a/testing/web-platform/tests/css/css-text/text-transform/reference/text-transform-capitalize-028-ref.html b/testing/web-platform/tests/css/css-text/text-transform/reference/text-transform-capitalize-028-ref.html index a4df1a045e89..653386289dd8 100644 --- a/testing/web-platform/tests/css/css-text/text-transform/reference/text-transform-capitalize-028-ref.html +++ b/testing/web-platform/tests/css/css-text/text-transform/reference/text-transform-capitalize-028-ref.html @@ -1,5 +1,5 @@ - + CSS3 Text, text transform: capitalize, Deseret @@ -19,8 +19,5 @@ The text is arranged in pairs of three-letter 'words'. Test passes if the words in each pair match If you are missing a font glyph for a character, ignore that pair, but report which characters were ignored. 𐐀𐐨𐐨 𐐀𐐨𐐨 𐐁𐐩𐐩 𐐁𐐩𐐩 𐐂𐐪𐐪 𐐂𐐪𐐪 𐐃𐐫𐐫 𐐃𐐫𐐫 𐐄𐐬𐐬 𐐄𐐬𐐬 𐐅𐐭𐐭 𐐅𐐭𐐭 𐐆𐐮𐐮 𐐆𐐮𐐮 𐐇𐐯𐐯 𐐇𐐯𐐯 𐐈𐐰𐐰 𐐈𐐰𐐰 𐐉𐐱𐐱 𐐉𐐱𐐱 𐐊𐐲𐐲 𐐊𐐲𐐲 𐐋𐐳𐐳 𐐋𐐳𐐳 𐐌𐐴𐐴 𐐌𐐴𐐴 𐐍𐐵𐐵 𐐍𐐵𐐵 𐐎𐐶𐐶 𐐎𐐶𐐶 𐐏𐐷𐐷 𐐏𐐷𐐷 𐐐𐐸𐐸 𐐐𐐸𐐸 𐐑𐐹𐐹 𐐑𐐹𐐹 𐐒𐐺𐐺 𐐒𐐺𐐺 𐐓𐐻𐐻 𐐓𐐻𐐻 𐐔𐐼𐐼 𐐔𐐼𐐼 𐐕𐐽𐐽 𐐕𐐽𐐽 𐐖𐐾𐐾 𐐖𐐾𐐾 𐐗𐐿𐐿 𐐗𐐿𐐿 𐐘𐑀𐑀 𐐘𐑀𐑀 𐐙𐑁𐑁 𐐙𐑁𐑁 𐐚𐑂𐑂 𐐚𐑂𐑂 𐐛𐑃𐑃 𐐛𐑃𐑃 𐐜𐑄𐑄 𐐜𐑄𐑄 𐐝𐑅𐑅 𐐝𐑅𐑅 𐐞𐑆𐑆 𐐞𐑆𐑆 𐐟𐑇𐑇 𐐟𐑇𐑇 𐐠𐑈𐑈 𐐠𐑈𐑈 𐐡𐑉𐑉 𐐡𐑉𐑉 𐐢𐑊𐑊 𐐢𐑊𐑊 𐐣𐑋𐑋 𐐣𐑋𐑋 𐐤𐑌𐑌 𐐤𐑌𐑌 𐐥𐑍𐑍 𐐥𐑍𐑍 𐐦𐑎𐑎 𐐦𐑎𐑎 𐐧𐑏𐑏 𐐧𐑏𐑏 - diff --git a/testing/web-platform/tests/css/css-text/text-transform/reference/text-transform-capitalize-030-ref.html b/testing/web-platform/tests/css/css-text/text-transform/reference/text-transform-capitalize-030-ref.html index d5c5df445093..e848e64622d0 100644 --- a/testing/web-platform/tests/css/css-text/text-transform/reference/text-transform-capitalize-030-ref.html +++ b/testing/web-platform/tests/css/css-text/text-transform/reference/text-transform-capitalize-030-ref.html @@ -1,5 +1,5 @@ - + CSS3 Text, text transform: capitalize, Georgian Supplement @@ -19,8 +19,5 @@ The text is arranged in pairs of three-letter 'words'. Test passes if the words in each pair match If you are missing a font glyph for a character, ignore that pair, but report which characters were ignored. Ⴀⴀⴀ Ⴀⴀⴀ Ⴁⴁⴁ Ⴁⴁⴁ Ⴂⴂⴂ Ⴂⴂⴂ Ⴃⴃⴃ Ⴃⴃⴃ Ⴄⴄⴄ Ⴄⴄⴄ Ⴅⴅⴅ Ⴅⴅⴅ Ⴆⴆⴆ Ⴆⴆⴆ Ⴇⴇⴇ Ⴇⴇⴇ Ⴈⴈⴈ Ⴈⴈⴈ Ⴉⴉⴉ Ⴉⴉⴉ Ⴊⴊⴊ Ⴊⴊⴊ Ⴋⴋⴋ Ⴋⴋⴋ Ⴌⴌⴌ Ⴌⴌⴌ Ⴍⴍⴍ Ⴍⴍⴍ Ⴎⴎⴎ Ⴎⴎⴎ Ⴏⴏⴏ Ⴏⴏⴏ Ⴐⴐⴐ Ⴐⴐⴐ Ⴑⴑⴑ Ⴑⴑⴑ Ⴒⴒⴒ Ⴒⴒⴒ Ⴓⴓⴓ Ⴓⴓⴓ Ⴔⴔⴔ Ⴔⴔⴔ Ⴕⴕⴕ Ⴕⴕⴕ Ⴖⴖⴖ Ⴖⴖⴖ Ⴗⴗⴗ Ⴗⴗⴗ Ⴘⴘⴘ Ⴘⴘⴘ Ⴙⴙⴙ Ⴙⴙⴙ Ⴚⴚⴚ Ⴚⴚⴚ Ⴛⴛⴛ Ⴛⴛⴛ Ⴜⴜⴜ Ⴜⴜⴜ Ⴝⴝⴝ Ⴝⴝⴝ Ⴞⴞⴞ Ⴞⴞⴞ Ⴟⴟⴟ Ⴟⴟⴟ Ⴠⴠⴠ Ⴠⴠⴠ Ⴡⴡⴡ Ⴡⴡⴡ Ⴢⴢⴢ Ⴢⴢⴢ Ⴣⴣⴣ Ⴣⴣⴣ Ⴤⴤⴤ Ⴤⴤⴤ Ⴥⴥⴥ Ⴥⴥⴥ Ⴧⴧⴧ Ⴧⴧⴧ Ⴭⴭⴭ Ⴭⴭⴭ - diff --git a/testing/web-platform/tests/css/css-text/text-transform/reference/text-transform-capitalize-031-ref.html b/testing/web-platform/tests/css/css-text/text-transform/reference/text-transform-capitalize-031-ref.html index 91858fe205b4..2d0d9324bdf8 100644 --- a/testing/web-platform/tests/css/css-text/text-transform/reference/text-transform-capitalize-031-ref.html +++ b/testing/web-platform/tests/css/css-text/text-transform/reference/text-transform-capitalize-031-ref.html @@ -1,5 +1,5 @@ - + CSS3 Text, text transform: capitalize, initial punctuation diff --git a/testing/web-platform/tests/css/css-text/text-transform/reference/text-transform-full-size-kana-001-ref.html b/testing/web-platform/tests/css/css-text/text-transform/reference/text-transform-full-size-kana-001-ref.html index f9dd3b8e8fa6..a81a5eacb516 100644 --- a/testing/web-platform/tests/css/css-text/text-transform/reference/text-transform-full-size-kana-001-ref.html +++ b/testing/web-platform/tests/css/css-text/text-transform/reference/text-transform-full-size-kana-001-ref.html @@ -65,8 +65,5 @@ ユ ユ ヨ ヨ - diff --git a/testing/web-platform/tests/css/css-text/text-transform/reference/text-transform-full-size-kana-002-ref.html b/testing/web-platform/tests/css/css-text/text-transform/reference/text-transform-full-size-kana-002-ref.html index 15da056b7bbd..fe0b11995ebc 100644 --- a/testing/web-platform/tests/css/css-text/text-transform/reference/text-transform-full-size-kana-002-ref.html +++ b/testing/web-platform/tests/css/css-text/text-transform/reference/text-transform-full-size-kana-002-ref.html @@ -221,8 +221,5 @@ ゙ ゙ ゚ ゚ - diff --git a/testing/web-platform/tests/css/css-text/text-transform/reference/text-transform-tailoring-001-ref.html b/testing/web-platform/tests/css/css-text/text-transform/reference/text-transform-tailoring-001-ref.html index 6f5dfc5898bf..6fe91c7828bb 100644 --- a/testing/web-platform/tests/css/css-text/text-transform/reference/text-transform-tailoring-001-ref.html +++ b/testing/web-platform/tests/css/css-text/text-transform/reference/text-transform-tailoring-001-ref.html @@ -1,5 +1,5 @@ - + CSS3 Text, text transform: capitalize, Dutch IJ diff --git a/testing/web-platform/tests/css/css-text/text-transform/reference/text-transform-tailoring-002-ref.html b/testing/web-platform/tests/css/css-text/text-transform/reference/text-transform-tailoring-002-ref.html index e9d94031d7bf..5259caa77038 100644 --- a/testing/web-platform/tests/css/css-text/text-transform/reference/text-transform-tailoring-002-ref.html +++ b/testing/web-platform/tests/css/css-text/text-transform/reference/text-transform-tailoring-002-ref.html @@ -1,5 +1,5 @@ - + CSS3 Text, text transform: uppercase, Greek tonos diff --git a/testing/web-platform/tests/css/css-text/text-transform/reference/text-transform-tailoring-002a-ref.html b/testing/web-platform/tests/css/css-text/text-transform/reference/text-transform-tailoring-002a-ref.html index f57adcb68b48..2108495c9490 100644 --- a/testing/web-platform/tests/css/css-text/text-transform/reference/text-transform-tailoring-002a-ref.html +++ b/testing/web-platform/tests/css/css-text/text-transform/reference/text-transform-tailoring-002a-ref.html @@ -1,5 +1,5 @@ - + CSS3 Text, text transform: uppercase, Greek dialytika diff --git a/testing/web-platform/tests/css/css-text/text-transform/reference/text-transform-tailoring-003-ref.html b/testing/web-platform/tests/css/css-text/text-transform/reference/text-transform-tailoring-003-ref.html index ee6bd786cb1e..818d5006f6dc 100644 --- a/testing/web-platform/tests/css/css-text/text-transform/reference/text-transform-tailoring-003-ref.html +++ b/testing/web-platform/tests/css/css-text/text-transform/reference/text-transform-tailoring-003-ref.html @@ -1,5 +1,5 @@ - + CSS3 Text, text transform: uppercase, more Greek accents diff --git a/testing/web-platform/tests/css/css-text/text-transform/reference/text-transform-tailoring-004-ref.html b/testing/web-platform/tests/css/css-text/text-transform/reference/text-transform-tailoring-004-ref.html index 141066cc970d..3047f66b13c1 100644 --- a/testing/web-platform/tests/css/css-text/text-transform/reference/text-transform-tailoring-004-ref.html +++ b/testing/web-platform/tests/css/css-text/text-transform/reference/text-transform-tailoring-004-ref.html @@ -1,5 +1,5 @@ - + CSS3 Text, text transform: capitalize, Greek initial stress diff --git a/testing/web-platform/tests/css/css-text/text-transform/reference/text-transform-tailoring-005-ref.html b/testing/web-platform/tests/css/css-text/text-transform/reference/text-transform-tailoring-005-ref.html index 7de769ebf2ce..66ce847e30a1 100644 --- a/testing/web-platform/tests/css/css-text/text-transform/reference/text-transform-tailoring-005-ref.html +++ b/testing/web-platform/tests/css/css-text/text-transform/reference/text-transform-tailoring-005-ref.html @@ -1,5 +1,5 @@ - + CSS3 Text, text transform: uppercase, Greek disjunctive eta diff --git a/testing/web-platform/tests/css/css-text/text-transform/reference/text-transform-upperlower-001-ref.html b/testing/web-platform/tests/css/css-text/text-transform/reference/text-transform-upperlower-001-ref.html index fd9b5a7be5bb..9f990b7479ab 100644 --- a/testing/web-platform/tests/css/css-text/text-transform/reference/text-transform-upperlower-001-ref.html +++ b/testing/web-platform/tests/css/css-text/text-transform/reference/text-transform-upperlower-001-ref.html @@ -1,5 +1,5 @@ - + CSS3 Text, text transform: Latin Basic and Latin-1 uppercase @@ -18,8 +18,5 @@ Test passes if both characters in each pair match. If you are missing a font glyph for a character, ignore that pair, but report which characters were ignored. A A B B C C D D E E F F G G H H I I J J K K L L M M N N O O P P Q Q R R S S T T U U V V W W X X Y Y Z Z Μ Μ À À Á Á Â Â Ã Ã Ä Ä Å Å Æ Æ Ç Ç È È É É Ê Ê Ë Ë Ì Ì Í Í Î Î Ï Ï Ð Ð Ñ Ñ Ò Ò Ó Ó Ô Ô Õ Õ Ö Ö Ø Ø Ù Ù Ú Ú Û Û Ü Ü Ý Ý Þ Þ Ÿ Ÿ - - \ No newline at end of file + diff --git a/testing/web-platform/tests/css/css-text/text-transform/reference/text-transform-upperlower-002-ref.html b/testing/web-platform/tests/css/css-text/text-transform/reference/text-transform-upperlower-002-ref.html index ae7327048b34..2f32a815a09b 100644 --- a/testing/web-platform/tests/css/css-text/text-transform/reference/text-transform-upperlower-002-ref.html +++ b/testing/web-platform/tests/css/css-text/text-transform/reference/text-transform-upperlower-002-ref.html @@ -1,5 +1,5 @@ - + CSS3 Text, text transform: Latin Basic and Latin-1 lowercase @@ -18,8 +18,5 @@ Test passes if both characters in each pair match. If you are missing a font glyph for a character, ignore that pair, but report which characters were ignored. a a b b c c d d e e f f g g h h i i j j k k l l m m n n o o p p q q r r s s t t u u v v w w x x y y z z à à á á â â ã ã ä ä å å æ æ ç ç è è é é ê ê ë ë ì ì í í î î ï ï ð ð ñ ñ ò ò ó ó ô ô õ õ ö ö ø ø ù ù ú ú û û ü ü ý ý þ þ - - \ No newline at end of file + diff --git a/testing/web-platform/tests/css/css-text/text-transform/reference/text-transform-upperlower-003-ref.html b/testing/web-platform/tests/css/css-text/text-transform/reference/text-transform-upperlower-003-ref.html index bc8750daeba4..6df7d7d8f5ed 100644 --- a/testing/web-platform/tests/css/css-text/text-transform/reference/text-transform-upperlower-003-ref.html +++ b/testing/web-platform/tests/css/css-text/text-transform/reference/text-transform-upperlower-003-ref.html @@ -1,5 +1,5 @@ - + CSS3 Text, text transform: Latin Extended Additional, uppercase @@ -20,7 +20,6 @@ Ḁ Ḁ Ḃ Ḃ Ḅ Ḅ Ḇ Ḇ Ḉ Ḉ Ḋ Ḋ Ḍ Ḍ Ḏ Ḏ Ḑ Ḑ Ḓ Ḓ Ḕ Ḕ Ḗ Ḗ Ḙ Ḙ Ḛ Ḛ Ḝ Ḝ Ḟ Ḟ Ḡ Ḡ Ḣ Ḣ Ḥ Ḥ Ḧ Ḧ Ḩ Ḩ Ḫ Ḫ Ḭ Ḭ Ḯ Ḯ Ḱ Ḱ Ḳ Ḳ Ḵ Ḵ Ḷ Ḷ Ḹ Ḹ Ḻ Ḻ Ḽ Ḽ Ḿ Ḿ Ṁ Ṁ Ṃ Ṃ Ṅ Ṅ Ṇ Ṇ Ṉ Ṉ Ṋ Ṋ Ṍ Ṍ Ṏ Ṏ Ṑ Ṑ Ṓ Ṓ Ṕ Ṕ Ṗ Ṗ Ṙ Ṙ Ṛ Ṛ Ṝ Ṝ Ṟ Ṟ Ṡ Ṡ Ṣ Ṣ Ṥ Ṥ Ṧ Ṧ Ṩ Ṩ Ṫ Ṫ Ṭ Ṭ Ṯ Ṯ Ṱ Ṱ Ṳ Ṳ Ṵ Ṵ Ṷ Ṷ Ṹ Ṹ Ṻ Ṻ Ṽ Ṽ Ṿ Ṿ Ẁ Ẁ Ẃ Ẃ Ẅ Ẅ Ẇ Ẇ Ẉ Ẉ Ẋ Ẋ Ẍ Ẍ Ẏ Ẏ Ẑ Ẑ Ẓ Ẓ Ẕ Ẕ Ṡ Ṡ Ạ Ạ Ả Ả Ấ Ấ Ầ Ầ Ẩ Ẩ Ẫ Ẫ Ậ Ậ Ắ Ắ Ằ Ằ Ẳ Ẳ Ẵ Ẵ Ặ Ặ Ẹ Ẹ Ẻ Ẻ Ẽ Ẽ Ế Ế Ề Ề Ể Ể Ễ Ễ Ệ Ệ Ỉ Ỉ Ị Ị Ọ Ọ Ỏ Ỏ Ố Ố Ồ Ồ Ổ Ổ Ỗ Ỗ Ộ Ộ Ớ Ớ Ờ Ờ Ở Ở Ỡ Ỡ Ợ Ợ Ụ Ụ Ủ Ủ Ứ Ứ Ừ Ừ Ử Ử Ữ Ữ Ự Ự Ỳ Ỳ Ỵ Ỵ Ỷ Ỷ Ỹ Ỹ Ỻ Ỻ Ỽ Ỽ Ỿ Ỿ - \ No newline at end of file + diff --git a/testing/web-platform/tests/css/css-text/text-transform/reference/text-transform-upperlower-004-ref.html b/testing/web-platform/tests/css/css-text/text-transform/reference/text-transform-upperlower-004-ref.html index 99d7c91d063d..c43a76641091 100644 --- a/testing/web-platform/tests/css/css-text/text-transform/reference/text-transform-upperlower-004-ref.html +++ b/testing/web-platform/tests/css/css-text/text-transform/reference/text-transform-upperlower-004-ref.html @@ -1,5 +1,5 @@ - + CSS3 Text, text transform: Latin Extended Additional, lowercase @@ -20,7 +20,6 @@ ḁ ḁ ḃ ḃ ḅ ḅ ḇ ḇ ḉ ḉ ḋ ḋ ḍ ḍ ḏ ḏ ḑ ḑ ḓ ḓ ḕ ḕ ḗ ḗ ḙ ḙ ḛ ḛ ḝ ḝ ḟ ḟ ḡ ḡ ḣ ḣ ḥ ḥ ḧ ḧ ḩ ḩ ḫ ḫ ḭ ḭ ḯ ḯ ḱ ḱ ḳ ḳ ḵ ḵ ḷ ḷ ḹ ḹ ḻ ḻ ḽ ḽ ḿ ḿ ṁ ṁ ṃ ṃ ṅ ṅ ṇ ṇ ṉ ṉ ṋ ṋ ṍ ṍ ṏ ṏ ṑ ṑ ṓ ṓ ṕ ṕ ṗ ṗ ṙ ṙ ṛ ṛ ṝ ṝ ṟ ṟ ṡ ṡ ṣ ṣ ṥ ṥ ṧ ṧ ṩ ṩ ṫ ṫ ṭ ṭ ṯ ṯ ṱ ṱ ṳ ṳ ṵ ṵ ṷ ṷ ṹ ṹ ṻ ṻ ṽ ṽ ṿ ṿ ẁ ẁ ẃ ẃ ẅ ẅ ẇ ẇ ẉ ẉ ẋ ẋ ẍ ẍ ẏ ẏ ẑ ẑ ẓ ẓ ẕ ẕ ß ß ạ ạ ả ả ấ ấ ầ ầ ẩ ẩ ẫ ẫ ậ ậ ắ ắ ằ ằ ẳ ẳ ẵ ẵ ặ ặ ẹ ẹ ẻ ẻ ẽ ẽ ế ế ề ề ể ể ễ ễ ệ ệ ỉ ỉ ị ị ọ ọ ỏ ỏ ố ố ồ ồ ổ ổ ỗ ỗ ộ ộ ớ ớ ờ ờ ở ở ỡ ỡ ợ ợ ụ ụ ủ ủ ứ ứ ừ ừ ử ử ữ ữ ự ự ỳ ỳ ỵ ỵ ỷ ỷ ỹ ỹ ỻ ỻ ỽ ỽ ỿ ỿ - \ No newline at end of file + diff --git a/testing/web-platform/tests/css/css-text/text-transform/reference/text-transform-upperlower-005-ref.html b/testing/web-platform/tests/css/css-text/text-transform/reference/text-transform-upperlower-005-ref.html index 5919ccd98bc8..2b686f4896cf 100644 --- a/testing/web-platform/tests/css/css-text/text-transform/reference/text-transform-upperlower-005-ref.html +++ b/testing/web-platform/tests/css/css-text/text-transform/reference/text-transform-upperlower-005-ref.html @@ -1,5 +1,5 @@ - + CSS3 Text, text transform: Latin Extended-A, uppercase @@ -20,7 +20,6 @@ Ā Ā Ă Ă Ą Ą Ć Ć Ĉ Ĉ Ċ Ċ Č Č Ď Ď Đ Đ Ē Ē Ĕ Ĕ Ė Ė Ę Ę Ě Ě Ĝ Ĝ Ğ Ğ Ġ Ġ Ģ Ģ Ĥ Ĥ Ħ Ħ Ĩ Ĩ Ī Ī Ĭ Ĭ Į Į I I IJ IJ Ĵ Ĵ Ķ Ķ Ĺ Ĺ Ļ Ļ Ľ Ľ Ŀ Ŀ Ł Ł Ń Ń Ņ Ņ Ň Ň Ŋ Ŋ Ō Ō Ŏ Ŏ Ő Ő Œ Œ Ŕ Ŕ Ŗ Ŗ Ř Ř Ś Ś Ŝ Ŝ Ş Ş Š Š Ţ Ţ Ť Ť Ŧ Ŧ Ũ Ũ Ū Ū Ŭ Ŭ Ů Ů Ű Ű Ų Ų Ŵ Ŵ Ŷ Ŷ Ź Ź Ż Ż Ž Ž S S - \ No newline at end of file + diff --git a/testing/web-platform/tests/css/css-text/text-transform/reference/text-transform-upperlower-006-ref.html b/testing/web-platform/tests/css/css-text/text-transform/reference/text-transform-upperlower-006-ref.html index ebcc1141ffc7..2a43c803b91f 100644 --- a/testing/web-platform/tests/css/css-text/text-transform/reference/text-transform-upperlower-006-ref.html +++ b/testing/web-platform/tests/css/css-text/text-transform/reference/text-transform-upperlower-006-ref.html @@ -1,5 +1,5 @@ - + CSS3 Text, text transform: Latin Extended-A, lowercase @@ -20,7 +20,6 @@ ā ā ă ă ą ą ć ć ĉ ĉ ċ ċ č č ď ď đ đ ē ē ĕ ĕ ė ė ę ę ě ě ĝ ĝ ğ ğ ġ ġ ģ ģ ĥ ĥ ħ ħ ĩ ĩ ī ī ĭ ĭ į į i i ij ij ĵ ĵ ķ ķ ĺ ĺ ļ ļ ľ ľ ŀ ŀ ł ł ń ń ņ ņ ň ň ŋ ŋ ō ō ŏ ŏ ő ő œ œ ŕ ŕ ŗ ŗ ř ř ś ś ŝ ŝ ş ş š š ţ ţ ť ť ŧ ŧ ũ ũ ū ū ŭ ŭ ů ů ű ű ų ų ŵ ŵ ŷ ŷ ÿ ÿ ź ź ż ż ž ž - \ No newline at end of file + diff --git a/testing/web-platform/tests/css/css-text/text-transform/reference/text-transform-upperlower-007-ref.html b/testing/web-platform/tests/css/css-text/text-transform/reference/text-transform-upperlower-007-ref.html index 255d7fcd291b..d2f5640195b4 100644 --- a/testing/web-platform/tests/css/css-text/text-transform/reference/text-transform-upperlower-007-ref.html +++ b/testing/web-platform/tests/css/css-text/text-transform/reference/text-transform-upperlower-007-ref.html @@ -1,5 +1,5 @@ - + CSS3 Text, text transform: Latin Extended-B, uppercase @@ -20,7 +20,6 @@ Ƀ Ƀ Ƃ Ƃ Ƅ Ƅ Ƈ Ƈ Ƌ Ƌ Ƒ Ƒ Ƕ Ƕ Ƙ Ƙ Ƚ Ƚ Ƞ Ƞ Ơ Ơ Ƣ Ƣ Ƥ Ƥ Ƨ Ƨ Ƭ Ƭ Ư Ư Ƴ Ƴ Ƶ Ƶ Ƹ Ƹ Ƽ Ƽ Ƿ Ƿ DŽ DŽ DŽ DŽ LJ LJ LJ LJ NJ NJ NJ NJ Ǎ Ǎ Ǐ Ǐ Ǒ Ǒ Ǔ Ǔ Ǖ Ǖ Ǘ Ǘ Ǚ Ǚ Ǜ Ǜ Ǝ Ǝ Ǟ Ǟ Ǡ Ǡ Ǣ Ǣ Ǥ Ǥ Ǧ Ǧ Ǩ Ǩ Ǫ Ǫ Ǭ Ǭ Ǯ Ǯ DZ DZ DZ DZ Ǵ Ǵ Ǹ Ǹ Ǻ Ǻ Ǽ Ǽ Ǿ Ǿ Ȁ Ȁ Ȃ Ȃ Ȅ Ȅ Ȇ Ȇ Ȉ Ȉ Ȋ Ȋ Ȍ Ȍ Ȏ Ȏ Ȑ Ȑ Ȓ Ȓ Ȕ Ȕ Ȗ Ȗ Ș Ș Ț Ț Ȝ Ȝ Ȟ Ȟ Ȣ Ȣ Ȥ Ȥ Ȧ Ȧ Ȩ Ȩ Ȫ Ȫ Ȭ Ȭ Ȯ Ȯ Ȱ Ȱ Ȳ Ȳ Ȼ Ȼ Ȿ Ȿ Ɀ Ɀ Ɂ Ɂ Ɇ Ɇ Ɉ Ɉ Ɋ Ɋ Ɍ Ɍ Ɏ Ɏ - \ No newline at end of file + diff --git a/testing/web-platform/tests/css/css-text/text-transform/reference/text-transform-upperlower-008-ref.html b/testing/web-platform/tests/css/css-text/text-transform/reference/text-transform-upperlower-008-ref.html index b794e1197815..7a98633c386e 100644 --- a/testing/web-platform/tests/css/css-text/text-transform/reference/text-transform-upperlower-008-ref.html +++ b/testing/web-platform/tests/css/css-text/text-transform/reference/text-transform-upperlower-008-ref.html @@ -1,5 +1,5 @@ - + CSS3 Text, text transform: Latin Extended-B, lowercase @@ -20,6 +20,5 @@ ɓ ɓ ƃ ƃ ƅ ƅ ɔ ɔ ƈ ƈ ɖ ɖ ɗ ɗ ƌ ƌ ǝ ǝ ə ə ɛ ɛ ƒ ƒ ɠ ɠ ɣ ɣ ɩ ɩ ɨ ɨ ƙ ƙ ɯ ɯ ɲ ɲ ɵ ɵ ơ ơ ƣ ƣ ƥ ƥ ʀ ʀ ƨ ƨ ʃ ʃ ƭ ƭ ʈ ʈ ư ư ʊ ʊ ʋ ʋ ƴ ƴ ƶ ƶ ʒ ʒ ƹ ƹ ƽ ƽ dž dž dž dž lj lj lj lj nj nj nj nj ǎ ǎ ǐ ǐ ǒ ǒ ǔ ǔ ǖ ǖ ǘ ǘ ǚ ǚ ǜ ǜ ǟ ǟ ǡ ǡ ǣ ǣ ǥ ǥ ǧ ǧ ǩ ǩ ǫ ǫ ǭ ǭ ǯ ǯ dz dz dz dz ǵ ǵ ƕ ƕ ƿ ƿ ǹ ǹ ǻ ǻ ǽ ǽ ǿ ǿ ȁ ȁ ȃ ȃ ȅ ȅ ȇ ȇ ȉ ȉ ȋ ȋ ȍ ȍ ȏ ȏ ȑ ȑ ȓ ȓ ȕ ȕ ȗ ȗ ș ș ț ț ȝ ȝ ȟ ȟ ƞ ƞ ȣ ȣ ȥ ȥ ȧ ȧ ȩ ȩ ȫ ȫ ȭ ȭ ȯ ȯ ȱ ȱ ȳ ȳ ⱥ ⱥ ȼ ȼ ƚ ƚ ⱦ ⱦ ɂ ɂ ƀ ƀ ʉ ʉ ʌ ʌ ɇ ɇ ɉ ɉ ɋ ɋ ɍ ɍ ɏ ɏ - \ No newline at end of file + diff --git a/testing/web-platform/tests/css/css-text/text-transform/reference/text-transform-upperlower-009-ref.html b/testing/web-platform/tests/css/css-text/text-transform/reference/text-transform-upperlower-009-ref.html index 446fb2c26e83..b03e2015c1d2 100644 --- a/testing/web-platform/tests/css/css-text/text-transform/reference/text-transform-upperlower-009-ref.html +++ b/testing/web-platform/tests/css/css-text/text-transform/reference/text-transform-upperlower-009-ref.html @@ -1,5 +1,5 @@ - + CSS3 Text, text transform: Latin Extended-C, uppercase @@ -20,7 +20,6 @@ Ⱡ Ⱡ Ⱥ Ⱥ Ⱦ Ⱦ Ⱨ Ⱨ Ⱪ Ⱪ Ⱬ Ⱬ Ⱳ Ⱳ Ⱶ Ⱶ - \ No newline at end of file + diff --git a/testing/web-platform/tests/css/css-text/text-transform/reference/text-transform-upperlower-010-ref.html b/testing/web-platform/tests/css/css-text/text-transform/reference/text-transform-upperlower-010-ref.html index d2c61f9e8820..feace76b8e3c 100644 --- a/testing/web-platform/tests/css/css-text/text-transform/reference/text-transform-upperlower-010-ref.html +++ b/testing/web-platform/tests/css/css-text/text-transform/reference/text-transform-upperlower-010-ref.html @@ -1,5 +1,5 @@ - + CSS3 Text, text transform: Latin Extended-C, lowercase @@ -20,6 +20,5 @@ ⱡ ⱡ ɫ ɫ ᵽ ᵽ ɽ ɽ ⱨ ⱨ ⱪ ⱪ ⱬ ⱬ ɑ ɑ ɱ ɱ ɐ ɐ ɒ ɒ ⱳ ⱳ ⱶ ⱶ ȿ ȿ ɀ ɀ - \ No newline at end of file + diff --git a/testing/web-platform/tests/css/css-text/text-transform/reference/text-transform-upperlower-011-ref.html b/testing/web-platform/tests/css/css-text/text-transform/reference/text-transform-upperlower-011-ref.html index 17f80261ab44..25aca08eaa8b 100644 --- a/testing/web-platform/tests/css/css-text/text-transform/reference/text-transform-upperlower-011-ref.html +++ b/testing/web-platform/tests/css/css-text/text-transform/reference/text-transform-upperlower-011-ref.html @@ -1,5 +1,5 @@ - + CSS3 Text, text transform: Full-width Latin, uppercase @@ -20,7 +20,6 @@ A A B B C C D D E E F F G G H H I I J J K K L L M M N N O O P P Q Q R R S S T T U U V V W W X X Y Y Z Z - \ No newline at end of file + diff --git a/testing/web-platform/tests/css/css-text/text-transform/reference/text-transform-upperlower-012-ref.html b/testing/web-platform/tests/css/css-text/text-transform/reference/text-transform-upperlower-012-ref.html index 52e3aeab98a3..ba83c03b38de 100644 --- a/testing/web-platform/tests/css/css-text/text-transform/reference/text-transform-upperlower-012-ref.html +++ b/testing/web-platform/tests/css/css-text/text-transform/reference/text-transform-upperlower-012-ref.html @@ -1,5 +1,5 @@ - + CSS3 Text, text transform: Full-width Latin, lowercase @@ -20,6 +20,5 @@ a a b b c c d d e e f f g g h h i i j j k k l l m m n n o o p p q q r r s s t t u u v v w w x x y y z z - \ No newline at end of file + diff --git a/testing/web-platform/tests/css/css-text/text-transform/reference/text-transform-upperlower-014-ref.html b/testing/web-platform/tests/css/css-text/text-transform/reference/text-transform-upperlower-014-ref.html index b9d1a910482b..c22131c0bed3 100644 --- a/testing/web-platform/tests/css/css-text/text-transform/reference/text-transform-upperlower-014-ref.html +++ b/testing/web-platform/tests/css/css-text/text-transform/reference/text-transform-upperlower-014-ref.html @@ -1,5 +1,5 @@ - + CSS3 Text, text transform: Greek and Coptic, uppercase @@ -20,7 +20,6 @@ Ͱ Ͱ Ͳ Ͳ Ͷ Ͷ Ͻ Ͻ Ͼ Ͼ Ͽ Ͽ Ά Ά Έ Έ Ή Ή Ί Ί Α Α Β Β Γ Γ Δ Δ Ε Ε Ζ Ζ Η Η Θ Θ Ι Ι Κ Κ Λ Λ Μ Μ Ν Ν Ξ Ξ Ο Ο Π Π Ρ Ρ Σ Σ Σ Σ Τ Τ Υ Υ Φ Φ Χ Χ Ψ Ψ Ω Ω Ϊ Ϊ Ϋ Ϋ Ό Ό Ύ Ύ Ώ Ώ Β Β Θ Θ Φ Φ Π Π Ϗ Ϗ Ϙ Ϙ Ϛ Ϛ Ϝ Ϝ Ϟ Ϟ Ϡ Ϡ Ϣ Ϣ Ϥ Ϥ Ϧ Ϧ Ϩ Ϩ Ϫ Ϫ Ϭ Ϭ Ϯ Ϯ Κ Κ Ρ Ρ Ϲ Ϲ Ϳ Ϳ Ε Ε Ϸ Ϸ Ϻ Ϻ - \ No newline at end of file + diff --git a/testing/web-platform/tests/css/css-text/text-transform/reference/text-transform-upperlower-015-ref.html b/testing/web-platform/tests/css/css-text/text-transform/reference/text-transform-upperlower-015-ref.html index fa717923d327..332845b11387 100644 --- a/testing/web-platform/tests/css/css-text/text-transform/reference/text-transform-upperlower-015-ref.html +++ b/testing/web-platform/tests/css/css-text/text-transform/reference/text-transform-upperlower-015-ref.html @@ -1,5 +1,5 @@ - + CSS3 Text, text transform: Greek and Coptic, lowercase @@ -20,7 +20,6 @@ ͱ ͱ ͳ ͳ ͷ ͷ ϳ ϳ ά ά έ έ ή ή ί ί ό ό ύ ύ ώ ώ α α β β γ γ δ δ ε ε ζ ζ η η θ θ ι ι κ κ λ λ μ μ ν ν ξ ξ ο ο π π ρ ρ σ σ τ τ υ υ φ φ χ χ ψ ψ ω ω ϊ ϊ ϋ ϋ ϗ ϗ ϙ ϙ ϛ ϛ ϝ ϝ ϟ ϟ ϡ ϡ ϣ ϣ ϥ ϥ ϧ ϧ ϩ ϩ ϫ ϫ ϭ ϭ ϯ ϯ θ θ ϸ ϸ ϲ ϲ ϻ ϻ ͻ ͻ ͼ ͼ ͽ ͽ - \ No newline at end of file + diff --git a/testing/web-platform/tests/css/css-text/text-transform/reference/text-transform-upperlower-016-ref.html b/testing/web-platform/tests/css/css-text/text-transform/reference/text-transform-upperlower-016-ref.html index e900de1be7cc..e5f2e6549ded 100644 --- a/testing/web-platform/tests/css/css-text/text-transform/reference/text-transform-upperlower-016-ref.html +++ b/testing/web-platform/tests/css/css-text/text-transform/reference/text-transform-upperlower-016-ref.html @@ -1,5 +1,5 @@ - + CSS3 Text, text transform: Greek Extended, uppercase @@ -22,7 +22,6 @@ - \ No newline at end of file + diff --git a/testing/web-platform/tests/css/css-text/text-transform/reference/text-transform-upperlower-017-ref.html b/testing/web-platform/tests/css/css-text/text-transform/reference/text-transform-upperlower-017-ref.html index 4f727de685eb..da8ada0d28ad 100644 --- a/testing/web-platform/tests/css/css-text/text-transform/reference/text-transform-upperlower-017-ref.html +++ b/testing/web-platform/tests/css/css-text/text-transform/reference/text-transform-upperlower-017-ref.html @@ -1,5 +1,5 @@ - + CSS3 Text, text transform: Greek Extended, lowercase @@ -21,6 +21,5 @@ ἀ ἀ ἁ ἁ ἂ ἂ ἃ ἃ ἄ ἄ ἅ ἅ ἆ ἆ ἇ ἇ ἐ ἐ ἑ ἑ ἒ ἒ ἓ ἓ ἔ ἔ ἕ ἕ ἠ ἠ ἡ ἡ ἢ ἢ ἣ ἣ ἤ ἤ ἥ ἥ ἦ ἦ ἧ ἧ ἰ ἰ ἱ ἱ ἲ ἲ ἳ ἳ ἴ ἴ ἵ ἵ ἶ ἶ ἷ ἷ ὀ ὀ ὁ ὁ ὂ ὂ ὃ ὃ ὄ ὄ ὅ ὅ ὑ ὑ ὓ ὓ ὕ ὕ ὗ ὗ ὠ ὠ ὡ ὡ ὢ ὢ ὣ ὣ ὤ ὤ ὥ ὥ ὦ ὦ ὧ ὧ ᾀ ᾀ ᾁ ᾁ ᾂ ᾂ ᾃ ᾃ ᾄ ᾄ ᾅ ᾅ ᾆ ᾆ ᾇ ᾇ ᾐ ᾐ ᾑ ᾑ ᾒ ᾒ ᾓ ᾓ ᾔ ᾔ ᾕ ᾕ ᾖ ᾖ ᾗ ᾗ ᾠ ᾠ ᾡ ᾡ ᾢ ᾢ ᾣ ᾣ ᾤ ᾤ ᾥ ᾥ ᾦ ᾦ ᾧ ᾧ ᾰ ᾰ ᾱ ᾱ ὰ ὰ ά ά ᾳ ᾳ ὲ ὲ έ έ ὴ ὴ ή ή ῃ ῃ ῐ ῐ ῑ ῑ ὶ ὶ ί ί ῠ ῠ ῡ ῡ ὺ ὺ ύ ύ ῥ ῥ ὸ ὸ ό ό ὼ ὼ ώ ώ ῳ ῳ - \ No newline at end of file + diff --git a/testing/web-platform/tests/css/css-text/text-transform/reference/text-transform-upperlower-018-ref.html b/testing/web-platform/tests/css/css-text/text-transform/reference/text-transform-upperlower-018-ref.html index bcb4a58cbe9d..b53b0d1b9a92 100644 --- a/testing/web-platform/tests/css/css-text/text-transform/reference/text-transform-upperlower-018-ref.html +++ b/testing/web-platform/tests/css/css-text/text-transform/reference/text-transform-upperlower-018-ref.html @@ -1,5 +1,5 @@ - + CSS3 Text, text transform: Cyrillic, uppercase @@ -22,7 +22,6 @@ А А Б Б В В Г Г Д Д Е Е Ж Ж З З И И Й Й К К Л Л М М Н Н О О П П Р Р С С Т Т У У Ф Ф Х Х Ц Ц Ч Ч Ш Ш Щ Щ Ъ Ъ Ы Ы Ь Ь Э Э Ю Ю Я Я Ѐ Ѐ Ё Ё Ђ Ђ Ѓ Ѓ Є Є Ѕ Ѕ І І Ї Ї Ј Ј Љ Љ Њ Њ Ћ Ћ Ќ Ќ Ѝ Ѝ Ў Ў Џ Џ Ѡ Ѡ Ѣ Ѣ Ѥ Ѥ Ѧ Ѧ Ѩ Ѩ Ѫ Ѫ Ѭ Ѭ Ѯ Ѯ Ѱ Ѱ Ѳ Ѳ Ѵ Ѵ Ѷ Ѷ Ѹ Ѹ Ѻ Ѻ Ѽ Ѽ Ѿ Ѿ Ҁ Ҁ Ҋ Ҋ Ҍ Ҍ Ҏ Ҏ Ґ Ґ Ғ Ғ Ҕ Ҕ Җ Җ Ҙ Ҙ Қ Қ Ҝ Ҝ Ҟ Ҟ Ҡ Ҡ Ң Ң Ҥ Ҥ Ҧ Ҧ Ҩ Ҩ Ҫ Ҫ Ҭ Ҭ Ү Ү Ұ Ұ Ҳ Ҳ Ҵ Ҵ Ҷ Ҷ Ҹ Ҹ Һ Һ Ҽ Ҽ Ҿ Ҿ Ӂ Ӂ Ӄ Ӄ Ӆ Ӆ Ӈ Ӈ Ӊ Ӊ Ӌ Ӌ Ӎ Ӎ Ӏ Ӏ Ӑ Ӑ Ӓ Ӓ Ӕ Ӕ Ӗ Ӗ Ә Ә Ӛ Ӛ Ӝ Ӝ Ӟ Ӟ Ӡ Ӡ Ӣ Ӣ Ӥ Ӥ Ӧ Ӧ Ө Ө Ӫ Ӫ Ӭ Ӭ Ӯ Ӯ Ӱ Ӱ Ӳ Ӳ Ӵ Ӵ Ӷ Ӷ Ӹ Ӹ Ӻ Ӻ Ӽ Ӽ Ӿ Ӿ - \ No newline at end of file + diff --git a/testing/web-platform/tests/css/css-text/text-transform/reference/text-transform-upperlower-019-ref.html b/testing/web-platform/tests/css/css-text/text-transform/reference/text-transform-upperlower-019-ref.html index f63be7d86b25..84b72feea54b 100644 --- a/testing/web-platform/tests/css/css-text/text-transform/reference/text-transform-upperlower-019-ref.html +++ b/testing/web-platform/tests/css/css-text/text-transform/reference/text-transform-upperlower-019-ref.html @@ -1,5 +1,5 @@ - + CSS3 Text, text transform: Cyrillic, lowercase @@ -22,6 +22,5 @@ ѐ ѐ ё ё ђ ђ ѓ ѓ є є ѕ ѕ і і ї ї ј ј љ љ њ њ ћ ћ ќ ќ ѝ ѝ ў ў џ џ а а б б в в г г д д е е ж ж з з и и й й к к л л м м н н о о п п р р с с т т у у ф ф х х ц ц ч ч ш ш щ щ ъ ъ ы ы ь ь э э ю ю я я ѡ ѡ ѣ ѣ ѥ ѥ ѧ ѧ ѩ ѩ ѫ ѫ ѭ ѭ ѯ ѯ ѱ ѱ ѳ ѳ ѵ ѵ ѷ ѷ ѹ ѹ ѻ ѻ ѽ ѽ ѿ ѿ ҁ ҁ ҋ ҋ ҍ ҍ ҏ ҏ ґ ґ ғ ғ ҕ ҕ җ җ ҙ ҙ қ қ ҝ ҝ ҟ ҟ ҡ ҡ ң ң ҥ ҥ ҧ ҧ ҩ ҩ ҫ ҫ ҭ ҭ ү ү ұ ұ ҳ ҳ ҵ ҵ ҷ ҷ ҹ ҹ һ һ ҽ ҽ ҿ ҿ ӏ ӏ ӂ ӂ ӄ ӄ ӆ ӆ ӈ ӈ ӊ ӊ ӌ ӌ ӎ ӎ ӑ ӑ ӓ ӓ ӕ ӕ ӗ ӗ ә ә ӛ ӛ ӝ ӝ ӟ ӟ ӡ ӡ ӣ ӣ ӥ ӥ ӧ ӧ ө ө ӫ ӫ ӭ ӭ ӯ ӯ ӱ ӱ ӳ ӳ ӵ ӵ ӷ ӷ ӹ ӹ ӻ ӻ ӽ ӽ ӿ ӿ - \ No newline at end of file + diff --git a/testing/web-platform/tests/css/css-text/text-transform/reference/text-transform-upperlower-020-ref.html b/testing/web-platform/tests/css/css-text/text-transform/reference/text-transform-upperlower-020-ref.html index 5c757b38e41d..47d2e6d9bb0b 100644 --- a/testing/web-platform/tests/css/css-text/text-transform/reference/text-transform-upperlower-020-ref.html +++ b/testing/web-platform/tests/css/css-text/text-transform/reference/text-transform-upperlower-020-ref.html @@ -1,5 +1,5 @@ - + CSS3 Text, text transform: Cyrillic Supplement, uppercase @@ -19,8 +19,5 @@ Test passes if both characters in each pair match. If you are missing a font glyph for a character, ignore that pair, but report which characters were ignored. Ԁ Ԁ Ԃ Ԃ Ԅ Ԅ Ԇ Ԇ Ԉ Ԉ Ԋ Ԋ Ԍ Ԍ Ԏ Ԏ Ԑ Ԑ Ԓ Ԓ Ԕ Ԕ Ԗ Ԗ Ԙ Ԙ Ԛ Ԛ Ԝ Ԝ Ԟ Ԟ Ԡ Ԡ Ԣ Ԣ Ԥ Ԥ Ԧ Ԧ Ԩ Ԩ Ԫ Ԫ Ԭ Ԭ Ԯ Ԯ - - \ No newline at end of file + diff --git a/testing/web-platform/tests/css/css-text/text-transform/reference/text-transform-upperlower-021-ref.html b/testing/web-platform/tests/css/css-text/text-transform/reference/text-transform-upperlower-021-ref.html index 842a21271598..64d7929c5f4a 100644 --- a/testing/web-platform/tests/css/css-text/text-transform/reference/text-transform-upperlower-021-ref.html +++ b/testing/web-platform/tests/css/css-text/text-transform/reference/text-transform-upperlower-021-ref.html @@ -1,5 +1,5 @@ - + CSS3 Text, text transform: Cyrillic Extended, lowercase @@ -19,8 +19,5 @@ Test passes if both characters in each pair match. If you are missing a font glyph for a character, ignore that pair, but report which characters were ignored. ԁ ԁ ԃ ԃ ԅ ԅ ԇ ԇ ԉ ԉ ԋ ԋ ԍ ԍ ԏ ԏ ԑ ԑ ԓ ԓ ԕ ԕ ԗ ԗ ԙ ԙ ԛ ԛ ԝ ԝ ԟ ԟ ԡ ԡ ԣ ԣ ԥ ԥ ԧ ԧ ԩ ԩ ԫ ԫ ԭ ԭ ԯ ԯ - - \ No newline at end of file + diff --git a/testing/web-platform/tests/css/css-text/text-transform/reference/text-transform-upperlower-022-ref.html b/testing/web-platform/tests/css/css-text/text-transform/reference/text-transform-upperlower-022-ref.html index b96879aea1e8..94c44df696bf 100644 --- a/testing/web-platform/tests/css/css-text/text-transform/reference/text-transform-upperlower-022-ref.html +++ b/testing/web-platform/tests/css/css-text/text-transform/reference/text-transform-upperlower-022-ref.html @@ -1,5 +1,5 @@ - + CSS3 Text, text transform: Armenian, uppercase @@ -20,7 +20,6 @@ Ա Ա Բ Բ Գ Գ Դ Դ Ե Ե Զ Զ Է Է Ը Ը Թ Թ Ժ Ժ Ի Ի Լ Լ Խ Խ Ծ Ծ Կ Կ Հ Հ Ձ Ձ Ղ Ղ Ճ Ճ Մ Մ Յ Յ Ն Ն Շ Շ Ո Ո Չ Չ Պ Պ Ջ Ջ Ռ Ռ Ս Ս Վ Վ Տ Տ Ր Ր Ց Ց Ւ Ւ Փ Փ Ք Ք Օ Օ Ֆ Ֆ diff --git a/testing/web-platform/tests/css/css-text/text-transform/reference/text-transform-upperlower-023-ref.html b/testing/web-platform/tests/css/css-text/text-transform/reference/text-transform-upperlower-023-ref.html index e054d06005f2..70f45dca8c5d 100644 --- a/testing/web-platform/tests/css/css-text/text-transform/reference/text-transform-upperlower-023-ref.html +++ b/testing/web-platform/tests/css/css-text/text-transform/reference/text-transform-upperlower-023-ref.html @@ -1,5 +1,5 @@ - + CSS3 Text, text transform: Latin Extended-D, lowercase @@ -20,6 +20,5 @@ ա ա բ բ գ գ դ դ ե ե զ զ է է ը ը թ թ ժ ժ ի ի լ լ խ խ ծ ծ կ կ հ հ ձ ձ ղ ղ ճ ճ մ մ յ յ ն ն շ շ ո ո չ չ պ պ ջ ջ ռ ռ ս ս վ վ տ տ ր ր ց ց ւ ւ փ փ ք ք օ օ ֆ ֆ diff --git a/testing/web-platform/tests/css/css-text/text-transform/reference/text-transform-upperlower-024-ref.html b/testing/web-platform/tests/css/css-text/text-transform/reference/text-transform-upperlower-024-ref.html index fca2cebbe30a..77380841ff06 100644 --- a/testing/web-platform/tests/css/css-text/text-transform/reference/text-transform-upperlower-024-ref.html +++ b/testing/web-platform/tests/css/css-text/text-transform/reference/text-transform-upperlower-024-ref.html @@ -1,5 +1,5 @@ - + CSS3 Text, text transform: Number Forms, uppercase @@ -20,7 +20,6 @@ Ⅰ Ⅰ Ⅱ Ⅱ Ⅲ Ⅲ Ⅳ Ⅳ Ⅴ Ⅴ Ⅵ Ⅵ Ⅶ Ⅶ Ⅷ Ⅷ Ⅸ Ⅸ Ⅹ Ⅹ Ⅺ Ⅺ Ⅻ Ⅻ Ⅼ Ⅼ Ⅽ Ⅽ Ⅾ Ⅾ Ⅿ Ⅿ Ↄ Ↄ diff --git a/testing/web-platform/tests/css/css-text/text-transform/reference/text-transform-upperlower-025-ref.html b/testing/web-platform/tests/css/css-text/text-transform/reference/text-transform-upperlower-025-ref.html index 7304d5fdcbc7..d7fdd0a8a2ac 100644 --- a/testing/web-platform/tests/css/css-text/text-transform/reference/text-transform-upperlower-025-ref.html +++ b/testing/web-platform/tests/css/css-text/text-transform/reference/text-transform-upperlower-025-ref.html @@ -1,5 +1,5 @@ - + CSS3 Text, text transform: Number Forms, lowercase @@ -20,6 +20,5 @@ ⅰ ⅰ ⅱ ⅱ ⅲ ⅲ ⅳ ⅳ ⅴ ⅴ ⅵ ⅵ ⅶ ⅶ ⅷ ⅷ ⅸ ⅸ ⅹ ⅹ ⅺ ⅺ ⅻ ⅻ ⅼ ⅼ ⅽ ⅽ ⅾ ⅾ ⅿ ⅿ ↄ ↄ diff --git a/testing/web-platform/tests/css/css-text/text-transform/reference/text-transform-upperlower-026-ref.html b/testing/web-platform/tests/css/css-text/text-transform/reference/text-transform-upperlower-026-ref.html index 9582472fd158..ce4e9e4be9ee 100644 --- a/testing/web-platform/tests/css/css-text/text-transform/reference/text-transform-upperlower-026-ref.html +++ b/testing/web-platform/tests/css/css-text/text-transform/reference/text-transform-upperlower-026-ref.html @@ -1,5 +1,5 @@ - + CSS3 Text, text transform: Enclosed Alphanumerics, uppercase @@ -20,7 +20,6 @@ Ⓐ Ⓐ Ⓑ Ⓑ Ⓒ Ⓒ Ⓓ Ⓓ Ⓔ Ⓔ Ⓕ Ⓕ Ⓖ Ⓖ Ⓗ Ⓗ Ⓘ Ⓘ Ⓙ Ⓙ Ⓚ Ⓚ Ⓛ Ⓛ Ⓜ Ⓜ Ⓝ Ⓝ Ⓞ Ⓞ Ⓟ Ⓟ Ⓠ Ⓠ Ⓡ Ⓡ Ⓢ Ⓢ Ⓣ Ⓣ Ⓤ Ⓤ Ⓥ Ⓥ Ⓦ Ⓦ Ⓧ Ⓧ Ⓨ Ⓨ Ⓩ Ⓩ diff --git a/testing/web-platform/tests/css/css-text/text-transform/reference/text-transform-upperlower-027-ref.html b/testing/web-platform/tests/css/css-text/text-transform/reference/text-transform-upperlower-027-ref.html index 1e327b7d3674..08b3fd3d8c64 100644 --- a/testing/web-platform/tests/css/css-text/text-transform/reference/text-transform-upperlower-027-ref.html +++ b/testing/web-platform/tests/css/css-text/text-transform/reference/text-transform-upperlower-027-ref.html @@ -1,5 +1,5 @@ - + CSS3 Text, text transform: Enclosed Alphanumerics, lowercase @@ -20,6 +20,5 @@ ⓐ ⓐ ⓑ ⓑ ⓒ ⓒ ⓓ ⓓ ⓔ ⓔ ⓕ ⓕ ⓖ ⓖ ⓗ ⓗ ⓘ ⓘ ⓙ ⓙ ⓚ ⓚ ⓛ ⓛ ⓜ ⓜ ⓝ ⓝ ⓞ ⓞ ⓟ ⓟ ⓠ ⓠ ⓡ ⓡ ⓢ ⓢ ⓣ ⓣ ⓤ ⓤ ⓥ ⓥ ⓦ ⓦ ⓧ ⓧ ⓨ ⓨ ⓩ ⓩ diff --git a/testing/web-platform/tests/css/css-text/text-transform/reference/text-transform-upperlower-028-ref.html b/testing/web-platform/tests/css/css-text/text-transform/reference/text-transform-upperlower-028-ref.html index 041def4eba4e..e4d900aeb77c 100644 --- a/testing/web-platform/tests/css/css-text/text-transform/reference/text-transform-upperlower-028-ref.html +++ b/testing/web-platform/tests/css/css-text/text-transform/reference/text-transform-upperlower-028-ref.html @@ -1,5 +1,5 @@ - + CSS3 Text, text transform: Deseret, uppercase @@ -18,8 +18,5 @@ Test passes if both characters in each pair match. If you are missing a font glyph for a character, ignore that pair, but report which characters were ignored. 𐐀 𐐀 𐐁 𐐁 𐐂 𐐂 𐐃 𐐃 𐐄 𐐄 𐐅 𐐅 𐐆 𐐆 𐐇 𐐇 𐐈 𐐈 𐐉 𐐉 𐐊 𐐊 𐐋 𐐋 𐐌 𐐌 𐐍 𐐍 𐐎 𐐎 𐐏 𐐏 𐐐 𐐐 𐐑 𐐑 𐐒 𐐒 𐐓 𐐓 𐐔 𐐔 𐐕 𐐕 𐐖 𐐖 𐐗 𐐗 𐐘 𐐘 𐐙 𐐙 𐐚 𐐚 𐐛 𐐛 𐐜 𐐜 𐐝 𐐝 𐐞 𐐞 𐐟 𐐟 𐐠 𐐠 𐐡 𐐡 𐐢 𐐢 𐐣 𐐣 𐐤 𐐤 𐐥 𐐥 𐐦 𐐦 𐐧 𐐧 - diff --git a/testing/web-platform/tests/css/css-text/text-transform/reference/text-transform-upperlower-029-ref.html b/testing/web-platform/tests/css/css-text/text-transform/reference/text-transform-upperlower-029-ref.html index 74847094d237..d7658c9027a7 100644 --- a/testing/web-platform/tests/css/css-text/text-transform/reference/text-transform-upperlower-029-ref.html +++ b/testing/web-platform/tests/css/css-text/text-transform/reference/text-transform-upperlower-029-ref.html @@ -1,5 +1,5 @@ - + CSS3 Text, text transform: Deseret, lowercase @@ -18,7 +18,4 @@ Test passes if both characters in each pair match. If you are missing a font glyph for a character, ignore that pair, but report which characters were ignored. 𐐨 𐐨 𐐩 𐐩 𐐪 𐐪 𐐫 𐐫 𐐬 𐐬 𐐭 𐐭 𐐮 𐐮 𐐯 𐐯 𐐰 𐐰 𐐱 𐐱 𐐲 𐐲 𐐳 𐐳 𐐴 𐐴 𐐵 𐐵 𐐶 𐐶 𐐷 𐐷 𐐸 𐐸 𐐹 𐐹 𐐺 𐐺 𐐻 𐐻 𐐼 𐐼 𐐽 𐐽 𐐾 𐐾 𐐿 𐐿 𐑀 𐑀 𐑁 𐑁 𐑂 𐑂 𐑃 𐑃 𐑄 𐑄 𐑅 𐑅 𐑆 𐑆 𐑇 𐑇 𐑈 𐑈 𐑉 𐑉 𐑊 𐑊 𐑋 𐑋 𐑌 𐑌 𐑍 𐑍 𐑎 𐑎 𐑏 𐑏 - diff --git a/testing/web-platform/tests/css/css-text/text-transform/reference/text-transform-upperlower-030-ref.html b/testing/web-platform/tests/css/css-text/text-transform/reference/text-transform-upperlower-030-ref.html index ae88eb251310..45460bc49dc0 100644 --- a/testing/web-platform/tests/css/css-text/text-transform/reference/text-transform-upperlower-030-ref.html +++ b/testing/web-platform/tests/css/css-text/text-transform/reference/text-transform-upperlower-030-ref.html @@ -1,5 +1,5 @@ - + CSS3 Text, text transform: Georgian Supplement, uppercase @@ -18,8 +18,5 @@ Test passes if both characters in each pair match. If you are missing a font glyph for a character, ignore that pair, but report which characters were ignored. Ⴀ Ⴀ Ⴁ Ⴁ Ⴂ Ⴂ Ⴃ Ⴃ Ⴄ Ⴄ Ⴅ Ⴅ Ⴆ Ⴆ Ⴇ Ⴇ Ⴈ Ⴈ Ⴉ Ⴉ Ⴊ Ⴊ Ⴋ Ⴋ Ⴌ Ⴌ Ⴍ Ⴍ Ⴎ Ⴎ Ⴏ Ⴏ Ⴐ Ⴐ Ⴑ Ⴑ Ⴒ Ⴒ Ⴓ Ⴓ Ⴔ Ⴔ Ⴕ Ⴕ Ⴖ Ⴖ Ⴗ Ⴗ Ⴘ Ⴘ Ⴙ Ⴙ Ⴚ Ⴚ Ⴛ Ⴛ Ⴜ Ⴜ Ⴝ Ⴝ Ⴞ Ⴞ Ⴟ Ⴟ Ⴠ Ⴠ Ⴡ Ⴡ Ⴢ Ⴢ Ⴣ Ⴣ Ⴤ Ⴤ Ⴥ Ⴥ Ⴧ Ⴧ Ⴭ Ⴭ - diff --git a/testing/web-platform/tests/css/css-text/text-transform/reference/text-transform-upperlower-031-ref.html b/testing/web-platform/tests/css/css-text/text-transform/reference/text-transform-upperlower-031-ref.html index 5ee04a6b5b01..f5eb0ade748b 100644 --- a/testing/web-platform/tests/css/css-text/text-transform/reference/text-transform-upperlower-031-ref.html +++ b/testing/web-platform/tests/css/css-text/text-transform/reference/text-transform-upperlower-031-ref.html @@ -1,5 +1,5 @@ - + CSS3 Text, text transform: Georgian, lowercase @@ -20,6 +20,5 @@ ⴀ ⴀ ⴁ ⴁ ⴂ ⴂ ⴃ ⴃ ⴄ ⴄ ⴅ ⴅ ⴆ ⴆ ⴇ ⴇ ⴈ ⴈ ⴉ ⴉ ⴊ ⴊ ⴋ ⴋ ⴌ ⴌ ⴍ ⴍ ⴎ ⴎ ⴏ ⴏ ⴐ ⴐ ⴑ ⴑ ⴒ ⴒ ⴓ ⴓ ⴔ ⴔ ⴕ ⴕ ⴖ ⴖ ⴗ ⴗ ⴘ ⴘ ⴙ ⴙ ⴚ ⴚ ⴛ ⴛ ⴜ ⴜ ⴝ ⴝ ⴞ ⴞ ⴟ ⴟ ⴠ ⴠ ⴡ ⴡ ⴢ ⴢ ⴣ ⴣ ⴤ ⴤ ⴥ ⴥ ⴧ ⴧ ⴭ ⴭ diff --git a/testing/web-platform/tests/css/css-text/text-transform/reference/text-transform-upperlower-032-ref.html b/testing/web-platform/tests/css/css-text/text-transform/reference/text-transform-upperlower-032-ref.html index c8183da90847..d2db63003405 100644 --- a/testing/web-platform/tests/css/css-text/text-transform/reference/text-transform-upperlower-032-ref.html +++ b/testing/web-platform/tests/css/css-text/text-transform/reference/text-transform-upperlower-032-ref.html @@ -1,5 +1,5 @@ - + CSS3 Text, text transform: German sharp S, uppercase diff --git a/testing/web-platform/tests/css/css-text/text-transform/reference/text-transform-upperlower-033-ref.html b/testing/web-platform/tests/css/css-text/text-transform/reference/text-transform-upperlower-033-ref.html index 28c8624bd4c6..b0364476e637 100644 --- a/testing/web-platform/tests/css/css-text/text-transform/reference/text-transform-upperlower-033-ref.html +++ b/testing/web-platform/tests/css/css-text/text-transform/reference/text-transform-upperlower-033-ref.html @@ -1,5 +1,5 @@ - + CSS3 Text, text transform: Latin ligatures, uppercase diff --git a/testing/web-platform/tests/css/css-text/text-transform/reference/text-transform-upperlower-034-ref.html b/testing/web-platform/tests/css/css-text/text-transform/reference/text-transform-upperlower-034-ref.html index eafe6308d116..680c663734cc 100644 --- a/testing/web-platform/tests/css/css-text/text-transform/reference/text-transform-upperlower-034-ref.html +++ b/testing/web-platform/tests/css/css-text/text-transform/reference/text-transform-upperlower-034-ref.html @@ -1,5 +1,5 @@ - + CSS3 Text, text transform: Armenian ligatures, uppercase diff --git a/testing/web-platform/tests/css/css-text/text-transform/reference/text-transform-upperlower-035-ref.html b/testing/web-platform/tests/css/css-text/text-transform/reference/text-transform-upperlower-035-ref.html index cfd3720d29b6..bcfe1504ad95 100644 --- a/testing/web-platform/tests/css/css-text/text-transform/reference/text-transform-upperlower-035-ref.html +++ b/testing/web-platform/tests/css/css-text/text-transform/reference/text-transform-upperlower-035-ref.html @@ -1,5 +1,5 @@ - + CSS3 Text, text transform: Greek specials, uppercase diff --git a/testing/web-platform/tests/css/css-text/text-transform/reference/text-transform-upperlower-038-ref.html b/testing/web-platform/tests/css/css-text/text-transform/reference/text-transform-upperlower-038-ref.html index bc7f562d9976..6532f2fc0c68 100644 --- a/testing/web-platform/tests/css/css-text/text-transform/reference/text-transform-upperlower-038-ref.html +++ b/testing/web-platform/tests/css/css-text/text-transform/reference/text-transform-upperlower-038-ref.html @@ -1,5 +1,5 @@ - + CSS3 Text, text transform: Greek final sigma, lowercase diff --git a/testing/web-platform/tests/css/css-text/text-transform/reference/text-transform-upperlower-039-ref.html b/testing/web-platform/tests/css/css-text/text-transform/reference/text-transform-upperlower-039-ref.html index a00b836217c5..0e243edde50e 100644 --- a/testing/web-platform/tests/css/css-text/text-transform/reference/text-transform-upperlower-039-ref.html +++ b/testing/web-platform/tests/css/css-text/text-transform/reference/text-transform-upperlower-039-ref.html @@ -1,5 +1,5 @@ - + CSS3 Text, text transform: Lithuanian, lowercase diff --git a/testing/web-platform/tests/css/css-text/text-transform/reference/text-transform-upperlower-040-ref.html b/testing/web-platform/tests/css/css-text/text-transform/reference/text-transform-upperlower-040-ref.html index 143ba2a58910..f2624f13f634 100644 --- a/testing/web-platform/tests/css/css-text/text-transform/reference/text-transform-upperlower-040-ref.html +++ b/testing/web-platform/tests/css/css-text/text-transform/reference/text-transform-upperlower-040-ref.html @@ -1,5 +1,5 @@ - + CSS3 Text, text transform: Turkish, uppercase diff --git a/testing/web-platform/tests/css/css-text/text-transform/reference/text-transform-upperlower-041-ref.html b/testing/web-platform/tests/css/css-text/text-transform/reference/text-transform-upperlower-041-ref.html index 0b80eb935708..8b784924a14b 100644 --- a/testing/web-platform/tests/css/css-text/text-transform/reference/text-transform-upperlower-041-ref.html +++ b/testing/web-platform/tests/css/css-text/text-transform/reference/text-transform-upperlower-041-ref.html @@ -1,5 +1,5 @@ - + CSS3 Text, text transform: Turkish, lowercase diff --git a/testing/web-platform/tests/css/css-text/text-transform/reference/text-transform-upperlower-042-ref.html b/testing/web-platform/tests/css/css-text/text-transform/reference/text-transform-upperlower-042-ref.html index 10c0d36aa956..2277c4fe334f 100644 --- a/testing/web-platform/tests/css/css-text/text-transform/reference/text-transform-upperlower-042-ref.html +++ b/testing/web-platform/tests/css/css-text/text-transform/reference/text-transform-upperlower-042-ref.html @@ -1,5 +1,5 @@ - + CSS3 Text, text transform: Azeri, uppercase diff --git a/testing/web-platform/tests/css/css-text/text-transform/reference/text-transform-upperlower-043-ref.html b/testing/web-platform/tests/css/css-text/text-transform/reference/text-transform-upperlower-043-ref.html index d629a319716d..5c5e18c2f745 100644 --- a/testing/web-platform/tests/css/css-text/text-transform/reference/text-transform-upperlower-043-ref.html +++ b/testing/web-platform/tests/css/css-text/text-transform/reference/text-transform-upperlower-043-ref.html @@ -1,5 +1,5 @@ - + CSS3 Text, text transform: Azeri, lowercase diff --git a/testing/web-platform/tests/css/css-text/text-transform/reference/text-transform-upperlower-101-ref.html b/testing/web-platform/tests/css/css-text/text-transform/reference/text-transform-upperlower-101-ref.html index 3d21333ed46d..0105b021d468 100644 --- a/testing/web-platform/tests/css/css-text/text-transform/reference/text-transform-upperlower-101-ref.html +++ b/testing/web-platform/tests/css/css-text/text-transform/reference/text-transform-upperlower-101-ref.html @@ -1,5 +1,5 @@ - + CSS3 Text, text transform: Latin Extended-D, uppercase @@ -20,7 +20,6 @@ Ꜣ Ꜣ Ꜥ Ꜥ Ꜧ Ꜧ Ꜩ Ꜩ Ꜫ Ꜫ Ꜭ Ꜭ Ꜯ Ꜯ Ꜳ Ꜳ Ꜵ Ꜵ Ꜷ Ꜷ Ꜹ Ꜹ Ꜻ Ꜻ Ꜽ Ꜽ Ꜿ Ꜿ Ꝁ Ꝁ Ꝃ Ꝃ Ꝅ Ꝅ Ꝇ Ꝇ Ꝉ Ꝉ Ꝋ Ꝋ Ꝍ Ꝍ Ꝏ Ꝏ Ꝑ Ꝑ Ꝓ Ꝓ Ꝕ Ꝕ Ꝗ Ꝗ Ꝙ Ꝙ Ꝛ Ꝛ Ꝝ Ꝝ Ꝟ Ꝟ Ꝡ Ꝡ Ꝣ Ꝣ Ꝥ Ꝥ Ꝧ Ꝧ Ꝩ Ꝩ Ꝫ Ꝫ Ꝭ Ꝭ Ꝯ Ꝯ Ꝺ Ꝺ Ꝼ Ꝼ Ꝿ Ꝿ Ꞁ Ꞁ Ꞃ Ꞃ Ꞅ Ꞅ Ꞇ Ꞇ Ꞌ Ꞌ Ꞑ Ꞑ Ꞓ Ꞓ Ꞗ Ꞗ Ꞙ Ꞙ Ꞛ Ꞛ Ꞝ Ꞝ Ꞟ Ꞟ Ꞡ Ꞡ Ꞣ Ꞣ Ꞥ Ꞥ Ꞧ Ꞧ Ꞩ Ꞩ - \ No newline at end of file + diff --git a/testing/web-platform/tests/css/css-text/text-transform/reference/text-transform-upperlower-102-ref.html b/testing/web-platform/tests/css/css-text/text-transform/reference/text-transform-upperlower-102-ref.html index 0328b65c72f5..adcc9a3a5e14 100644 --- a/testing/web-platform/tests/css/css-text/text-transform/reference/text-transform-upperlower-102-ref.html +++ b/testing/web-platform/tests/css/css-text/text-transform/reference/text-transform-upperlower-102-ref.html @@ -1,5 +1,5 @@ - + CSS3 Text, text transform: Latin Extended-D, lowercase @@ -20,6 +20,5 @@ ꜣ ꜣ ꜥ ꜥ ꜧ ꜧ ꜩ ꜩ ꜫ ꜫ ꜭ ꜭ ꜯ ꜯ ꜳ ꜳ ꜵ ꜵ ꜷ ꜷ ꜹ ꜹ ꜻ ꜻ ꜽ ꜽ ꜿ ꜿ ꝁ ꝁ ꝃ ꝃ ꝅ ꝅ ꝇ ꝇ ꝉ ꝉ ꝋ ꝋ ꝍ ꝍ ꝏ ꝏ ꝑ ꝑ ꝓ ꝓ ꝕ ꝕ ꝗ ꝗ ꝙ ꝙ ꝛ ꝛ ꝝ ꝝ ꝟ ꝟ ꝡ ꝡ ꝣ ꝣ ꝥ ꝥ ꝧ ꝧ ꝩ ꝩ ꝫ ꝫ ꝭ ꝭ ꝯ ꝯ ꝺ ꝺ ꝼ ꝼ ᵹ ᵹ ꝿ ꝿ ꞁ ꞁ ꞃ ꞃ ꞅ ꞅ ꞇ ꞇ ꞌ ꞌ ɥ ɥ ꞑ ꞑ ꞓ ꞓ ꞗ ꞗ ꞙ ꞙ ꞛ ꞛ ꞝ ꞝ ꞟ ꞟ ꞡ ꞡ ꞣ ꞣ ꞥ ꞥ ꞧ ꞧ ꞩ ꞩ ɦ ɦ ɜ ɜ ɡ ɡ ɬ ɬ ʞ ʞ ʇ ʇ diff --git a/testing/web-platform/tests/css/css-text/text-transform/reference/text-transform-upperlower-103-ref.html b/testing/web-platform/tests/css/css-text/text-transform/reference/text-transform-upperlower-103-ref.html index 1f4d42190941..30ecf1e199dc 100644 --- a/testing/web-platform/tests/css/css-text/text-transform/reference/text-transform-upperlower-103-ref.html +++ b/testing/web-platform/tests/css/css-text/text-transform/reference/text-transform-upperlower-103-ref.html @@ -1,5 +1,5 @@ - + CSS3 Text, text transform: Cyrillic Extended-B, uppercase @@ -21,7 +21,6 @@ Ꙁ Ꙁ Ꙃ Ꙃ Ꙅ Ꙅ Ꙇ Ꙇ Ꙉ Ꙉ Ꙋ Ꙋ Ꙍ Ꙍ Ꙏ Ꙏ Ꙑ Ꙑ Ꙓ Ꙓ Ꙕ Ꙕ Ꙗ Ꙗ Ꙙ Ꙙ Ꙛ Ꙛ Ꙝ Ꙝ Ꙟ Ꙟ Ꙡ Ꙡ Ꙣ Ꙣ Ꙥ Ꙥ Ꙧ Ꙧ Ꙩ Ꙩ Ꙫ Ꙫ Ꙭ Ꙭ Ꚁ Ꚁ Ꚃ Ꚃ Ꚅ Ꚅ Ꚇ Ꚇ Ꚉ Ꚉ Ꚋ Ꚋ Ꚍ Ꚍ Ꚏ Ꚏ Ꚑ Ꚑ Ꚓ Ꚓ Ꚕ Ꚕ Ꚗ Ꚗ Ꚙ Ꚙ Ꚛ Ꚛ diff --git a/testing/web-platform/tests/css/css-text/text-transform/reference/text-transform-upperlower-104-ref.html b/testing/web-platform/tests/css/css-text/text-transform/reference/text-transform-upperlower-104-ref.html index 878393c4f735..52245cb150ce 100644 --- a/testing/web-platform/tests/css/css-text/text-transform/reference/text-transform-upperlower-104-ref.html +++ b/testing/web-platform/tests/css/css-text/text-transform/reference/text-transform-upperlower-104-ref.html @@ -1,5 +1,5 @@ - + CSS3 Text, text transform: Cyrillic Extended-B, lowercase @@ -21,6 +21,5 @@ ꙁ ꙁ ꙃ ꙃ ꙅ ꙅ ꙇ ꙇ ꙉ ꙉ ꙋ ꙋ ꙍ ꙍ ꙏ ꙏ ꙑ ꙑ ꙓ ꙓ ꙕ ꙕ ꙗ ꙗ ꙙ ꙙ ꙛ ꙛ ꙝ ꙝ ꙟ ꙟ ꙡ ꙡ ꙣ ꙣ ꙥ ꙥ ꙧ ꙧ ꙩ ꙩ ꙫ ꙫ ꙭ ꙭ ꚁ ꚁ ꚃ ꚃ ꚅ ꚅ ꚇ ꚇ ꚉ ꚉ ꚋ ꚋ ꚍ ꚍ ꚏ ꚏ ꚑ ꚑ ꚓ ꚓ ꚕ ꚕ ꚗ ꚗ ꚙ ꚙ ꚛ ꚛ diff --git a/testing/web-platform/tests/css/css-text/text-transform/text-transform-capitalize-001.html b/testing/web-platform/tests/css/css-text/text-transform/text-transform-capitalize-001.html index be0dc73110b8..0dfbfb624151 100644 --- a/testing/web-platform/tests/css/css-text/text-transform/text-transform-capitalize-001.html +++ b/testing/web-platform/tests/css/css-text/text-transform/text-transform-capitalize-001.html @@ -1,5 +1,5 @@ - + CSS3 Text, text transform: capitalize, Latin Basic and Latin-1 @@ -24,8 +24,5 @@ The text is arranged in pairs of three-letter 'words'. Test passes if the words in each pair match If you are missing a font glyph for a character, ignore that pair, but report which characters were ignored. aaa Aaa bbb Bbb ccc Ccc ddd Ddd eee Eee fff Fff ggg Ggg hhh Hhh iii Iii jjj Jjj kkk Kkk lll Lll mmm Mmm nnn Nnn ooo Ooo ppp Ppp qqq Qqq rrr Rrr sss Sss ttt Ttt uuu Uuu vvv Vvv www Www xxx Xxx yyy Yyy zzz Zzz µµµ Μµµ ààà Ààà ááá Ááá âââ Âââ ããã Ããã äää Äää ååå Ååå æææ Æææ ççç Ççç èèè Èèè ééé Ééé êêê Êêê ëëë Ëëë ììì Ììì ííí Ííí îîî Îîî ïïï Ïïï ððð Ððð ñññ Ñññ òòò Òòò óóó Óóó ôôô Ôôô õõõ Õõõ ööö Ööö øøø Øøø ùùù Ùùù úúú Úúú ûûû Ûûû üüü Üüü ýýý Ýýý þþþ Þþþ ÿÿÿ Ÿÿÿ - - \ No newline at end of file + diff --git a/testing/web-platform/tests/css/css-text/text-transform/text-transform-capitalize-003.html b/testing/web-platform/tests/css/css-text/text-transform/text-transform-capitalize-003.html index 33664a337e46..ab198975187c 100644 --- a/testing/web-platform/tests/css/css-text/text-transform/text-transform-capitalize-003.html +++ b/testing/web-platform/tests/css/css-text/text-transform/text-transform-capitalize-003.html @@ -1,5 +1,5 @@ - + CSS3 Text, text transform: capitalize, Latin Extended Additional @@ -24,8 +24,5 @@ The text is arranged in pairs of three-letter 'words'. Test passes if the words in each pair match If you are missing a font glyph for a character, ignore that pair, but report which characters were ignored. ḁḁḁ Ḁḁḁ ḃḃḃ Ḃḃḃ ḅḅḅ Ḅḅḅ ḇḇḇ Ḇḇḇ ḉḉḉ Ḉḉḉ ḋḋḋ Ḋḋḋ ḍḍḍ Ḍḍḍ ḏḏḏ Ḏḏḏ ḑḑḑ Ḑḑḑ ḓḓḓ Ḓḓḓ ḕḕḕ Ḕḕḕ ḗḗḗ Ḗḗḗ ḙḙḙ Ḙḙḙ ḛḛḛ Ḛḛḛ ḝḝḝ Ḝḝḝ ḟḟḟ Ḟḟḟ ḡḡḡ Ḡḡḡ ḣḣḣ Ḣḣḣ ḥḥḥ Ḥḥḥ ḧḧḧ Ḧḧḧ ḩḩḩ Ḩḩḩ ḫḫḫ Ḫḫḫ ḭḭḭ Ḭḭḭ ḯḯḯ Ḯḯḯ ḱḱḱ Ḱḱḱ ḳḳḳ Ḳḳḳ ḵḵḵ Ḵḵḵ ḷḷḷ Ḷḷḷ ḹḹḹ Ḹḹḹ ḻḻḻ Ḻḻḻ ḽḽḽ Ḽḽḽ ḿḿḿ Ḿḿḿ ṁṁṁ Ṁṁṁ ṃṃṃ Ṃṃṃ ṅṅṅ Ṅṅṅ ṇṇṇ Ṇṇṇ ṉṉṉ Ṉṉṉ ṋṋṋ Ṋṋṋ ṍṍṍ Ṍṍṍ ṏṏṏ Ṏṏṏ ṑṑṑ Ṑṑṑ ṓṓṓ Ṓṓṓ ṕṕṕ Ṕṕṕ ṗṗṗ Ṗṗṗ ṙṙṙ Ṙṙṙ ṛṛṛ Ṛṛṛ ṝṝṝ Ṝṝṝ ṟṟṟ Ṟṟṟ ṡṡṡ Ṡṡṡ ṣṣṣ Ṣṣṣ ṥṥṥ Ṥṥṥ ṧṧṧ Ṧṧṧ ṩṩṩ Ṩṩṩ ṫṫṫ Ṫṫṫ ṭṭṭ Ṭṭṭ ṯṯṯ Ṯṯṯ ṱṱṱ Ṱṱṱ ṳṳṳ Ṳṳṳ ṵṵṵ Ṵṵṵ ṷṷṷ Ṷṷṷ ṹṹṹ Ṹṹṹ ṻṻṻ Ṻṻṻ ṽṽṽ Ṽṽṽ ṿṿṿ Ṿṿṿ ẁẁẁ Ẁẁẁ ẃẃẃ Ẃẃẃ ẅẅẅ Ẅẅẅ ẇẇẇ Ẇẇẇ ẉẉẉ Ẉẉẉ ẋẋẋ Ẋẋẋ ẍẍẍ Ẍẍẍ ẏẏẏ Ẏẏẏ ẑẑẑ Ẑẑẑ ẓẓẓ Ẓẓẓ ẕẕẕ Ẕẕẕ ẛẛẛ Ṡẛẛ ạạạ Ạạạ ảảả Ảảả ấấấ Ấấấ ầầầ Ầầầ ẩẩẩ Ẩẩẩ ẫẫẫ Ẫẫẫ ậậậ Ậậậ ắắắ Ắắắ ằằằ Ằằằ ẳẳẳ Ẳẳẳ ẵẵẵ Ẵẵẵ ặặặ Ặặặ ẹẹẹ Ẹẹẹ ẻẻẻ Ẻẻẻ ẽẽẽ Ẽẽẽ ếếế Ếếế ềềề Ềềề ểểể Ểểể ễễễ Ễễễ ệệệ Ệệệ ỉỉỉ Ỉỉỉ ịịị Ịịị ọọọ Ọọọ ỏỏỏ Ỏỏỏ ốốố Ốốố ồồồ Ồồồ ổổổ Ổổổ ỗỗỗ Ỗỗỗ ộộộ Ộộộ ớớớ Ớớớ ờờờ Ờờờ ởởở Ởởở ỡỡỡ Ỡỡỡ ợợợ Ợợợ ụụụ Ụụụ ủủủ Ủủủ ứứứ Ứứứ ừừừ Ừừừ ửửử Ửửử ữữữ Ữữữ ựựự Ựựự ỳỳỳ Ỳỳỳ ỵỵỵ Ỵỵỵ ỷỷỷ Ỷỷỷ ỹỹỹ Ỹỹỹ ỻỻỻ Ỻỻỻ ỽỽỽ Ỽỽỽ ỿỿỿ Ỿỿỿ - - \ No newline at end of file + diff --git a/testing/web-platform/tests/css/css-text/text-transform/text-transform-capitalize-005.html b/testing/web-platform/tests/css/css-text/text-transform/text-transform-capitalize-005.html index bdb44e559a40..ccb130eb535e 100644 --- a/testing/web-platform/tests/css/css-text/text-transform/text-transform-capitalize-005.html +++ b/testing/web-platform/tests/css/css-text/text-transform/text-transform-capitalize-005.html @@ -1,5 +1,5 @@ - + CSS3 Text, text transform: capitalize, Latin Extended-A @@ -24,8 +24,5 @@ The text is arranged in pairs of three-letter 'words'. Test passes if the words in each pair match If you are missing a font glyph for a character, ignore that pair, but report which characters were ignored. āāā Āāā ăăă Ăăă ąąą Ąąą ććć Ććć ĉĉĉ Ĉĉĉ ċċċ Ċċċ ččč Ččč ďďď Ďďď đđđ Đđđ ēēē Ēēē ĕĕĕ Ĕĕĕ ėėė Ėėė ęęę Ęęę ěěě Ěěě ĝĝĝ Ĝĝĝ ğğğ Ğğğ ġġġ Ġġġ ģģģ Ģģģ ĥĥĥ Ĥĥĥ ħħħ Ħħħ ĩĩĩ Ĩĩĩ īīī Īīī ĭĭĭ Ĭĭĭ įįį Įįį ııı Iıı ijijij IJijij ĵĵĵ Ĵĵĵ ķķķ Ķķķ ĺĺĺ Ĺĺĺ ļļļ Ļļļ ľľľ Ľľľ ŀŀŀ Ŀŀŀ łłł Łłł ńńń Ńńń ņņņ Ņņņ ňňň Ňňň ŋŋŋ Ŋŋŋ ōōō Ōōō ŏŏŏ Ŏŏŏ őőő Őőő œœœ Œœœ ŕŕŕ Ŕŕŕ ŗŗŗ Ŗŗŗ řřř Řřř śśś Śśś ŝŝŝ Ŝŝŝ şşş Şşş ššš Ššš ţţţ Ţţţ ťťť Ťťť ŧŧŧ Ŧŧŧ ũũũ Ũũũ ūūū Ūūū ŭŭŭ Ŭŭŭ ůůů Ůůů űűű Űűű ųųų Ųųų ŵŵŵ Ŵŵŵ ŷŷŷ Ŷŷŷ źźź Źźź żżż Żżż žžž Žžž ſſſ Sſſ - - \ No newline at end of file + diff --git a/testing/web-platform/tests/css/css-text/text-transform/text-transform-capitalize-007.html b/testing/web-platform/tests/css/css-text/text-transform/text-transform-capitalize-007.html index f99412cfdc41..4d15b280d278 100644 --- a/testing/web-platform/tests/css/css-text/text-transform/text-transform-capitalize-007.html +++ b/testing/web-platform/tests/css/css-text/text-transform/text-transform-capitalize-007.html @@ -1,5 +1,5 @@ - + CSS3 Text, text transform: capitalize, Latin Extended-B @@ -24,8 +24,5 @@ The text is arranged in pairs of three-letter 'words'. Test passes if the words in each pair match If you are missing a font glyph for a character, ignore that pair, but report which characters were ignored. ƀƀƀ Ƀƀƀ ƃƃƃ Ƃƃƃ ƅƅƅ Ƅƅƅ ƈƈƈ Ƈƈƈ ƌƌƌ Ƌƌƌ ƒƒƒ Ƒƒƒ ƕƕƕ Ƕƕƕ ƙƙƙ Ƙƙƙ ƚƚƚ Ƚƚƚ ƞƞƞ Ƞƞƞ ơơơ Ơơơ ƣƣƣ Ƣƣƣ ƥƥƥ Ƥƥƥ ƨƨƨ Ƨƨƨ ƭƭƭ Ƭƭƭ ưưư Ưưư ƴƴƴ Ƴƴƴ ƶƶƶ Ƶƶƶ ƹƹƹ Ƹƹƹ ƽƽƽ Ƽƽƽ ƿƿƿ Ƿƿƿ DŽdždž Dždždž dždždž Dždždž LJljlj Ljljlj ljljlj Ljljlj NJnjnj Njnjnj njnjnj Njnjnj ǎǎǎ Ǎǎǎ ǐǐǐ Ǐǐǐ ǒǒǒ Ǒǒǒ ǔǔǔ Ǔǔǔ ǖǖǖ Ǖǖǖ ǘǘǘ Ǘǘǘ ǚǚǚ Ǚǚǚ ǜǜǜ Ǜǜǜ ǝǝǝ Ǝǝǝ ǟǟǟ Ǟǟǟ ǡǡǡ Ǡǡǡ ǣǣǣ Ǣǣǣ ǥǥǥ Ǥǥǥ ǧǧǧ Ǧǧǧ ǩǩǩ Ǩǩǩ ǫǫǫ Ǫǫǫ ǭǭǭ Ǭǭǭ ǯǯǯ Ǯǯǯ DZdzdz Dzdzdz dzdzdz Dzdzdz ǵǵǵ Ǵǵǵ ǹǹǹ Ǹǹǹ ǻǻǻ Ǻǻǻ ǽǽǽ Ǽǽǽ ǿǿǿ Ǿǿǿ ȁȁȁ Ȁȁȁ ȃȃȃ Ȃȃȃ ȅȅȅ Ȅȅȅ ȇȇȇ Ȇȇȇ ȉȉȉ Ȉȉȉ ȋȋȋ Ȋȋȋ ȍȍȍ Ȍȍȍ ȏȏȏ Ȏȏȏ ȑȑȑ Ȑȑȑ ȓȓȓ Ȓȓȓ ȕȕȕ Ȕȕȕ ȗȗȗ Ȗȗȗ șșș Șșș țțț Țțț ȝȝȝ Ȝȝȝ ȟȟȟ Ȟȟȟ ȣȣȣ Ȣȣȣ ȥȥȥ Ȥȥȥ ȧȧȧ Ȧȧȧ ȩȩȩ Ȩȩȩ ȫȫȫ Ȫȫȫ ȭȭȭ Ȭȭȭ ȯȯȯ Ȯȯȯ ȱȱȱ Ȱȱȱ ȳȳȳ Ȳȳȳ ȼȼȼ Ȼȼȼ ȿȿȿ Ȿȿȿ ɀɀɀ Ɀɀɀ ɂɂɂ Ɂɂɂ ɇɇɇ Ɇɇɇ ɉɉɉ Ɉɉɉ ɋɋɋ Ɋɋɋ ɍɍɍ Ɍɍɍ ɏɏɏ Ɏɏɏ - - \ No newline at end of file + diff --git a/testing/web-platform/tests/css/css-text/text-transform/text-transform-capitalize-009.html b/testing/web-platform/tests/css/css-text/text-transform/text-transform-capitalize-009.html index 868e62904f7d..b835fc7f47ee 100644 --- a/testing/web-platform/tests/css/css-text/text-transform/text-transform-capitalize-009.html +++ b/testing/web-platform/tests/css/css-text/text-transform/text-transform-capitalize-009.html @@ -1,5 +1,5 @@ - + CSS3 Text, text transform: capitalize, Latin Extended-C @@ -24,8 +24,5 @@ The text is arranged in pairs of three-letter 'words'. Test passes if the words in each pair match If you are missing a font glyph for a character, ignore that pair, but report which characters were ignored. ⱡⱡⱡ Ⱡⱡⱡ ⱥⱥⱥ Ⱥⱥⱥ ⱦⱦⱦ Ⱦⱦⱦ ⱨⱨⱨ Ⱨⱨⱨ ⱪⱪⱪ Ⱪⱪⱪ ⱬⱬⱬ Ⱬⱬⱬ ⱳⱳⱳ Ⱳⱳⱳ ⱶⱶⱶ Ⱶⱶⱶ - - \ No newline at end of file + diff --git a/testing/web-platform/tests/css/css-text/text-transform/text-transform-capitalize-010.html b/testing/web-platform/tests/css/css-text/text-transform/text-transform-capitalize-010.html index 25aa18ba65df..032a10df47d4 100644 --- a/testing/web-platform/tests/css/css-text/text-transform/text-transform-capitalize-010.html +++ b/testing/web-platform/tests/css/css-text/text-transform/text-transform-capitalize-010.html @@ -1,5 +1,5 @@ - + CSS3 Text, text transform: capitalize, Latin Extended-D @@ -24,8 +24,5 @@ The text is arranged in pairs of three-letter 'words'. Test passes if the words in each pair match If you are missing a font glyph for a character, ignore that pair, but report which characters were ignored. ꜣꜣꜣ Ꜣꜣꜣ ꜥꜥꜥ Ꜥꜥꜥ ꜧꜧꜧ Ꜧꜧꜧ ꜩꜩꜩ Ꜩꜩꜩ ꜫꜫꜫ Ꜫꜫꜫ ꜭꜭꜭ Ꜭꜭꜭ ꜯꜯꜯ Ꜯꜯꜯ ꜳꜳꜳ Ꜳꜳꜳ ꜵꜵꜵ Ꜵꜵꜵ ꜷꜷꜷ Ꜷꜷꜷ ꜹꜹꜹ Ꜹꜹꜹ ꜻꜻꜻ Ꜻꜻꜻ ꜽꜽꜽ Ꜽꜽꜽ ꜿꜿꜿ Ꜿꜿꜿ ꝁꝁꝁ Ꝁꝁꝁ ꝃꝃꝃ Ꝃꝃꝃ ꝅꝅꝅ Ꝅꝅꝅ ꝇꝇꝇ Ꝇꝇꝇ ꝉꝉꝉ Ꝉꝉꝉ ꝋꝋꝋ Ꝋꝋꝋ ꝍꝍꝍ Ꝍꝍꝍ ꝏꝏꝏ Ꝏꝏꝏ ꝑꝑꝑ Ꝑꝑꝑ ꝓꝓꝓ Ꝓꝓꝓ ꝕꝕꝕ Ꝕꝕꝕ ꝗꝗꝗ Ꝗꝗꝗ ꝙꝙꝙ Ꝙꝙꝙ ꝛꝛꝛ Ꝛꝛꝛ ꝝꝝꝝ Ꝝꝝꝝ ꝟꝟꝟ Ꝟꝟꝟ ꝡꝡꝡ Ꝡꝡꝡ ꝣꝣꝣ Ꝣꝣꝣ ꝥꝥꝥ Ꝥꝥꝥ ꝧꝧꝧ Ꝧꝧꝧ ꝩꝩꝩ Ꝩꝩꝩ ꝫꝫꝫ Ꝫꝫꝫ ꝭꝭꝭ Ꝭꝭꝭ ꝯꝯꝯ Ꝯꝯꝯ ꝺꝺꝺ Ꝺꝺꝺ ꝼꝼꝼ Ꝼꝼꝼ ꝿꝿꝿ Ꝿꝿꝿ ꞁꞁꞁ Ꞁꞁꞁ ꞃꞃꞃ Ꞃꞃꞃ ꞅꞅꞅ Ꞅꞅꞅ ꞇꞇꞇ Ꞇꞇꞇ ꞌꞌꞌ Ꞌꞌꞌ ꞑꞑꞑ Ꞑꞑꞑ ꞓꞓꞓ Ꞓꞓꞓ ꞗꞗꞗ Ꞗꞗꞗ ꞙꞙꞙ Ꞙꞙꞙ ꞛꞛꞛ Ꞛꞛꞛ ꞝꞝꞝ Ꞝꞝꞝ ꞟꞟꞟ Ꞟꞟꞟ ꞡꞡꞡ Ꞡꞡꞡ ꞣꞣꞣ Ꞣꞣꞣ ꞥꞥꞥ Ꞥꞥꞥ ꞧꞧꞧ Ꞧꞧꞧ ꞩꞩꞩ Ꞩꞩꞩ - - \ No newline at end of file + diff --git a/testing/web-platform/tests/css/css-text/text-transform/text-transform-capitalize-011.html b/testing/web-platform/tests/css/css-text/text-transform/text-transform-capitalize-011.html index a66ef351e9c0..40b45f24344b 100644 --- a/testing/web-platform/tests/css/css-text/text-transform/text-transform-capitalize-011.html +++ b/testing/web-platform/tests/css/css-text/text-transform/text-transform-capitalize-011.html @@ -1,5 +1,5 @@ - + CSS3 Text, text transform: capitalize, Full-width Latin @@ -24,8 +24,5 @@ The text is arranged in pairs of three-letter 'words'. Test passes if the words in each pair match If you are missing a font glyph for a character, ignore that pair, but report which characters were ignored. aaa Aaa bbb Bbb ccc Ccc ddd Ddd eee Eee fff Fff ggg Ggg hhh Hhh iii Iii jjj Jjj kkk Kkk lll Lll mmm Mmm nnn Nnn ooo Ooo ppp Ppp qqq Qqq rrr Rrr sss Sss ttt Ttt uuu Uuu vvv Vvv www Www xxx Xxx yyy Yyy zzz Zzz - - \ No newline at end of file + diff --git a/testing/web-platform/tests/css/css-text/text-transform/text-transform-capitalize-014.html b/testing/web-platform/tests/css/css-text/text-transform/text-transform-capitalize-014.html index 6fbd05ebc132..73d5fab0fc82 100644 --- a/testing/web-platform/tests/css/css-text/text-transform/text-transform-capitalize-014.html +++ b/testing/web-platform/tests/css/css-text/text-transform/text-transform-capitalize-014.html @@ -1,5 +1,5 @@ - + CSS3 Text, text transform: capitalize, Greek and Coptic @@ -24,8 +24,5 @@ The text is arranged in pairs of three-letter 'words'. Test passes if the words in each pair match If you are missing a font glyph for a character, ignore that pair, but report which characters were ignored. ͱͱͱ Ͱͱͱ ͳͳͳ Ͳͳͳ ͷͷͷ Ͷͷͷ ͻͻͻ Ͻͻͻ ͼͼͼ Ͼͼͼ ͽͽͽ Ͽͽͽ άάά Άάά έέέ Έέέ ήήή Ήήή ίίί Ίίί ααα Ααα βββ Βββ γγγ Γγγ δδδ Δδδ εεε Εεε ζζζ Ζζζ ηηη Ηηη θθθ Θθθ ιιι Ιιι κκκ Κκκ λλλ Λλλ μμμ Μμμ ννν Ννν ξξξ Ξξξ οοο Οοο πππ Πππ ρρρ Ρρρ ςςς Σςς σσσ Σσσ τττ Τττ υυυ Υυυ φφφ Φφφ χχχ Χχχ ψψψ Ψψψ ωωω Ωωω ϊϊϊ Ϊϊϊ ϋϋϋ Ϋϋϋ όόό Όόό ύύύ Ύύύ ώώώ Ώώώ ϐϐϐ Βϐϐ ϑϑϑ Θϑϑ ϕϕϕ Φϕϕ ϖϖϖ Πϖϖ ϗϗϗ Ϗϗϗ ϙϙϙ Ϙϙϙ ϛϛϛ Ϛϛϛ ϝϝϝ Ϝϝϝ ϟϟϟ Ϟϟϟ ϡϡϡ Ϡϡϡ ϣϣϣ Ϣϣϣ ϥϥϥ Ϥϥϥ ϧϧϧ Ϧϧϧ ϩϩϩ Ϩϩϩ ϫϫϫ Ϫϫϫ ϭϭϭ Ϭϭϭ ϯϯϯ Ϯϯϯ ϰϰϰ Κϰϰ ϱϱϱ Ρϱϱ ϲϲϲ Ϲϲϲ ϳϳϳ Ϳϳϳ ϵϵϵ Εϵϵ ϸϸϸ Ϸϸϸ ϻϻϻ Ϻϻϻ - - \ No newline at end of file + diff --git a/testing/web-platform/tests/css/css-text/text-transform/text-transform-capitalize-016.html b/testing/web-platform/tests/css/css-text/text-transform/text-transform-capitalize-016.html index 2a45c965288d..502b24ea6c95 100644 --- a/testing/web-platform/tests/css/css-text/text-transform/text-transform-capitalize-016.html +++ b/testing/web-platform/tests/css/css-text/text-transform/text-transform-capitalize-016.html @@ -1,5 +1,5 @@ - + CSS3 Text, text transform: capitalize, Greek Extended @@ -25,8 +25,5 @@ The text is arranged in pairs of three-letter 'words'. Test passes if the words in each pair match If you are missing a font glyph for a character, ignore that pair, but report which characters were ignored. ἀἀἀ Ἀἀἀ ἁἁἁ Ἁἁἁ ἂἂἂ Ἂἂἂ ἃἃἃ Ἃἃἃ ἄἄἄ Ἄἄἄ ἅἅἅ Ἅἅἅ ἆἆἆ Ἆἆἆ ἇἇἇ Ἇἇἇ ἐἐἐ Ἐἐἐ ἑἑἑ Ἑἑἑ ἒἒἒ Ἒἒἒ ἓἓἓ Ἓἓἓ ἔἔἔ Ἔἔἔ ἕἕἕ Ἕἕἕ ἠἠἠ Ἠἠἠ ἡἡἡ Ἡἡἡ ἢἢἢ Ἢἢἢ ἣἣἣ Ἣἣἣ ἤἤἤ Ἤἤἤ ἥἥἥ Ἥἥἥ ἦἦἦ Ἦἦἦ ἧἧἧ Ἧἧἧ ἰἰἰ Ἰἰἰ ἱἱἱ Ἱἱἱ ἲἲἲ Ἲἲἲ ἳἳἳ Ἳἳἳ ἴἴἴ Ἴἴἴ ἵἵἵ Ἵἵἵ ἶἶἶ Ἶἶἶ ἷἷἷ Ἷἷἷ ὀὀὀ Ὀὀὀ ὁὁὁ Ὁὁὁ ὂὂὂ Ὂὂὂ ὃὃὃ Ὃὃὃ ὄὄὄ Ὄὄὄ ὅὅὅ Ὅὅὅ ὑὑὑ Ὑὑὑ ὓὓὓ Ὓὓὓ ὕὕὕ Ὕὕὕ ὗὗὗ Ὗὗὗ ὠὠὠ Ὠὠὠ ὡὡὡ Ὡὡὡ ὢὢὢ Ὢὢὢ ὣὣὣ Ὣὣὣ ὤὤὤ Ὤὤὤ ὥὥὥ Ὥὥὥ ὦὦὦ Ὦὦὦ ὧὧὧ Ὧὧὧ ὰὰὰ Ὰὰὰ άάά Άάά ὲὲὲ Ὲὲὲ έέέ Έέέ ὴὴὴ Ὴὴὴ ήήή Ήήή ὶὶὶ Ὶὶὶ ίίί Ίίί ὸὸὸ Ὸὸὸ όόό Όόό ὺὺὺ Ὺὺὺ ύύύ Ύύύ ὼὼὼ Ὼὼὼ ώώώ Ώώώ ᾀᾀᾀ ᾈᾀᾀ ᾁᾁᾁ ᾉᾁᾁ ᾂᾂᾂ ᾊᾂᾂ ᾃᾃᾃ ᾋᾃᾃ ᾄᾄᾄ ᾌᾄᾄ ᾅᾅᾅ ᾍᾅᾅ ᾆᾆᾆ ᾎᾆᾆ ᾇᾇᾇ ᾏᾇᾇ ᾐᾐᾐ ᾘᾐᾐ ᾑᾑᾑ ᾙᾑᾑ ᾒᾒᾒ ᾚᾒᾒ ᾓᾓᾓ ᾛᾓᾓ ᾔᾔᾔ ᾜᾔᾔ ᾕᾕᾕ ᾝᾕᾕ ᾖᾖᾖ ᾞᾖᾖ ᾗᾗᾗ ᾟᾗᾗ ᾠᾠᾠ ᾨᾠᾠ ᾡᾡᾡ ᾩᾡᾡ ᾢᾢᾢ ᾪᾢᾢ ᾣᾣᾣ ᾫᾣᾣ ᾤᾤᾤ ᾬᾤᾤ ᾥᾥᾥ ᾭᾥᾥ ᾦᾦᾦ ᾮᾦᾦ ᾧᾧᾧ ᾯᾧᾧ ᾰᾰᾰ Ᾰᾰᾰ ᾱᾱᾱ Ᾱᾱᾱ ᾳᾳᾳ ᾼᾳᾳ ιιι Ιιι ῃῃῃ ῌῃῃ ῐῐῐ Ῐῐῐ ῑῑῑ Ῑῑῑ ῠῠῠ Ῠῠῠ ῡῡῡ Ῡῡῡ ῥῥῥ Ῥῥῥ ῳῳῳ ῼῳῳ - - \ No newline at end of file + diff --git a/testing/web-platform/tests/css/css-text/text-transform/text-transform-capitalize-018.html b/testing/web-platform/tests/css/css-text/text-transform/text-transform-capitalize-018.html index 210ced550256..7c86116a9b91 100644 --- a/testing/web-platform/tests/css/css-text/text-transform/text-transform-capitalize-018.html +++ b/testing/web-platform/tests/css/css-text/text-transform/text-transform-capitalize-018.html @@ -1,5 +1,5 @@ - + CSS3 Text, text transform: capitalize, Cyrillic @@ -25,8 +25,5 @@ The text is arranged in pairs of three-letter 'words'. Test passes if the words in each pair match If you are missing a font glyph for a character, ignore that pair, but report which characters were ignored. ааа Ааа ббб Ббб ввв Ввв ггг Ггг ддд Ддд еее Еее жжж Жжж ззз Ззз иии Иии ййй Ййй ккк Ккк ллл Ллл ммм Ммм ннн Ннн ооо Ооо ппп Ппп ррр Ррр ссс Ссс ттт Ттт ууу Ууу ффф Ффф ххх Ххх ццц Ццц ччч Ччч шшш Шшш щщщ Щщщ ъъъ Ъъъ ыыы Ыыы ььь Ььь эээ Эээ ююю Ююю яяя Яяя ѐѐѐ Ѐѐѐ ёёё Ёёё ђђђ Ђђђ ѓѓѓ Ѓѓѓ єєє Єєє ѕѕѕ Ѕѕѕ ііі Ііі їїї Їїї јјј Јјј љљљ Љљљ њњњ Њњњ ћћћ Ћћћ ќќќ Ќќќ ѝѝѝ Ѝѝѝ ўўў Ўўў џџџ Џџџ ѡѡѡ Ѡѡѡ ѣѣѣ Ѣѣѣ ѥѥѥ Ѥѥѥ ѧѧѧ Ѧѧѧ ѩѩѩ Ѩѩѩ ѫѫѫ Ѫѫѫ ѭѭѭ Ѭѭѭ ѯѯѯ Ѯѯѯ ѱѱѱ Ѱѱѱ ѳѳѳ Ѳѳѳ ѵѵѵ Ѵѵѵ ѷѷѷ Ѷѷѷ ѹѹѹ Ѹѹѹ ѻѻѻ Ѻѻѻ ѽѽѽ Ѽѽѽ ѿѿѿ Ѿѿѿ ҁҁҁ Ҁҁҁ ҋҋҋ Ҋҋҋ ҍҍҍ Ҍҍҍ ҏҏҏ Ҏҏҏ ґґґ Ґґґ ғғғ Ғғғ ҕҕҕ Ҕҕҕ җҗҗ Җҗҗ ҙҙҙ Ҙҙҙ қққ Қққ ҝҝҝ Ҝҝҝ ҟҟҟ Ҟҟҟ ҡҡҡ Ҡҡҡ ңңң Ңңң ҥҥҥ Ҥҥҥ ҧҧҧ Ҧҧҧ ҩҩҩ Ҩҩҩ ҫҫҫ Ҫҫҫ ҭҭҭ Ҭҭҭ үүү Үүү ұұұ Ұұұ ҳҳҳ Ҳҳҳ ҵҵҵ Ҵҵҵ ҷҷҷ Ҷҷҷ ҹҹҹ Ҹҹҹ һһһ Һһһ ҽҽҽ Ҽҽҽ ҿҿҿ Ҿҿҿ ӂӂӂ Ӂӂӂ ӄӄӄ Ӄӄӄ ӆӆӆ Ӆӆӆ ӈӈӈ Ӈӈӈ ӊӊӊ Ӊӊӊ ӌӌӌ Ӌӌӌ ӎӎӎ Ӎӎӎ ӏӏӏ Ӏӏӏ ӑӑӑ Ӑӑӑ ӓӓӓ Ӓӓӓ ӕӕӕ Ӕӕӕ ӗӗӗ Ӗӗӗ әәә Әәә ӛӛӛ Ӛӛӛ ӝӝӝ Ӝӝӝ ӟӟӟ Ӟӟӟ ӡӡӡ Ӡӡӡ ӣӣӣ Ӣӣӣ ӥӥӥ Ӥӥӥ ӧӧӧ Ӧӧӧ өөө Өөө ӫӫӫ Ӫӫӫ ӭӭӭ Ӭӭӭ ӯӯӯ Ӯӯӯ ӱӱӱ Ӱӱӱ ӳӳӳ Ӳӳӳ ӵӵӵ Ӵӵӵ ӷӷӷ Ӷӷӷ ӹӹӹ Ӹӹӹ ӻӻӻ Ӻӻӻ ӽӽӽ Ӽӽӽ ӿӿӿ Ӿӿӿ - - \ No newline at end of file + diff --git a/testing/web-platform/tests/css/css-text/text-transform/text-transform-capitalize-020.html b/testing/web-platform/tests/css/css-text/text-transform/text-transform-capitalize-020.html index d46f34605f53..fd1426cf36e4 100644 --- a/testing/web-platform/tests/css/css-text/text-transform/text-transform-capitalize-020.html +++ b/testing/web-platform/tests/css/css-text/text-transform/text-transform-capitalize-020.html @@ -1,5 +1,5 @@ - + CSS3 Text, text transform: capitalize, Cyrillic Supplement @@ -25,8 +25,5 @@ The text is arranged in pairs of three-letter 'words'. Test passes if the words in each pair match If you are missing a font glyph for a character, ignore that pair, but report which characters were ignored. ԁԁԁ Ԁԁԁ ԃԃԃ Ԃԃԃ ԅԅԅ Ԅԅԅ ԇԇԇ Ԇԇԇ ԉԉԉ Ԉԉԉ ԋԋԋ Ԋԋԋ ԍԍԍ Ԍԍԍ ԏԏԏ Ԏԏԏ ԑԑԑ Ԑԑԑ ԓԓԓ Ԓԓԓ ԕԕԕ Ԕԕԕ ԗԗԗ Ԗԗԗ ԙԙԙ Ԙԙԙ ԛԛԛ Ԛԛԛ ԝԝԝ Ԝԝԝ ԟԟԟ Ԟԟԟ ԡԡԡ Ԡԡԡ ԣԣԣ Ԣԣԣ ԥԥԥ Ԥԥԥ ԧԧԧ Ԧԧԧ ԩԩԩ Ԩԩԩ ԫԫԫ Ԫԫԫ ԭԭԭ Ԭԭԭ ԯԯԯ Ԯԯԯ - - \ No newline at end of file + diff --git a/testing/web-platform/tests/css/css-text/text-transform/text-transform-capitalize-022.html b/testing/web-platform/tests/css/css-text/text-transform/text-transform-capitalize-022.html index f8b7489b38a8..2c77961741bb 100644 --- a/testing/web-platform/tests/css/css-text/text-transform/text-transform-capitalize-022.html +++ b/testing/web-platform/tests/css/css-text/text-transform/text-transform-capitalize-022.html @@ -1,5 +1,5 @@ - + CSS3 Text, text transform: capitalize, Armenian @@ -24,8 +24,5 @@ The text is arranged in pairs of three-letter 'words'. Test passes if the words in each pair match If you are missing a font glyph for a character, ignore that pair, but report which characters were ignored. աաա Աաա բբբ Բբբ գգգ Գգգ դդդ Դդդ եեե Եեե զզզ Զզզ էէէ Էէէ ըըը Ըըը թթթ Թթթ ժժժ Ժժժ իիի Իիի լլլ Լլլ խխխ Խխխ ծծծ Ծծծ կկկ Կկկ հհհ Հհհ ձձձ Ձձձ ղղղ Ղղղ ճճճ Ճճճ մմմ Մմմ յյյ Յյյ ննն Ննն շշշ Շշշ ոոո Ոոո չչչ Չչչ պպպ Պպպ ջջջ Ջջջ ռռռ Ռռռ սսս Սսս վվվ Վվվ տտտ Տտտ րրր Րրր ցցց Ցցց ւււ Ւււ փփփ Փփփ քքք Քքք օօօ Օօօ ֆֆֆ Ֆֆֆ - diff --git a/testing/web-platform/tests/css/css-text/text-transform/text-transform-capitalize-024.html b/testing/web-platform/tests/css/css-text/text-transform/text-transform-capitalize-024.html index 67a9304f93ec..2812951a4698 100644 --- a/testing/web-platform/tests/css/css-text/text-transform/text-transform-capitalize-024.html +++ b/testing/web-platform/tests/css/css-text/text-transform/text-transform-capitalize-024.html @@ -1,5 +1,5 @@ - + CSS3 Text, text transform: capitalize, Number Forms @@ -24,8 +24,5 @@ The text is arranged in pairs of three-letter 'words'. Test passes if the words in each pair match If you are missing a font glyph for a character, ignore that pair, but report which characters were ignored. ⅰⅰⅰ Ⅰⅰⅰ ⅱⅱⅱ Ⅱⅱⅱ ⅲⅲⅲ Ⅲⅲⅲ ⅳⅳⅳ Ⅳⅳⅳ ⅴⅴⅴ Ⅴⅴⅴ ⅵⅵⅵ Ⅵⅵⅵ ⅶⅶⅶ Ⅶⅶⅶ ⅷⅷⅷ Ⅷⅷⅷ ⅸⅸⅸ Ⅸⅸⅸ ⅹⅹⅹ Ⅹⅹⅹ ⅺⅺⅺ Ⅺⅺⅺ ⅻⅻⅻ Ⅻⅻⅻ ⅼⅼⅼ Ⅼⅼⅼ ⅽⅽⅽ Ⅽⅽⅽ ⅾⅾⅾ Ⅾⅾⅾ ⅿⅿⅿ Ⅿⅿⅿ ↄↄↄ Ↄↄↄ - diff --git a/testing/web-platform/tests/css/css-text/text-transform/text-transform-capitalize-026.html b/testing/web-platform/tests/css/css-text/text-transform/text-transform-capitalize-026.html index 76999c2f38c2..ee8903a0da75 100644 --- a/testing/web-platform/tests/css/css-text/text-transform/text-transform-capitalize-026.html +++ b/testing/web-platform/tests/css/css-text/text-transform/text-transform-capitalize-026.html @@ -1,5 +1,5 @@ - + CSS3 Text, text transform: capitalize, Enclosed Alphanumerics @@ -24,9 +24,5 @@ The text is arranged in pairs of three-letter 'words'. Test passes if there are NO uppercase letters. If you are missing a font glyph for a character, ignore that pair, but report which characters were ignored. ⓐⓐⓐ ⓑⓑⓑ ⓒⓒⓒ ⓓⓓⓓ ⓔⓔⓔ ⓕⓕⓕ ⓖⓖⓖ ⓗⓗⓗ ⓘⓘⓘ ⓙⓙⓙ ⓚⓚⓚ ⓛⓛⓛ ⓜⓜⓜ ⓝⓝⓝ ⓞⓞⓞ ⓟⓟⓟ ⓠⓠⓠ ⓡⓡⓡ ⓢⓢⓢ ⓣⓣⓣ ⓤⓤⓤ ⓥⓥⓥ ⓦⓦⓦ ⓧⓧⓧ ⓨⓨⓨ ⓩⓩⓩ - diff --git a/testing/web-platform/tests/css/css-text/text-transform/text-transform-capitalize-028.html b/testing/web-platform/tests/css/css-text/text-transform/text-transform-capitalize-028.html index b22597059c01..005e091012d5 100644 --- a/testing/web-platform/tests/css/css-text/text-transform/text-transform-capitalize-028.html +++ b/testing/web-platform/tests/css/css-text/text-transform/text-transform-capitalize-028.html @@ -1,5 +1,5 @@ - + CSS3 Text, text transform: capitalize, Deseret @@ -24,8 +24,5 @@ The text is arranged in pairs of three-letter 'words'. Test passes if the words in each pair match If you are missing a font glyph for a character, ignore that pair, but report which characters were ignored. 𐐨𐐨𐐨 𐐀𐐨𐐨 𐐩𐐩𐐩 𐐁𐐩𐐩 𐐪𐐪𐐪 𐐂𐐪𐐪 𐐫𐐫𐐫 𐐃𐐫𐐫 𐐬𐐬𐐬 𐐄𐐬𐐬 𐐭𐐭𐐭 𐐅𐐭𐐭 𐐮𐐮𐐮 𐐆𐐮𐐮 𐐯𐐯𐐯 𐐇𐐯𐐯 𐐰𐐰𐐰 𐐈𐐰𐐰 𐐱𐐱𐐱 𐐉𐐱𐐱 𐐲𐐲𐐲 𐐊𐐲𐐲 𐐳𐐳𐐳 𐐋𐐳𐐳 𐐴𐐴𐐴 𐐌𐐴𐐴 𐐵𐐵𐐵 𐐍𐐵𐐵 𐐶𐐶𐐶 𐐎𐐶𐐶 𐐷𐐷𐐷 𐐏𐐷𐐷 𐐸𐐸𐐸 𐐐𐐸𐐸 𐐹𐐹𐐹 𐐑𐐹𐐹 𐐺𐐺𐐺 𐐒𐐺𐐺 𐐻𐐻𐐻 𐐓𐐻𐐻 𐐼𐐼𐐼 𐐔𐐼𐐼 𐐽𐐽𐐽 𐐕𐐽𐐽 𐐾𐐾𐐾 𐐖𐐾𐐾 𐐿𐐿𐐿 𐐗𐐿𐐿 𐑀𐑀𐑀 𐐘𐑀𐑀 𐑁𐑁𐑁 𐐙𐑁𐑁 𐑂𐑂𐑂 𐐚𐑂𐑂 𐑃𐑃𐑃 𐐛𐑃𐑃 𐑄𐑄𐑄 𐐜𐑄𐑄 𐑅𐑅𐑅 𐐝𐑅𐑅 𐑆𐑆𐑆 𐐞𐑆𐑆 𐑇𐑇𐑇 𐐟𐑇𐑇 𐑈𐑈𐑈 𐐠𐑈𐑈 𐑉𐑉𐑉 𐐡𐑉𐑉 𐑊𐑊𐑊 𐐢𐑊𐑊 𐑋𐑋𐑋 𐐣𐑋𐑋 𐑌𐑌𐑌 𐐤𐑌𐑌 𐑍𐑍𐑍 𐐥𐑍𐑍 𐑎𐑎𐑎 𐐦𐑎𐑎 𐑏𐑏𐑏 𐐧𐑏𐑏 - diff --git a/testing/web-platform/tests/css/css-text/text-transform/text-transform-capitalize-030.html b/testing/web-platform/tests/css/css-text/text-transform/text-transform-capitalize-030.html index 1924d3e3476c..d5e254803ba8 100644 --- a/testing/web-platform/tests/css/css-text/text-transform/text-transform-capitalize-030.html +++ b/testing/web-platform/tests/css/css-text/text-transform/text-transform-capitalize-030.html @@ -1,5 +1,5 @@ - + CSS3 Text, text transform: capitalize, Georgian Supplement @@ -24,8 +24,5 @@ The text is arranged in pairs of three-letter 'words'. Test passes if the words in each pair match If you are missing a font glyph for a character, ignore that pair, but report which characters were ignored. ⴀⴀⴀ Ⴀⴀⴀ ⴁⴁⴁ Ⴁⴁⴁ ⴂⴂⴂ Ⴂⴂⴂ ⴃⴃⴃ Ⴃⴃⴃ ⴄⴄⴄ Ⴄⴄⴄ ⴅⴅⴅ Ⴅⴅⴅ ⴆⴆⴆ Ⴆⴆⴆ ⴇⴇⴇ Ⴇⴇⴇ ⴈⴈⴈ Ⴈⴈⴈ ⴉⴉⴉ Ⴉⴉⴉ ⴊⴊⴊ Ⴊⴊⴊ ⴋⴋⴋ Ⴋⴋⴋ ⴌⴌⴌ Ⴌⴌⴌ ⴍⴍⴍ Ⴍⴍⴍ ⴎⴎⴎ Ⴎⴎⴎ ⴏⴏⴏ Ⴏⴏⴏ ⴐⴐⴐ Ⴐⴐⴐ ⴑⴑⴑ Ⴑⴑⴑ ⴒⴒⴒ Ⴒⴒⴒ ⴓⴓⴓ Ⴓⴓⴓ ⴔⴔⴔ Ⴔⴔⴔ ⴕⴕⴕ Ⴕⴕⴕ ⴖⴖⴖ Ⴖⴖⴖ ⴗⴗⴗ Ⴗⴗⴗ ⴘⴘⴘ Ⴘⴘⴘ ⴙⴙⴙ Ⴙⴙⴙ ⴚⴚⴚ Ⴚⴚⴚ ⴛⴛⴛ Ⴛⴛⴛ ⴜⴜⴜ Ⴜⴜⴜ ⴝⴝⴝ Ⴝⴝⴝ ⴞⴞⴞ Ⴞⴞⴞ ⴟⴟⴟ Ⴟⴟⴟ ⴠⴠⴠ Ⴠⴠⴠ ⴡⴡⴡ Ⴡⴡⴡ ⴢⴢⴢ Ⴢⴢⴢ ⴣⴣⴣ Ⴣⴣⴣ ⴤⴤⴤ Ⴤⴤⴤ ⴥⴥⴥ Ⴥⴥⴥ ⴧⴧⴧ Ⴧⴧⴧ ⴭⴭⴭ Ⴭⴭⴭ - diff --git a/testing/web-platform/tests/css/css-text/text-transform/text-transform-capitalize-031.html b/testing/web-platform/tests/css/css-text/text-transform/text-transform-capitalize-031.html index 3ccd40e39c9e..3a5b5d153787 100644 --- a/testing/web-platform/tests/css/css-text/text-transform/text-transform-capitalize-031.html +++ b/testing/web-platform/tests/css/css-text/text-transform/text-transform-capitalize-031.html @@ -1,5 +1,5 @@ - + CSS3 Text, text transform: capitalize, initial punctuation diff --git a/testing/web-platform/tests/css/css-text/text-transform/text-transform-full-size-kana-001.html b/testing/web-platform/tests/css/css-text/text-transform/text-transform-full-size-kana-001.html index 856766859237..70584ef38935 100644 --- a/testing/web-platform/tests/css/css-text/text-transform/text-transform-full-size-kana-001.html +++ b/testing/web-platform/tests/css/css-text/text-transform/text-transform-full-size-kana-001.html @@ -67,8 +67,5 @@ ュ ユ ョ ヨ - diff --git a/testing/web-platform/tests/css/css-text/text-transform/text-transform-full-size-kana-002.html b/testing/web-platform/tests/css/css-text/text-transform/text-transform-full-size-kana-002.html index 75399f3798df..f77e09cc25e4 100644 --- a/testing/web-platform/tests/css/css-text/text-transform/text-transform-full-size-kana-002.html +++ b/testing/web-platform/tests/css/css-text/text-transform/text-transform-full-size-kana-002.html @@ -223,8 +223,5 @@ ゙ ゙ ゚ ゚ - diff --git a/testing/web-platform/tests/css/css-text/text-transform/text-transform-tailoring-001.html b/testing/web-platform/tests/css/css-text/text-transform/text-transform-tailoring-001.html index d028caeb7cc7..6cc2cdf345cc 100644 --- a/testing/web-platform/tests/css/css-text/text-transform/text-transform-tailoring-001.html +++ b/testing/web-platform/tests/css/css-text/text-transform/text-transform-tailoring-001.html @@ -1,5 +1,5 @@ - + CSS3 Text, text transform: capitalize, Dutch IJ diff --git a/testing/web-platform/tests/css/css-text/text-transform/text-transform-tailoring-002.html b/testing/web-platform/tests/css/css-text/text-transform/text-transform-tailoring-002.html index f170a25b4e15..090ed9349c5c 100644 --- a/testing/web-platform/tests/css/css-text/text-transform/text-transform-tailoring-002.html +++ b/testing/web-platform/tests/css/css-text/text-transform/text-transform-tailoring-002.html @@ -1,5 +1,5 @@ - + CSS3 Text, text transform: uppercase, Greek tonos diff --git a/testing/web-platform/tests/css/css-text/text-transform/text-transform-tailoring-002a.html b/testing/web-platform/tests/css/css-text/text-transform/text-transform-tailoring-002a.html index 4c7fa8da6f69..5cdbbfb832ef 100644 --- a/testing/web-platform/tests/css/css-text/text-transform/text-transform-tailoring-002a.html +++ b/testing/web-platform/tests/css/css-text/text-transform/text-transform-tailoring-002a.html @@ -1,5 +1,5 @@ - + CSS3 Text, text transform: uppercase, Greek dialytika diff --git a/testing/web-platform/tests/css/css-text/text-transform/text-transform-tailoring-003.html b/testing/web-platform/tests/css/css-text/text-transform/text-transform-tailoring-003.html index c25e87f3b36b..37409e0a21ae 100644 --- a/testing/web-platform/tests/css/css-text/text-transform/text-transform-tailoring-003.html +++ b/testing/web-platform/tests/css/css-text/text-transform/text-transform-tailoring-003.html @@ -1,5 +1,5 @@ - + CSS3 Text, text transform: uppercase, more Greek accents diff --git a/testing/web-platform/tests/css/css-text/text-transform/text-transform-tailoring-004.html b/testing/web-platform/tests/css/css-text/text-transform/text-transform-tailoring-004.html index 42ac34cda9fe..2d66c34cbea6 100644 --- a/testing/web-platform/tests/css/css-text/text-transform/text-transform-tailoring-004.html +++ b/testing/web-platform/tests/css/css-text/text-transform/text-transform-tailoring-004.html @@ -1,5 +1,5 @@ - + CSS3 Text, text transform: capitalize, Greek initial stress diff --git a/testing/web-platform/tests/css/css-text/text-transform/text-transform-tailoring-005.html b/testing/web-platform/tests/css/css-text/text-transform/text-transform-tailoring-005.html index 16333ea87c08..5dea8f9139f1 100644 --- a/testing/web-platform/tests/css/css-text/text-transform/text-transform-tailoring-005.html +++ b/testing/web-platform/tests/css/css-text/text-transform/text-transform-tailoring-005.html @@ -1,5 +1,5 @@ - + CSS3 Text, text transform: uppercase, Greek disjunctive eta diff --git a/testing/web-platform/tests/css/css-text/text-transform/text-transform-upperlower-001.html b/testing/web-platform/tests/css/css-text/text-transform/text-transform-upperlower-001.html index a30be4e888d8..748bfeaef4ba 100644 --- a/testing/web-platform/tests/css/css-text/text-transform/text-transform-upperlower-001.html +++ b/testing/web-platform/tests/css/css-text/text-transform/text-transform-upperlower-001.html @@ -1,5 +1,5 @@ - + CSS3 Text, text transform: Latin Basic and Latin-1 uppercase @@ -23,8 +23,5 @@ Test passes if both characters in each pair match. If you are missing a font glyph for a character, ignore that pair, but report which characters were ignored. a A b B c C d D e E f F g G h H i I j J k K l L m M n N o O p P q Q r R s S t T u U v V w W x X y Y z Z µ Μ à À á Á â  ã à ä Ä å Å æ Æ ç Ç è È é É ê Ê ë Ë ì Ì í Í î Î ï Ï ð Ð ñ Ñ ò Ò ó Ó ô Ô õ Õ ö Ö ø Ø ù Ù ú Ú û Û ü Ü ý Ý þ Þ ÿ Ÿ - - \ No newline at end of file + diff --git a/testing/web-platform/tests/css/css-text/text-transform/text-transform-upperlower-002.html b/testing/web-platform/tests/css/css-text/text-transform/text-transform-upperlower-002.html index e82a967658c7..ef6bda606763 100644 --- a/testing/web-platform/tests/css/css-text/text-transform/text-transform-upperlower-002.html +++ b/testing/web-platform/tests/css/css-text/text-transform/text-transform-upperlower-002.html @@ -1,5 +1,5 @@ - + CSS3 Text, text transform: Latin Basic and Latin-1 lowercase @@ -23,8 +23,5 @@ Test passes if both characters in each pair match. If you are missing a font glyph for a character, ignore that pair, but report which characters were ignored. A a B b C c D d E e F f G g H h I i J j K k L l M m N n O o P p Q q R r S s T t U u V v W w X x Y y Z z À à Á á  â à ã Ä ä Å å Æ æ Ç ç È è É é Ê ê Ë ë Ì ì Í í Î î Ï ï Ð ð Ñ ñ Ò ò Ó ó Ô ô Õ õ Ö ö Ø ø Ù ù Ú ú Û û Ü ü Ý ý Þ þ - - \ No newline at end of file + diff --git a/testing/web-platform/tests/css/css-text/text-transform/text-transform-upperlower-003.html b/testing/web-platform/tests/css/css-text/text-transform/text-transform-upperlower-003.html index 8422a9a64021..94526baf8d00 100644 --- a/testing/web-platform/tests/css/css-text/text-transform/text-transform-upperlower-003.html +++ b/testing/web-platform/tests/css/css-text/text-transform/text-transform-upperlower-003.html @@ -1,5 +1,5 @@ - + CSS3 Text, text transform: Latin Extended Additional, uppercase @@ -25,7 +25,6 @@ ḁ Ḁ ḃ Ḃ ḅ Ḅ ḇ Ḇ ḉ Ḉ ḋ Ḋ ḍ Ḍ ḏ Ḏ ḑ Ḑ ḓ Ḓ ḕ Ḕ ḗ Ḗ ḙ Ḙ ḛ Ḛ ḝ Ḝ ḟ Ḟ ḡ Ḡ ḣ Ḣ ḥ Ḥ ḧ Ḧ ḩ Ḩ ḫ Ḫ ḭ Ḭ ḯ Ḯ ḱ Ḱ ḳ Ḳ ḵ Ḵ ḷ Ḷ ḹ Ḹ ḻ Ḻ ḽ Ḽ ḿ Ḿ ṁ Ṁ ṃ Ṃ ṅ Ṅ ṇ Ṇ ṉ Ṉ ṋ Ṋ ṍ Ṍ ṏ Ṏ ṑ Ṑ ṓ Ṓ ṕ Ṕ ṗ Ṗ ṙ Ṙ ṛ Ṛ ṝ Ṝ ṟ Ṟ ṡ Ṡ ṣ Ṣ ṥ Ṥ ṧ Ṧ ṩ Ṩ ṫ Ṫ ṭ Ṭ ṯ Ṯ ṱ Ṱ ṳ Ṳ ṵ Ṵ ṷ Ṷ ṹ Ṹ ṻ Ṻ ṽ Ṽ ṿ Ṿ ẁ Ẁ ẃ Ẃ ẅ Ẅ ẇ Ẇ ẉ Ẉ ẋ Ẋ ẍ Ẍ ẏ Ẏ ẑ Ẑ ẓ Ẓ ẕ Ẕ ẛ Ṡ ạ Ạ ả Ả ấ Ấ ầ Ầ ẩ Ẩ ẫ Ẫ ậ Ậ ắ Ắ ằ Ằ ẳ Ẳ ẵ Ẵ ặ Ặ ẹ Ẹ ẻ Ẻ ẽ Ẽ ế Ế ề Ề ể Ể ễ Ễ ệ Ệ ỉ Ỉ ị Ị ọ Ọ ỏ Ỏ ố Ố ồ Ồ ổ Ổ ỗ Ỗ ộ Ộ ớ Ớ ờ Ờ ở Ở ỡ Ỡ ợ Ợ ụ Ụ ủ Ủ ứ Ứ ừ Ừ ử Ử ữ Ữ ự Ự ỳ Ỳ ỵ Ỵ ỷ Ỷ ỹ Ỹ ỻ Ỻ ỽ Ỽ ỿ Ỿ - \ No newline at end of file + diff --git a/testing/web-platform/tests/css/css-text/text-transform/text-transform-upperlower-004.html b/testing/web-platform/tests/css/css-text/text-transform/text-transform-upperlower-004.html index e6863834eb96..ef7cc5d9c6a3 100644 --- a/testing/web-platform/tests/css/css-text/text-transform/text-transform-upperlower-004.html +++ b/testing/web-platform/tests/css/css-text/text-transform/text-transform-upperlower-004.html @@ -1,5 +1,5 @@ - + CSS3 Text, text transform: Latin Extended Additional, lowercase @@ -25,7 +25,6 @@ Ḁ ḁ Ḃ ḃ Ḅ ḅ Ḇ ḇ Ḉ ḉ Ḋ ḋ Ḍ ḍ Ḏ ḏ Ḑ ḑ Ḓ ḓ Ḕ ḕ Ḗ ḗ Ḙ ḙ Ḛ ḛ Ḝ ḝ Ḟ ḟ Ḡ ḡ Ḣ ḣ Ḥ ḥ Ḧ ḧ Ḩ ḩ Ḫ ḫ Ḭ ḭ Ḯ ḯ Ḱ ḱ Ḳ ḳ Ḵ ḵ Ḷ ḷ Ḹ ḹ Ḻ ḻ Ḽ ḽ Ḿ ḿ Ṁ ṁ Ṃ ṃ Ṅ ṅ Ṇ ṇ Ṉ ṉ Ṋ ṋ Ṍ ṍ Ṏ ṏ Ṑ ṑ Ṓ ṓ Ṕ ṕ Ṗ ṗ Ṙ ṙ Ṛ ṛ Ṝ ṝ Ṟ ṟ Ṡ ṡ Ṣ ṣ Ṥ ṥ Ṧ ṧ Ṩ ṩ Ṫ ṫ Ṭ ṭ Ṯ ṯ Ṱ ṱ Ṳ ṳ Ṵ ṵ Ṷ ṷ Ṹ ṹ Ṻ ṻ Ṽ ṽ Ṿ ṿ Ẁ ẁ Ẃ ẃ Ẅ ẅ Ẇ ẇ Ẉ ẉ Ẋ ẋ Ẍ ẍ Ẏ ẏ Ẑ ẑ Ẓ ẓ Ẕ ẕ ẞ ß Ạ ạ Ả ả Ấ ấ Ầ ầ Ẩ ẩ Ẫ ẫ Ậ ậ Ắ ắ Ằ ằ Ẳ ẳ Ẵ ẵ Ặ ặ Ẹ ẹ Ẻ ẻ Ẽ ẽ Ế ế Ề ề Ể ể Ễ ễ Ệ ệ Ỉ ỉ Ị ị Ọ ọ Ỏ ỏ Ố ố Ồ ồ Ổ ổ Ỗ ỗ Ộ ộ Ớ ớ Ờ ờ Ở ở Ỡ ỡ Ợ ợ Ụ ụ Ủ ủ Ứ ứ Ừ ừ Ử ử Ữ ữ Ự ự Ỳ ỳ Ỵ ỵ Ỷ ỷ Ỹ ỹ Ỻ ỻ Ỽ ỽ Ỿ ỿ - \ No newline at end of file + diff --git a/testing/web-platform/tests/css/css-text/text-transform/text-transform-upperlower-005.html b/testing/web-platform/tests/css/css-text/text-transform/text-transform-upperlower-005.html index d8164b6cb388..d91a3f1fe698 100644 --- a/testing/web-platform/tests/css/css-text/text-transform/text-transform-upperlower-005.html +++ b/testing/web-platform/tests/css/css-text/text-transform/text-transform-upperlower-005.html @@ -1,5 +1,5 @@ - + CSS3 Text, text transform: Latin Extended-A, uppercase @@ -25,7 +25,6 @@ ā Ā ă Ă ą Ą ć Ć ĉ Ĉ ċ Ċ č Č ď Ď đ Đ ē Ē ĕ Ĕ ė Ė ę Ę ě Ě ĝ Ĝ ğ Ğ ġ Ġ ģ Ģ ĥ Ĥ ħ Ħ ĩ Ĩ ī Ī ĭ Ĭ į Į ı I ij IJ ĵ Ĵ ķ Ķ ĺ Ĺ ļ Ļ ľ Ľ ŀ Ŀ ł Ł ń Ń ņ Ņ ň Ň ŋ Ŋ ō Ō ŏ Ŏ ő Ő œ Œ ŕ Ŕ ŗ Ŗ ř Ř ś Ś ŝ Ŝ ş Ş š Š ţ Ţ ť Ť ŧ Ŧ ũ Ũ ū Ū ŭ Ŭ ů Ů ű Ű ų Ų ŵ Ŵ ŷ Ŷ ź Ź ż Ż ž Ž ſ S - \ No newline at end of file + diff --git a/testing/web-platform/tests/css/css-text/text-transform/text-transform-upperlower-006.html b/testing/web-platform/tests/css/css-text/text-transform/text-transform-upperlower-006.html index c4d607a14bb6..55704ede654c 100644 --- a/testing/web-platform/tests/css/css-text/text-transform/text-transform-upperlower-006.html +++ b/testing/web-platform/tests/css/css-text/text-transform/text-transform-upperlower-006.html @@ -1,5 +1,5 @@ - + CSS3 Text, text transform: Latin Extended-A, lowercase @@ -25,7 +25,6 @@ Ā ā Ă ă Ą ą Ć ć Ĉ ĉ Ċ ċ Č č Ď ď Đ đ Ē ē Ĕ ĕ Ė ė Ę ę Ě ě Ĝ ĝ Ğ ğ Ġ ġ Ģ ģ Ĥ ĥ Ħ ħ Ĩ ĩ Ī ī Ĭ ĭ Į į İ i IJ ij Ĵ ĵ Ķ ķ Ĺ ĺ Ļ ļ Ľ ľ Ŀ ŀ Ł ł Ń ń Ņ ņ Ň ň Ŋ ŋ Ō ō Ŏ ŏ Ő ő Œ œ Ŕ ŕ Ŗ ŗ Ř ř Ś ś Ŝ ŝ Ş ş Š š Ţ ţ Ť ť Ŧ ŧ Ũ ũ Ū ū Ŭ ŭ Ů ů Ű ű Ų ų Ŵ ŵ Ŷ ŷ Ÿ ÿ Ź ź Ż ż Ž ž - \ No newline at end of file + diff --git a/testing/web-platform/tests/css/css-text/text-transform/text-transform-upperlower-007.html b/testing/web-platform/tests/css/css-text/text-transform/text-transform-upperlower-007.html index 1d3e591a70fa..c95830a262c4 100644 --- a/testing/web-platform/tests/css/css-text/text-transform/text-transform-upperlower-007.html +++ b/testing/web-platform/tests/css/css-text/text-transform/text-transform-upperlower-007.html @@ -1,5 +1,5 @@ - + CSS3 Text, text transform: Latin Extended-B, uppercase @@ -25,7 +25,6 @@ ƀ Ƀ ƃ Ƃ ƅ Ƅ ƈ Ƈ ƌ Ƌ ƒ Ƒ ƕ Ƕ ƙ Ƙ ƚ Ƚ ƞ Ƞ ơ Ơ ƣ Ƣ ƥ Ƥ ƨ Ƨ ƭ Ƭ ư Ư ƴ Ƴ ƶ Ƶ ƹ Ƹ ƽ Ƽ ƿ Ƿ Dž DŽ dž DŽ Lj LJ lj LJ Nj NJ nj NJ ǎ Ǎ ǐ Ǐ ǒ Ǒ ǔ Ǔ ǖ Ǖ ǘ Ǘ ǚ Ǚ ǜ Ǜ ǝ Ǝ ǟ Ǟ ǡ Ǡ ǣ Ǣ ǥ Ǥ ǧ Ǧ ǩ Ǩ ǫ Ǫ ǭ Ǭ ǯ Ǯ Dz DZ dz DZ ǵ Ǵ ǹ Ǹ ǻ Ǻ ǽ Ǽ ǿ Ǿ ȁ Ȁ ȃ Ȃ ȅ Ȅ ȇ Ȇ ȉ Ȉ ȋ Ȋ ȍ Ȍ ȏ Ȏ ȑ Ȑ ȓ Ȓ ȕ Ȕ ȗ Ȗ ș Ș ț Ț ȝ Ȝ ȟ Ȟ ȣ Ȣ ȥ Ȥ ȧ Ȧ ȩ Ȩ ȫ Ȫ ȭ Ȭ ȯ Ȯ ȱ Ȱ ȳ Ȳ ȼ Ȼ ȿ Ȿ ɀ Ɀ ɂ Ɂ ɇ Ɇ ɉ Ɉ ɋ Ɋ ɍ Ɍ ɏ Ɏ - \ No newline at end of file + diff --git a/testing/web-platform/tests/css/css-text/text-transform/text-transform-upperlower-008.html b/testing/web-platform/tests/css/css-text/text-transform/text-transform-upperlower-008.html index 09e807917342..7ff767daf545 100644 --- a/testing/web-platform/tests/css/css-text/text-transform/text-transform-upperlower-008.html +++ b/testing/web-platform/tests/css/css-text/text-transform/text-transform-upperlower-008.html @@ -1,5 +1,5 @@ - + CSS3 Text, text transform: Latin Extended-B, lowercase @@ -25,6 +25,5 @@ Ɓ ɓ Ƃ ƃ Ƅ ƅ Ɔ ɔ Ƈ ƈ Ɖ ɖ Ɗ ɗ Ƌ ƌ Ǝ ǝ Ə ə Ɛ ɛ Ƒ ƒ Ɠ ɠ Ɣ ɣ Ɩ ɩ Ɨ ɨ Ƙ ƙ Ɯ ɯ Ɲ ɲ Ɵ ɵ Ơ ơ Ƣ ƣ Ƥ ƥ Ʀ ʀ Ƨ ƨ Ʃ ʃ Ƭ ƭ Ʈ ʈ Ư ư Ʊ ʊ Ʋ ʋ Ƴ ƴ Ƶ ƶ Ʒ ʒ Ƹ ƹ Ƽ ƽ DŽ dž Dž dž LJ lj Lj lj NJ nj Nj nj Ǎ ǎ Ǐ ǐ Ǒ ǒ Ǔ ǔ Ǖ ǖ Ǘ ǘ Ǚ ǚ Ǜ ǜ Ǟ ǟ Ǡ ǡ Ǣ ǣ Ǥ ǥ Ǧ ǧ Ǩ ǩ Ǫ ǫ Ǭ ǭ Ǯ ǯ DZ dz Dz dz Ǵ ǵ Ƕ ƕ Ƿ ƿ Ǹ ǹ Ǻ ǻ Ǽ ǽ Ǿ ǿ Ȁ ȁ Ȃ ȃ Ȅ ȅ Ȇ ȇ Ȉ ȉ Ȋ ȋ Ȍ ȍ Ȏ ȏ Ȑ ȑ Ȓ ȓ Ȕ ȕ Ȗ ȗ Ș ș Ț ț Ȝ ȝ Ȟ ȟ Ƞ ƞ Ȣ ȣ Ȥ ȥ Ȧ ȧ Ȩ ȩ Ȫ ȫ Ȭ ȭ Ȯ ȯ Ȱ ȱ Ȳ ȳ Ⱥ ⱥ Ȼ ȼ Ƚ ƚ Ⱦ ⱦ Ɂ ɂ Ƀ ƀ Ʉ ʉ Ʌ ʌ Ɇ ɇ Ɉ ɉ Ɋ ɋ Ɍ ɍ Ɏ ɏ - \ No newline at end of file + diff --git a/testing/web-platform/tests/css/css-text/text-transform/text-transform-upperlower-009.html b/testing/web-platform/tests/css/css-text/text-transform/text-transform-upperlower-009.html index dcb08962afa7..a04047d0dffd 100644 --- a/testing/web-platform/tests/css/css-text/text-transform/text-transform-upperlower-009.html +++ b/testing/web-platform/tests/css/css-text/text-transform/text-transform-upperlower-009.html @@ -1,5 +1,5 @@ - + CSS3 Text, text transform: Latin Extended-C, uppercase @@ -25,7 +25,6 @@ ⱡ Ⱡ ⱥ Ⱥ ⱦ Ⱦ ⱨ Ⱨ ⱪ Ⱪ ⱬ Ⱬ ⱳ Ⱳ ⱶ Ⱶ - \ No newline at end of file + diff --git a/testing/web-platform/tests/css/css-text/text-transform/text-transform-upperlower-010.html b/testing/web-platform/tests/css/css-text/text-transform/text-transform-upperlower-010.html index e36491a2ad05..bf98e32eda5e 100644 --- a/testing/web-platform/tests/css/css-text/text-transform/text-transform-upperlower-010.html +++ b/testing/web-platform/tests/css/css-text/text-transform/text-transform-upperlower-010.html @@ -1,5 +1,5 @@ - + CSS3 Text, text transform: Latin Extended-C, lowercase @@ -25,6 +25,5 @@ Ⱡ ⱡ Ɫ ɫ Ᵽ ᵽ Ɽ ɽ Ⱨ ⱨ Ⱪ ⱪ Ⱬ ⱬ Ɑ ɑ Ɱ ɱ Ɐ ɐ Ɒ ɒ Ⱳ ⱳ Ⱶ ⱶ Ȿ ȿ Ɀ ɀ - \ No newline at end of file + diff --git a/testing/web-platform/tests/css/css-text/text-transform/text-transform-upperlower-011.html b/testing/web-platform/tests/css/css-text/text-transform/text-transform-upperlower-011.html index 50dbbcd60f1d..ba6fdf141173 100644 --- a/testing/web-platform/tests/css/css-text/text-transform/text-transform-upperlower-011.html +++ b/testing/web-platform/tests/css/css-text/text-transform/text-transform-upperlower-011.html @@ -1,5 +1,5 @@ - + CSS3 Text, text transform: Full-width Latin, uppercase @@ -25,7 +25,6 @@ a A b B c C d D e E f F g G h H i I j J k K l L m M n N o O p P q Q r R s S t T u U v V w W x X y Y z Z - \ No newline at end of file + diff --git a/testing/web-platform/tests/css/css-text/text-transform/text-transform-upperlower-012.html b/testing/web-platform/tests/css/css-text/text-transform/text-transform-upperlower-012.html index 8e47999490d5..e63e319a47f2 100644 --- a/testing/web-platform/tests/css/css-text/text-transform/text-transform-upperlower-012.html +++ b/testing/web-platform/tests/css/css-text/text-transform/text-transform-upperlower-012.html @@ -1,5 +1,5 @@ - + CSS3 Text, text transform: Full-width Latin, lowercase @@ -25,6 +25,5 @@ A a B b C c D d E e F f G g H h I i J j K k L l M m N n O o P p Q q R r S s T t U u V v W w X x Y y Z z - \ No newline at end of file + diff --git a/testing/web-platform/tests/css/css-text/text-transform/text-transform-upperlower-014.html b/testing/web-platform/tests/css/css-text/text-transform/text-transform-upperlower-014.html index 3e391da81085..cca58f057975 100644 --- a/testing/web-platform/tests/css/css-text/text-transform/text-transform-upperlower-014.html +++ b/testing/web-platform/tests/css/css-text/text-transform/text-transform-upperlower-014.html @@ -1,5 +1,5 @@ - + CSS3 Text, text transform: Greek and Coptic, uppercase @@ -25,7 +25,6 @@ ͱ Ͱ ͳ Ͳ ͷ Ͷ ͻ Ͻ ͼ Ͼ ͽ Ͽ ά Ά έ Έ ή Ή ί Ί α Α β Β γ Γ δ Δ ε Ε ζ Ζ η Η θ Θ ι Ι κ Κ λ Λ μ Μ ν Ν ξ Ξ ο Ο π Π ρ Ρ ς Σ σ Σ τ Τ υ Υ φ Φ χ Χ ψ Ψ ω Ω ϊ Ϊ ϋ Ϋ ό Ό ύ Ύ ώ Ώ ϐ Β ϑ Θ ϕ Φ ϖ Π ϗ Ϗ ϙ Ϙ ϛ Ϛ ϝ Ϝ ϟ Ϟ ϡ Ϡ ϣ Ϣ ϥ Ϥ ϧ Ϧ ϩ Ϩ ϫ Ϫ ϭ Ϭ ϯ Ϯ ϰ Κ ϱ Ρ ϲ Ϲ ϳ Ϳ ϵ Ε ϸ Ϸ ϻ Ϻ - \ No newline at end of file + diff --git a/testing/web-platform/tests/css/css-text/text-transform/text-transform-upperlower-015.html b/testing/web-platform/tests/css/css-text/text-transform/text-transform-upperlower-015.html index a06cdf520999..293056303dcc 100644 --- a/testing/web-platform/tests/css/css-text/text-transform/text-transform-upperlower-015.html +++ b/testing/web-platform/tests/css/css-text/text-transform/text-transform-upperlower-015.html @@ -1,5 +1,5 @@ - + CSS3 Text, text transform: Greek and Coptic, lowercase @@ -25,7 +25,6 @@ Ͱ ͱ Ͳ ͳ Ͷ ͷ Ϳ ϳ Ά ά Έ έ Ή ή Ί ί Ό ό Ύ ύ Ώ ώ Α α Β β Γ γ Δ δ Ε ε Ζ ζ Η η Θ θ Ι ι Κ κ Λ λ Μ μ Ν ν Ξ ξ Ο ο Π π Ρ ρ Σ σ Τ τ Υ υ Φ φ Χ χ Ψ ψ Ω ω Ϊ ϊ Ϋ ϋ Ϗ ϗ Ϙ ϙ Ϛ ϛ Ϝ ϝ Ϟ ϟ Ϡ ϡ Ϣ ϣ Ϥ ϥ Ϧ ϧ Ϩ ϩ Ϫ ϫ Ϭ ϭ Ϯ ϯ ϴ θ Ϸ ϸ Ϲ ϲ Ϻ ϻ Ͻ ͻ Ͼ ͼ Ͽ ͽ - \ No newline at end of file + diff --git a/testing/web-platform/tests/css/css-text/text-transform/text-transform-upperlower-016.html b/testing/web-platform/tests/css/css-text/text-transform/text-transform-upperlower-016.html index e6cd03f68709..3a793c7dd880 100644 --- a/testing/web-platform/tests/css/css-text/text-transform/text-transform-upperlower-016.html +++ b/testing/web-platform/tests/css/css-text/text-transform/text-transform-upperlower-016.html @@ -1,5 +1,5 @@ - + CSS3 Text, text transform: Greek Extended, uppercase @@ -27,7 +27,6 @@ - \ No newline at end of file + diff --git a/testing/web-platform/tests/css/css-text/text-transform/text-transform-upperlower-017.html b/testing/web-platform/tests/css/css-text/text-transform/text-transform-upperlower-017.html index 821fcf91f27d..32a0e725f9ea 100644 --- a/testing/web-platform/tests/css/css-text/text-transform/text-transform-upperlower-017.html +++ b/testing/web-platform/tests/css/css-text/text-transform/text-transform-upperlower-017.html @@ -1,5 +1,5 @@ - + CSS3 Text, text transform: Greek Extended, lowercase @@ -26,6 +26,5 @@ Ἀ ἀ Ἁ ἁ Ἂ ἂ Ἃ ἃ Ἄ ἄ Ἅ ἅ Ἆ ἆ Ἇ ἇ Ἐ ἐ Ἑ ἑ Ἒ ἒ Ἓ ἓ Ἔ ἔ Ἕ ἕ Ἠ ἠ Ἡ ἡ Ἢ ἢ Ἣ ἣ Ἤ ἤ Ἥ ἥ Ἦ ἦ Ἧ ἧ Ἰ ἰ Ἱ ἱ Ἲ ἲ Ἳ ἳ Ἴ ἴ Ἵ ἵ Ἶ ἶ Ἷ ἷ Ὀ ὀ Ὁ ὁ Ὂ ὂ Ὃ ὃ Ὄ ὄ Ὅ ὅ Ὑ ὑ Ὓ ὓ Ὕ ὕ Ὗ ὗ Ὠ ὠ Ὡ ὡ Ὢ ὢ Ὣ ὣ Ὤ ὤ Ὥ ὥ Ὦ ὦ Ὧ ὧ ᾈ ᾀ ᾉ ᾁ ᾊ ᾂ ᾋ ᾃ ᾌ ᾄ ᾍ ᾅ ᾎ ᾆ ᾏ ᾇ ᾘ ᾐ ᾙ ᾑ ᾚ ᾒ ᾛ ᾓ ᾜ ᾔ ᾝ ᾕ ᾞ ᾖ ᾟ ᾗ ᾨ ᾠ ᾩ ᾡ ᾪ ᾢ ᾫ ᾣ ᾬ ᾤ ᾭ ᾥ ᾮ ᾦ ᾯ ᾧ Ᾰ ᾰ Ᾱ ᾱ Ὰ ὰ Ά ά ᾼ ᾳ Ὲ ὲ Έ έ Ὴ ὴ Ή ή ῌ ῃ Ῐ ῐ Ῑ ῑ Ὶ ὶ Ί ί Ῠ ῠ Ῡ ῡ Ὺ ὺ Ύ ύ Ῥ ῥ Ὸ ὸ Ό ό Ὼ ὼ Ώ ώ ῼ ῳ - \ No newline at end of file + diff --git a/testing/web-platform/tests/css/css-text/text-transform/text-transform-upperlower-018.html b/testing/web-platform/tests/css/css-text/text-transform/text-transform-upperlower-018.html index 0f4d314c4ebc..dcb1fac16aed 100644 --- a/testing/web-platform/tests/css/css-text/text-transform/text-transform-upperlower-018.html +++ b/testing/web-platform/tests/css/css-text/text-transform/text-transform-upperlower-018.html @@ -1,5 +1,5 @@ - + CSS3 Text, text transform: Cyrillic, uppercase @@ -26,7 +26,6 @@ а А б Б в В г Г д Д е Е ж Ж з З и И й Й к К л Л м М н Н о О п П р Р с С т Т у У ф Ф х Х ц Ц ч Ч ш Ш щ Щ ъ Ъ ы Ы ь Ь э Э ю Ю я Я ѐ Ѐ ё Ё ђ Ђ ѓ Ѓ є Є ѕ Ѕ і І ї Ї ј Ј љ Љ њ Њ ћ Ћ ќ Ќ ѝ Ѝ ў Ў џ Џ ѡ Ѡ ѣ Ѣ ѥ Ѥ ѧ Ѧ ѩ Ѩ ѫ Ѫ ѭ Ѭ ѯ Ѯ ѱ Ѱ ѳ Ѳ ѵ Ѵ ѷ Ѷ ѹ Ѹ ѻ Ѻ ѽ Ѽ ѿ Ѿ ҁ Ҁ ҋ Ҋ ҍ Ҍ ҏ Ҏ ґ Ґ ғ Ғ ҕ Ҕ җ Җ ҙ Ҙ қ Қ ҝ Ҝ ҟ Ҟ ҡ Ҡ ң Ң ҥ Ҥ ҧ Ҧ ҩ Ҩ ҫ Ҫ ҭ Ҭ ү Ү ұ Ұ ҳ Ҳ ҵ Ҵ ҷ Ҷ ҹ Ҹ һ Һ ҽ Ҽ ҿ Ҿ ӂ Ӂ ӄ Ӄ ӆ Ӆ ӈ Ӈ ӊ Ӊ ӌ Ӌ ӎ Ӎ ӏ Ӏ ӑ Ӑ ӓ Ӓ ӕ Ӕ ӗ Ӗ ә Ә ӛ Ӛ ӝ Ӝ ӟ Ӟ ӡ Ӡ ӣ Ӣ ӥ Ӥ ӧ Ӧ ө Ө ӫ Ӫ ӭ Ӭ ӯ Ӯ ӱ Ӱ ӳ Ӳ ӵ Ӵ ӷ Ӷ ӹ Ӹ ӻ Ӻ ӽ Ӽ ӿ Ӿ - \ No newline at end of file + diff --git a/testing/web-platform/tests/css/css-text/text-transform/text-transform-upperlower-019.html b/testing/web-platform/tests/css/css-text/text-transform/text-transform-upperlower-019.html index 683336e7702b..d43abbf18a84 100644 --- a/testing/web-platform/tests/css/css-text/text-transform/text-transform-upperlower-019.html +++ b/testing/web-platform/tests/css/css-text/text-transform/text-transform-upperlower-019.html @@ -1,5 +1,5 @@ - + CSS3 Text, text transform: Cyrillic, lowercase @@ -27,6 +27,5 @@ Ѐ ѐ Ё ё Ђ ђ Ѓ ѓ Є є Ѕ ѕ І і Ї ї Ј ј Љ љ Њ њ Ћ ћ Ќ ќ Ѝ ѝ Ў ў Џ џ А а Б б В в Г г Д д Е е Ж ж З з И и Й й К к Л л М м Н н О о П п Р р С с Т т У у Ф ф Х х Ц ц Ч ч Ш ш Щ щ Ъ ъ Ы ы Ь ь Э э Ю ю Я я Ѡ ѡ Ѣ ѣ Ѥ ѥ Ѧ ѧ Ѩ ѩ Ѫ ѫ Ѭ ѭ Ѯ ѯ Ѱ ѱ Ѳ ѳ Ѵ ѵ Ѷ ѷ Ѹ ѹ Ѻ ѻ Ѽ ѽ Ѿ ѿ Ҁ ҁ Ҋ ҋ Ҍ ҍ Ҏ ҏ Ґ ґ Ғ ғ Ҕ ҕ Җ җ Ҙ ҙ Қ қ Ҝ ҝ Ҟ ҟ Ҡ ҡ Ң ң Ҥ ҥ Ҧ ҧ Ҩ ҩ Ҫ ҫ Ҭ ҭ Ү ү Ұ ұ Ҳ ҳ Ҵ ҵ Ҷ ҷ Ҹ ҹ Һ һ Ҽ ҽ Ҿ ҿ Ӏ ӏ Ӂ ӂ Ӄ ӄ Ӆ ӆ Ӈ ӈ Ӊ ӊ Ӌ ӌ Ӎ ӎ Ӑ ӑ Ӓ ӓ Ӕ ӕ Ӗ ӗ Ә ә Ӛ ӛ Ӝ ӝ Ӟ ӟ Ӡ ӡ Ӣ ӣ Ӥ ӥ Ӧ ӧ Ө ө Ӫ ӫ Ӭ ӭ Ӯ ӯ Ӱ ӱ Ӳ ӳ Ӵ ӵ Ӷ ӷ Ӹ ӹ Ӻ ӻ Ӽ ӽ Ӿ ӿ - \ No newline at end of file + diff --git a/testing/web-platform/tests/css/css-text/text-transform/text-transform-upperlower-020.html b/testing/web-platform/tests/css/css-text/text-transform/text-transform-upperlower-020.html index 42b3906f617c..b97f25eaf997 100644 --- a/testing/web-platform/tests/css/css-text/text-transform/text-transform-upperlower-020.html +++ b/testing/web-platform/tests/css/css-text/text-transform/text-transform-upperlower-020.html @@ -1,5 +1,5 @@ - + CSS3 Text, text transform: Cyrillic Supplement, uppercase @@ -24,8 +24,5 @@ Test passes if both characters in each pair match. If you are missing a font glyph for a character, ignore that pair, but report which characters were ignored. ԁ Ԁ ԃ Ԃ ԅ Ԅ ԇ Ԇ ԉ Ԉ ԋ Ԋ ԍ Ԍ ԏ Ԏ ԑ Ԑ ԓ Ԓ ԕ Ԕ ԗ Ԗ ԙ Ԙ ԛ Ԛ ԝ Ԝ ԟ Ԟ ԡ Ԡ ԣ Ԣ ԥ Ԥ ԧ Ԧ ԩ Ԩ ԫ Ԫ ԭ Ԭ ԯ Ԯ - - \ No newline at end of file + diff --git a/testing/web-platform/tests/css/css-text/text-transform/text-transform-upperlower-021.html b/testing/web-platform/tests/css/css-text/text-transform/text-transform-upperlower-021.html index 4a4718f190a9..fdb3c3d43985 100644 --- a/testing/web-platform/tests/css/css-text/text-transform/text-transform-upperlower-021.html +++ b/testing/web-platform/tests/css/css-text/text-transform/text-transform-upperlower-021.html @@ -1,5 +1,5 @@ - + CSS3 Text, text transform: Cyrillic Extended, lowercase @@ -24,8 +24,5 @@ Test passes if both characters in each pair match. If you are missing a font glyph for a character, ignore that pair, but report which characters were ignored. Ԁ ԁ Ԃ ԃ Ԅ ԅ Ԇ ԇ Ԉ ԉ Ԋ ԋ Ԍ ԍ Ԏ ԏ Ԑ ԑ Ԓ ԓ Ԕ ԕ Ԗ ԗ Ԙ ԙ Ԛ ԛ Ԝ ԝ Ԟ ԟ Ԡ ԡ Ԣ ԣ Ԥ ԥ Ԧ ԧ Ԩ ԩ Ԫ ԫ Ԭ ԭ Ԯ ԯ - - \ No newline at end of file + diff --git a/testing/web-platform/tests/css/css-text/text-transform/text-transform-upperlower-022.html b/testing/web-platform/tests/css/css-text/text-transform/text-transform-upperlower-022.html index 2f89f31cd3fb..cb06c4bd4d59 100644 --- a/testing/web-platform/tests/css/css-text/text-transform/text-transform-upperlower-022.html +++ b/testing/web-platform/tests/css/css-text/text-transform/text-transform-upperlower-022.html @@ -1,5 +1,5 @@ - + CSS3 Text, text transform: Armenian, uppercase @@ -25,7 +25,6 @@ ա Ա բ Բ գ Գ դ Դ ե Ե զ Զ է Է ը Ը թ Թ ժ Ժ ի Ի լ Լ խ Խ ծ Ծ կ Կ հ Հ ձ Ձ ղ Ղ ճ Ճ մ Մ յ Յ ն Ն շ Շ ո Ո չ Չ պ Պ ջ Ջ ռ Ռ ս Ս վ Վ տ Տ ր Ր ց Ց ւ Ւ փ Փ ք Ք օ Օ ֆ Ֆ diff --git a/testing/web-platform/tests/css/css-text/text-transform/text-transform-upperlower-023.html b/testing/web-platform/tests/css/css-text/text-transform/text-transform-upperlower-023.html index e92ca8273213..9b1af86b7e67 100644 --- a/testing/web-platform/tests/css/css-text/text-transform/text-transform-upperlower-023.html +++ b/testing/web-platform/tests/css/css-text/text-transform/text-transform-upperlower-023.html @@ -1,5 +1,5 @@ - + CSS3 Text, text transform: Latin Extended-D, lowercase @@ -25,6 +25,5 @@ Ա ա Բ բ Գ գ Դ դ Ե ե Զ զ Է է Ը ը Թ թ Ժ ժ Ի ի Լ լ Խ խ Ծ ծ Կ կ Հ հ Ձ ձ Ղ ղ Ճ ճ Մ մ Յ յ Ն ն Շ շ Ո ո Չ չ Պ պ Ջ ջ Ռ ռ Ս ս Վ վ Տ տ Ր ր Ց ց Ւ ւ Փ փ Ք ք Օ օ Ֆ ֆ diff --git a/testing/web-platform/tests/css/css-text/text-transform/text-transform-upperlower-024.html b/testing/web-platform/tests/css/css-text/text-transform/text-transform-upperlower-024.html index ec3312b6fd6d..a8fe5f4af040 100644 --- a/testing/web-platform/tests/css/css-text/text-transform/text-transform-upperlower-024.html +++ b/testing/web-platform/tests/css/css-text/text-transform/text-transform-upperlower-024.html @@ -1,5 +1,5 @@ - + CSS3 Text, text transform: Number Forms, uppercase @@ -25,7 +25,6 @@ ⅰ Ⅰ ⅱ Ⅱ ⅲ Ⅲ ⅳ Ⅳ ⅴ Ⅴ ⅵ Ⅵ ⅶ Ⅶ ⅷ Ⅷ ⅸ Ⅸ ⅹ Ⅹ ⅺ Ⅺ ⅻ Ⅻ ⅼ Ⅼ ⅽ Ⅽ ⅾ Ⅾ ⅿ Ⅿ ↄ Ↄ diff --git a/testing/web-platform/tests/css/css-text/text-transform/text-transform-upperlower-025.html b/testing/web-platform/tests/css/css-text/text-transform/text-transform-upperlower-025.html index 4974553eb282..0e9ec6604c35 100644 --- a/testing/web-platform/tests/css/css-text/text-transform/text-transform-upperlower-025.html +++ b/testing/web-platform/tests/css/css-text/text-transform/text-transform-upperlower-025.html @@ -1,5 +1,5 @@ - + CSS3 Text, text transform: Number Forms, lowercase @@ -25,6 +25,5 @@ Ⅰ ⅰ Ⅱ ⅱ Ⅲ ⅲ Ⅳ ⅳ Ⅴ ⅴ Ⅵ ⅵ Ⅶ ⅶ Ⅷ ⅷ Ⅸ ⅸ Ⅹ ⅹ Ⅺ ⅺ Ⅻ ⅻ Ⅼ ⅼ Ⅽ ⅽ Ⅾ ⅾ Ⅿ ⅿ Ↄ ↄ diff --git a/testing/web-platform/tests/css/css-text/text-transform/text-transform-upperlower-026.html b/testing/web-platform/tests/css/css-text/text-transform/text-transform-upperlower-026.html index b44d8925353c..f7beb60f044a 100644 --- a/testing/web-platform/tests/css/css-text/text-transform/text-transform-upperlower-026.html +++ b/testing/web-platform/tests/css/css-text/text-transform/text-transform-upperlower-026.html @@ -1,5 +1,5 @@ - + CSS3 Text, text transform: Enclosed Alphanumerics, uppercase @@ -25,7 +25,6 @@ ⓐ Ⓐ ⓑ Ⓑ ⓒ Ⓒ ⓓ Ⓓ ⓔ Ⓔ ⓕ Ⓕ ⓖ Ⓖ ⓗ Ⓗ ⓘ Ⓘ ⓙ Ⓙ ⓚ Ⓚ ⓛ Ⓛ ⓜ Ⓜ ⓝ Ⓝ ⓞ Ⓞ ⓟ Ⓟ ⓠ Ⓠ ⓡ Ⓡ ⓢ Ⓢ ⓣ Ⓣ ⓤ Ⓤ ⓥ Ⓥ ⓦ Ⓦ ⓧ Ⓧ ⓨ Ⓨ ⓩ Ⓩ diff --git a/testing/web-platform/tests/css/css-text/text-transform/text-transform-upperlower-027.html b/testing/web-platform/tests/css/css-text/text-transform/text-transform-upperlower-027.html index 0e48060071c1..8bc19ee51616 100644 --- a/testing/web-platform/tests/css/css-text/text-transform/text-transform-upperlower-027.html +++ b/testing/web-platform/tests/css/css-text/text-transform/text-transform-upperlower-027.html @@ -1,5 +1,5 @@ - + CSS3 Text, text transform: Enclosed Alphanumerics, lowercase @@ -25,6 +25,5 @@ Ⓐ ⓐ Ⓑ ⓑ Ⓒ ⓒ Ⓓ ⓓ Ⓔ ⓔ Ⓕ ⓕ Ⓖ ⓖ Ⓗ ⓗ Ⓘ ⓘ Ⓙ ⓙ Ⓚ ⓚ Ⓛ ⓛ Ⓜ ⓜ Ⓝ ⓝ Ⓞ ⓞ Ⓟ ⓟ Ⓠ ⓠ Ⓡ ⓡ Ⓢ ⓢ Ⓣ ⓣ Ⓤ ⓤ Ⓥ ⓥ Ⓦ ⓦ Ⓧ ⓧ Ⓨ ⓨ Ⓩ ⓩ diff --git a/testing/web-platform/tests/css/css-text/text-transform/text-transform-upperlower-028.html b/testing/web-platform/tests/css/css-text/text-transform/text-transform-upperlower-028.html index 0e85b79c7c2a..b3011f535272 100644 --- a/testing/web-platform/tests/css/css-text/text-transform/text-transform-upperlower-028.html +++ b/testing/web-platform/tests/css/css-text/text-transform/text-transform-upperlower-028.html @@ -1,5 +1,5 @@ - + CSS3 Text, text transform: Deseret, uppercase @@ -23,8 +23,5 @@ Test passes if both characters in each pair match. If you are missing a font glyph for a character, ignore that pair, but report which characters were ignored. 𐐨 𐐀 𐐩 𐐁 𐐪 𐐂 𐐫 𐐃 𐐬 𐐄 𐐭 𐐅 𐐮 𐐆 𐐯 𐐇 𐐰 𐐈 𐐱 𐐉 𐐲 𐐊 𐐳 𐐋 𐐴 𐐌 𐐵 𐐍 𐐶 𐐎 𐐷 𐐏 𐐸 𐐐 𐐹 𐐑 𐐺 𐐒 𐐻 𐐓 𐐼 𐐔 𐐽 𐐕 𐐾 𐐖 𐐿 𐐗 𐑀 𐐘 𐑁 𐐙 𐑂 𐐚 𐑃 𐐛 𐑄 𐐜 𐑅 𐐝 𐑆 𐐞 𐑇 𐐟 𐑈 𐐠 𐑉 𐐡 𐑊 𐐢 𐑋 𐐣 𐑌 𐐤 𐑍 𐐥 𐑎 𐐦 𐑏 𐐧 - diff --git a/testing/web-platform/tests/css/css-text/text-transform/text-transform-upperlower-029.html b/testing/web-platform/tests/css/css-text/text-transform/text-transform-upperlower-029.html index eb56f45b6d14..504b64caa99f 100644 --- a/testing/web-platform/tests/css/css-text/text-transform/text-transform-upperlower-029.html +++ b/testing/web-platform/tests/css/css-text/text-transform/text-transform-upperlower-029.html @@ -1,5 +1,5 @@ - + CSS3 Text, text transform: Deseret, lowercase @@ -23,7 +23,4 @@ Test passes if both characters in each pair match. If you are missing a font glyph for a character, ignore that pair, but report which characters were ignored. 𐐀 𐐨 𐐁 𐐩 𐐂 𐐪 𐐃 𐐫 𐐄 𐐬 𐐅 𐐭 𐐆 𐐮 𐐇 𐐯 𐐈 𐐰 𐐉 𐐱 𐐊 𐐲 𐐋 𐐳 𐐌 𐐴 𐐍 𐐵 𐐎 𐐶 𐐏 𐐷 𐐐 𐐸 𐐑 𐐹 𐐒 𐐺 𐐓 𐐻 𐐔 𐐼 𐐕 𐐽 𐐖 𐐾 𐐗 𐐿 𐐘 𐑀 𐐙 𐑁 𐐚 𐑂 𐐛 𐑃 𐐜 𐑄 𐐝 𐑅 𐐞 𐑆 𐐟 𐑇 𐐠 𐑈 𐐡 𐑉 𐐢 𐑊 𐐣 𐑋 𐐤 𐑌 𐐥 𐑍 𐐦 𐑎 𐐧 𐑏 - diff --git a/testing/web-platform/tests/css/css-text/text-transform/text-transform-upperlower-030.html b/testing/web-platform/tests/css/css-text/text-transform/text-transform-upperlower-030.html index 554aa9e7427a..745228e110c2 100644 --- a/testing/web-platform/tests/css/css-text/text-transform/text-transform-upperlower-030.html +++ b/testing/web-platform/tests/css/css-text/text-transform/text-transform-upperlower-030.html @@ -1,5 +1,5 @@ - + CSS3 Text, text transform: Georgian Supplement, uppercase @@ -23,8 +23,5 @@ Test passes if both characters in each pair match. If you are missing a font glyph for a character, ignore that pair, but report which characters were ignored. ⴀ Ⴀ ⴁ Ⴁ ⴂ Ⴂ ⴃ Ⴃ ⴄ Ⴄ ⴅ Ⴅ ⴆ Ⴆ ⴇ Ⴇ ⴈ Ⴈ ⴉ Ⴉ ⴊ Ⴊ ⴋ Ⴋ ⴌ Ⴌ ⴍ Ⴍ ⴎ Ⴎ ⴏ Ⴏ ⴐ Ⴐ ⴑ Ⴑ ⴒ Ⴒ ⴓ Ⴓ ⴔ Ⴔ ⴕ Ⴕ ⴖ Ⴖ ⴗ Ⴗ ⴘ Ⴘ ⴙ Ⴙ ⴚ Ⴚ ⴛ Ⴛ ⴜ Ⴜ ⴝ Ⴝ ⴞ Ⴞ ⴟ Ⴟ ⴠ Ⴠ ⴡ Ⴡ ⴢ Ⴢ ⴣ Ⴣ ⴤ Ⴤ ⴥ Ⴥ ⴧ Ⴧ ⴭ Ⴭ - diff --git a/testing/web-platform/tests/css/css-text/text-transform/text-transform-upperlower-031.html b/testing/web-platform/tests/css/css-text/text-transform/text-transform-upperlower-031.html index 0393ae5c7898..ace5e329e9e3 100644 --- a/testing/web-platform/tests/css/css-text/text-transform/text-transform-upperlower-031.html +++ b/testing/web-platform/tests/css/css-text/text-transform/text-transform-upperlower-031.html @@ -1,5 +1,5 @@ - + CSS3 Text, text transform: Georgian, lowercase @@ -25,6 +25,5 @@ Ⴀ ⴀ Ⴁ ⴁ Ⴂ ⴂ Ⴃ ⴃ Ⴄ ⴄ Ⴅ ⴅ Ⴆ ⴆ Ⴇ ⴇ Ⴈ ⴈ Ⴉ ⴉ Ⴊ ⴊ Ⴋ ⴋ Ⴌ ⴌ Ⴍ ⴍ Ⴎ ⴎ Ⴏ ⴏ Ⴐ ⴐ Ⴑ ⴑ Ⴒ ⴒ Ⴓ ⴓ Ⴔ ⴔ Ⴕ ⴕ Ⴖ ⴖ Ⴗ ⴗ Ⴘ ⴘ Ⴙ ⴙ Ⴚ ⴚ Ⴛ ⴛ Ⴜ ⴜ Ⴝ ⴝ Ⴞ ⴞ Ⴟ ⴟ Ⴠ ⴠ Ⴡ ⴡ Ⴢ ⴢ Ⴣ ⴣ Ⴤ ⴤ Ⴥ ⴥ Ⴧ ⴧ Ⴭ ⴭ diff --git a/testing/web-platform/tests/css/css-text/text-transform/text-transform-upperlower-032.html b/testing/web-platform/tests/css/css-text/text-transform/text-transform-upperlower-032.html index feb92a81089b..37130efe7b4d 100644 --- a/testing/web-platform/tests/css/css-text/text-transform/text-transform-upperlower-032.html +++ b/testing/web-platform/tests/css/css-text/text-transform/text-transform-upperlower-032.html @@ -1,5 +1,5 @@ - + CSS3 Text, text transform: German sharp S, uppercase diff --git a/testing/web-platform/tests/css/css-text/text-transform/text-transform-upperlower-033.html b/testing/web-platform/tests/css/css-text/text-transform/text-transform-upperlower-033.html index 6cd59895e510..9525db2e1f2c 100644 --- a/testing/web-platform/tests/css/css-text/text-transform/text-transform-upperlower-033.html +++ b/testing/web-platform/tests/css/css-text/text-transform/text-transform-upperlower-033.html @@ -1,5 +1,5 @@ - + CSS3 Text, text transform: Latin ligatures, uppercase diff --git a/testing/web-platform/tests/css/css-text/text-transform/text-transform-upperlower-034.html b/testing/web-platform/tests/css/css-text/text-transform/text-transform-upperlower-034.html index 2fa234e65c9e..5751ad5a16dc 100644 --- a/testing/web-platform/tests/css/css-text/text-transform/text-transform-upperlower-034.html +++ b/testing/web-platform/tests/css/css-text/text-transform/text-transform-upperlower-034.html @@ -1,5 +1,5 @@ - + CSS3 Text, text transform: Armenian ligatures, uppercase diff --git a/testing/web-platform/tests/css/css-text/text-transform/text-transform-upperlower-035.html b/testing/web-platform/tests/css/css-text/text-transform/text-transform-upperlower-035.html index cc5e984b8b60..0b3398c7c1fe 100644 --- a/testing/web-platform/tests/css/css-text/text-transform/text-transform-upperlower-035.html +++ b/testing/web-platform/tests/css/css-text/text-transform/text-transform-upperlower-035.html @@ -1,5 +1,5 @@ - + CSS3 Text, text transform: Greek specials, uppercase diff --git a/testing/web-platform/tests/css/css-text/text-transform/text-transform-upperlower-038.html b/testing/web-platform/tests/css/css-text/text-transform/text-transform-upperlower-038.html index 462ed6a88fa9..0fd7486adb61 100644 --- a/testing/web-platform/tests/css/css-text/text-transform/text-transform-upperlower-038.html +++ b/testing/web-platform/tests/css/css-text/text-transform/text-transform-upperlower-038.html @@ -1,5 +1,5 @@ - + CSS3 Text, text transform: Greek final sigma, lowercase diff --git a/testing/web-platform/tests/css/css-text/text-transform/text-transform-upperlower-039.html b/testing/web-platform/tests/css/css-text/text-transform/text-transform-upperlower-039.html index d15c225d653f..40f36e0be3cd 100644 --- a/testing/web-platform/tests/css/css-text/text-transform/text-transform-upperlower-039.html +++ b/testing/web-platform/tests/css/css-text/text-transform/text-transform-upperlower-039.html @@ -1,5 +1,5 @@ - + CSS3 Text, text transform: Lithuanian, lowercase diff --git a/testing/web-platform/tests/css/css-text/text-transform/text-transform-upperlower-040.html b/testing/web-platform/tests/css/css-text/text-transform/text-transform-upperlower-040.html index b430764c5785..0528c78f9d9f 100644 --- a/testing/web-platform/tests/css/css-text/text-transform/text-transform-upperlower-040.html +++ b/testing/web-platform/tests/css/css-text/text-transform/text-transform-upperlower-040.html @@ -1,5 +1,5 @@ - + CSS3 Text, text transform: Turkish, uppercase diff --git a/testing/web-platform/tests/css/css-text/text-transform/text-transform-upperlower-041.html b/testing/web-platform/tests/css/css-text/text-transform/text-transform-upperlower-041.html index dc2495086c33..30708b64ff98 100644 --- a/testing/web-platform/tests/css/css-text/text-transform/text-transform-upperlower-041.html +++ b/testing/web-platform/tests/css/css-text/text-transform/text-transform-upperlower-041.html @@ -1,5 +1,5 @@ - + CSS3 Text, text transform: Turkish, lowercase diff --git a/testing/web-platform/tests/css/css-text/text-transform/text-transform-upperlower-042.html b/testing/web-platform/tests/css/css-text/text-transform/text-transform-upperlower-042.html index d4d9225cd88f..ffe602f59454 100644 --- a/testing/web-platform/tests/css/css-text/text-transform/text-transform-upperlower-042.html +++ b/testing/web-platform/tests/css/css-text/text-transform/text-transform-upperlower-042.html @@ -1,5 +1,5 @@ - + CSS3 Text, text transform: Azeri, uppercase diff --git a/testing/web-platform/tests/css/css-text/text-transform/text-transform-upperlower-043.html b/testing/web-platform/tests/css/css-text/text-transform/text-transform-upperlower-043.html index 5f5d32518378..d56f6b3ee3bf 100644 --- a/testing/web-platform/tests/css/css-text/text-transform/text-transform-upperlower-043.html +++ b/testing/web-platform/tests/css/css-text/text-transform/text-transform-upperlower-043.html @@ -1,5 +1,5 @@ - + CSS3 Text, text transform: Azeri, lowercase diff --git a/testing/web-platform/tests/css/css-text/text-transform/text-transform-upperlower-101.html b/testing/web-platform/tests/css/css-text/text-transform/text-transform-upperlower-101.html index 46b48a920e1e..e4f2ca7d9f51 100644 --- a/testing/web-platform/tests/css/css-text/text-transform/text-transform-upperlower-101.html +++ b/testing/web-platform/tests/css/css-text/text-transform/text-transform-upperlower-101.html @@ -1,5 +1,5 @@ - + CSS3 Text, text transform: Latin Extended-D, uppercase @@ -25,7 +25,6 @@ ꜣ Ꜣ ꜥ Ꜥ ꜧ Ꜧ ꜩ Ꜩ ꜫ Ꜫ ꜭ Ꜭ ꜯ Ꜯ ꜳ Ꜳ ꜵ Ꜵ ꜷ Ꜷ ꜹ Ꜹ ꜻ Ꜻ ꜽ Ꜽ ꜿ Ꜿ ꝁ Ꝁ ꝃ Ꝃ ꝅ Ꝅ ꝇ Ꝇ ꝉ Ꝉ ꝋ Ꝋ ꝍ Ꝍ ꝏ Ꝏ ꝑ Ꝑ ꝓ Ꝓ ꝕ Ꝕ ꝗ Ꝗ ꝙ Ꝙ ꝛ Ꝛ ꝝ Ꝝ ꝟ Ꝟ ꝡ Ꝡ ꝣ Ꝣ ꝥ Ꝥ ꝧ Ꝧ ꝩ Ꝩ ꝫ Ꝫ ꝭ Ꝭ ꝯ Ꝯ ꝺ Ꝺ ꝼ Ꝼ ꝿ Ꝿ ꞁ Ꞁ ꞃ Ꞃ ꞅ Ꞅ ꞇ Ꞇ ꞌ Ꞌ ꞑ Ꞑ ꞓ Ꞓ ꞗ Ꞗ ꞙ Ꞙ ꞛ Ꞛ ꞝ Ꞝ ꞟ Ꞟ ꞡ Ꞡ ꞣ Ꞣ ꞥ Ꞥ ꞧ Ꞧ ꞩ Ꞩ - \ No newline at end of file + diff --git a/testing/web-platform/tests/css/css-text/text-transform/text-transform-upperlower-102.html b/testing/web-platform/tests/css/css-text/text-transform/text-transform-upperlower-102.html index d36bc364a20d..2eae842e2a84 100644 --- a/testing/web-platform/tests/css/css-text/text-transform/text-transform-upperlower-102.html +++ b/testing/web-platform/tests/css/css-text/text-transform/text-transform-upperlower-102.html @@ -1,5 +1,5 @@ - + CSS3 Text, text transform: Latin Extended-D, lowercase @@ -25,6 +25,5 @@ Ꜣ ꜣ Ꜥ ꜥ Ꜧ ꜧ Ꜩ ꜩ Ꜫ ꜫ Ꜭ ꜭ Ꜯ ꜯ Ꜳ ꜳ Ꜵ ꜵ Ꜷ ꜷ Ꜹ ꜹ Ꜻ ꜻ Ꜽ ꜽ Ꜿ ꜿ Ꝁ ꝁ Ꝃ ꝃ Ꝅ ꝅ Ꝇ ꝇ Ꝉ ꝉ Ꝋ ꝋ Ꝍ ꝍ Ꝏ ꝏ Ꝑ ꝑ Ꝓ ꝓ Ꝕ ꝕ Ꝗ ꝗ Ꝙ ꝙ Ꝛ ꝛ Ꝝ ꝝ Ꝟ ꝟ Ꝡ ꝡ Ꝣ ꝣ Ꝥ ꝥ Ꝧ ꝧ Ꝩ ꝩ Ꝫ ꝫ Ꝭ ꝭ Ꝯ ꝯ Ꝺ ꝺ Ꝼ ꝼ Ᵹ ᵹ Ꝿ ꝿ Ꞁ ꞁ Ꞃ ꞃ Ꞅ ꞅ Ꞇ ꞇ Ꞌ ꞌ Ɥ ɥ Ꞑ ꞑ Ꞓ ꞓ Ꞗ ꞗ Ꞙ ꞙ Ꞛ ꞛ Ꞝ ꞝ Ꞟ ꞟ Ꞡ ꞡ Ꞣ ꞣ Ꞥ ꞥ Ꞧ ꞧ Ꞩ ꞩ Ɦ ɦ Ɜ ɜ Ɡ ɡ Ɬ ɬ Ʞ ʞ Ʇ ʇ diff --git a/testing/web-platform/tests/css/css-text/text-transform/text-transform-upperlower-103.html b/testing/web-platform/tests/css/css-text/text-transform/text-transform-upperlower-103.html index ba669c022ea8..07ceb60c3d8f 100644 --- a/testing/web-platform/tests/css/css-text/text-transform/text-transform-upperlower-103.html +++ b/testing/web-platform/tests/css/css-text/text-transform/text-transform-upperlower-103.html @@ -1,5 +1,5 @@ - + CSS3 Text, text transform: Cyrillic Extended-B, uppercase @@ -26,7 +26,6 @@ ꙁ Ꙁ ꙃ Ꙃ ꙅ Ꙅ ꙇ Ꙇ ꙉ Ꙉ ꙋ Ꙋ ꙍ Ꙍ ꙏ Ꙏ ꙑ Ꙑ ꙓ Ꙓ ꙕ Ꙕ ꙗ Ꙗ ꙙ Ꙙ ꙛ Ꙛ ꙝ Ꙝ ꙟ Ꙟ ꙡ Ꙡ ꙣ Ꙣ ꙥ Ꙥ ꙧ Ꙧ ꙩ Ꙩ ꙫ Ꙫ ꙭ Ꙭ ꚁ Ꚁ ꚃ Ꚃ ꚅ Ꚅ ꚇ Ꚇ ꚉ Ꚉ ꚋ Ꚋ ꚍ Ꚍ ꚏ Ꚏ ꚑ Ꚑ ꚓ Ꚓ ꚕ Ꚕ ꚗ Ꚗ ꚙ Ꚙ ꚛ Ꚛ diff --git a/testing/web-platform/tests/css/css-text/text-transform/text-transform-upperlower-104.html b/testing/web-platform/tests/css/css-text/text-transform/text-transform-upperlower-104.html index 9d5c26939afc..9d6b2c2bc7d0 100644 --- a/testing/web-platform/tests/css/css-text/text-transform/text-transform-upperlower-104.html +++ b/testing/web-platform/tests/css/css-text/text-transform/text-transform-upperlower-104.html @@ -1,5 +1,5 @@ - + CSS3 Text, text transform: Cyrillic Extended-B, lowercase @@ -26,6 +26,5 @@ Ꙁ ꙁ Ꙃ ꙃ Ꙅ ꙅ Ꙇ ꙇ Ꙉ ꙉ Ꙋ ꙋ Ꙍ ꙍ Ꙏ ꙏ Ꙑ ꙑ Ꙓ ꙓ Ꙕ ꙕ Ꙗ ꙗ Ꙙ ꙙ Ꙛ ꙛ Ꙝ ꙝ Ꙟ ꙟ Ꙡ ꙡ Ꙣ ꙣ Ꙥ ꙥ Ꙧ ꙧ Ꙩ ꙩ Ꙫ ꙫ Ꙭ ꙭ Ꚁ ꚁ Ꚃ ꚃ Ꚅ ꚅ Ꚇ ꚇ Ꚉ ꚉ Ꚋ ꚋ Ꚍ ꚍ Ꚏ ꚏ Ꚑ ꚑ Ꚓ ꚓ Ꚕ ꚕ Ꚗ ꚗ Ꚙ ꚙ Ꚛ ꚛ diff --git a/testing/web-platform/tests/feature-policy/experimental-features/lazyload/lazyload-disabled-image-tentative.sub.html b/testing/web-platform/tests/feature-policy/experimental-features/lazyload/lazyload-disabled-image-tentative.sub.html new file mode 100644 index 000000000000..0d46d2f26625 --- /dev/null +++ b/testing/web-platform/tests/feature-policy/experimental-features/lazyload/lazyload-disabled-image-tentative.sub.html @@ -0,0 +1,61 @@ + + +Verify behavior of 'lazyload' attribute state 'OFF' when the feature policy 'lazyload' is + disabled. + + + + + + + + Image inserted further below. + + + + + + \ No newline at end of file diff --git a/testing/web-platform/tests/feature-policy/experimental-features/lazyload/lazyload-disabled-image-tentative.sub.html.headers b/testing/web-platform/tests/feature-policy/experimental-features/lazyload/lazyload-disabled-image-tentative.sub.html.headers new file mode 100644 index 000000000000..7974815fc9cc --- /dev/null +++ b/testing/web-platform/tests/feature-policy/experimental-features/lazyload/lazyload-disabled-image-tentative.sub.html.headers @@ -0,0 +1,2 @@ +Feature-Policy: lazyload 'none' +Cache-Control: no-cache, no-store, max-age=0 diff --git a/testing/web-platform/tests/feature-policy/experimental-features/lazyload/lazyload-enabled-image-tentative.sub.html b/testing/web-platform/tests/feature-policy/experimental-features/lazyload/lazyload-enabled-image-tentative.sub.html new file mode 100644 index 000000000000..2dc6a6cc70d3 --- /dev/null +++ b/testing/web-platform/tests/feature-policy/experimental-features/lazyload/lazyload-enabled-image-tentative.sub.html @@ -0,0 +1,45 @@ + + +Verify behavior of 'lazyload' attribute state 'OFF' when the feature policy 'lazyload' is + enabled. + + + + + + + Image inserted further below. + + + + + \ No newline at end of file diff --git a/testing/web-platform/tests/feature-policy/experimental-features/lazyload/lazyload-image-attribute-on-sanity-check-tentative.sub.html b/testing/web-platform/tests/feature-policy/experimental-features/lazyload/lazyload-image-attribute-on-sanity-check-tentative.sub.html new file mode 100644 index 000000000000..6111e691c82b --- /dev/null +++ b/testing/web-platform/tests/feature-policy/experimental-features/lazyload/lazyload-image-attribute-on-sanity-check-tentative.sub.html @@ -0,0 +1,48 @@ + + +Verify behavior of 'lazyload' attribute state 'ON' (sanity-check for lazyload policy tests). + + + + + + + Image inserted further below. + + + + + \ No newline at end of file diff --git a/testing/web-platform/tests/feature-policy/experimental-features/resources/common.js b/testing/web-platform/tests/feature-policy/experimental-features/resources/common.js index 10c28be7741b..64cfca59d6c8 100644 --- a/testing/web-platform/tests/feature-policy/experimental-features/resources/common.js +++ b/testing/web-platform/tests/feature-policy/experimental-features/resources/common.js @@ -58,3 +58,10 @@ function createIframe(container, attributes) { container.appendChild(new_iframe); return new_iframe; } + +// Returns a promise which is resolved when |load| event is dispatched for |e|. +function wait_for_load(e) { + return new Promise((resolve) => { + e.addEventListener("load", resolve); + }); +} \ No newline at end of file diff --git a/testing/web-platform/tests/feature-policy/experimental-features/resources/lazyload.png b/testing/web-platform/tests/feature-policy/experimental-features/resources/lazyload.png new file mode 100644 index 000000000000..fd3da53a29c3 Binary files /dev/null and b/testing/web-platform/tests/feature-policy/experimental-features/resources/lazyload.png differ diff --git a/testing/web-platform/tests/feature-policy/picture-in-picture-allowed-by-feature-policy-attribute-redirect-on-load.https.sub.html b/testing/web-platform/tests/feature-policy/picture-in-picture-allowed-by-feature-policy-attribute-redirect-on-load.https.sub.html index e2b52f257a12..a5ea5139a937 100644 --- a/testing/web-platform/tests/feature-policy/picture-in-picture-allowed-by-feature-policy-attribute-redirect-on-load.https.sub.html +++ b/testing/web-platform/tests/feature-policy/picture-in-picture-allowed-by-feature-policy-attribute-redirect-on-load.https.sub.html @@ -16,13 +16,13 @@ relative_path; const header = 'Feature-Policy allow="picture-in-picture"'; - async_test(t => { + async_pip_test(t => { test_feature_availability( 'picture-in-picture', t, same_origin_src, expect_feature_available_default, 'picture-in-picture'); }, header + ' allows same-origin navigation in an iframe.'); - async_test(t => { + async_pip_test(t => { test_feature_availability( 'picture-in-picture', t, cross_origin_src, expect_feature_unavailable_default, 'picture-in-picture'); diff --git a/testing/web-platform/tests/feature-policy/picture-in-picture-allowed-by-feature-policy-attribute.https.sub.html b/testing/web-platform/tests/feature-policy/picture-in-picture-allowed-by-feature-policy-attribute.https.sub.html index 0c3897a4ad0f..b0e160e938d3 100644 --- a/testing/web-platform/tests/feature-policy/picture-in-picture-allowed-by-feature-policy-attribute.https.sub.html +++ b/testing/web-platform/tests/feature-policy/picture-in-picture-allowed-by-feature-policy-attribute.https.sub.html @@ -15,13 +15,13 @@ const feature_name = 'Feature policy "picture-in-picture"'; const header = 'allow="picture-in-picture" attribute'; - async_test(t => { + async_pip_test(t => { test_feature_availability( 'picture-in-picture', t, same_origin_src, expect_feature_available_default, 'picture-in-picture'); }, feature_name + ' can be enabled in same-origin iframe using ' + header); - async_test(t => { + async_pip_test(t => { test_feature_availability( 'picture-in-picture', t, cross_origin_src, expect_feature_available_default, 'picture-in-picture'); diff --git a/testing/web-platform/tests/feature-policy/picture-in-picture-allowed-by-feature-policy.https.sub.html b/testing/web-platform/tests/feature-policy/picture-in-picture-allowed-by-feature-policy.https.sub.html index 1ecd874c009a..b09335a6de38 100644 --- a/testing/web-platform/tests/feature-policy/picture-in-picture-allowed-by-feature-policy.https.sub.html +++ b/testing/web-platform/tests/feature-policy/picture-in-picture-allowed-by-feature-policy.https.sub.html @@ -14,18 +14,18 @@ same_origin_src; const header = 'Feature-Policy header: picture-in-picture *'; - async_test(t => { + async_pip_test(t => { isPictureInPictureAllowed().then(t.step_func_done((result) => { assert_true(result); })); }, header + ' allows the top-level document.'); - async_test(t => { + async_pip_test(t => { test_feature_availability('picture-in-picture', t, same_origin_src, expect_feature_available_default); }, header + ' allows same-origin iframes.'); - async_test(t => { + async_pip_test(t => { test_feature_availability('picture-in-picture', t, cross_origin_src, expect_feature_available_default); }, header + ' allows cross-origin iframes.'); diff --git a/testing/web-platform/tests/feature-policy/picture-in-picture-default-feature-policy.https.sub.html b/testing/web-platform/tests/feature-policy/picture-in-picture-default-feature-policy.https.sub.html index 12bbf7f2f1f8..477cf7ba51db 100644 --- a/testing/web-platform/tests/feature-policy/picture-in-picture-default-feature-policy.https.sub.html +++ b/testing/web-platform/tests/feature-policy/picture-in-picture-default-feature-policy.https.sub.html @@ -14,18 +14,18 @@ same_origin_src; const header = 'Default "picture-in-picture" feature policy [*]'; - async_test(t => { + async_pip_test(t => { isPictureInPictureAllowed().then(t.step_func_done((result) => { assert_true(result); })); }, header + ' allows the top-level document.'); - async_test(t => { + async_pip_test(t => { test_feature_availability('picture-in-picture', t, same_origin_src, expect_feature_available_default); }, header + ' allows same-origin iframes.'); - async_test(t => { + async_pip_test(t => { test_feature_availability('picture-in-picture', t, cross_origin_src, expect_feature_available_default); }, header + ' allows cross-origin iframes.'); diff --git a/testing/web-platform/tests/feature-policy/picture-in-picture-disabled-by-feature-policy.https.sub.html b/testing/web-platform/tests/feature-policy/picture-in-picture-disabled-by-feature-policy.https.sub.html index b36afbda503f..513d04c2fa91 100644 --- a/testing/web-platform/tests/feature-policy/picture-in-picture-disabled-by-feature-policy.https.sub.html +++ b/testing/web-platform/tests/feature-policy/picture-in-picture-disabled-by-feature-policy.https.sub.html @@ -14,18 +14,18 @@ same_origin_src; const header = 'Feature-Policy header: picture-in-picture "none"'; - async_test(t => { + async_pip_test(t => { isPictureInPictureAllowed().then(t.step_func_done((result) => { assert_false(result); })); }, header + ' disallows the top-level document.'); - async_test(t => { + async_pip_test(t => { test_feature_availability('picture-in-picture', t, same_origin_src, expect_feature_unavailable_default); }, header + ' disallows same-origin iframes.'); - async_test(t => { + async_pip_test(t => { test_feature_availability('picture-in-picture', t, cross_origin_src, expect_feature_unavailable_default); }, header + ' disallows cross-origin iframes.'); diff --git a/testing/web-platform/tests/feature-policy/reporting/generic-sensor-reporting.https.html b/testing/web-platform/tests/feature-policy/reporting/generic-sensor-reporting.https.html new file mode 100644 index 000000000000..c60e3e81a1dd --- /dev/null +++ b/testing/web-platform/tests/feature-policy/reporting/generic-sensor-reporting.https.html @@ -0,0 +1,55 @@ + + + + + + + + + + diff --git a/testing/web-platform/tests/feature-policy/reporting/generic-sensor-reporting.https.html.headers b/testing/web-platform/tests/feature-policy/reporting/generic-sensor-reporting.https.html.headers new file mode 100644 index 000000000000..80cc02753044 --- /dev/null +++ b/testing/web-platform/tests/feature-policy/reporting/generic-sensor-reporting.https.html.headers @@ -0,0 +1 @@ +Feature-Policy: ambient-light-sensor 'none'; accelerometer 'none'; gyroscope 'none'; magnetometer 'none' diff --git a/testing/web-platform/tests/feature-policy/reporting/picture-in-picture-reporting.html b/testing/web-platform/tests/feature-policy/reporting/picture-in-picture-reporting.html index 60e4825d9882..e3cbf1036871 100644 --- a/testing/web-platform/tests/feature-policy/reporting/picture-in-picture-reporting.html +++ b/testing/web-platform/tests/feature-policy/reporting/picture-in-picture-reporting.html @@ -6,6 +6,7 @@ + diff --git a/testing/web-platform/tests/infrastructure/assumptions/blank.html b/testing/web-platform/tests/infrastructure/assumptions/blank.html new file mode 100644 index 000000000000..6d8da5e89ce6 --- /dev/null +++ b/testing/web-platform/tests/infrastructure/assumptions/blank.html @@ -0,0 +1,2 @@ +Blank Document + diff --git a/testing/web-platform/tests/interfaces/webrtc.idl b/testing/web-platform/tests/interfaces/webrtc.idl index cdeb5204e6a0..7496fff41dcb 100644 --- a/testing/web-platform/tests/interfaces/webrtc.idl +++ b/testing/web-platform/tests/interfaces/webrtc.idl @@ -297,6 +297,7 @@ dictionary RTCRtpSendParameters : RTCRtpParameters { required DOMString transactionId; required sequence encodings; RTCDegradationPreference degradationPreference = "balanced"; + RTCPriorityType priority = "low"; }; dictionary RTCRtpReceiveParameters : RTCRtpParameters { @@ -314,7 +315,6 @@ dictionary RTCRtpEncodingParameters : RTCRtpCodingParameters { octet codecPayloadType; RTCDtxStatus dtx; boolean active = true; - RTCPriorityType priority = "low"; unsigned long ptime; unsigned long maxBitrate; double maxFramerate; diff --git a/testing/web-platform/tests/picture-in-picture/resources/picture-in-picture-helpers.js b/testing/web-platform/tests/picture-in-picture/resources/picture-in-picture-helpers.js index 96972dcbc8ef..7561944a18d0 100644 --- a/testing/web-platform/tests/picture-in-picture/resources/picture-in-picture-helpers.js +++ b/testing/web-platform/tests/picture-in-picture/resources/picture-in-picture-helpers.js @@ -1,9 +1,3 @@ -if (!('pictureInPictureEnabled' in document)) { - HTMLVideoElement.prototype.requestPictureInPicture = function() { - return Promise.reject('Picture-in-Picture API is not available'); - } -} - function loadVideo(activeDocument, sourceUrl) { return new Promise((resolve, reject) => { const document = activeDocument || window.document; diff --git a/testing/web-platform/tests/resource-timing/resource_timing_buffer_full_eventually.html b/testing/web-platform/tests/resource-timing/resource_timing_buffer_full_eventually.html index 7ca8237b02cc..ce745237c065 100644 --- a/testing/web-platform/tests/resource-timing/resource_timing_buffer_full_eventually.html +++ b/testing/web-platform/tests/resource-timing/resource_timing_buffer_full_eventually.html @@ -16,15 +16,23 @@ function() { // Scripts appended in JS to ensure setResourceTimingBufferSize is called before. let counter = performance.getEntriesByType("resource").length; - function appendScript() { - const src = "resources/empty.js?" + counter; - const script = document.createElement('script'); - script.type = 'text/javascript'; - script.onload = function() { ++counter; appendScript()}; - script.src = src; - document.body.appendChild(script); + function appendScripts() { + const documentFragment = document.createDocumentFragment(); + // Add 100 elements at a time to avoid page reflow every time. + let numScriptsAccumulated = 0; + while (numScriptsAccumulated < 100) { + const src = "resources/empty.js?" + counter; + const script = document.createElement('script'); + script.type = 'text/javascript'; + script.src = src; + documentFragment.appendChild(script); + ++counter; + ++numScriptsAccumulated; + } + document.body.appendChild(documentFragment); + t.step_timeout(appendScripts, 20); } - appendScript(); + appendScripts(); }); diff --git a/testing/web-platform/tests/resources/chromium/generic_sensor_mocks.js b/testing/web-platform/tests/resources/chromium/generic_sensor_mocks.js index d9a23f447140..531c3b8fe054 100644 --- a/testing/web-platform/tests/resources/chromium/generic_sensor_mocks.js +++ b/testing/web-platform/tests/resources/chromium/generic_sensor_mocks.js @@ -109,7 +109,7 @@ var GenericSensorTest = (() => { this.readingSizeInBytes_ = device.mojom.SensorInitParams.kReadBufferSizeForTests; this.sharedBufferSizeInBytes_ = this.readingSizeInBytes_ * - (device.mojom.SensorType.RELATIVE_ORIENTATION_QUATERNION + 1); + (device.mojom.SensorType.MAX_VALUE + 1); let rv = Mojo.createSharedBuffer(this.sharedBufferSizeInBytes_); assert_equals(rv.result, Mojo.RESULT_OK, "Failed to create buffer"); this.sharedBufferHandle_ = rv.handle; diff --git a/testing/web-platform/tests/resources/chromium/sensor.mojom.js b/testing/web-platform/tests/resources/chromium/sensor.mojom.js index ffbd25b57df5..7578dd6d64f0 100644 --- a/testing/web-platform/tests/resources/chromium/sensor.mojom.js +++ b/testing/web-platform/tests/resources/chromium/sensor.mojom.js @@ -31,6 +31,8 @@ SensorType.ABSOLUTE_ORIENTATION_QUATERNION = SensorType.ABSOLUTE_ORIENTATION_EULER_ANGLES + 1; SensorType.RELATIVE_ORIENTATION_EULER_ANGLES = SensorType.ABSOLUTE_ORIENTATION_QUATERNION + 1; SensorType.RELATIVE_ORIENTATION_QUATERNION = SensorType.RELATIVE_ORIENTATION_EULER_ANGLES + 1; + SensorType.MIN_VALUE = 0, + SensorType.MAX_VALUE = 10, SensorType.isKnownEnumValue = function(value) { switch (value) { @@ -60,6 +62,8 @@ var ReportingMode = {}; ReportingMode.ON_CHANGE = 0; ReportingMode.CONTINUOUS = ReportingMode.ON_CHANGE + 1; + ReportingMode.MIN_VALUE = 0, + ReportingMode.MAX_VALUE = 1, ReportingMode.isKnownEnumValue = function(value) { switch (value) { @@ -688,13 +692,13 @@ }; SensorProxy.prototype.getDefaultConfiguration = function() { - var params = new Sensor_GetDefaultConfiguration_Params(); + var params_ = new Sensor_GetDefaultConfiguration_Params(); return new Promise(function(resolve, reject) { var builder = new codec.MessageV1Builder( kSensor_GetDefaultConfiguration_Name, codec.align(Sensor_GetDefaultConfiguration_Params.encodedSize), codec.kMessageExpectsResponse, 0); - builder.encodeStruct(Sensor_GetDefaultConfiguration_Params, params); + builder.encodeStruct(Sensor_GetDefaultConfiguration_Params, params_); var message = builder.finish(); this.receiver_.acceptAndExpectResponse(message).then(function(message) { var reader = new codec.MessageReader(message); @@ -712,14 +716,14 @@ }; SensorProxy.prototype.addConfiguration = function(configuration) { - var params = new Sensor_AddConfiguration_Params(); - params.configuration = configuration; + var params_ = new Sensor_AddConfiguration_Params(); + params_.configuration = configuration; return new Promise(function(resolve, reject) { var builder = new codec.MessageV1Builder( kSensor_AddConfiguration_Name, codec.align(Sensor_AddConfiguration_Params.encodedSize), codec.kMessageExpectsResponse, 0); - builder.encodeStruct(Sensor_AddConfiguration_Params, params); + builder.encodeStruct(Sensor_AddConfiguration_Params, params_); var message = builder.finish(); this.receiver_.acceptAndExpectResponse(message).then(function(message) { var reader = new codec.MessageReader(message); @@ -737,12 +741,12 @@ }; SensorProxy.prototype.removeConfiguration = function(configuration) { - var params = new Sensor_RemoveConfiguration_Params(); - params.configuration = configuration; + var params_ = new Sensor_RemoveConfiguration_Params(); + params_.configuration = configuration; var builder = new codec.MessageV0Builder( kSensor_RemoveConfiguration_Name, codec.align(Sensor_RemoveConfiguration_Params.encodedSize)); - builder.encodeStruct(Sensor_RemoveConfiguration_Params, params); + builder.encodeStruct(Sensor_RemoveConfiguration_Params, params_); var message = builder.finish(); this.receiver_.accept(message); }; @@ -752,11 +756,11 @@ }; SensorProxy.prototype.suspend = function() { - var params = new Sensor_Suspend_Params(); + var params_ = new Sensor_Suspend_Params(); var builder = new codec.MessageV0Builder( kSensor_Suspend_Name, codec.align(Sensor_Suspend_Params.encodedSize)); - builder.encodeStruct(Sensor_Suspend_Params, params); + builder.encodeStruct(Sensor_Suspend_Params, params_); var message = builder.finish(); this.receiver_.accept(message); }; @@ -766,11 +770,11 @@ }; SensorProxy.prototype.resume = function() { - var params = new Sensor_Resume_Params(); + var params_ = new Sensor_Resume_Params(); var builder = new codec.MessageV0Builder( kSensor_Resume_Name, codec.align(Sensor_Resume_Params.encodedSize)); - builder.encodeStruct(Sensor_Resume_Params, params); + builder.encodeStruct(Sensor_Resume_Params, params_); var message = builder.finish(); this.receiver_.accept(message); }; @@ -780,12 +784,12 @@ }; SensorProxy.prototype.configureReadingChangeNotifications = function(enabled) { - var params = new Sensor_ConfigureReadingChangeNotifications_Params(); - params.enabled = enabled; + var params_ = new Sensor_ConfigureReadingChangeNotifications_Params(); + params_.enabled = enabled; var builder = new codec.MessageV0Builder( kSensor_ConfigureReadingChangeNotifications_Name, codec.align(Sensor_ConfigureReadingChangeNotifications_Params.encodedSize)); - builder.encodeStruct(Sensor_ConfigureReadingChangeNotifications_Params, params); + builder.encodeStruct(Sensor_ConfigureReadingChangeNotifications_Params, params_); var message = builder.finish(); this.receiver_.accept(message); }; @@ -967,11 +971,11 @@ }; SensorClientProxy.prototype.raiseError = function() { - var params = new SensorClient_RaiseError_Params(); + var params_ = new SensorClient_RaiseError_Params(); var builder = new codec.MessageV0Builder( kSensorClient_RaiseError_Name, codec.align(SensorClient_RaiseError_Params.encodedSize)); - builder.encodeStruct(SensorClient_RaiseError_Params, params); + builder.encodeStruct(SensorClient_RaiseError_Params, params_); var message = builder.finish(); this.receiver_.accept(message); }; @@ -981,11 +985,11 @@ }; SensorClientProxy.prototype.sensorReadingChanged = function() { - var params = new SensorClient_SensorReadingChanged_Params(); + var params_ = new SensorClient_SensorReadingChanged_Params(); var builder = new codec.MessageV0Builder( kSensorClient_SensorReadingChanged_Name, codec.align(SensorClient_SensorReadingChanged_Params.encodedSize)); - builder.encodeStruct(SensorClient_SensorReadingChanged_Params, params); + builder.encodeStruct(SensorClient_SensorReadingChanged_Params, params_); var message = builder.finish(); this.receiver_.accept(message); }; @@ -1067,4 +1071,4 @@ exports.SensorClient = SensorClient; exports.SensorClientPtr = SensorClientPtr; exports.SensorClientAssociatedPtr = SensorClientAssociatedPtr; -})(); +})(); \ No newline at end of file diff --git a/testing/web-platform/tests/resources/idlharness.js b/testing/web-platform/tests/resources/idlharness.js index c22b31775528..9e6ed236b0a4 100644 --- a/testing/web-platform/tests/resources/idlharness.js +++ b/testing/web-platform/tests/resources/idlharness.js @@ -1256,6 +1256,48 @@ IdlInterface.prototype.is_global = function() }); }; +/** + * Value of the LegacyNamespace extended attribute, if any. + * + * https://heycam.github.io/webidl/#LegacyNamespace + */ +IdlInterface.prototype.get_legacy_namespace = function() +{ + var legacyNamespace = this.extAttrs.find(function(attribute) { + return attribute.name === "LegacyNamespace"; + }); + return legacyNamespace ? legacyNamespace.rhs.value : undefined; +}; + +IdlInterface.prototype.get_interface_object_owner = function() +{ + var legacyNamespace = this.get_legacy_namespace(); + return legacyNamespace ? self[legacyNamespace] : self; +}; + +IdlInterface.prototype.assert_interface_object_exists = function() +{ + var owner = this.get_legacy_namespace() || "self"; + assert_own_property(self[owner], this.name, owner + " does not have own property " + format_value(this.name)); +}; + +IdlInterface.prototype.get_interface_object = function() { + if (this.has_extended_attribute("NoInterfaceObject")) { + throw new IdlHarnessError(this.name + " has no interface object due to NoInterfaceObject"); + } + + return this.get_interface_object_owner()[this.name]; +}; + +IdlInterface.prototype.get_qualified_name = function() { + // https://heycam.github.io/webidl/#qualified-name + var legacyNamespace = this.get_legacy_namespace(); + if (legacyNamespace) { + return legacyNamespace + "." + this.name; + } + return this.name; +}; + IdlInterface.prototype.has_to_json_regular_operation = function() { return this.members.some(function(m) { return m.is_to_json_regular_operation(); @@ -1436,9 +1478,8 @@ IdlInterface.prototype.test_self = function() // TODO: Should we test here that the property is actually writable // etc., or trust getOwnPropertyDescriptor? - assert_own_property(self, this.name, - "self does not have own property " + format_value(this.name)); - var desc = Object.getOwnPropertyDescriptor(self, this.name); + this.assert_interface_object_exists(); + var desc = Object.getOwnPropertyDescriptor(this.get_interface_object_owner(), this.name); assert_false("get" in desc, "self's property " + format_value(this.name) + " should not have a getter"); assert_false("set" in desc, "self's property " + format_value(this.name) + " should not have a setter"); assert_true(desc.writable, "self's property " + format_value(this.name) + " should be writable"); @@ -1448,7 +1489,7 @@ IdlInterface.prototype.test_self = function() if (this.is_callback()) { // "The internal [[Prototype]] property of an interface object for // a callback interface must be the Function.prototype object." - assert_equals(Object.getPrototypeOf(self[this.name]), Function.prototype, + assert_equals(Object.getPrototypeOf(this.get_interface_object()), Function.prototype, "prototype of self's property " + format_value(this.name) + " is not Object.prototype"); return; @@ -1478,24 +1519,19 @@ IdlInterface.prototype.test_self = function() // ES6 (rev 30) 19.1.3.6: // "Else, if O has a [[Call]] internal method, then let builtinTag be // "Function"." - assert_class_string(self[this.name], "Function", "class string of " + this.name); + assert_class_string(this.get_interface_object(), "Function", "class string of " + this.name); // "The [[Prototype]] internal property of an interface object for a // non-callback interface is determined as follows:" - var prototype = Object.getPrototypeOf(self[this.name]); + var prototype = Object.getPrototypeOf(this.get_interface_object()); if (this.base) { // "* If the interface inherits from some other interface, the // value of [[Prototype]] is the interface object for that other // interface." - var has_interface_object = - !this.array - .members[this.base] - .has_extended_attribute("NoInterfaceObject"); - if (has_interface_object) { - assert_own_property(self, this.base, - 'should inherit from ' + this.base + - ', but self has no such property'); - assert_equals(prototype, self[this.base], + var inherited_interface = this.array.members[this.base]; + if (!inherited_interface.has_extended_attribute("NoInterfaceObject")) { + inherited_interface.assert_interface_object_exists(); + assert_equals(prototype, inherited_interface.get_interface_object(), 'prototype of ' + this.name + ' is not ' + this.base); } @@ -1513,12 +1549,13 @@ IdlInterface.prototype.test_self = function() // // "If I was not declared with a [Constructor] extended attribute, // then throw a TypeError." + var interface_object = this.get_interface_object(); assert_throws(new TypeError(), function() { - self[this.name](); - }.bind(this), "interface object didn't throw TypeError when called as a function"); + interface_object(); + }, "interface object didn't throw TypeError when called as a function"); assert_throws(new TypeError(), function() { - new self[this.name](); - }.bind(this), "interface object didn't throw TypeError when called as a constructor"); + new interface_object(); + }, "interface object didn't throw TypeError when called as a constructor"); } }.bind(this), this.name + " interface: existence and properties of interface object"); @@ -1527,15 +1564,14 @@ IdlInterface.prototype.test_self = function() // This function tests WebIDL as of 2014-10-25. // https://heycam.github.io/webidl/#es-interface-call - assert_own_property(self, this.name, - "self does not have own property " + format_value(this.name)); + this.assert_interface_object_exists(); // "Interface objects for non-callback interfaces MUST have a // property named “length” with attributes { [[Writable]]: false, // [[Enumerable]]: false, [[Configurable]]: true } whose value is // a Number." - assert_own_property(self[this.name], "length"); - var desc = Object.getOwnPropertyDescriptor(self[this.name], "length"); + assert_own_property(this.get_interface_object(), "length"); + var desc = Object.getOwnPropertyDescriptor(this.get_interface_object(), "length"); assert_false("get" in desc, this.name + ".length should not have a getter"); assert_false("set" in desc, this.name + ".length should not have a setter"); assert_false(desc.writable, this.name + ".length should not be writable"); @@ -1545,7 +1581,7 @@ IdlInterface.prototype.test_self = function() var constructors = this.extAttrs .filter(function(attr) { return attr.name == "Constructor"; }); var expected_length = minOverloadLength(constructors); - assert_equals(self[this.name].length, expected_length, "wrong value for " + this.name + ".length"); + assert_equals(this.get_interface_object().length, expected_length, "wrong value for " + this.name + ".length"); }.bind(this), this.name + " interface object length"); } @@ -1554,22 +1590,21 @@ IdlInterface.prototype.test_self = function() // This function tests WebIDL as of 2015-11-17. // https://heycam.github.io/webidl/#interface-object - assert_own_property(self, this.name, - "self does not have own property " + format_value(this.name)); + this.assert_interface_object_exists(); // "All interface objects must have a property named “name” with // attributes { [[Writable]]: false, [[Enumerable]]: false, // [[Configurable]]: true } whose value is the identifier of the // corresponding interface." - assert_own_property(self[this.name], "name"); - var desc = Object.getOwnPropertyDescriptor(self[this.name], "name"); + assert_own_property(this.get_interface_object(), "name"); + var desc = Object.getOwnPropertyDescriptor(this.get_interface_object(), "name"); assert_false("get" in desc, this.name + ".name should not have a getter"); assert_false("set" in desc, this.name + ".name should not have a setter"); assert_false(desc.writable, this.name + ".name should not be writable"); assert_false(desc.enumerable, this.name + ".name should not be enumerable"); assert_true(desc.configurable, this.name + ".name should be configurable"); - assert_equals(self[this.name].name, this.name, "wrong value for " + this.name + ".name"); + assert_equals(this.get_interface_object().name, this.name, "wrong value for " + this.name + ".name"); }.bind(this), this.name + " interface object name"); } @@ -1608,9 +1643,9 @@ IdlInterface.prototype.test_self = function() if (exposed_in(exposure_set(this, this.exposureSet)) && 'document' in self) { for (alias of aliases) { assert_true(alias in self, alias + " should exist"); - assert_equals(self[alias], self[this.name], "self." + alias + " should be the same value as self." + this.name); + assert_equals(self[alias], this.get_interface_object(), "self." + alias + " should be the same value as self." + this.get_qualified_name()); var desc = Object.getOwnPropertyDescriptor(self, alias); - assert_equals(desc.value, self[this.name], "wrong value in " + alias + " property descriptor"); + assert_equals(desc.value, this.get_interface_object(), "wrong value in " + alias + " property descriptor"); assert_true(desc.writable, alias + " should be writable"); assert_false(desc.enumerable, alias + " should not be enumerable"); assert_true(desc.configurable, alias + " should be configurable"); @@ -1636,11 +1671,10 @@ IdlInterface.prototype.test_self = function() return; } - assert_own_property(self, this.name, - "self does not have own property " + format_value(this.name)); + this.assert_interface_object_exists(); if (this.is_callback()) { - assert_false("prototype" in self[this.name], + assert_false("prototype" in this.get_interface_object(), this.name + ' should not have a "prototype" property'); return; } @@ -1652,9 +1686,9 @@ IdlInterface.prototype.test_self = function() // properties that correspond to the regular attributes and regular // operations defined on the interface, and is described in more detail // in section 4.5.4 below." - assert_own_property(self[this.name], "prototype", + assert_own_property(this.get_interface_object(), "prototype", 'interface "' + this.name + '" does not have own property "prototype"'); - var desc = Object.getOwnPropertyDescriptor(self[this.name], "prototype"); + var desc = Object.getOwnPropertyDescriptor(this.get_interface_object(), "prototype"); assert_false("get" in desc, this.name + ".prototype should not have a getter"); assert_false("set" in desc, this.name + ".prototype should not have a setter"); assert_false(desc.writable, this.name + ".prototype should not be writable"); @@ -1687,38 +1721,39 @@ IdlInterface.prototype.test_self = function() // object %ErrorPrototype%." // if (this.name === "Window") { - assert_class_string(Object.getPrototypeOf(self[this.name].prototype), + assert_class_string(Object.getPrototypeOf(this.get_interface_object().prototype), 'WindowProperties', 'Class name for prototype of Window' + '.prototype is not "WindowProperties"'); } else { - var inherit_interface, inherit_interface_has_interface_object; + var inherit_interface, inherit_interface_interface_object; if (this.base) { inherit_interface = this.base; - inherit_interface_has_interface_object = - !this.array - .members[inherit_interface] - .has_extended_attribute("NoInterfaceObject"); + var parent = this.array.members[inherit_interface]; + if (!parent.has_extended_attribute("NoInterfaceObject")) { + parent.assert_interface_object_exists(); + inherit_interface_interface_object = parent.get_interface_object(); + } } else if (this.name === "DOMException") { inherit_interface = 'Error'; - inherit_interface_has_interface_object = true; + inherit_interface_interface_object = self.Error; } else { inherit_interface = 'Object'; - inherit_interface_has_interface_object = true; + inherit_interface_interface_object = self.Object; } - if (inherit_interface_has_interface_object) { - assert_own_property(self, inherit_interface, - 'should inherit from ' + inherit_interface + ', but self has no such property'); - assert_own_property(self[inherit_interface], 'prototype', + if (inherit_interface_interface_object) { + assert_not_equals(inherit_interface_interface_object, undefined, + 'should inherit from ' + inherit_interface + ', but there is no such property'); + assert_own_property(inherit_interface_interface_object, 'prototype', 'should inherit from ' + inherit_interface + ', but that object has no "prototype" property'); - assert_equals(Object.getPrototypeOf(self[this.name].prototype), - self[inherit_interface].prototype, + assert_equals(Object.getPrototypeOf(this.get_interface_object().prototype), + inherit_interface_interface_object.prototype, 'prototype of ' + this.name + '.prototype is not ' + inherit_interface + '.prototype'); } else { // We can't test that we get the correct object, because this is the // only way to get our hands on it. We only test that its class // string, at least, is correct. - assert_class_string(Object.getPrototypeOf(self[this.name].prototype), + assert_class_string(Object.getPrototypeOf(this.get_interface_object().prototype), inherit_interface + 'Prototype', 'Class name for prototype of ' + this.name + '.prototype is not "' + inherit_interface + 'Prototype"'); @@ -1726,20 +1761,20 @@ IdlInterface.prototype.test_self = function() } // "The class string of an interface prototype object is the - // concatenation of the interface’s identifier and the string + // concatenation of the interface’s qualified identifier and the string // “Prototype”." // Skip these tests for now due to a specification issue about // prototype name. // https://www.w3.org/Bugs/Public/show_bug.cgi?id=28244 - // assert_class_string(self[this.name].prototype, this.name + "Prototype", + // assert_class_string(this.get_interface_object().prototype, this.get_qualified_name() + "Prototype", // "class string of " + this.name + ".prototype"); // String() should end up calling {}.toString if nothing defines a // stringifier. if (!this.has_stringifier()) { - // assert_equals(String(self[this.name].prototype), "[object " + this.name + "Prototype]", + // assert_equals(String(this.get_interface_object().prototype), "[object " + this.get_qualified_name() + "Prototype]", // "String(" + this.name + ".prototype)"); } }.bind(this), this.name + " interface: existence and properties of interface prototype object"); @@ -1751,7 +1786,7 @@ IdlInterface.prototype.test_self = function() // prototype exotic object." // https://heycam.github.io/webidl/#interface-prototype-object if (this.is_global()) { - this.test_immutable_prototype("interface prototype object", self[this.name].prototype); + this.test_immutable_prototype("interface prototype object", this.get_interface_object().prototype); } subsetTestByKey(this.name, test, function() @@ -1760,16 +1795,15 @@ IdlInterface.prototype.test_self = function() return; } - assert_own_property(self, this.name, - "self does not have own property " + format_value(this.name)); + this.assert_interface_object_exists(); if (this.is_callback()) { - assert_false("prototype" in self[this.name], + assert_false("prototype" in this.get_interface_object(), this.name + ' should not have a "prototype" property'); return; } - assert_own_property(self[this.name], "prototype", + assert_own_property(this.get_interface_object(), "prototype", 'interface "' + this.name + '" does not have own property "prototype"'); // "If the [NoInterfaceObject] extended attribute was not specified on @@ -1777,15 +1811,15 @@ IdlInterface.prototype.test_self = function() // property named “constructor” with attributes { [[Writable]]: true, // [[Enumerable]]: false, [[Configurable]]: true } whose value is a // reference to the interface object for the interface." - assert_own_property(self[this.name].prototype, "constructor", + assert_own_property(this.get_interface_object().prototype, "constructor", this.name + '.prototype does not have own property "constructor"'); - var desc = Object.getOwnPropertyDescriptor(self[this.name].prototype, "constructor"); + var desc = Object.getOwnPropertyDescriptor(this.get_interface_object().prototype, "constructor"); assert_false("get" in desc, this.name + ".prototype.constructor should not have a getter"); assert_false("set" in desc, this.name + ".prototype.constructor should not have a setter"); assert_true(desc.writable, this.name + ".prototype.constructor should be writable"); assert_false(desc.enumerable, this.name + ".prototype.constructor should not be enumerable"); assert_true(desc.configurable, this.name + ".prototype.constructor should be configurable"); - assert_equals(self[this.name].prototype.constructor, self[this.name], + assert_equals(this.get_interface_object().prototype.constructor, this.get_interface_object(), this.name + '.prototype.constructor is not the same object as ' + this.name); }.bind(this), this.name + ' interface: existence and properties of interface prototype object\'s "constructor" property'); @@ -1796,16 +1830,15 @@ IdlInterface.prototype.test_self = function() return; } - assert_own_property(self, this.name, - "self does not have own property " + format_value(this.name)); + this.assert_interface_object_exists(); if (this.is_callback()) { - assert_false("prototype" in self[this.name], + assert_false("prototype" in this.get_interface_object(), this.name + ' should not have a "prototype" property'); return; } - assert_own_property(self[this.name], "prototype", + assert_own_property(this.get_interface_object(), "prototype", 'interface "' + this.name + '" does not have own property "prototype"'); // If the interface has any member declared with the [Unscopable] extended @@ -1814,7 +1847,7 @@ IdlInterface.prototype.test_self = function() // { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: true }, // and whose value is an object created as follows... var unscopables = this.get_unscopables().map(m => m.name); - var proto = self[this.name].prototype; + var proto = this.get_interface_object().prototype; if (unscopables.length != 0) { assert_own_property( proto, Symbol.unscopables, @@ -1836,15 +1869,18 @@ IdlInterface.prototype.test_self = function() 0, this.name + '.prototype[Symbol.unscopables] should have the right number of symbol-named properties'); - // It would be nice to check that we do not have _extra_ - // unscopables, but someone might be calling us with only a subset - // of the IDL the browser know about, and our subset may exclude - // unscopable things that really do exist. + // Check that we do not have _extra_ unscopables. Checking that we + // have all the ones we should will happen in the per-member tests. + var observed = Object.getOwnPropertyNames(desc.value); + for (var prop of observed) { + assert_not_equals(unscopables.indexOf(prop), + -1, + this.name + '.prototype[Symbol.unscopables] has unexpected property "' + prop + '"'); + } } else { - // It would be nice to assert that there is no @@unscopables on this - // prototype, but someone might be calling us with only a subset of - // the IDL the browser know about, and our subset may exclude - // unscopable things that really do exist. + assert_equals(Object.getOwnPropertyDescriptor(this.get_interface_object().prototype, Symbol.unscopables), + undefined, + this.name + '.prototype should not have @@unscopables'); } }.bind(this), this.name + ' interface: existence and properties of interface prototype object\'s @@unscopables property'); }; @@ -1959,21 +1995,20 @@ IdlInterface.prototype.test_member_const = function(member) subsetTestByKey(this.name, test, function() { - assert_own_property(self, this.name, - "self does not have own property " + format_value(this.name)); + this.assert_interface_object_exists(); // "For each constant defined on an interface A, there must be // a corresponding property on the interface object, if it // exists." - assert_own_property(self[this.name], member.name); + assert_own_property(this.get_interface_object(), member.name); // "The value of the property is that which is obtained by // converting the constant’s IDL value to an ECMAScript // value." - assert_equals(self[this.name][member.name], constValue(member.value), + assert_equals(this.get_interface_object()[member.name], constValue(member.value), "property has wrong value"); // "The property has attributes { [[Writable]]: false, // [[Enumerable]]: true, [[Configurable]]: false }." - var desc = Object.getOwnPropertyDescriptor(self[this.name], member.name); + var desc = Object.getOwnPropertyDescriptor(this.get_interface_object(), member.name); assert_false("get" in desc, "property should not have a getter"); assert_false("set" in desc, "property should not have a setter"); assert_false(desc.writable, "property should not be writable"); @@ -1985,22 +2020,21 @@ IdlInterface.prototype.test_member_const = function(member) // exist on the interface prototype object." subsetTestByKey(this.name, test, function() { - assert_own_property(self, this.name, - "self does not have own property " + format_value(this.name)); + this.assert_interface_object_exists(); if (this.is_callback()) { - assert_false("prototype" in self[this.name], + assert_false("prototype" in this.get_interface_object(), this.name + ' should not have a "prototype" property'); return; } - assert_own_property(self[this.name], "prototype", + assert_own_property(this.get_interface_object(), "prototype", 'interface "' + this.name + '" does not have own property "prototype"'); - assert_own_property(self[this.name].prototype, member.name); - assert_equals(self[this.name].prototype[member.name], constValue(member.value), + assert_own_property(this.get_interface_object().prototype, member.name); + assert_equals(this.get_interface_object().prototype[member.name], constValue(member.value), "property has wrong value"); - var desc = Object.getOwnPropertyDescriptor(self[this.name], member.name); + var desc = Object.getOwnPropertyDescriptor(this.get_interface_object(), member.name); assert_false("get" in desc, "property should not have a getter"); assert_false("set" in desc, "property should not have a setter"); assert_false(desc.writable, "property should not be writable"); @@ -2023,13 +2057,12 @@ IdlInterface.prototype.test_member_attribute = function(member) return; } - assert_own_property(self, this.name, - "self does not have own property " + format_value(this.name)); - assert_own_property(self[this.name], "prototype", + this.assert_interface_object_exists(); + assert_own_property(this.get_interface_object(), "prototype", 'interface "' + this.name + '" does not have own property "prototype"'); if (member["static"]) { - assert_own_property(self[this.name], member.name, + assert_own_property(this.get_interface_object(), member.name, "The interface object must have a property " + format_value(member.name)); a_test.done(); @@ -2042,7 +2075,7 @@ IdlInterface.prototype.test_member_attribute = function(member) assert_own_property(self, member.name, "The global object must have a property " + format_value(member.name)); - assert_false(member.name in self[this.name].prototype, + assert_false(member.name in this.get_interface_object().prototype, "The prototype object should not have a property " + format_value(member.name)); @@ -2070,34 +2103,34 @@ IdlInterface.prototype.test_member_attribute = function(member) // since it will call done() on a_test. this.do_interface_attribute_asserts(self, member, a_test); } else { - assert_true(member.name in self[this.name].prototype, + assert_true(member.name in this.get_interface_object().prototype, "The prototype object must have a property " + format_value(member.name)); if (!member.has_extended_attribute("LenientThis")) { if (member.idlType.generic !== "Promise") { assert_throws(new TypeError(), function() { - self[this.name].prototype[member.name]; + this.get_interface_object().prototype[member.name]; }.bind(this), "getting property on prototype object must throw TypeError"); // do_interface_attribute_asserts must be the last thing we // do, since it will call done() on a_test. - this.do_interface_attribute_asserts(self[this.name].prototype, member, a_test); + this.do_interface_attribute_asserts(this.get_interface_object().prototype, member, a_test); } else { promise_rejects(a_test, new TypeError(), - self[this.name].prototype[member.name]) + this.get_interface_object().prototype[member.name]) .then(function() { // do_interface_attribute_asserts must be the last // thing we do, since it will call done() on a_test. - this.do_interface_attribute_asserts(self[this.name].prototype, + this.do_interface_attribute_asserts(this.get_interface_object().prototype, member, a_test); }.bind(this)); } } else { - assert_equals(self[this.name].prototype[member.name], undefined, + assert_equals(this.get_interface_object().prototype[member.name], undefined, "getting property on prototype object must return undefined"); // do_interface_attribute_asserts must be the last thing we do, // since it will call done() on a_test. - this.do_interface_attribute_asserts(self[this.name].prototype, member, a_test); + this.do_interface_attribute_asserts(this.get_interface_object().prototype, member, a_test); } } }.bind(this)); @@ -2122,17 +2155,16 @@ IdlInterface.prototype.test_member_operation = function(member) return; } - assert_own_property(self, this.name, - "self does not have own property " + format_value(this.name)); + this.assert_interface_object_exists(); if (this.is_callback()) { - assert_false("prototype" in self[this.name], + assert_false("prototype" in this.get_interface_object(), this.name + ' should not have a "prototype" property'); a_test.done(); return; } - assert_own_property(self[this.name], "prototype", + assert_own_property(this.get_interface_object(), "prototype", 'interface "' + this.name + '" does not have own property "prototype"'); // "For each unique identifier of an exposed operation defined on the @@ -2147,9 +2179,9 @@ IdlInterface.prototype.test_member_operation = function(member) // "* If the operation is static, then the property exists on the // interface object." if (member["static"]) { - assert_own_property(self[this.name], member.name, + assert_own_property(this.get_interface_object(), member.name, "interface object missing static operation"); - memberHolderObject = self[this.name]; + memberHolderObject = this.get_interface_object(); // "* Otherwise, [...] if the interface was declared with the [Global] // extended attribute, then the property exists // on every object that implements the interface." @@ -2160,9 +2192,9 @@ IdlInterface.prototype.test_member_operation = function(member) // "* Otherwise, the property exists solely on the interface’s // interface prototype object." } else { - assert_own_property(self[this.name].prototype, member.name, + assert_own_property(this.get_interface_object().prototype, member.name, "interface prototype object missing non-static operation"); - memberHolderObject = self[this.name].prototype; + memberHolderObject = this.get_interface_object().prototype; } this.do_member_unscopable_asserts(member); this.do_member_operation_asserts(memberHolderObject, member, a_test); @@ -2177,9 +2209,7 @@ IdlInterface.prototype.do_member_unscopable_asserts = function(member) return; } - var unscopables = self[this.name].prototype[Symbol.unscopables]; - assert_equals(typeof unscopables, "object", - this.name + '.prototype[Symbol.unscopables] must exist'); + var unscopables = this.get_interface_object().prototype[Symbol.unscopables]; var prop = member.name; var propDesc = Object.getOwnPropertyDescriptor(unscopables, prop); assert_equals(typeof propDesc, "object", @@ -2307,27 +2337,26 @@ IdlInterface.prototype.test_to_json_operation = function(memberHolderObject, mem IdlInterface.prototype.test_member_iterable = function(member) { - var interfaceName = this.name; var isPairIterator = member.idlType.length === 2; subsetTestByKey(this.name, test, function() { - var descriptor = Object.getOwnPropertyDescriptor(self[interfaceName].prototype, Symbol.iterator); + var descriptor = Object.getOwnPropertyDescriptor(this.get_interface_object().prototype, Symbol.iterator); assert_true(descriptor.writable, "property should be writable"); assert_true(descriptor.configurable, "property should be configurable"); assert_false(descriptor.enumerable, "property should not be enumerable"); - assert_equals(self[interfaceName].prototype[Symbol.iterator].name, isPairIterator ? "entries" : "values", "@@iterator function does not have the right name"); - }, "Testing Symbol.iterator property of iterable interface " + interfaceName); + assert_equals(this.get_interface_object().prototype[Symbol.iterator].name, isPairIterator ? "entries" : "values", "@@iterator function does not have the right name"); + }.bind(this), "Testing Symbol.iterator property of iterable interface " + this.name); if (isPairIterator) { subsetTestByKey(this.name, test, function() { - assert_equals(self[interfaceName].prototype[Symbol.iterator], self[interfaceName].prototype["entries"], "entries method is not the same as @@iterator"); - }, "Testing pair iterable interface " + interfaceName); + assert_equals(this.get_interface_object().prototype[Symbol.iterator], this.get_interface_object().prototype["entries"], "entries method is not the same as @@iterator"); + }.bind(this), "Testing pair iterable interface " + this.name); } else { subsetTestByKey(this.name, test, function() { ["entries", "keys", "values", "forEach", Symbol.Iterator].forEach(function(property) { - assert_equals(self[interfaceName].prototype[property], Array.prototype[property], property + " function is not the same as Array one"); - }); - }, "Testing value iterable interface " + interfaceName); + assert_equals(this.get_interface_object().prototype[property], Array.prototype[property], property + " function is not the same as Array one"); + }.bind(this)); + }.bind(this), "Testing value iterable interface " + this.name); } }; @@ -2339,21 +2368,20 @@ IdlInterface.prototype.test_member_stringifier = function(member) return; } - assert_own_property(self, this.name, - "self does not have own property " + format_value(this.name)); + this.assert_interface_object_exists(); if (this.is_callback()) { - assert_false("prototype" in self[this.name], + assert_false("prototype" in this.get_interface_object(), this.name + ' should not have a "prototype" property'); return; } - assert_own_property(self[this.name], "prototype", + assert_own_property(this.get_interface_object(), "prototype", 'interface "' + this.name + '" does not have own property "prototype"'); // ". . . the property exists on the interface prototype object." - var interfacePrototypeObject = self[this.name].prototype; - assert_own_property(self[this.name].prototype, "toString", + var interfacePrototypeObject = this.get_interface_object().prototype; + assert_own_property(interfacePrototypeObject, "toString", "interface prototype object missing non-static operation"); var stringifierUnforgeable = member.isUnforgeable; @@ -2379,7 +2407,7 @@ IdlInterface.prototype.test_member_stringifier = function(member) // "Let O be the result of calling ToObject on the this value." assert_throws(new TypeError(), function() { - self[this.name].prototype.toString.apply(null, []); + interfacePrototypeObject.toString.apply(null, []); }, "calling stringifier with this = null didn't throw TypeError"); // "If O is not an object that implements the interface on which the @@ -2388,7 +2416,7 @@ IdlInterface.prototype.test_member_stringifier = function(member) // TODO: Test a platform object that implements some other // interface. (Have to be sure to get inheritance right.) assert_throws(new TypeError(), function() { - self[this.name].prototype.toString.apply({}, []); + interfacePrototypeObject.toString.apply({}, []); }, "calling stringifier with this = {} didn't throw TypeError"); }.bind(this), this.name + " interface: stringifier"); }; @@ -2418,10 +2446,10 @@ IdlInterface.prototype.test_members = function() if (!exposed_in(exposure_set(member, this.exposureSet))) { subsetTestByKey(this.name, test, function() { // It's not exposed, so we shouldn't find it anywhere. - assert_false(member.name in self[this.name], + assert_false(member.name in this.get_interface_object(), "The interface object must not have a property " + format_value(member.name)); - assert_false(member.name in self[this.name].prototype, + assert_false(member.name in this.get_interface_object().prototype, "The prototype object must not have a property " + format_value(member.name)); }.bind(this), this.name + " interface: member " + member.name); @@ -2537,9 +2565,8 @@ IdlInterface.prototype.test_primary_interface_of = function(desc, obj, exception { assert_equals(exception, null, "Unexpected exception when evaluating object"); assert_equals(typeof obj, expected_typeof, "wrong typeof object"); - assert_own_property(self, this.name, - "self does not have own property " + format_value(this.name)); - assert_own_property(self[this.name], "prototype", + this.assert_interface_object_exists(); + assert_own_property(this.get_interface_object(), "prototype", 'interface "' + this.name + '" does not have own property "prototype"'); // "The value of the internal [[Prototype]] property of the @@ -2547,22 +2574,22 @@ IdlInterface.prototype.test_primary_interface_of = function(desc, obj, exception // interface from the platform object’s associated global // environment." assert_equals(Object.getPrototypeOf(obj), - self[this.name].prototype, + this.get_interface_object().prototype, desc + "'s prototype is not " + this.name + ".prototype"); }.bind(this), this.name + " must be primary interface of " + desc); } // "The class string of a platform object that implements one or more - // interfaces must be the identifier of the primary interface of the + // interfaces must be the qualified name of the primary interface of the // platform object." subsetTestByKey(this.name, test, function() { assert_equals(exception, null, "Unexpected exception when evaluating object"); assert_equals(typeof obj, expected_typeof, "wrong typeof object"); - assert_class_string(obj, this.name, "class string of " + desc); + assert_class_string(obj, this.get_qualified_name(), "class string of " + desc); if (!this.has_stringifier()) { - assert_equals(String(obj), "[object " + this.name + "]", "String(" + desc + ")"); + assert_equals(String(obj), "[object " + this.get_qualified_name() + "]", "String(" + desc + ")"); } }.bind(this), "Stringification of " + desc); }; diff --git a/testing/web-platform/tests/resources/test/tests/unit/IdlInterface/get_interface_object.html b/testing/web-platform/tests/resources/test/tests/unit/IdlInterface/get_interface_object.html new file mode 100644 index 000000000000..a3d901a752de --- /dev/null +++ b/testing/web-platform/tests/resources/test/tests/unit/IdlInterface/get_interface_object.html @@ -0,0 +1,22 @@ + +IdlInterface.prototype.get_interface_object() + + + + + + + diff --git a/testing/web-platform/tests/resources/test/tests/unit/IdlInterface/get_interface_object_owner.html b/testing/web-platform/tests/resources/test/tests/unit/IdlInterface/get_interface_object_owner.html new file mode 100644 index 000000000000..51ab2067bc5b --- /dev/null +++ b/testing/web-platform/tests/resources/test/tests/unit/IdlInterface/get_interface_object_owner.html @@ -0,0 +1,21 @@ + +IdlInterface.prototype.get_interface_object_owner() + + + + + + + diff --git a/testing/web-platform/tests/resources/test/tests/unit/IdlInterface/get_legacy_namespace.html b/testing/web-platform/tests/resources/test/tests/unit/IdlInterface/get_legacy_namespace.html new file mode 100644 index 000000000000..e2d42bb09e3e --- /dev/null +++ b/testing/web-platform/tests/resources/test/tests/unit/IdlInterface/get_legacy_namespace.html @@ -0,0 +1,20 @@ + +IdlInterface.prototype.get_legacy_namespace() + + + + + + + diff --git a/testing/web-platform/tests/resources/test/tests/unit/IdlInterface/get_qualified_name.html b/testing/web-platform/tests/resources/test/tests/unit/IdlInterface/get_qualified_name.html new file mode 100644 index 000000000000..677a31b5e708 --- /dev/null +++ b/testing/web-platform/tests/resources/test/tests/unit/IdlInterface/get_qualified_name.html @@ -0,0 +1,20 @@ + +IdlInterface.prototype.get_qualified_name() + + + + + + + diff --git a/testing/web-platform/tests/service-workers/service-worker/resources/service-worker-header.py b/testing/web-platform/tests/service-workers/service-worker/resources/service-worker-header.py index 2e82e78107ad..74f57a72a904 100644 --- a/testing/web-platform/tests/service-workers/service-worker/resources/service-worker-header.py +++ b/testing/web-platform/tests/service-workers/service-worker/resources/service-worker-header.py @@ -1,7 +1,20 @@ def main(request, response): service_worker_header = request.headers.get('service-worker') - if service_worker_header == 'script': - body = '// Request has `Service-Worker: script` header' - return 200, [('Content-Type', 'application/javascript')], body - else: + + if 'header' in request.GET and service_worker_header != 'script': return 400, [('Content-Type', 'text/plain')], 'Bad Request' + + if 'no-header' in request.GET and service_worker_header == 'script': + return 400, [('Content-Type', 'text/plain')], 'Bad Request' + + # no-cache itself to ensure the user agent finds a new version for each + # update. + headers = [('Cache-Control', 'no-cache, must-revalidate'), + ('Pragma', 'no-cache'), + ('Content-Type', 'application/javascript')] + body = '/* This is a service worker script */\n' + + if 'import' in request.GET: + body += "importScripts('%s');" % request.GET['import'] + + return 200, headers, body diff --git a/testing/web-platform/tests/service-workers/service-worker/service-worker-header.https.html b/testing/web-platform/tests/service-workers/service-worker/service-worker-header.https.html index 2584485c65ab..fb902cd1b455 100644 --- a/testing/web-platform/tests/service-workers/service-worker/service-worker-header.https.html +++ b/testing/web-platform/tests/service-workers/service-worker/service-worker-header.https.html @@ -5,14 +5,19 @@ diff --git a/testing/web-platform/tests/tools/ci/check_stability.py b/testing/web-platform/tests/tools/ci/check_stability.py index a0633110860a..7dae5de852f7 100644 --- a/testing/web-platform/tests/tools/ci/check_stability.py +++ b/testing/web-platform/tests/tools/ci/check_stability.py @@ -119,6 +119,7 @@ def call(*args): logger.critical(e.output) raise + def fetch_wpt(user, *args): git = get_git_cmd(wpt_root) git("fetch", "https://github.com/%s/web-platform-tests.git" % user, *args) @@ -274,6 +275,8 @@ def run(venv, wpt_args, **kwargs): wpt_kwargs["repeat"] = 10 wpt_kwargs["headless"] = False + wpt_kwargs["log_tbpl"] = [sys.stdout] + wpt_kwargs = setup_wptrunner(venv, **wpt_kwargs) logger.info("Using binary %s" % wpt_kwargs["binary"]) diff --git a/testing/web-platform/tests/tools/ci/ci_wptrunner_infrastructure.sh b/testing/web-platform/tests/tools/ci/ci_wptrunner_infrastructure.sh index 3147164ac886..0d4c2a519125 100755 --- a/testing/web-platform/tests/tools/ci/ci_wptrunner_infrastructure.sh +++ b/testing/web-platform/tests/tools/ci/ci_wptrunner_infrastructure.sh @@ -14,7 +14,7 @@ test_infrastructure() { else ARGS=$1 fi - ./wpt run --yes --manifest ~/meta/MANIFEST.json --metadata infrastructure/metadata/ --install-fonts $ARGS $PRODUCT infrastructure/ + ./wpt run --log-tbpl - --yes --manifest ~/meta/MANIFEST.json --metadata infrastructure/metadata/ --install-fonts $ARGS $PRODUCT infrastructure/ } main() { diff --git a/testing/web-platform/tests/tools/lint/lint.py b/testing/web-platform/tests/tools/lint/lint.py index cf668faea6f5..4c7605876c87 100644 --- a/testing/web-platform/tests/tools/lint/lint.py +++ b/testing/web-platform/tests/tools/lint/lint.py @@ -458,10 +458,15 @@ def check_parsed(repo_root, path, f): if source_file.type == "visual" and not source_file.name_is_visual: errors.append(("CONTENT-VISUAL", "Visual test whose filename doesn't end in '-visual'", path, None)) + about_blank_parts = urlsplit("about:blank") for reftest_node in source_file.reftest_nodes: href = reftest_node.attrib.get("href", "").strip(space_chars) parts = urlsplit(href) - if (parts.scheme or parts.netloc) and parts != urlsplit("about:blank"): + + if parts == about_blank_parts: + continue + + if (parts.scheme or parts.netloc): errors.append(("ABSOLUTE-URL-REF", "Reference test with a reference file specified via an absolute URL: '%s'" % href, path, None)) continue diff --git a/testing/web-platform/tests/tools/wpt/run.py b/testing/web-platform/tests/tools/wpt/run.py index 7bc43a314c9c..303dbdca543b 100644 --- a/testing/web-platform/tests/tools/wpt/run.py +++ b/testing/web-platform/tests/tools/wpt/run.py @@ -461,6 +461,7 @@ product_setup = { def setup_wptrunner(venv, prompt=True, install_browser=False, **kwargs): from wptrunner import wptrunner, wptcommandline + import mozlog global logger @@ -470,7 +471,12 @@ def setup_wptrunner(venv, prompt=True, install_browser=False, **kwargs): kwargs["product"] = product_parts[0] sub_product = product_parts[1:] - wptrunner.setup_logging(kwargs, {"mach": sys.stdout}) + # Use the grouped formatter by default where mozlog 3.9+ is installed + if hasattr(mozlog.formatters, "GroupingFormatter"): + default_formatter = "grouped" + else: + default_formatter = "mach" + wptrunner.setup_logging(kwargs, {default_formatter: sys.stdout}) logger = wptrunner.logger check_environ(kwargs["product"]) diff --git a/testing/web-platform/tests/tools/wptrunner/requirements.txt b/testing/web-platform/tests/tools/wptrunner/requirements.txt index 1f06f18e6260..2ae1622a6a39 100644 --- a/testing/web-platform/tests/tools/wptrunner/requirements.txt +++ b/testing/web-platform/tests/tools/wptrunner/requirements.txt @@ -1,5 +1,5 @@ html5lib == 1.0.1 mozinfo == 0.10 -mozlog == 3.8 +mozlog==3.9 mozdebug == 0.1 urllib3[secure]==1.23 diff --git a/testing/web-platform/tests/tools/wptrunner/wptrunner/tests/test_wpttest.py b/testing/web-platform/tests/tools/wptrunner/wptrunner/tests/test_wpttest.py index b60cff05e451..33eec4b46c9c 100644 --- a/testing/web-platform/tests/tools/wptrunner/wptrunner/tests/test_wpttest.py +++ b/testing/web-platform/tests/tools/wptrunner/wptrunner/tests/test_wpttest.py @@ -99,7 +99,7 @@ def test_metadata_lsan_stack_depth(): test = tests[1][2].pop() test_obj = wpttest.from_manifest(test, [], test_metadata.get_test(test.id)) - assert test_obj.lsan_max_stack_depth == None + assert test_obj.lsan_max_stack_depth is None test_metadata = manifestexpected.static.compile(BytesIO(test_0), {}, diff --git a/testing/web-platform/tests/tools/wptserve/tests/functional/base.py b/testing/web-platform/tests/tools/wptserve/tests/functional/base.py index f8331f5086d3..190e385f1020 100644 --- a/testing/web-platform/tests/tools/wptserve/tests/functional/base.py +++ b/testing/web-platform/tests/tools/wptserve/tests/functional/base.py @@ -9,7 +9,7 @@ import unittest from six.moves.urllib.parse import urlencode, urlunsplit from six.moves.urllib.request import Request as BaseRequest from six.moves.urllib.request import urlopen -from six import binary_type, iteritems +from six import binary_type, iteritems, PY3 from hyper import HTTP20Connection, tls import ssl @@ -79,6 +79,11 @@ class TestUsingServer(unittest.TestCase): return urlopen(req) + def assert_multiple_headers(self, resp, name, values): + if PY3: + assert resp.info().get_all(name) == values + else: + assert resp.info()[name] == ", ".join(values) @pytest.mark.skipif(not wptserve.utils.http2_compatible(), reason="h2 server only works in python 2.7.15") class TestUsingH2Server: diff --git a/testing/web-platform/tests/tools/wptserve/tests/functional/test_pipes.py b/testing/web-platform/tests/tools/wptserve/tests/functional/test_pipes.py index fdac4537d64f..693cb82e2410 100644 --- a/testing/web-platform/tests/tools/wptserve/tests/functional/test_pipes.py +++ b/testing/web-platform/tests/tools/wptserve/tests/functional/test_pipes.py @@ -35,10 +35,9 @@ class TestHeader(TestUsingServer): resp = self.request("/document.txt", query="pipe=header(Content-Type,FAIL)|header(Content-Type,text/html)") self.assertEqual(resp.info()["Content-Type"], "text/html") - @pytest.mark.xfail(sys.version_info >= (3,), reason="wptserve only works on Py2") def test_multiple_append(self): resp = self.request("/document.txt", query="pipe=header(X-Test,1)|header(X-Test,2,True)") - self.assertEqual(resp.info()["X-Test"], "1, 2") + self.assert_multiple_headers(resp, "X-Test", ["1", "2"]) class TestSlice(TestUsingServer): def test_both_bounds(self): diff --git a/testing/web-platform/tests/trusted-types/Document-write.tentative.html b/testing/web-platform/tests/trusted-types/Document-write.tentative.html index 79247fb4d68e..87e9e724699e 100644 --- a/testing/web-platform/tests/trusted-types/Document-write.tentative.html +++ b/testing/web-platform/tests/trusted-types/Document-write.tentative.html @@ -4,10 +4,11 @@ diff --git a/testing/web-platform/tests/trusted-types/block-string-assignment-to-Document-write.tentative.html b/testing/web-platform/tests/trusted-types/block-string-assignment-to-Document-write.tentative.html index beb31445b475..5e7039705a82 100644 --- a/testing/web-platform/tests/trusted-types/block-string-assignment-to-Document-write.tentative.html +++ b/testing/web-platform/tests/trusted-types/block-string-assignment-to-Document-write.tentative.html @@ -9,14 +9,6 @@ + + diff --git a/testing/web-platform/tests/webrtc/RTCDTMFSender-helper.js b/testing/web-platform/tests/webrtc/RTCDTMFSender-helper.js index 1dd2bccb361d..84cc771dda28 100644 --- a/testing/web-platform/tests/webrtc/RTCDTMFSender-helper.js +++ b/testing/web-platform/tests/webrtc/RTCDTMFSender-helper.js @@ -109,12 +109,16 @@ function test_tone_change_events(testFunc, toneChanges, desc) { const now = Date.now(); const duration = now - lastEventTime; - assert_approx_equals(duration, expectedDuration, 400, + // We check that the delay is at least the expected one, but + // system load may cause random delay, so we do not put any + // realistic upper bound on the timing of the event. + assert_between_inclusive(duration, expectedDuration, + expectedDuration + 4000, `Expect tonechange event for "${tone}" to be fired approximately after ${expectedDuration} milliseconds`); lastEventTime = now; - if(toneChanges.length === 0) { + if (toneChanges.length === 0) { // Wait for same duration as last expected duration + 100ms // before passing test in case there are new tone events fired, // in which case the test should fail. diff --git a/testing/web-platform/tests/webrtc/RTCDTMFSender-ontonechange.https.html b/testing/web-platform/tests/webrtc/RTCDTMFSender-ontonechange.https.html index 6beefb5287d6..ff6d117b3c75 100644 --- a/testing/web-platform/tests/webrtc/RTCDTMFSender-ontonechange.https.html +++ b/testing/web-platform/tests/webrtc/RTCDTMFSender-ontonechange.https.html @@ -161,13 +161,7 @@ test_tone_change_events((t, dtmfSender) => { dtmfSender.addEventListener('tonechange', ev => { if(ev.tone === 'B') { - // Set a timeout to make sure the toneBuffer - // is changed after the tonechange event listener - // by test_tone_change_events is called. - // This is to correctly test the expected toneBuffer. - t.step_timeout(() => { - dtmfSender.insertDTMF('12', 100, 70); - }, 10); + dtmfSender.insertDTMF('12', 100, 70); } }); @@ -189,10 +183,8 @@ test_tone_change_events((t, dtmfSender) => { dtmfSender.addEventListener('tonechange', ev => { if(ev.tone === 'B') { - t.step_timeout(() => { - dtmfSender.insertDTMF('12', 100, 70); - dtmfSender.insertDTMF('34', 100, 70); - }, 10); + dtmfSender.insertDTMF('12', 100, 70); + dtmfSender.insertDTMF('34', 100, 70); } }); @@ -213,9 +205,7 @@ test_tone_change_events((t, dtmfSender) => { dtmfSender.addEventListener('tonechange', ev => { if(ev.tone === 'B') { - t.step_timeout(() => { - dtmfSender.insertDTMF(''); - }, 10); + dtmfSender.insertDTMF(''); } }); diff --git a/testing/web-platform/tests/xhr/setrequestheader-header-allowed.htm b/testing/web-platform/tests/xhr/setrequestheader-header-allowed.htm index cd11e334a0f3..14b7187d3ac6 100644 --- a/testing/web-platform/tests/xhr/setrequestheader-header-allowed.htm +++ b/testing/web-platform/tests/xhr/setrequestheader-header-allowed.htm @@ -28,6 +28,7 @@ request("If") request("Status-URI") request("X-Pink-Unicorn") + request("!#$%&'*+-.^_`|~0123456789abcdefghijklmnopqrstuvwxyz") diff --git a/toolkit/components/extensions/webrequest/ChannelWrapper.cpp b/toolkit/components/extensions/webrequest/ChannelWrapper.cpp index 7b203232cffa..2a96a76531b1 100644 --- a/toolkit/components/extensions/webrequest/ChannelWrapper.cpp +++ b/toolkit/components/extensions/webrequest/ChannelWrapper.cpp @@ -16,6 +16,7 @@ #include "nsITransportSecurityInfo.h" #include "mozilla/AddonManagerWebAPI.h" +#include "mozilla/ClearOnShutdown.h" #include "mozilla/ErrorNames.h" #include "mozilla/ResultExtensions.h" #include "mozilla/Unused.h" @@ -32,6 +33,7 @@ #include "nsIProxiedChannel.h" #include "nsIProxyInfo.h" #include "nsITraceableChannel.h" +#include "nsIWritablePropertyBag.h" #include "nsIWritablePropertyBag2.h" #include "nsNetUtil.h" #include "nsProxyRelease.h" @@ -45,12 +47,81 @@ namespace extensions { #define CHANNELWRAPPER_PROP_KEY NS_LITERAL_STRING("ChannelWrapper::CachedInstance") +/***************************************************************************** + * Lifetimes + *****************************************************************************/ + +namespace { +class ChannelListHolder : public LinkedList +{ +public: + ChannelListHolder() + : LinkedList() + {} + + ~ChannelListHolder(); +}; + +} // anonymous namespace + +ChannelListHolder::~ChannelListHolder() +{ + while (ChannelWrapper* wrapper = popFirst()) { + wrapper->Die(); + } +} + + +static LinkedList& +ChannelList() +{ + static UniquePtr sChannelList; + if (!sChannelList) { + sChannelList.reset(new ChannelListHolder()); + ClearOnShutdown(&sChannelList, ShutdownPhase::Shutdown); + } + return *sChannelList; +} + +NS_IMPL_CYCLE_COLLECTING_ADDREF(ChannelWrapper::ChannelWrapperStub) +NS_IMPL_CYCLE_COLLECTING_RELEASE(ChannelWrapper::ChannelWrapperStub) + +NS_IMPL_CYCLE_COLLECTION(ChannelWrapper::ChannelWrapperStub, mChannelWrapper) + +NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(ChannelWrapper::ChannelWrapperStub) + NS_INTERFACE_MAP_ENTRY_TEAROFF(ChannelWrapper, mChannelWrapper) + NS_INTERFACE_MAP_ENTRY(nsISupports) +NS_INTERFACE_MAP_END + /***************************************************************************** * Initialization *****************************************************************************/ -/* static */ +ChannelWrapper::ChannelWrapper(nsISupports* aParent, nsIChannel* aChannel) + : ChannelHolder(aChannel) + , mParent(aParent) +{ + mStub = new ChannelWrapperStub(this); + ChannelList().insertBack(this); +} + +ChannelWrapper::~ChannelWrapper() +{ + if (LinkedListElement::isInList()) { + LinkedListElement::remove(); + } +} + +void +ChannelWrapper::Die() +{ + if (mStub) { + mStub->mChannelWrapper = nullptr; + } +} + +/* static */ already_AddRefed ChannelWrapper::Get(const GlobalObject& global, nsIChannel* channel) { @@ -72,7 +143,7 @@ ChannelWrapper::Get(const GlobalObject& global, nsIChannel* channel) wrapper = new ChannelWrapper(global.GetAsSupports(), channel); if (props) { Unused << props->SetPropertyAsInterface(CHANNELWRAPPER_PROP_KEY, - wrapper); + wrapper->mStub); } } @@ -1055,10 +1126,12 @@ NS_INTERFACE_MAP_END_INHERITING(DOMEventTargetHelper) NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(ChannelWrapper, DOMEventTargetHelper) NS_IMPL_CYCLE_COLLECTION_UNLINK(mParent) + NS_IMPL_CYCLE_COLLECTION_UNLINK(mStub) NS_IMPL_CYCLE_COLLECTION_UNLINK_END NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(ChannelWrapper, DOMEventTargetHelper) NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mParent) + NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mStub) NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN_INHERITED(ChannelWrapper, DOMEventTargetHelper) diff --git a/toolkit/components/extensions/webrequest/ChannelWrapper.h b/toolkit/components/extensions/webrequest/ChannelWrapper.h index e662284bd417..d0c4db2250f0 100644 --- a/toolkit/components/extensions/webrequest/ChannelWrapper.h +++ b/toolkit/components/extensions/webrequest/ChannelWrapper.h @@ -15,6 +15,7 @@ #include "mozilla/extensions/WebExtensionPolicy.h" #include "mozilla/Attributes.h" +#include "mozilla/LinkedList.h" #include "mozilla/Maybe.h" #include "mozilla/UniquePtr.h" #include "mozilla/WeakPtr.h" @@ -111,6 +112,7 @@ class WebRequestChannelEntry; class ChannelWrapper final : public DOMEventTargetHelper , public SupportsWeakPtr + , public LinkedListElement , private detail::ChannelHolder { public: @@ -120,6 +122,8 @@ public: NS_DECLARE_STATIC_IID_ACCESSOR(NS_CHANNELWRAPPER_IID) + void Die(); + static already_AddRefed Get(const dom::GlobalObject& global, nsIChannel* channel); static already_AddRefed GetRegisteredChannel(const dom::GlobalObject& global, uint64_t aChannelId, const WebExtensionPolicy& aAddon, nsITabParent* aTabParent); @@ -241,13 +245,10 @@ public: JSObject* WrapObject(JSContext* aCx, JS::HandleObject aGivenProto) override; protected: - ~ChannelWrapper() = default; + ~ChannelWrapper(); private: - ChannelWrapper(nsISupports* aParent, nsIChannel* aChannel) - : ChannelHolder(aChannel) - , mParent(aParent) - {} + ChannelWrapper(nsISupports* aParent, nsIChannel* aChannel); void ClearCachedAttributes(); @@ -279,6 +280,27 @@ private: void CheckEventListeners(); + class ChannelWrapperStub final : public nsISupports + { + public: + NS_DECL_CYCLE_COLLECTING_ISUPPORTS + NS_DECL_CYCLE_COLLECTION_CLASS(ChannelWrapperStub) + + explicit ChannelWrapperStub(ChannelWrapper* aChannelWrapper) + : mChannelWrapper(aChannelWrapper) + {} + + private: + friend class ChannelWrapper; + + RefPtr mChannelWrapper; + + protected: + ~ChannelWrapperStub() = default; + }; + + RefPtr mStub; + mutable Maybe mFinalURLInfo; mutable Maybe mDocumentURLInfo; diff --git a/toolkit/components/telemetry/Histograms.json b/toolkit/components/telemetry/Histograms.json index ca50d0dada75..79b47bcb2caf 100644 --- a/toolkit/components/telemetry/Histograms.json +++ b/toolkit/components/telemetry/Histograms.json @@ -53,6 +53,15 @@ "high": 60000, "n_buckets": 50 }, + "ABOUT_CONFIG_FEATURES_USAGE": { + "record_in_processes": ["main"], + "alert_emails": ["pamadini@mozilla.com"], + "expires_in_version": "67", + "kind": "categorical", + "labels": ["Show", "Search", "RegexSearch", "SortByName", "SortByStatus", "SortByType", "SortByValue", "ModifyValue", "Copy", "CopyName", "CopyValue", "CreateNew", "Reset"], + "bug_numbers": [1493445], + "description": "Record number of times particular features on about:config are used" + }, "ADDON_MANAGER_UPGRADE_UI_SHOWN": { "record_in_processes": ["main", "content"], "expires_in_version": "53", diff --git a/toolkit/components/telemetry/pingsender/pingsender.exe.manifest b/toolkit/components/telemetry/pingsender/pingsender.exe.manifest new file mode 100644 index 000000000000..8e4bb8749bce --- /dev/null +++ b/toolkit/components/telemetry/pingsender/pingsender.exe.manifest @@ -0,0 +1,19 @@ + + + + + + + + + diff --git a/toolkit/components/viewconfig/content/config.js b/toolkit/components/viewconfig/content/config.js index 2adf226db83e..7f081432fc9e 100644 --- a/toolkit/components/viewconfig/content/config.js +++ b/toolkit/components/viewconfig/content/config.js @@ -33,6 +33,8 @@ var gSortFunction = null; var gSortDirection = 1; // 1 is ascending; -1 is descending var gFilter = null; +let gCategoriesRecordedOnce = new Set(); + var view = { get rowCount() { return gPrefView.length; }, getCellText(index, col) { @@ -74,6 +76,7 @@ var view = { toggleOpenState(index) {}, cycleHeader(col) { var index = this.selection.currentIndex; + recordTelemetryOnce(gCategoryLabelForSortColumn[col.id]); if (col.id == gSortedColumn) { gSortDirection = -gSortDirection; gPrefArray.reverse(); @@ -331,6 +334,7 @@ async function onConfigLoad() { // Unhide the warning message function ShowPrefs() { + recordTelemetryOnce("Show"); gPrefBranch.getChildList("").forEach(fetchPref); var descending = document.getElementsByAttribute("sortDirection", "descending"); @@ -390,6 +394,7 @@ function FilterPrefs() { var substring = document.getElementById("textbox").value; // Check for "/regex/[i]" if (substring.charAt(0) == "/") { + recordTelemetryOnce("RegexSearch"); var r = substring.match(/^\/(.*)\/(i?)$/); try { gFilter = RegExp(r[1], r[2]); @@ -397,6 +402,7 @@ function FilterPrefs() { return; // Do nothing on incomplete or bad RegExp } } else if (substring) { + recordTelemetryOnce("Search"); gFilter = RegExp(substring.replace(/([^* \w])/g, "\\$1") .replace(/^\*+/, "").replace(/\*+/g, ".*"), "i"); } else { @@ -454,6 +460,13 @@ const gSortFunctions = valueCol: valueColSortFunction, }; +const gCategoryLabelForSortColumn = { + prefCol: "SortByName", + lockCol: "SortByStatus", + typeCol: "SortByType", + valueCol: "SortByValue", +}; + const configController = { supportsCommand: function supportsCommand(command) { return command == "cmd_copy"; @@ -509,29 +522,35 @@ function updateContextMenu() { } function copyPref() { + recordTelemetryOnce("Copy"); var pref = gPrefView[view.selection.currentIndex]; gClipboardHelper.copyString(pref.prefCol + ";" + pref.valueCol); } function copyName() { + recordTelemetryOnce("CopyName"); gClipboardHelper.copyString(gPrefView[view.selection.currentIndex].prefCol); } function copyValue() { + recordTelemetryOnce("CopyValue"); gClipboardHelper.copyString(gPrefView[view.selection.currentIndex].valueCol); } function ModifySelected() { + recordTelemetryOnce("ModifyValue"); if (view.selection.currentIndex >= 0) ModifyPref(gPrefView[view.selection.currentIndex]); } function ResetSelected() { + recordTelemetryOnce("Reset"); var entry = gPrefView[view.selection.currentIndex]; gPrefBranch.clearUserPref(entry.prefCol); } async function NewPref(type) { + recordTelemetryOnce("CreateNew"); var result = { value: "" }; var dummy = { value: 0 }; @@ -609,3 +628,13 @@ async function ModifyPref(entry) { Services.prefs.savePrefFile(null); return true; } + +function recordTelemetryOnce(categoryLabel) { + if (!gCategoriesRecordedOnce.has(categoryLabel)) { + // Don't raise an exception if Telemetry is not available. + try { + Services.telemetry.getHistogramById("ABOUT_CONFIG_FEATURES_USAGE").add(categoryLabel); + } catch (ex) {} + gCategoriesRecordedOnce.add(categoryLabel); + } +} diff --git a/toolkit/crashreporter/minidump-analyzer/minidump-analyzer.exe.manifest b/toolkit/crashreporter/minidump-analyzer/minidump-analyzer.exe.manifest new file mode 100644 index 000000000000..731502e805d3 --- /dev/null +++ b/toolkit/crashreporter/minidump-analyzer/minidump-analyzer.exe.manifest @@ -0,0 +1,19 @@ + + + + + + + + + diff --git a/toolkit/mozapps/installer/packager.py b/toolkit/mozapps/installer/packager.py index 0ea4713c6992..50da87f6a8ab 100644 --- a/toolkit/mozapps/installer/packager.py +++ b/toolkit/mozapps/installer/packager.py @@ -311,8 +311,9 @@ def main(): LibSignFile(os.path.join(args.destination, libname))) - # Include pdb files for llvm-symbolizer to resolve symbols. - if buildconfig.substs.get('LLVM_SYMBOLIZER') and mozinfo.isWin: + # If a pdb file is present and we were instructed to copy it, include it. + # Run on all OSes to capture MinGW builds + if buildconfig.substs.get('MOZ_COPY_PDBS'): for p, f in copier: if isinstance(f, ExecutableFile): pdbname = os.path.splitext(f.inputs()[0])[0] + '.pdb' diff --git a/toolkit/recordreplay/Assembler.cpp b/toolkit/recordreplay/Assembler.cpp index 335ac79f8227..3035c9325957 100644 --- a/toolkit/recordreplay/Assembler.cpp +++ b/toolkit/recordreplay/Assembler.cpp @@ -247,17 +247,11 @@ Assembler::MoveRaxToRegister(/*ud_type*/ int aRegister) { MOZ_RELEASE_ASSERT(aRegister == NormalizeRegister(aRegister)); - uint8_t* ip = Current(); if (aRegister <= UD_R_RDI) { - ip[0] = 0x48; - ip[1] = 0x89; - ip[2] = 0xC0 + aRegister - UD_R_RAX; + NewInstruction(0x48, 0x89, 0xC0 + aRegister - UD_R_RAX); } else { - ip[0] = 0x49; - ip[1] = 0x89; - ip[2] = 0xC0 + aRegister - UD_R_R8; + NewInstruction(0x49, 0x89, 0xC0 + aRegister - UD_R_R8); } - Advance(3); } void @@ -265,17 +259,29 @@ Assembler::MoveRegisterToRax(/*ud_type*/ int aRegister) { MOZ_RELEASE_ASSERT(aRegister == NormalizeRegister(aRegister)); - uint8_t* ip = Current(); if (aRegister <= UD_R_RDI) { - ip[0] = 0x48; - ip[1] = 0x89; - ip[2] = 0xC0 + (aRegister - UD_R_RAX) * 8; + NewInstruction(0x48, 0x89, 0xC0 + (aRegister - UD_R_RAX) * 8); } else { - ip[0] = 0x4C; - ip[1] = 0x89; - ip[2] = 0xC0 + (aRegister - UD_R_R8) * 8; + NewInstruction(0x4C, 0x89, 0xC0 + (aRegister - UD_R_R8) * 8); } - Advance(3); +} + +void +Assembler::ExchangeByteRegisterWithAddressAtRbx(/*ud_type*/ int aRegister) +{ + MOZ_RELEASE_ASSERT(aRegister == NormalizeRegister(aRegister)); + + if (aRegister <= UD_R_RDI) { + NewInstruction(0x86, 0x03 + (aRegister - UD_R_RAX) * 8); + } else { + NewInstruction(0x44, 0x86, 0x03 + (aRegister - UD_R_R8) * 8); + } +} + +void +Assembler::ExchangeByteRbxWithAddressAtRax() +{ + NewInstruction(0x86, 0x18); } /* static */ /*ud_type*/ int diff --git a/toolkit/recordreplay/Assembler.h b/toolkit/recordreplay/Assembler.h index ca5e870687d6..62e6b829acfd 100644 --- a/toolkit/recordreplay/Assembler.h +++ b/toolkit/recordreplay/Assembler.h @@ -88,6 +88,12 @@ public: // movq register, %rax void MoveRegisterToRax(/*ud_type*/ int aRegister); + // xchgb register, 0(%rbx) + void ExchangeByteRegisterWithAddressAtRbx(/*ud_type*/ int aRegister); + + // xchgb $bl, 0(%rax) + void ExchangeByteRbxWithAddressAtRax(); + // Normalize a Udis86 register to its 8 byte version, returning UD_NONE/zero // for unexpected registers. static /*ud_type*/ int NormalizeRegister(/*ud_type*/ int aRegister); diff --git a/toolkit/recordreplay/ProcessRedirect.cpp b/toolkit/recordreplay/ProcessRedirect.cpp index 0eb38b0aa3f3..9aa859099b67 100644 --- a/toolkit/recordreplay/ProcessRedirect.cpp +++ b/toolkit/recordreplay/ProcessRedirect.cpp @@ -536,6 +536,35 @@ CopySpecialInstruction(uint8_t* aIp, ud_t* aUd, size_t aNbytes, Assembler& aAsse } } + if (mnemonic == UD_Ixchg) { + const ud_operand* dst = ud_insn_opr(aUd, 0); + const ud_operand* src = ud_insn_opr(aUd, 1); + if (src->type == UD_OP_REG && src->size == 8 && + dst->type == UD_OP_MEM && dst->base == UD_R_RIP && !dst->index && dst->offset == 32) { + // xchgb reg, $offset32(%rip) + int reg = Assembler::NormalizeRegister(src->base); + if (!reg) { + return false; + } + uint8_t* addr = aIp + aNbytes + dst->lval.sdword; + if (reg == UD_R_RBX) { + aAssembler.PushRax(); + aAssembler.MoveImmediateToRax(addr); + aAssembler.ExchangeByteRbxWithAddressAtRax(); + aAssembler.PopRax(); + } else { + aAssembler.PushRbx(); + aAssembler.PushRax(); + aAssembler.MoveImmediateToRax(addr); + aAssembler.MoveRaxToRegister(UD_R_RBX); + aAssembler.PopRax(); + aAssembler.ExchangeByteRegisterWithAddressAtRbx(reg); + aAssembler.PopRbx(); + } + return true; + } + } + return false; } diff --git a/widget/cocoa/nsClipboard.mm b/widget/cocoa/nsClipboard.mm index 2463eb71a776..96cd5c651d6e 100644 --- a/widget/cocoa/nsClipboard.mm +++ b/widget/cocoa/nsClipboard.mm @@ -427,7 +427,7 @@ nsClipboard::HasDataMatchingFlavors(const char** aFlavorList, uint32_t aLength, nsresult rv = mTransferable->FlavorsTransferableCanImport(flavors); if (NS_SUCCEEDED(rv)) { for (uint32_t j = 0; j < flavors.Length(); j++) { - nsCString transferableFlavorStr = flavors[j]; + const nsCString& transferableFlavorStr = flavors[j]; for (uint32_t k = 0; k < aLength; k++) { if (transferableFlavorStr.Equals(aFlavorList[k])) { diff --git a/widget/cocoa/nsDragService.mm b/widget/cocoa/nsDragService.mm index 9d051edf09c0..288f74eabb42 100644 --- a/widget/cocoa/nsDragService.mm +++ b/widget/cocoa/nsDragService.mm @@ -582,7 +582,7 @@ nsDragService::IsDataFlavorSupported(const char *aDataFlavor, bool *_retval) continue; for (uint32_t j = 0; j < flavors.Length(); j++) { - if (dataFlavor.Equals(flavors[i])) { + if (dataFlavor.Equals(flavors[j])) { *_retval = true; return NS_OK; } diff --git a/widget/windows/nsWindow.cpp b/widget/windows/nsWindow.cpp index 5eabc2f5455e..197ce80000d8 100644 --- a/widget/windows/nsWindow.cpp +++ b/widget/windows/nsWindow.cpp @@ -6,7 +6,7 @@ /* * nsWindow - Native window management and event handling. - * + * * nsWindow is organized into a set of major blocks and * block subsections. The layout is as follows: * @@ -228,7 +228,7 @@ using namespace mozilla::plugins; ** ** BLOCK: Variables ** - ** nsWindow Class static initializations and global variables. + ** nsWindow Class static initializations and global variables. ** ************************************************************** **************************************************************/ @@ -865,7 +865,7 @@ nsWindow::Create(nsIWidget* aParent, mDefaultScale = -1.0; if (mIsRTL) { - DWORD dwAttribute = TRUE; + DWORD dwAttribute = TRUE; DwmSetWindowAttribute(mWnd, DWMWA_NONCLIENT_RTL_LAYOUT, &dwAttribute, sizeof dwAttribute); } @@ -1002,7 +1002,7 @@ void nsWindow::Destroy() // function first destroys child or owned windows, and then it destroys the parent or owner // window. VERIFY(::DestroyWindow(mWnd)); - + // Our windows can be subclassed which may prevent us receiving WM_DESTROY. If OnDestroy() // didn't get called, call it now. if (false == mOnDestroyCalled) { @@ -1391,7 +1391,7 @@ nsWindow::GetParentWindowBase(bool aIncludeOwner) return static_cast(widget); } - + BOOL CALLBACK nsWindow::EnumAllChildWindProc(HWND aWnd, LPARAM aParam) { @@ -1718,7 +1718,7 @@ void nsWindow::SetThemeRegion() (mPopupType == ePopupTypeTooltip || mPopupType == ePopupTypePanel))) { HRGN hRgn = nullptr; RECT rect = {0,0,mBounds.Width(),mBounds.Height()}; - + HDC dc = ::GetDC(mWnd); GetThemeBackgroundRegion(nsUXThemeData::GetTheme(eUXTooltip), dc, TTP_STANDARD, TS_NORMAL, &rect, &hRgn); if (hRgn) { @@ -2501,13 +2501,13 @@ GetWindowInfoHook(HWND hWnd, PWINDOWINFO pwi) NS_ASSERTION(FALSE, "Something is horribly wrong in GetWindowInfoHook!"); return FALSE; } - int windowStatus = + int windowStatus = reinterpret_cast(GetPropW(hWnd, kManageWindowInfoProperty)); // No property set, return the default data. if (!windowStatus) return sGetWindowInfoPtrStub(hWnd, pwi); // Call GetWindowInfo and update dwWindowStatus with our - // internally tracked value. + // internally tracked value. BOOL result = sGetWindowInfoPtrStub(hWnd, pwi); if (result && pwi) pwi->dwWindowStatus = (windowStatus == 1 ? 0 : WS_ACTIVECAPTION); @@ -2776,7 +2776,7 @@ nsWindow::InvalidateNonClientRegion() // | | app content | | } area we don't want to invalidate // | +-----------------------+ | } // | | app client chrome | | } - // | +-----------------------+ | + // | +-----------------------+ | // +---------------------------+ < // ^ ^ windows non-client chrome // client area = app * @@ -2994,7 +2994,7 @@ nsWindow::SetCursor(nsCursor aCursor) if (nullptr != newCursor) { mCursor = aCursor; HCURSOR oldCursor = ::SetCursor(newCursor); - + if (sHCursor == oldCursor) { NS_IF_RELEASE(sCursorImgContainer); if (sHCursor != nullptr) @@ -3721,7 +3721,7 @@ nsWindow::SetIcon(const nsAString& aIconSpec) else { NS_LossyConvertUTF16toASCII cPath(iconPath); MOZ_LOG(gWindowsLog, LogLevel::Info, - ("\nIcon load error; icon=%s, rc=0x%08X\n\n", + ("\nIcon load error; icon=%s, rc=0x%08X\n\n", cPath.get(), ::GetLastError())); } #endif @@ -3735,7 +3735,7 @@ nsWindow::SetIcon(const nsAString& aIconSpec) else { NS_LossyConvertUTF16toASCII cPath(iconPath); MOZ_LOG(gWindowsLog, LogLevel::Info, - ("\nSmall icon load error; icon=%s, rc=0x%08X\n\n", + ("\nSmall icon load error; icon=%s, rc=0x%08X\n\n", cPath.get(), ::GetLastError())); } #endif @@ -3881,7 +3881,7 @@ nsWindow::GetAttention(int32_t aCycleCount) HWND fgWnd = ::GetForegroundWindow(); // Don't flash if the flash count is 0 or if the foreground window is our // window handle or that of our owned-most window. - if (aCycleCount == 0 || + if (aCycleCount == 0 || flashWnd == fgWnd || flashWnd == WinUtils::GetTopLevelHWND(fgWnd, false, false)) { return NS_OK; @@ -4139,7 +4139,7 @@ nsWindow::SetWindowClass(const nsAString& xulWinType) ** ** BLOCK: Moz Events ** - ** Moz GUI event management. + ** Moz GUI event management. ** ************************************************************** **************************************************************/ @@ -4668,7 +4668,7 @@ nsWindow::DispatchMouseEvent(EventMessage aEventMessage, WPARAM wParam, if ((nullptr != sCurrentWindow) && (!sCurrentWindow->mInDtor)) { LPARAM pos = sCurrentWindow->lParamToClient(lParamToScreen(lParam)); sCurrentWindow->DispatchMouseEvent(eMouseExitFromWidget, - wParam, pos, false, + wParam, pos, false, WidgetMouseEvent::eLeftButton, aInputSource, aPointerInfo); } @@ -5266,7 +5266,7 @@ nsWindow::ProcessMessage(UINT msg, WPARAM& wParam, LPARAM& lParam, case WM_THEMECHANGED: { - // Update non-client margin offsets + // Update non-client margin offsets UpdateNonClientMargins(); nsUXThemeData::UpdateNativeThemeInfo(); @@ -5971,7 +5971,7 @@ nsWindow::ProcessMessage(UINT msg, WPARAM& wParam, LPARAM& lParam, DispatchMouseEvent(eMouseDoubleClick, 0, lParamToClient(lParam), false, WidgetMouseEvent::eLeftButton, MOUSE_INPUT_SOURCE()); - result = + result = DispatchMouseEvent(eMouseUp, 0, lParamToClient(lParam), false, WidgetMouseEvent::eLeftButton, MOUSE_INPUT_SOURCE()); @@ -6393,7 +6393,7 @@ BOOL CALLBACK nsWindow::BroadcastMsg(HWND aTopWindow, LPARAM aMsg) * * SECTION: Event processing helpers * - * Special processing for certain event types and + * Special processing for certain event types and * synthesized events. * **************************************************************/ @@ -6752,15 +6752,15 @@ void nsWindow::OnWindowPosChanged(WINDOWPOS* wp) #ifdef WINSTATE_DEBUG_OUTPUT switch (mSizeMode) { case nsSizeMode_Normal: - MOZ_LOG(gWindowsLog, LogLevel::Info, + MOZ_LOG(gWindowsLog, LogLevel::Info, ("*** mSizeMode: nsSizeMode_Normal\n")); break; case nsSizeMode_Minimized: - MOZ_LOG(gWindowsLog, LogLevel::Info, + MOZ_LOG(gWindowsLog, LogLevel::Info, ("*** mSizeMode: nsSizeMode_Minimized\n")); break; case nsSizeMode_Maximized: - MOZ_LOG(gWindowsLog, LogLevel::Info, + MOZ_LOG(gWindowsLog, LogLevel::Info, ("*** mSizeMode: nsSizeMode_Maximized\n")); break; default: @@ -6772,7 +6772,7 @@ void nsWindow::OnWindowPosChanged(WINDOWPOS* wp) if (mWidgetListener && mSizeMode != previousSizeMode) mWidgetListener->SizeModeChanged(mSizeMode); - // If window was restored, window activation was bypassed during the + // If window was restored, window activation was bypassed during the // SetSizeMode call originating from OnWindowPosChanging to avoid saving // pre-restore attributes. Force activation now to get correct attributes. if (mLastSizeMode != nsSizeMode_Normal && mSizeMode == nsSizeMode_Normal) @@ -6841,8 +6841,8 @@ void nsWindow::OnWindowPosChanged(WINDOWPOS* wp) mLastSize.height = newHeight; #ifdef WINSTATE_DEBUG_OUTPUT - MOZ_LOG(gWindowsLog, LogLevel::Info, - ("*** Resize window: %d x %d x %d x %d\n", wp->x, wp->y, + MOZ_LOG(gWindowsLog, LogLevel::Info, + ("*** Resize window: %d x %d x %d x %d\n", wp->x, wp->y, newWidth, newHeight)); #endif @@ -6882,7 +6882,7 @@ void nsWindow::OnWindowPosChanging(LPWINDOWPOS& info) // Update non-client margins if the frame size is changing, and let the // browser know we are changing size modes, so alternative css can kick in. // If we're going into fullscreen mode, ignore this, since it'll reset - // margins to normal mode. + // margins to normal mode. if ((info->flags & SWP_FRAMECHANGED && !(info->flags & SWP_NOSIZE)) && mSizeMode != nsSizeMode_Fullscreen) { WINDOWPLACEMENT pl; @@ -7114,7 +7114,7 @@ bool nsWindow::OnGesture(WPARAM wParam, LPARAM lParam) if ( !mGesture.ProcessGestureMessage(mWnd, wParam, lParam, event) ) { return false; // fall through to DefWndProc } - + // Polish up and send off the new event ModifierKeyState modifierKeyState; modifierKeyState.InitInputEvent(event); @@ -7256,7 +7256,7 @@ void nsWindow::OnDestroy() // Make sure we don't get destroyed in the process of tearing down. nsCOMPtr kungFuDeathGrip(this); - + // Dispatch the destroy notification. if (!mInDtor) NotifyWindowDestroyed(); @@ -7282,7 +7282,7 @@ void nsWindow::OnDestroy() // Release references to children, device context, toolkit, and app shell. nsBaseWidget::OnDestroy(); - + // Clear our native parent handle. // XXX Windows will take care of this in the proper order, and SetParent(nullptr)'s // remove child on the parent already took place in nsBaseWidget's Destroy call above. @@ -7683,14 +7683,14 @@ LRESULT CALLBACK nsWindow::MozSpecialMsgFilter(int code, WPARAM wParam, LPARAM l if (code != gLastMsgCode) { if (gMSGFEvents[inx].mId == code) { #ifdef DEBUG - MOZ_LOG(gWindowsLog, LogLevel::Info, - ("MozSpecialMessageProc - code: 0x%X - %s hw: %p\n", + MOZ_LOG(gWindowsLog, LogLevel::Info, + ("MozSpecialMessageProc - code: 0x%X - %s hw: %p\n", code, gMSGFEvents[inx].mStr, pMsg->hwnd)); #endif } else { #ifdef DEBUG - MOZ_LOG(gWindowsLog, LogLevel::Info, - ("MozSpecialMessageProc - code: 0x%X - %d hw: %p\n", + MOZ_LOG(gWindowsLog, LogLevel::Info, + ("MozSpecialMessageProc - code: 0x%X - %d hw: %p\n", code, gMSGFEvents[inx].mId, pMsg->hwnd)); #endif } @@ -7775,7 +7775,7 @@ void nsWindow::RegisterSpecialDropdownHooks() nullptr, GetCurrentThreadId()); #ifdef POPUP_ROLLUP_DEBUG_OUTPUT if (!sMsgFilterHook) { - MOZ_LOG(gWindowsLog, LogLevel::Info, + MOZ_LOG(gWindowsLog, LogLevel::Info, ("***** SetWindowsHookEx is NOT installed for WH_MSGFILTER!\n")); } #endif @@ -7788,7 +7788,7 @@ void nsWindow::RegisterSpecialDropdownHooks() nullptr, GetCurrentThreadId()); #ifdef POPUP_ROLLUP_DEBUG_OUTPUT if (!sCallProcHook) { - MOZ_LOG(gWindowsLog, LogLevel::Info, + MOZ_LOG(gWindowsLog, LogLevel::Info, ("***** SetWindowsHookEx is NOT installed for WH_CALLWNDPROC!\n")); } #endif @@ -7801,7 +7801,7 @@ void nsWindow::RegisterSpecialDropdownHooks() nullptr, GetCurrentThreadId()); #ifdef POPUP_ROLLUP_DEBUG_OUTPUT if (!sCallMouseHook) { - MOZ_LOG(gWindowsLog, LogLevel::Info, + MOZ_LOG(gWindowsLog, LogLevel::Info, ("***** SetWindowsHookEx is NOT installed for WH_MOUSE!\n")); } #endif @@ -7869,7 +7869,7 @@ BOOL CALLBACK nsWindow::ClearResourcesCallback(HWND aWnd, LPARAM aMsg) nsWindow *window = WinUtils::GetNSWindowPtr(aWnd); if (window) { window->ClearCachedResources(); - } + } return TRUE; } diff --git a/xpcom/build/XPCOMInit.cpp b/xpcom/build/XPCOMInit.cpp index bef4f22c55bb..5897fc1b4d86 100644 --- a/xpcom/build/XPCOMInit.cpp +++ b/xpcom/build/XPCOMInit.cpp @@ -199,7 +199,6 @@ NS_GENERIC_FACTORY_CONSTRUCTOR(nsSupportsDouble) NS_GENERIC_FACTORY_CONSTRUCTOR(nsSupportsInterfacePointer) NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsConsoleService, Init) -NS_GENERIC_FACTORY_CONSTRUCTOR(nsTimer) NS_GENERIC_FACTORY_CONSTRUCTOR(nsBinaryOutputStream) NS_GENERIC_FACTORY_CONSTRUCTOR(nsBinaryInputStream) NS_GENERIC_FACTORY_CONSTRUCTOR(nsStorageStream) diff --git a/xpcom/build/XPCOMModule.inc b/xpcom/build/XPCOMModule.inc index 376d2bcd7e24..a57f81369ff5 100644 --- a/xpcom/build/XPCOMModule.inc +++ b/xpcom/build/XPCOMModule.inc @@ -16,7 +16,7 @@ COMPONENT(CONSOLESERVICE, nsConsoleServiceConstructor) COMPONENT_M(OBSERVERSERVICE, nsObserverService::Create, Module::ALLOW_IN_GPU_PROCESS) - COMPONENT_M(TIMER, nsTimerConstructor, Module::ALLOW_IN_GPU_PROCESS) + COMPONENT_M(TIMER, nsTimer::XPCOMConstructor, Module::ALLOW_IN_GPU_PROCESS) #define COMPONENT_SUPPORTS(TYPE, Type) \ COMPONENT(SUPPORTS_##TYPE, nsSupports##Type##Constructor) diff --git a/xpcom/reflect/xptcall/md/unix/xptcstubs_ppc64_linux.cpp b/xpcom/reflect/xptcall/md/unix/xptcstubs_ppc64_linux.cpp index 073dee2abba8..edf2dcd69ea3 100644 --- a/xpcom/reflect/xptcall/md/unix/xptcstubs_ppc64_linux.cpp +++ b/xpcom/reflect/xptcall/md/unix/xptcstubs_ppc64_linux.cpp @@ -66,6 +66,8 @@ PrepareAndDispatch(nsXPTCStubBase* self, const uint8_t indexOfJSContext = info->IndexOfJSContext(); uint64_t* ap = args; + uint32_t iCount = 0; + uint32_t fpCount = 0; uint64_t tempu64; for(i = 0; i < paramCount; i++) { @@ -73,16 +75,23 @@ PrepareAndDispatch(nsXPTCStubBase* self, const nsXPTType& type = param.GetType(); nsXPTCMiniVariant* dp = &dispatchParams[i]; - MOZ_CRASH("NYI: support implicit JSContext*, bug 1475699"); + if (i == indexOfJSContext) { + if (iCount < GPR_COUNT) + iCount++; + else + ap++; + } if (!param.IsOut() && type == nsXPTType::T_DOUBLE) { - if (i < FPR_COUNT) - dp->val.d = fprData[i]; + if (fpCount < FPR_COUNT) { + dp->val.d = fprData[fpCount++]; + } else dp->val.d = *(double*) ap; } else if (!param.IsOut() && type == nsXPTType::T_FLOAT) { - if (i < FPR_COUNT) - dp->val.f = (float) fprData[i]; // in registers floats are passed as doubles + if (fpCount < FPR_COUNT) { + dp->val.f = (float) fprData[fpCount++]; // in registers floats are passed as doubles + } else { float *p = (float *)ap; #ifndef __LITTLE_ENDIAN__ @@ -91,8 +100,8 @@ PrepareAndDispatch(nsXPTCStubBase* self, dp->val.f = *p; } } else { /* integer type or pointer */ - if (i < GPR_COUNT) - tempu64 = gprData[i]; + if (iCount < GPR_COUNT) + tempu64 = gprData[iCount]; else tempu64 = *ap; @@ -124,7 +133,9 @@ PrepareAndDispatch(nsXPTCStubBase* self, NS_ERROR("bad type"); } - if (i >= 7) + if (iCount < GPR_COUNT) + iCount++; // gprs are skipped for fp args, so this always needs inc + else ap++; } diff --git a/xpcom/threads/nsTimerImpl.cpp b/xpcom/threads/nsTimerImpl.cpp index f7304f12f4d3..8a12104079f9 100644 --- a/xpcom/threads/nsTimerImpl.cpp +++ b/xpcom/threads/nsTimerImpl.cpp @@ -60,17 +60,13 @@ NS_GetTimerDeadlineHintOnCurrentThread(TimeStamp aDefault, uint32_t aSearchBound already_AddRefed NS_NewTimer() { - return do_AddRef(new nsTimer()); + return NS_NewTimer(nullptr); } already_AddRefed NS_NewTimer(nsIEventTarget* aTarget) { - auto timer = MakeRefPtr(); - if (aTarget && MOZ_LIKELY(timer)) { - MOZ_ALWAYS_SUCCEEDS(timer->SetTarget(aTarget)); - } - return timer.forget(); + return nsTimer::WithEventTarget(aTarget).forget(); } mozilla::Result, nsresult> @@ -94,10 +90,7 @@ NS_NewTimerWithObserver(nsITimer** aTimer, uint32_t aType, nsIEventTarget* aTarget) { - auto timer = MakeRefPtr(); - if (aTarget) { - MOZ_ALWAYS_SUCCEEDS(timer->SetTarget(aTarget)); - } + auto timer = nsTimer::WithEventTarget(aTarget); MOZ_TRY(timer->Init(aObserver, aDelay, aType)); timer.forget(aTimer); @@ -125,10 +118,7 @@ NS_NewTimerWithCallback(nsITimer** aTimer, uint32_t aType, nsIEventTarget* aTarget) { - auto timer = MakeRefPtr(); - if (aTarget) { - MOZ_ALWAYS_SUCCEEDS(timer->SetTarget(aTarget)); - } + auto timer = nsTimer::WithEventTarget(aTarget); MOZ_TRY(timer->InitWithCallback(aCallback, aDelay, aType)); timer.forget(aTimer); @@ -156,10 +146,7 @@ NS_NewTimerWithCallback(nsITimer** aTimer, uint32_t aType, nsIEventTarget* aTarget) { - auto timer = MakeRefPtr(); - if (aTarget) { - MOZ_ALWAYS_SUCCEEDS(timer->SetTarget(aTarget)); - } + auto timer = nsTimer::WithEventTarget(aTarget); MOZ_TRY(timer->InitHighResolutionWithCallback(aCallback, aDelay, aType)); timer.forget(aTimer); @@ -193,10 +180,7 @@ NS_NewTimerWithFuncCallback(nsITimer** aTimer, const char* aNameString, nsIEventTarget* aTarget) { - auto timer = MakeRefPtr(); - if (aTarget) { - MOZ_ALWAYS_SUCCEEDS(timer->SetTarget(aTarget)); - } + auto timer = nsTimer::WithEventTarget(aTarget); MOZ_TRY(timer->InitWithNamedFuncCallback(aCallback, aClosure, aDelay, aType, @@ -232,10 +216,7 @@ NS_NewTimerWithFuncCallback(nsITimer** aTimer, nsTimerNameCallbackFunc aNameCallback, nsIEventTarget* aTarget) { - auto timer = MakeRefPtr(); - if (aTarget) { - MOZ_ALWAYS_SUCCEEDS(timer->SetTarget(aTarget)); - } + auto timer = nsTimer::WithEventTarget(aTarget); MOZ_TRY(timer->InitWithNameableFuncCallback(aCallback, aClosure, aDelay, aType, @@ -330,15 +311,17 @@ nsTimer::Release(void) return count; } -nsTimerImpl::nsTimerImpl(nsITimer* aTimer) : +nsTimerImpl::nsTimerImpl(nsITimer* aTimer, nsIEventTarget* aTarget) : + mEventTarget(aTarget), mHolder(nullptr), mType(0), mGeneration(0), mITimer(aTimer), mMutex("nsTimerImpl::mMutex") { - // XXXbsmedberg: shouldn't this be in Init()? - mEventTarget = mozilla::GetCurrentThreadEventTarget(); + // XXX some code creates timers during xpcom shutdown, when threads are no + // longer available, so we cannot turn this on yet. + //MOZ_ASSERT(mEventTarget); } //static @@ -910,6 +893,28 @@ nsTimer::SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const return aMallocSizeOf(this); } +/* static */ RefPtr +nsTimer::WithEventTarget(nsIEventTarget* aTarget) +{ + if (!aTarget) { + aTarget = mozilla::GetCurrentThreadEventTarget(); + } + return do_AddRef(new nsTimer(aTarget)); +} + +/* static */ nsresult +nsTimer::XPCOMConstructor(nsISupports* aOuter, REFNSIID aIID, void** aResult) +{ + *aResult = nullptr; + if (aOuter != nullptr) { + return NS_ERROR_NO_AGGREGATION; + } + + auto timer = WithEventTarget(nullptr); + + return timer->QueryInterface(aIID, aResult); +} + /* static */ const nsTimerImpl::Callback::NameNothing nsTimerImpl::Callback::Nothing = 0; diff --git a/xpcom/threads/nsTimerImpl.h b/xpcom/threads/nsTimerImpl.h index 1cb530c0be3d..95788f98a963 100644 --- a/xpcom/threads/nsTimerImpl.h +++ b/xpcom/threads/nsTimerImpl.h @@ -48,7 +48,7 @@ class nsTimerImpl public: typedef mozilla::TimeStamp TimeStamp; - explicit nsTimerImpl(nsITimer* aTimer); + nsTimerImpl(nsITimer* aTimer, nsIEventTarget* aTarget); NS_INLINE_DECL_THREADSAFE_REFCOUNTING(nsTimerImpl) NS_DECL_NON_VIRTUAL_NSITIMER @@ -219,10 +219,12 @@ public: class nsTimer final : public nsITimer { + explicit nsTimer(nsIEventTarget* aTarget) + : mImpl(new nsTimerImpl(this, aTarget)) + {} + virtual ~nsTimer(); public: - nsTimer() : mImpl(new nsTimerImpl(this)) {} - friend class TimerThread; friend class nsTimerEvent; @@ -231,6 +233,12 @@ public: virtual size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const override; + // Create a timer targeting the given target. nullptr indicates that the + // current thread should be used as the timer's target. + static RefPtr WithEventTarget(nsIEventTarget* aTarget); + + static nsresult XPCOMConstructor(nsISupports* aOuter, REFNSIID aIID, void** aResult); + private: // nsTimerImpl holds a strong ref to us. When our refcount goes to 1, we will // null this to break the cycle.
The text is arranged in pairs of three-letter 'words'. Test passes if the words in each pair match If you are missing a font glyph for a character, ignore that pair, but report which characters were ignored.
The text is arranged in pairs of three-letter 'words'. Test passes if there are NO uppercase letters. If you are missing a font glyph for a character, ignore that pair, but report which characters were ignored.
Test passes if both characters in each pair match. If you are missing a font glyph for a character, ignore that pair, but report which characters were ignored.
Image inserted further below.