new FontFace() should not throw when failing to parse arguments
authorcommit-queue@webkit.org <commit-queue@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sat, 15 Feb 2020 01:18:49 +0000 (01:18 +0000)
committercommit-queue@webkit.org <commit-queue@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sat, 15 Feb 2020 01:18:49 +0000 (01:18 +0000)
https://bugs.webkit.org/show_bug.cgi?id=205770

Patch by Nikos Mouchtaris <nmouchtaris@apple.com> on 2020-02-14
Reviewed by Myles Maxfield.

Source/WebCore:

Change FontFace constructor to conform to API specification:
https://drafts.csswg.org/css-font-loading/#dom-fontface-fontface.
No longer throws. For parsing failure, now rejects promise, sets
status to error, and sets FontFace members to default string.

Test: http/tests/css/font-face-constructor.html

* css/CSSFontFace.cpp:
(WebCore::CSSFontFace::setErrorState):
* css/CSSFontFace.h:
* css/CSSFontFaceSet.cpp:
(WebCore::CSSFontFaceSet::addToFacesLookupTable):
(WebCore::CSSFontFaceSet::remove):
(WebCore::CSSFontFaceSet::fontFace):
* css/CSSSegmentedFontFace.cpp:
(WebCore::CSSSegmentedFontFace::fontRanges):
* css/FontFace.cpp:
(WebCore::FontFace::setErrorState):
(WebCore::FontFace::create):
(WebCore::FontFace::family const):
(WebCore::FontFace::style const):
(WebCore::FontFace::weight const):
(WebCore::FontFace::stretch const):
(WebCore::FontFace::unicodeRange const):
(WebCore::FontFace::featureSettings const):
(WebCore::FontFace::display const):
(WebCore::FontFace::fontStateChanged):
* css/FontFace.h:
* css/FontFace.idl:

LayoutTests:

Tests that constructor doesn't throw, sets members to corresponding default strings.

* http/tests/css/font-face-constructor-expected.txt: Added.
* http/tests/css/font-face-constructor.html: Added.

git-svn-id: http://svn.webkit.org/repository/webkit/trunk@256659 268f45cc-cd09-0410-ab3c-d52691b4dbfc

28 files changed:
LayoutTests/ChangeLog
LayoutTests/fast/text/font-face-javascript-expected.txt
LayoutTests/fast/text/font-face-javascript.html
LayoutTests/fast/text/font-loading-global-keyword-expected.txt
LayoutTests/fast/text/font-loading-global-keyword.html
LayoutTests/fast/text/variations/font-loading-api-parse-ranges-expected.txt
LayoutTests/fast/text/variations/font-loading-api-parse-ranges.html
LayoutTests/http/tests/css/font-face-constructor-expected.txt [new file with mode: 0644]
LayoutTests/http/tests/css/font-face-constructor.html [new file with mode: 0644]
LayoutTests/imported/w3c/web-platform-tests/2dcontext/drawing-text-to-the-canvas/2d.text.measure.actualBoundingBox-expected.txt
LayoutTests/imported/w3c/web-platform-tests/2dcontext/drawing-text-to-the-canvas/2d.text.measure.advances-expected.txt
LayoutTests/imported/w3c/web-platform-tests/2dcontext/drawing-text-to-the-canvas/2d.text.measure.baselines-expected.txt
LayoutTests/imported/w3c/web-platform-tests/2dcontext/drawing-text-to-the-canvas/2d.text.measure.emHeights-expected.txt
LayoutTests/imported/w3c/web-platform-tests/2dcontext/drawing-text-to-the-canvas/2d.text.measure.fontBoundingBox-expected.txt
LayoutTests/imported/w3c/web-platform-tests/2dcontext/drawing-text-to-the-canvas/2d.text.measure.width.basic-expected.txt
LayoutTests/imported/w3c/web-platform-tests/2dcontext/drawing-text-to-the-canvas/2d.text.measure.width.empty-expected.txt
LayoutTests/imported/w3c/web-platform-tests/2dcontext/text-styles/2d.text.measure.width.space-expected.txt
LayoutTests/imported/w3c/web-platform-tests/WebIDL/current-realm-expected.txt
LayoutTests/imported/w3c/web-platform-tests/css/css-font-loading/fontfacesetloadevent-constructor-expected.txt
LayoutTests/imported/w3c/web-platform-tests/css/css-font-loading/idlharness.https-expected.txt
Source/WebCore/ChangeLog
Source/WebCore/css/CSSFontFace.cpp
Source/WebCore/css/CSSFontFace.h
Source/WebCore/css/CSSFontFaceSet.cpp
Source/WebCore/css/CSSSegmentedFontFace.cpp
Source/WebCore/css/FontFace.cpp
Source/WebCore/css/FontFace.h
Source/WebCore/css/FontFace.idl

index aa72cdc..c878f16 100644 (file)
@@ -1,3 +1,15 @@
+2020-02-14  Nikos Mouchtaris  <nmouchtaris@apple.com>
+
+        new FontFace() should not throw when failing to parse arguments
+        https://bugs.webkit.org/show_bug.cgi?id=205770
+
+        Reviewed by Myles Maxfield.
+
+        Tests that constructor doesn't throw, sets members to corresponding default strings.
+
+        * http/tests/css/font-face-constructor-expected.txt: Added.
+        * http/tests/css/font-face-constructor.html: Added.
+
 2020-02-14  Ben Nham  <nham@apple.com>
 
         Fix flaky tests that scroll before first paint
index bd5285d..f649292 100644 (file)
@@ -5,16 +5,16 @@ PASS new FontFace('family_name', 'url(\'asdf\')', {}).stretch is "normal"
 PASS new FontFace('family_name', 'url(\'asdf\')', {}).unicodeRange is "U+0-10ffff"
 PASS new FontFace('family_name', 'url(\'asdf\')', {}).featureSettings is "normal"
 PASS new FontFace('family_name', 'url(\'asdf\')', {'style': 'normal'}).style is "normal"
-PASS new FontFace('family_name', 'url(\'asdf\')', {'style': 'inherit'}).style threw exception SyntaxError: The string did not match the expected pattern..
+PASS new FontFace('family_name', 'url(\'asdf\')', {'style': 'inherit'}).status is "error"
 PASS new FontFace('family_name', 'url(\'asdf\')', {'style': 'italic'}).style is "italic"
 PASS new FontFace('family_name', 'url(\'asdf\')', {'style': 'oblique'}).style is "italic"
-PASS new FontFace('family_name', 'url(\'asdf\')', {'style': 'asdf'}) threw exception SyntaxError: The string did not match the expected pattern..
+PASS new FontFace('family_name', 'url(\'asdf\')', {'style': 'asdf'}).status is "error"
 PASS new FontFace('family_name', 'url(\'asdf\')', {'weight': 'normal'}).weight is "normal"
 PASS new FontFace('family_name', 'url(\'asdf\')', {'weight': '200'}).weight is "200"
 PASS new FontFace('family_name', 'url(\'asdf\')', {'weight': 'bold'}).weight is "bold"
 PASS new FontFace('family_name', 'url(\'asdf\')', {'weight': 'bolder'}).weight is "bold"
 PASS new FontFace('family_name', 'url(\'asdf\')', {'weight': 'lighter'}).weight is "200"
-PASS new FontFace('family_name', 'url(\'asdf\')', {'weight': 'inherit'}).weight threw exception SyntaxError: The string did not match the expected pattern..
+PASS new FontFace('family_name', 'url(\'asdf\')', {'weight': 'inherit'}).status is "error"
 PASS new FontFace('family_name', 'url(\'asdf\')', {'stretch': 'ultra-expanded'}).stretch is "ultra-expanded"
 PASS new FontFace('family_name', 'url(\'asdf\')', {'unicodeRange': 'U+26'}).unicodeRange is "U+26"
 PASS new FontFace('family_name', 'url(\'asdf\')', {'unicodeRange': 'U+0-7F'}).unicodeRange is "U+0-7f"
@@ -34,10 +34,10 @@ PASS new FontFace('family_name', 'url(\'asdf\')', {}) did not throw exception.
 PASS new FontFace('family_name', newArrayBuffer, {}) did not throw exception.
 PASS new FontFace('family_name', new DataView(newArrayBuffer), {}) did not throw exception.
 PASS new FontFace('family_name', new Uint8Array(newArrayBuffer), {}) did not throw exception.
-PASS new FontFace('family_name', 5, {}) threw exception SyntaxError: The string did not match the expected pattern..
-PASS new FontFace('family_name', {}, {}) threw exception SyntaxError: The string did not match the expected pattern..
-PASS new FontFace('family_name', new Array(), {}) threw exception SyntaxError: The string did not match the expected pattern..
-PASS new FontFace('family_name', { toString: function() { return 5; } }, {}) threw exception SyntaxError: The string did not match the expected pattern..
+PASS new FontFace('family_name', 5, {}).status is "error"
+PASS new FontFace('family_name', {}, {}).status is "error"
+PASS new FontFace('family_name', new Array(), {}).status is "error"
+PASS new FontFace('family_name', { toString: function() { return 5; } }, {}).status is "error"
 PASS new FontFace('family_name', { toString: function() { throw "Error"; } }, {}) threw exception Error.
 PASS new FontFace('family_name', { toString: function() { return "url('asdf')"; } }, {}).family is "family_name"
 PASS new FontFace('family_name', 'url(\'asdf\')', {}).status is "unloaded"
index e8c555c..c692456 100644 (file)
@@ -13,16 +13,16 @@ shouldBeEqualToString("new FontFace('family_name', 'url(\\'asdf\\')', {}).unicod
 shouldBeEqualToString("new FontFace('family_name', 'url(\\'asdf\\')', {}).featureSettings", "normal");
 
 shouldBeEqualToString("new FontFace('family_name', 'url(\\'asdf\\')', {'style': 'normal'}).style", "normal");
-shouldThrow("new FontFace('family_name', 'url(\\'asdf\\')', {'style': 'inherit'}).style");
+shouldBeEqualToString("new FontFace('family_name', 'url(\\'asdf\\')', {'style': 'inherit'}).status","error");
 shouldBeEqualToString("new FontFace('family_name', 'url(\\'asdf\\')', {'style': 'italic'}).style", "italic");
 shouldBeEqualToString("new FontFace('family_name', 'url(\\'asdf\\')', {'style': 'oblique'}).style", "italic");
-shouldThrow("new FontFace('family_name', 'url(\\'asdf\\')', {'style': 'asdf'})");
+shouldBeEqualToString("new FontFace('family_name', 'url(\\'asdf\\')', {'style': 'asdf'}).status", "error");
 shouldBeEqualToString("new FontFace('family_name', 'url(\\'asdf\\')', {'weight': 'normal'}).weight", "normal");
 shouldBeEqualToString("new FontFace('family_name', 'url(\\'asdf\\')', {'weight': '200'}).weight", "200");
 shouldBeEqualToString("new FontFace('family_name', 'url(\\'asdf\\')', {'weight': 'bold'}).weight", "bold");
 shouldBeEqualToString("new FontFace('family_name', 'url(\\'asdf\\')', {'weight': 'bolder'}).weight", "bold");
 shouldBeEqualToString("new FontFace('family_name', 'url(\\'asdf\\')', {'weight': 'lighter'}).weight", "200");
-shouldThrow("new FontFace('family_name', 'url(\\'asdf\\')', {'weight': 'inherit'}).weight");
+shouldBeEqualToString("new FontFace('family_name', 'url(\\'asdf\\')', {'weight': 'inherit'}).status", "error");
 shouldBeEqualToString("new FontFace('family_name', 'url(\\'asdf\\')', {'stretch': 'ultra-expanded'}).stretch", "ultra-expanded");
 shouldBeEqualToString("new FontFace('family_name', 'url(\\'asdf\\')', {'unicodeRange': 'U+26'}).unicodeRange", "U+26");
 shouldBeEqualToString("new FontFace('family_name', 'url(\\'asdf\\')', {'unicodeRange': 'U+0-7F'}).unicodeRange", "U+0-7f");
@@ -53,10 +53,10 @@ var newArrayBuffer = new ArrayBuffer(100);
 shouldNotThrow("new FontFace('family_name', newArrayBuffer, {})");
 shouldNotThrow("new FontFace('family_name', new DataView(newArrayBuffer), {})");
 shouldNotThrow("new FontFace('family_name', new Uint8Array(newArrayBuffer), {})");
-shouldThrow("new FontFace('family_name', 5, {})");
-shouldThrow("new FontFace('family_name', {}, {})");
-shouldThrow("new FontFace('family_name', new Array(), {})");
-shouldThrow("new FontFace('family_name', { toString: function() { return 5; } }, {})");
+shouldBeEqualToString("new FontFace('family_name', 5, {}).status", "error");
+shouldBeEqualToString("new FontFace('family_name', {}, {}).status", "error");
+shouldBeEqualToString("new FontFace('family_name', new Array(), {}).status", "error");
+shouldBeEqualToString("new FontFace('family_name', { toString: function() { return 5; } }, {}).status", "error");
 shouldThrow("new FontFace('family_name', { toString: function() { throw \"Error\"; } }, {})");
 shouldBeEqualToString("new FontFace('family_name', { toString: function() { return \"url(\'asdf\')\"; } }, {}).family", "family_name");
 
index 80e3ab8..dead8bd 100644 (file)
@@ -7,34 +7,34 @@ PASS document.fonts.check('initial', 'A') threw exception SyntaxError: The strin
 PASS document.fonts.check('inherited', 'A') threw exception SyntaxError: The string did not match the expected pattern..
 PASS document.fonts.check('unset', 'A') threw exception SyntaxError: The string did not match the expected pattern..
 PASS document.fonts.check('revert', 'A') threw exception SyntaxError: The string did not match the expected pattern..
-PASS new FontFace('abc', 'url(asdf)', {'style': 'initial'}) threw exception SyntaxError: The string did not match the expected pattern..
-PASS new FontFace('abc', 'url(asdf)', {'style': 'inherited'}) threw exception SyntaxError: The string did not match the expected pattern..
-PASS new FontFace('abc', 'url(asdf)', {'style': 'unset'}) threw exception SyntaxError: The string did not match the expected pattern..
-PASS new FontFace('abc', 'url(asdf)', {'style': 'revert'}) threw exception SyntaxError: The string did not match the expected pattern..
-PASS new FontFace('abc', 'url(asdf)', {'weight': 'initial'}) threw exception SyntaxError: The string did not match the expected pattern..
-PASS new FontFace('abc', 'url(asdf)', {'weight': 'inherited'}) threw exception SyntaxError: The string did not match the expected pattern..
-PASS new FontFace('abc', 'url(asdf)', {'weight': 'unset'}) threw exception SyntaxError: The string did not match the expected pattern..
-PASS new FontFace('abc', 'url(asdf)', {'weight': 'revert'}) threw exception SyntaxError: The string did not match the expected pattern..
-PASS new FontFace('abc', 'url(asdf)', {'stretch': 'initial'}) threw exception SyntaxError: The string did not match the expected pattern..
-PASS new FontFace('abc', 'url(asdf)', {'stretch': 'inherited'}) threw exception SyntaxError: The string did not match the expected pattern..
-PASS new FontFace('abc', 'url(asdf)', {'stretch': 'unset'}) threw exception SyntaxError: The string did not match the expected pattern..
-PASS new FontFace('abc', 'url(asdf)', {'stretch': 'revert'}) threw exception SyntaxError: The string did not match the expected pattern..
-PASS new FontFace('abc', 'url(asdf)', {'unicodeRange': 'initial'}) threw exception SyntaxError: The string did not match the expected pattern..
-PASS new FontFace('abc', 'url(asdf)', {'unicodeRange': 'inherited'}) threw exception SyntaxError: The string did not match the expected pattern..
-PASS new FontFace('abc', 'url(asdf)', {'unicodeRange': 'unset'}) threw exception SyntaxError: The string did not match the expected pattern..
-PASS new FontFace('abc', 'url(asdf)', {'unicodeRange': 'revert'}) threw exception SyntaxError: The string did not match the expected pattern..
-PASS new FontFace('abc', 'url(asdf)', {'featureSettings': 'initial'}) threw exception SyntaxError: The string did not match the expected pattern..
-PASS new FontFace('abc', 'url(asdf)', {'featureSettings': 'inherited'}) threw exception SyntaxError: The string did not match the expected pattern..
-PASS new FontFace('abc', 'url(asdf)', {'featureSettings': 'unset'}) threw exception SyntaxError: The string did not match the expected pattern..
-PASS new FontFace('abc', 'url(asdf)', {'featureSettings': 'revert'}) threw exception SyntaxError: The string did not match the expected pattern..
-PASS new FontFace('abc', 'url(asdf)', {'display': 'initial'}) threw exception SyntaxError: The string did not match the expected pattern..
-PASS new FontFace('abc', 'url(asdf)', {'display': 'inherited'}) threw exception SyntaxError: The string did not match the expected pattern..
-PASS new FontFace('abc', 'url(asdf)', {'display': 'unset'}) threw exception SyntaxError: The string did not match the expected pattern..
-PASS new FontFace('abc', 'url(asdf)', {'display': 'initial'}) threw exception SyntaxError: The string did not match the expected pattern..
-PASS new FontFace('abc', 'inherited') threw exception SyntaxError: The string did not match the expected pattern..
-PASS new FontFace('abc', 'unset') threw exception SyntaxError: The string did not match the expected pattern..
-PASS new FontFace('abc', 'revert') threw exception SyntaxError: The string did not match the expected pattern..
-PASS new FontFace('abc', 'revert') threw exception SyntaxError: The string did not match the expected pattern..
+PASS new FontFace('abc', 'url(asdf)', {'style': 'initial'}).status is "error"
+PASS new FontFace('abc', 'url(asdf)', {'style': 'inherited'}).status is "error"
+PASS new FontFace('abc', 'url(asdf)', {'style': 'unset'}).status is "error"
+PASS new FontFace('abc', 'url(asdf)', {'style': 'revert'}).status is "error"
+PASS new FontFace('abc', 'url(asdf)', {'weight': 'initial'}).status is "error"
+PASS new FontFace('abc', 'url(asdf)', {'weight': 'inherited'}).status is "error"
+PASS new FontFace('abc', 'url(asdf)', {'weight': 'unset'}).status is "error"
+PASS new FontFace('abc', 'url(asdf)', {'weight': 'revert'}).status is "error"
+PASS new FontFace('abc', 'url(asdf)', {'stretch': 'initial'}).status is "error"
+PASS new FontFace('abc', 'url(asdf)', {'stretch': 'inherited'}).status is "error"
+PASS new FontFace('abc', 'url(asdf)', {'stretch': 'unset'}).status is "error"
+PASS new FontFace('abc', 'url(asdf)', {'stretch': 'revert'}).status is "error"
+PASS new FontFace('abc', 'url(asdf)', {'unicodeRange': 'initial'}).status is "error"
+PASS new FontFace('abc', 'url(asdf)', {'unicodeRange': 'inherited'}).status is "error"
+PASS new FontFace('abc', 'url(asdf)', {'unicodeRange': 'unset'}).status is "error"
+PASS new FontFace('abc', 'url(asdf)', {'unicodeRange': 'revert'}).status is "error"
+PASS new FontFace('abc', 'url(asdf)', {'featureSettings': 'initial'}).status is "error"
+PASS new FontFace('abc', 'url(asdf)', {'featureSettings': 'inherited'}).status is "error"
+PASS new FontFace('abc', 'url(asdf)', {'featureSettings': 'unset'}).status is "error"
+PASS new FontFace('abc', 'url(asdf)', {'featureSettings': 'revert'}).status is "error"
+PASS new FontFace('abc', 'url(asdf)', {'display': 'initial'}).status is "error"
+PASS new FontFace('abc', 'url(asdf)', {'display': 'inherited'}).status is "error"
+PASS new FontFace('abc', 'url(asdf)', {'display': 'unset'}).status is "error"
+PASS new FontFace('abc', 'url(asdf)', {'display': 'initial'}).status is "error"
+PASS new FontFace('abc', 'inherited').status is "error"
+PASS new FontFace('abc', 'unset').status is "error"
+PASS new FontFace('abc', 'revert').status is "error"
+PASS new FontFace('abc', 'revert').status is "error"
 PASS document.fonts.load('initial', 'A') rejected promise  with SyntaxError: The string did not match the expected pattern..
 PASS document.fonts.load('inherited', 'A') rejected promise  with SyntaxError: The string did not match the expected pattern..
 PASS document.fonts.load('unset', 'A') rejected promise  with SyntaxError: The string did not match the expected pattern..
index b21f69a..709f4b3 100644 (file)
@@ -14,34 +14,34 @@ shouldReject("document.fonts.load('initial', 'A')");
 shouldReject("document.fonts.load('inherited', 'A')");
 shouldReject("document.fonts.load('unset', 'A')");
 shouldReject("document.fonts.load('revert', 'A')");
-shouldThrowErrorName("new FontFace('abc', 'url(asdf)', {'style': 'initial'})", "SyntaxError");
-shouldThrowErrorName("new FontFace('abc', 'url(asdf)', {'style': 'inherited'})", "SyntaxError");
-shouldThrowErrorName("new FontFace('abc', 'url(asdf)', {'style': 'unset'})", "SyntaxError");
-shouldThrowErrorName("new FontFace('abc', 'url(asdf)', {'style': 'revert'})", "SyntaxError");
-shouldThrowErrorName("new FontFace('abc', 'url(asdf)', {'weight': 'initial'})", "SyntaxError");
-shouldThrowErrorName("new FontFace('abc', 'url(asdf)', {'weight': 'inherited'})", "SyntaxError");
-shouldThrowErrorName("new FontFace('abc', 'url(asdf)', {'weight': 'unset'})", "SyntaxError");
-shouldThrowErrorName("new FontFace('abc', 'url(asdf)', {'weight': 'revert'})", "SyntaxError");
-shouldThrowErrorName("new FontFace('abc', 'url(asdf)', {'stretch': 'initial'})", "SyntaxError");
-shouldThrowErrorName("new FontFace('abc', 'url(asdf)', {'stretch': 'inherited'})", "SyntaxError");
-shouldThrowErrorName("new FontFace('abc', 'url(asdf)', {'stretch': 'unset'})", "SyntaxError");
-shouldThrowErrorName("new FontFace('abc', 'url(asdf)', {'stretch': 'revert'})", "SyntaxError");
-shouldThrowErrorName("new FontFace('abc', 'url(asdf)', {'unicodeRange': 'initial'})", "SyntaxError");
-shouldThrowErrorName("new FontFace('abc', 'url(asdf)', {'unicodeRange': 'inherited'})", "SyntaxError");
-shouldThrowErrorName("new FontFace('abc', 'url(asdf)', {'unicodeRange': 'unset'})", "SyntaxError");
-shouldThrowErrorName("new FontFace('abc', 'url(asdf)', {'unicodeRange': 'revert'})", "SyntaxError");
-shouldThrowErrorName("new FontFace('abc', 'url(asdf)', {'featureSettings': 'initial'})", "SyntaxError");
-shouldThrowErrorName("new FontFace('abc', 'url(asdf)', {'featureSettings': 'inherited'})", "SyntaxError");
-shouldThrowErrorName("new FontFace('abc', 'url(asdf)', {'featureSettings': 'unset'})", "SyntaxError");
-shouldThrowErrorName("new FontFace('abc', 'url(asdf)', {'featureSettings': 'revert'})", "SyntaxError");
-shouldThrowErrorName("new FontFace('abc', 'url(asdf)', {'display': 'initial'})", "SyntaxError");
-shouldThrowErrorName("new FontFace('abc', 'url(asdf)', {'display': 'inherited'})", "SyntaxError");
-shouldThrowErrorName("new FontFace('abc', 'url(asdf)', {'display': 'unset'})", "SyntaxError");
-shouldThrowErrorName("new FontFace('abc', 'url(asdf)', {'display': 'initial'})", "SyntaxError");
-shouldThrowErrorName("new FontFace('abc', 'inherited')", "SyntaxError");
-shouldThrowErrorName("new FontFace('abc', 'unset')", "SyntaxError");
-shouldThrowErrorName("new FontFace('abc', 'revert')", "SyntaxError");
-shouldThrowErrorName("new FontFace('abc', 'revert')", "SyntaxError");
+shouldBeEqualToString("new FontFace('abc', 'url(asdf)', {'style': 'initial'}).status","error");
+shouldBeEqualToString("new FontFace('abc', 'url(asdf)', {'style': 'inherited'}).status","error");
+shouldBeEqualToString("new FontFace('abc', 'url(asdf)', {'style': 'unset'}).status","error");
+shouldBeEqualToString("new FontFace('abc', 'url(asdf)', {'style': 'revert'}).status","error");
+shouldBeEqualToString("new FontFace('abc', 'url(asdf)', {'weight': 'initial'}).status","error");
+shouldBeEqualToString("new FontFace('abc', 'url(asdf)', {'weight': 'inherited'}).status","error");
+shouldBeEqualToString("new FontFace('abc', 'url(asdf)', {'weight': 'unset'}).status","error");
+shouldBeEqualToString("new FontFace('abc', 'url(asdf)', {'weight': 'revert'}).status","error");
+shouldBeEqualToString("new FontFace('abc', 'url(asdf)', {'stretch': 'initial'}).status","error");
+shouldBeEqualToString("new FontFace('abc', 'url(asdf)', {'stretch': 'inherited'}).status","error");
+shouldBeEqualToString("new FontFace('abc', 'url(asdf)', {'stretch': 'unset'}).status","error");
+shouldBeEqualToString("new FontFace('abc', 'url(asdf)', {'stretch': 'revert'}).status","error");
+shouldBeEqualToString("new FontFace('abc', 'url(asdf)', {'unicodeRange': 'initial'}).status","error");
+shouldBeEqualToString("new FontFace('abc', 'url(asdf)', {'unicodeRange': 'inherited'}).status","error");
+shouldBeEqualToString("new FontFace('abc', 'url(asdf)', {'unicodeRange': 'unset'}).status","error");
+shouldBeEqualToString("new FontFace('abc', 'url(asdf)', {'unicodeRange': 'revert'}).status","error");
+shouldBeEqualToString("new FontFace('abc', 'url(asdf)', {'featureSettings': 'initial'}).status","error");
+shouldBeEqualToString("new FontFace('abc', 'url(asdf)', {'featureSettings': 'inherited'}).status","error");
+shouldBeEqualToString("new FontFace('abc', 'url(asdf)', {'featureSettings': 'unset'}).status","error");
+shouldBeEqualToString("new FontFace('abc', 'url(asdf)', {'featureSettings': 'revert'}).status","error");
+shouldBeEqualToString("new FontFace('abc', 'url(asdf)', {'display': 'initial'}).status","error");
+shouldBeEqualToString("new FontFace('abc', 'url(asdf)', {'display': 'inherited'}).status","error");
+shouldBeEqualToString("new FontFace('abc', 'url(asdf)', {'display': 'unset'}).status","error");
+shouldBeEqualToString("new FontFace('abc', 'url(asdf)', {'display': 'initial'}).status","error");
+shouldBeEqualToString("new FontFace('abc', 'inherited').status","error");
+shouldBeEqualToString("new FontFace('abc', 'unset').status","error");
+shouldBeEqualToString("new FontFace('abc', 'revert').status","error");
+shouldBeEqualToString("new FontFace('abc', 'revert').status","error");
 </script>
 <script src="../../resources/js-test-post.js"></script>
 </body>
index 85f5634..1adb82a 100644 (file)
@@ -1,45 +1,45 @@
 PASS (new FontFace('asdf', 'url(notreal)', { weight: '100 200' })).weight is "100 200"
-PASS (new FontFace('asdf', 'url(notreal)', { weight: 'a100 200' })).weight threw exception SyntaxError: The string did not match the expected pattern..
-PASS (new FontFace('asdf', 'url(notreal)', { weight: '100a 200' })).weight threw exception SyntaxError: The string did not match the expected pattern..
+PASS (new FontFace('asdf', 'url(notreal)', { weight: 'a100 200' })).status is "error"
+PASS (new FontFace('asdf', 'url(notreal)', { weight: '100a 200' })).status is "error"
 PASS (new FontFace('asdf', 'url(notreal)', { weight: '100   200' })).weight is "100 200"
-PASS (new FontFace('asdf', 'url(notreal)', { weight: '100 a 200' })).weight threw exception SyntaxError: The string did not match the expected pattern..
-PASS (new FontFace('asdf', 'url(notreal)', { weight: '100 a200' })).weight threw exception SyntaxError: The string did not match the expected pattern..
-PASS (new FontFace('asdf', 'url(notreal)', { weight: '100 200a' })).weight threw exception SyntaxError: The string did not match the expected pattern..
+PASS (new FontFace('asdf', 'url(notreal)', { weight: '100 a 200' })).status is "error"
+PASS (new FontFace('asdf', 'url(notreal)', { weight: '100 a200' })).status is "error"
+PASS (new FontFace('asdf', 'url(notreal)', { weight: '100 200a' })).status is "error"
 PASS (new FontFace('asdf', 'url(notreal)', { weight: '50 150' })).weight is "50 150"
 PASS (new FontFace('asdf', 'url(notreal)', { weight: '2 3' })).weight is "2 3"
-PASS (new FontFace('asdf', 'url(notreal)', { weight: '-3 -2' })).weight threw exception SyntaxError: The string did not match the expected pattern..
-PASS (new FontFace('asdf', 'url(notreal)', { weight: '5 4' })).weight threw exception SyntaxError: The string did not match the expected pattern..
-PASS (new FontFace('asdf', 'url(notreal)', { weight: '100 200 3' })).weight threw exception SyntaxError: The string did not match the expected pattern..
-PASS (new FontFace('asdf', 'url(notreal)', { weight: '100 200 a' })).weight threw exception SyntaxError: The string did not match the expected pattern..
-PASS (new FontFace('asdf', 'url(notreal)', { weight: '-3' })).weight threw exception SyntaxError: The string did not match the expected pattern..
-PASS (new FontFace('asdf', 'url(notreal)', { stretch: 'semi-expanded expanded' })).stretch threw exception SyntaxError: The string did not match the expected pattern..
+PASS (new FontFace('asdf', 'url(notreal)', { weight: '-3 -2' })).status is "error"
+PASS (new FontFace('asdf', 'url(notreal)', { weight: '5 4' })).status is "error"
+PASS (new FontFace('asdf', 'url(notreal)', { weight: '100 200 3' })).status is "error"
+PASS (new FontFace('asdf', 'url(notreal)', { weight: '100 200 a' })).status is "error"
+PASS (new FontFace('asdf', 'url(notreal)', { weight: '-3' })).status is "error"
+PASS (new FontFace('asdf', 'url(notreal)', { stretch: 'semi-expanded expanded' })).status is "error"
 PASS (new FontFace('asdf', 'url(notreal)', { stretch: '100% 200%' })).stretch is "100% 200%"
-PASS (new FontFace('asdf', 'url(notreal)', { stretch: 'a100% 200%' })).stretch threw exception SyntaxError: The string did not match the expected pattern..
-PASS (new FontFace('asdf', 'url(notreal)', { stretch: '100%a 200%' })).stretch threw exception SyntaxError: The string did not match the expected pattern..
+PASS (new FontFace('asdf', 'url(notreal)', { stretch: 'a100% 200%' })).status is "error"
+PASS (new FontFace('asdf', 'url(notreal)', { stretch: '100%a 200%' })).status is "error"
 PASS (new FontFace('asdf', 'url(notreal)', { stretch: '100%   200%' })).stretch is "100% 200%"
-PASS (new FontFace('asdf', 'url(notreal)', { stretch: '100% a 200%' })).stretch threw exception SyntaxError: The string did not match the expected pattern..
-PASS (new FontFace('asdf', 'url(notreal)', { stretch: '100% a200%' })).stretch threw exception SyntaxError: The string did not match the expected pattern..
-PASS (new FontFace('asdf', 'url(notreal)', { stretch: '100% 200%a' })).stretch threw exception SyntaxError: The string did not match the expected pattern..
+PASS (new FontFace('asdf', 'url(notreal)', { stretch: '100% a 200%' })).status is "error"
+PASS (new FontFace('asdf', 'url(notreal)', { stretch: '100% a200%' })).status is "error"
+PASS (new FontFace('asdf', 'url(notreal)', { stretch: '100% 200%a' })).status is "error"
 PASS (new FontFace('asdf', 'url(notreal)', { stretch: '50% 60%' })).stretch is "50% 60%"
 PASS (new FontFace('asdf', 'url(notreal)', { stretch: '2% 3%' })).stretch is "2% 3%"
-PASS (new FontFace('asdf', 'url(notreal)', { stretch: '-3% -2%' })).stretch threw exception SyntaxError: The string did not match the expected pattern..
-PASS (new FontFace('asdf', 'url(notreal)', { stretch: '5% 4%' })).stretch threw exception SyntaxError: The string did not match the expected pattern..
-PASS (new FontFace('asdf', 'url(notreal)', { stretch: '100% 200% 3%' })).stretch threw exception SyntaxError: The string did not match the expected pattern..
-PASS (new FontFace('asdf', 'url(notreal)', { stretch: '100% 200% a' })).stretch threw exception SyntaxError: The string did not match the expected pattern..
-PASS (new FontFace('asdf', 'url(notreal)', { stretch: '-3%' })).stretch threw exception SyntaxError: The string did not match the expected pattern..
+PASS (new FontFace('asdf', 'url(notreal)', { stretch: '-3% -2%' })).status is "error"
+PASS (new FontFace('asdf', 'url(notreal)', { stretch: '5% 4%' })).status is "error"
+PASS (new FontFace('asdf', 'url(notreal)', { stretch: '100% 200% 3%' })).status is "error"
+PASS (new FontFace('asdf', 'url(notreal)', { stretch: '100% 200% a' })).status is "error"
+PASS (new FontFace('asdf', 'url(notreal)', { stretch: '-3%' })).status is "error"
 PASS (new FontFace('asdf', 'url(notreal)', { style: 'oblique 10deg 20deg' })).style is "oblique 10deg 20deg"
-PASS (new FontFace('asdf', 'url(notreal)', { style: 'oblique a10deg 20deg' })).style threw exception SyntaxError: The string did not match the expected pattern..
-PASS (new FontFace('asdf', 'url(notreal)', { style: 'oblique 10dega 20deg' })).style threw exception SyntaxError: The string did not match the expected pattern..
+PASS (new FontFace('asdf', 'url(notreal)', { style: 'oblique a10deg 20deg' })).status is "error"
+PASS (new FontFace('asdf', 'url(notreal)', { style: 'oblique 10dega 20deg' })).status is "error"
 PASS (new FontFace('asdf', 'url(notreal)', { style: 'oblique 10deg  20deg' })).style is "oblique 10deg 20deg"
-PASS (new FontFace('asdf', 'url(notreal)', { style: 'oblique 10deg a 20deg' })).style threw exception SyntaxError: The string did not match the expected pattern..
-PASS (new FontFace('asdf', 'url(notreal)', { style: 'oblique 10deg a20deg' })).style threw exception SyntaxError: The string did not match the expected pattern..
-PASS (new FontFace('asdf', 'url(notreal)', { style: 'oblique 10deg 20dega' })).style threw exception SyntaxError: The string did not match the expected pattern..
+PASS (new FontFace('asdf', 'url(notreal)', { style: 'oblique 10deg a 20deg' })).status is "error"
+PASS (new FontFace('asdf', 'url(notreal)', { style: 'oblique 10deg a20deg' })).status is "error"
+PASS (new FontFace('asdf', 'url(notreal)', { style: 'oblique 10deg 20dega' })).status is "error"
 PASS (new FontFace('asdf', 'url(notreal)', { style: 'oblique 50deg 60deg' })).style is "oblique 50deg 60deg"
 PASS (new FontFace('asdf', 'url(notreal)', { style: 'oblique 2deg 3deg' })).style is "oblique 2deg 3deg"
 PASS (new FontFace('asdf', 'url(notreal)', { style: 'oblique -3deg -2deg' })).style is "oblique -3deg -2deg"
-PASS (new FontFace('asdf', 'url(notreal)', { style: 'oblique 5deg 4deg' })).style threw exception SyntaxError: The string did not match the expected pattern..
-PASS (new FontFace('asdf', 'url(notreal)', { style: 'oblique 10deg 20deg 3deg' })).style threw exception SyntaxError: The string did not match the expected pattern..
-PASS (new FontFace('asdf', 'url(notreal)', { style: 'oblique 10deg 20deg a' })).style threw exception SyntaxError: The string did not match the expected pattern..
+PASS (new FontFace('asdf', 'url(notreal)', { style: 'oblique 5deg 4deg' })).status is "error"
+PASS (new FontFace('asdf', 'url(notreal)', { style: 'oblique 10deg 20deg 3deg' })).status is "error"
+PASS (new FontFace('asdf', 'url(notreal)', { style: 'oblique 10deg 20deg a' })).status is "error"
 PASS (new FontFace('asdf', 'url(notreal)', { style: 'oblique -3deg' })).style is "oblique -3deg"
 PASS successfullyParsed is true
 
index 2ff3a57..a5106bb 100644 (file)
@@ -6,49 +6,49 @@
 <body>
 <script>
 shouldBeEqualToString("(new FontFace('asdf', 'url(notreal)', { weight: '100 200' })).weight", "100 200");
-shouldThrow("(new FontFace('asdf', 'url(notreal)', { weight: 'a100 200' })).weight");
-shouldThrow("(new FontFace('asdf', 'url(notreal)', { weight: '100a 200' })).weight");
+shouldBeEqualToString("(new FontFace('asdf', 'url(notreal)', { weight: 'a100 200' })).status","error");
+shouldBeEqualToString("(new FontFace('asdf', 'url(notreal)', { weight: '100a 200' })).status","error");
 shouldBeEqualToString("(new FontFace('asdf', 'url(notreal)', { weight: '100   200' })).weight", "100 200");
-shouldThrow("(new FontFace('asdf', 'url(notreal)', { weight: '100 a 200' })).weight");
-shouldThrow("(new FontFace('asdf', 'url(notreal)', { weight: '100 a200' })).weight");
-shouldThrow("(new FontFace('asdf', 'url(notreal)', { weight: '100 200a' })).weight");
+shouldBeEqualToString("(new FontFace('asdf', 'url(notreal)', { weight: '100 a 200' })).status","error");
+shouldBeEqualToString("(new FontFace('asdf', 'url(notreal)', { weight: '100 a200' })).status","error");
+shouldBeEqualToString("(new FontFace('asdf', 'url(notreal)', { weight: '100 200a' })).status","error");
 shouldBeEqualToString("(new FontFace('asdf', 'url(notreal)', { weight: '50 150' })).weight", "50 150");
 shouldBeEqualToString("(new FontFace('asdf', 'url(notreal)', { weight: '2 3' })).weight", "2 3");
-shouldThrow("(new FontFace('asdf', 'url(notreal)', { weight: '-3 -2' })).weight");
-shouldThrow("(new FontFace('asdf', 'url(notreal)', { weight: '5 4' })).weight");
-shouldThrow("(new FontFace('asdf', 'url(notreal)', { weight: '100 200 3' })).weight");
-shouldThrow("(new FontFace('asdf', 'url(notreal)', { weight: '100 200 a' })).weight");
-shouldThrow("(new FontFace('asdf', 'url(notreal)', { weight: '-3' })).weight");
+shouldBeEqualToString("(new FontFace('asdf', 'url(notreal)', { weight: '-3 -2' })).status","error");
+shouldBeEqualToString("(new FontFace('asdf', 'url(notreal)', { weight: '5 4' })).status","error");
+shouldBeEqualToString("(new FontFace('asdf', 'url(notreal)', { weight: '100 200 3' })).status","error");
+shouldBeEqualToString("(new FontFace('asdf', 'url(notreal)', { weight: '100 200 a' })).status","error");
+shouldBeEqualToString("(new FontFace('asdf', 'url(notreal)', { weight: '-3' })).status","error");
 
-shouldThrow("(new FontFace('asdf', 'url(notreal)', { stretch: 'semi-expanded expanded' })).stretch");
+shouldBeEqualToString("(new FontFace('asdf', 'url(notreal)', { stretch: 'semi-expanded expanded' })).status","error");
 shouldBeEqualToString("(new FontFace('asdf', 'url(notreal)', { stretch: '100% 200%' })).stretch", "100% 200%");
-shouldThrow("(new FontFace('asdf', 'url(notreal)', { stretch: 'a100% 200%' })).stretch");
-shouldThrow("(new FontFace('asdf', 'url(notreal)', { stretch: '100%a 200%' })).stretch");
+shouldBeEqualToString("(new FontFace('asdf', 'url(notreal)', { stretch: 'a100% 200%' })).status","error");
+shouldBeEqualToString("(new FontFace('asdf', 'url(notreal)', { stretch: '100%a 200%' })).status","error");
 shouldBeEqualToString("(new FontFace('asdf', 'url(notreal)', { stretch: '100%   200%' })).stretch", "100% 200%");
-shouldThrow("(new FontFace('asdf', 'url(notreal)', { stretch: '100% a 200%' })).stretch");
-shouldThrow("(new FontFace('asdf', 'url(notreal)', { stretch: '100% a200%' })).stretch");
-shouldThrow("(new FontFace('asdf', 'url(notreal)', { stretch: '100% 200%a' })).stretch");
+shouldBeEqualToString("(new FontFace('asdf', 'url(notreal)', { stretch: '100% a 200%' })).status","error");
+shouldBeEqualToString("(new FontFace('asdf', 'url(notreal)', { stretch: '100% a200%' })).status","error");
+shouldBeEqualToString("(new FontFace('asdf', 'url(notreal)', { stretch: '100% 200%a' })).status","error");
 shouldBeEqualToString("(new FontFace('asdf', 'url(notreal)', { stretch: '50% 60%' })).stretch", "50% 60%");
 shouldBeEqualToString("(new FontFace('asdf', 'url(notreal)', { stretch: '2% 3%' })).stretch", "2% 3%");
-shouldThrow("(new FontFace('asdf', 'url(notreal)', { stretch: '-3% -2%' })).stretch");
-shouldThrow("(new FontFace('asdf', 'url(notreal)', { stretch: '5% 4%' })).stretch");
-shouldThrow("(new FontFace('asdf', 'url(notreal)', { stretch: '100% 200% 3%' })).stretch");
-shouldThrow("(new FontFace('asdf', 'url(notreal)', { stretch: '100% 200% a' })).stretch");
-shouldThrow("(new FontFace('asdf', 'url(notreal)', { stretch: '-3%' })).stretch");
+shouldBeEqualToString("(new FontFace('asdf', 'url(notreal)', { stretch: '-3% -2%' })).status","error");
+shouldBeEqualToString("(new FontFace('asdf', 'url(notreal)', { stretch: '5% 4%' })).status","error");
+shouldBeEqualToString("(new FontFace('asdf', 'url(notreal)', { stretch: '100% 200% 3%' })).status","error");
+shouldBeEqualToString("(new FontFace('asdf', 'url(notreal)', { stretch: '100% 200% a' })).status","error");
+shouldBeEqualToString("(new FontFace('asdf', 'url(notreal)', { stretch: '-3%' })).status","error");
 
 shouldBeEqualToString("(new FontFace('asdf', 'url(notreal)', { style: 'oblique 10deg 20deg' })).style", "oblique 10deg 20deg");
-shouldThrow("(new FontFace('asdf', 'url(notreal)', { style: 'oblique a10deg 20deg' })).style");
-shouldThrow("(new FontFace('asdf', 'url(notreal)', { style: 'oblique 10dega 20deg' })).style");
+shouldBeEqualToString("(new FontFace('asdf', 'url(notreal)', { style: 'oblique a10deg 20deg' })).status","error");
+shouldBeEqualToString("(new FontFace('asdf', 'url(notreal)', { style: 'oblique 10dega 20deg' })).status","error");
 shouldBeEqualToString("(new FontFace('asdf', 'url(notreal)', { style: 'oblique 10deg  20deg' })).style", "oblique 10deg 20deg");
-shouldThrow("(new FontFace('asdf', 'url(notreal)', { style: 'oblique 10deg a 20deg' })).style");
-shouldThrow("(new FontFace('asdf', 'url(notreal)', { style: 'oblique 10deg a20deg' })).style");
-shouldThrow("(new FontFace('asdf', 'url(notreal)', { style: 'oblique 10deg 20dega' })).style");
+shouldBeEqualToString("(new FontFace('asdf', 'url(notreal)', { style: 'oblique 10deg a 20deg' })).status","error");
+shouldBeEqualToString("(new FontFace('asdf', 'url(notreal)', { style: 'oblique 10deg a20deg' })).status","error");
+shouldBeEqualToString("(new FontFace('asdf', 'url(notreal)', { style: 'oblique 10deg 20dega' })).status","error");
 shouldBeEqualToString("(new FontFace('asdf', 'url(notreal)', { style: 'oblique 50deg 60deg' })).style", "oblique 50deg 60deg");
 shouldBeEqualToString("(new FontFace('asdf', 'url(notreal)', { style: 'oblique 2deg 3deg' })).style", "oblique 2deg 3deg");
 shouldBeEqualToString("(new FontFace('asdf', 'url(notreal)', { style: 'oblique -3deg -2deg' })).style", "oblique -3deg -2deg");
-shouldThrow("(new FontFace('asdf', 'url(notreal)', { style: 'oblique 5deg 4deg' })).style");
-shouldThrow("(new FontFace('asdf', 'url(notreal)', { style: 'oblique 10deg 20deg 3deg' })).style");
-shouldThrow("(new FontFace('asdf', 'url(notreal)', { style: 'oblique 10deg 20deg a' })).style");
+shouldBeEqualToString("(new FontFace('asdf', 'url(notreal)', { style: 'oblique 5deg 4deg' })).status","error");
+shouldBeEqualToString("(new FontFace('asdf', 'url(notreal)', { style: 'oblique 10deg 20deg 3deg' })).status","error");
+shouldBeEqualToString("(new FontFace('asdf', 'url(notreal)', { style: 'oblique 10deg 20deg a' })).status","error");
 shouldBeEqualToString("(new FontFace('asdf', 'url(notreal)', { style: 'oblique -3deg' })).style", "oblique -3deg");
 </script>
 <script src="../../../resources/js-test-post.js"></script>
diff --git a/LayoutTests/http/tests/css/font-face-constructor-expected.txt b/LayoutTests/http/tests/css/font-face-constructor-expected.txt
new file mode 100644 (file)
index 0000000..b01a2f4
--- /dev/null
@@ -0,0 +1,18 @@
+Test Font Face constructor
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS (new FontFace('asdf', 'url(notreal)', { weight: '100a 200' }, { stretch: 'semi-expanded expanded' })).status is "error"
+PASS (new FontFace('asdf', 'url(notreal)', { weight: '100a 200' }, { stretch: 'semi-expanded expanded' })).style is "normal"
+PASS (new FontFace('asdf', 'url(notreal)', { weight: '100a 200' }, { stretch: 'semi-expanded expanded' })).weight is "normal"
+PASS (new FontFace('asdf', 'url(notreal)', { weight: '100a 200' }, { stretch: 'semi-expanded expanded' })).stretch is "normal"
+PASS (new FontFace('asdf', 'url(notreal)', { weight: '100a 200' })).unicodeRange is "U+0-10FFFF"
+PASS (new FontFace('asdf', 'url(notreal)', { weight: '100a 200' })).featureSettings is "normal"
+PASS (new FontFace('asdf', 'url(notreal)', { weight: '100a 200' })).display is "auto"
+PASS: Did not throw
+Good
+PASS successfullyParsed is true
+
+TEST COMPLETE
+a
diff --git a/LayoutTests/http/tests/css/font-face-constructor.html b/LayoutTests/http/tests/css/font-face-constructor.html
new file mode 100644 (file)
index 0000000..645ac5e
--- /dev/null
@@ -0,0 +1,43 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<script src="/js-test-resources/ui-helper.js"></script>
+<script src="/resources/js-test-pre.js"></script>
+<script src="/resources/payment-request.js"></script>
+</head>
+<body>
+<script>
+
+description("Test Font Face constructor");
+
+window.jsTestIsAsync = true;
+async function runTests() {
+    try{
+        var testFontFace = new FontFace('TestFontFace', 'invalid');
+        shouldBeEqualToString("(new FontFace('asdf', 'url(notreal)', { weight: '100a 200' }, { stretch: 'semi-expanded expanded' })).status","error");
+        shouldBeEqualToString("(new FontFace('asdf', 'url(notreal)', { weight: '100a 200' }, { stretch: 'semi-expanded expanded' })).style","normal");
+        shouldBeEqualToString("(new FontFace('asdf', 'url(notreal)', { weight: '100a 200' }, { stretch: 'semi-expanded expanded' })).weight","normal");
+        shouldBeEqualToString("(new FontFace('asdf', 'url(notreal)', { weight: '100a 200' }, { stretch: 'semi-expanded expanded' })).stretch","normal");
+        shouldBeEqualToString("(new FontFace('asdf', 'url(notreal)', { weight: '100a 200' })).unicodeRange","U+0-10FFFF");
+        shouldBeEqualToString("(new FontFace('asdf', 'url(notreal)', { weight: '100a 200' })).featureSettings","normal");
+        shouldBeEqualToString("(new FontFace('asdf', 'url(notreal)', { weight: '100a 200' })).display","auto");
+        document.fonts.add(testFontFace);
+        debug("PASS: Did not throw");
+        
+    } catch (e) {
+        debug("Fail: Exception thrown: " + e);
+    }
+
+    debug("Good");
+
+    finishJSTest();
+}
+
+runTests();
+</script>
+<script src="/resources/js-test-post.js"></script>
+<div style="font-family: TestFontFace;">a</div>
+</body>
+</html>
+
index 1bb9914..1d49d2b 100644 (file)
@@ -2,5 +2,5 @@
 Testing actualBoundingBox
 Actual output:
 
-FAIL Testing actualBoundingBox The string did not match the expected pattern.
+FAIL Testing actualBoundingBox assert_equals: Math.abs(ctx.measureText('A').actualBoundingBoxDescent) === 0 (got 1[number], expected 0[number]) expected 0 but got 1
 
index 197f3ff..04f465e 100644 (file)
@@ -2,5 +2,5 @@
 Testing baselines
 Actual output:
 
-FAIL Testing baselines The string did not match the expected pattern.
+FAIL Testing baselines ctx.measureText('A').getBaselines is not a function. (In 'ctx.measureText('A').getBaselines()', 'ctx.measureText('A').getBaselines' is undefined)
 
index 4219f2e..3d06c88 100644 (file)
@@ -2,5 +2,5 @@
 Testing emHeights
 Actual output:
 
-FAIL Testing emHeights The string did not match the expected pattern.
+FAIL Testing emHeights assert_equals: ctx.measureText('A').emHeightAscent === 37.5 (got 85[number], expected 37.5[number]) expected 37.5 but got 85
 
index 7316d54..135008b 100644 (file)
@@ -2,5 +2,5 @@
 Space characters are converted to U+0020 and collapsed (per CSS)
 Actual output:
 
-FAIL Space characters are converted to U+0020 and collapsed (per CSS) The string did not match the expected pattern.
+FAIL Space characters are converted to U+0020 and collapsed (per CSS) assert_equals: ctx.measureText('A  B').width === 150 (got 200[number], expected 150[number]) expected 150 but got 200
 
index 09c6122..62d5fa1 100644 (file)
@@ -31,5 +31,5 @@ PASS getContext 2d
 PASS getContext webgl 
 PASS createImageData 
 PASS getImageData 
-FAIL FontFace's load() The string did not match the expected pattern.
+PASS FontFace's load() 
 
index 97f388d..b751dd6 100644 (file)
@@ -1,4 +1,4 @@
 
 FAIL FontFaceSetLoadEvent constructor without FontFaceSetLoadEventInit dictionary Can't find variable: FontFaceSetLoadEvent
-FAIL FontFaceSetLoadEvent constructor with FontFaceSetLoadEventInit dictionary The string did not match the expected pattern.
+FAIL FontFaceSetLoadEvent constructor with FontFaceSetLoadEventInit dictionary Can't find variable: FontFaceSetLoadEvent
 
index 163a981..64b2afd 100644 (file)
@@ -1,5 +1,5 @@
 
-FAIL idl_test setup promise_test: Unhandled rejection with value: object "SyntaxError: The string did not match the expected pattern."
+FAIL idl_test setup promise_test: Unhandled rejection with value: object "ReferenceError: Can't find variable: FontFaceSetLoadEvent"
 PASS idl_test validation 
 PASS Partial interface Document: member names are unique 
 PASS Partial interface Document[2]: member names are unique 
@@ -29,20 +29,20 @@ PASS FontFace interface: attribute display
 PASS FontFace interface: attribute status 
 PASS FontFace interface: operation load() 
 PASS FontFace interface: attribute loaded 
-FAIL FontFace must be primary interface of fontFace assert_equals: Unexpected exception when evaluating object expected null but got object "ReferenceError: Can't find variable: fontFace"
-FAIL Stringification of fontFace assert_equals: Unexpected exception when evaluating object expected null but got object "ReferenceError: Can't find variable: fontFace"
-FAIL FontFace interface: fontFace must inherit property "family" with the proper type assert_equals: Unexpected exception when evaluating object expected null but got object "ReferenceError: Can't find variable: fontFace"
-FAIL FontFace interface: fontFace must inherit property "style" with the proper type assert_equals: Unexpected exception when evaluating object expected null but got object "ReferenceError: Can't find variable: fontFace"
-FAIL FontFace interface: fontFace must inherit property "weight" with the proper type assert_equals: Unexpected exception when evaluating object expected null but got object "ReferenceError: Can't find variable: fontFace"
-FAIL FontFace interface: fontFace must inherit property "stretch" with the proper type assert_equals: Unexpected exception when evaluating object expected null but got object "ReferenceError: Can't find variable: fontFace"
-FAIL FontFace interface: fontFace must inherit property "unicodeRange" with the proper type assert_equals: Unexpected exception when evaluating object expected null but got object "ReferenceError: Can't find variable: fontFace"
-FAIL FontFace interface: fontFace must inherit property "variant" with the proper type assert_equals: Unexpected exception when evaluating object expected null but got object "ReferenceError: Can't find variable: fontFace"
-FAIL FontFace interface: fontFace must inherit property "featureSettings" with the proper type assert_equals: Unexpected exception when evaluating object expected null but got object "ReferenceError: Can't find variable: fontFace"
-FAIL FontFace interface: fontFace must inherit property "variationSettings" with the proper type assert_equals: Unexpected exception when evaluating object expected null but got object "ReferenceError: Can't find variable: fontFace"
-FAIL FontFace interface: fontFace must inherit property "display" with the proper type assert_equals: Unexpected exception when evaluating object expected null but got object "ReferenceError: Can't find variable: fontFace"
-FAIL FontFace interface: fontFace must inherit property "status" with the proper type assert_equals: Unexpected exception when evaluating object expected null but got object "ReferenceError: Can't find variable: fontFace"
-FAIL FontFace interface: fontFace must inherit property "load()" with the proper type assert_equals: Unexpected exception when evaluating object expected null but got object "ReferenceError: Can't find variable: fontFace"
-FAIL FontFace interface: fontFace must inherit property "loaded" with the proper type assert_equals: Unexpected exception when evaluating object expected null but got object "ReferenceError: Can't find variable: fontFace"
+PASS FontFace must be primary interface of fontFace 
+PASS Stringification of fontFace 
+PASS FontFace interface: fontFace must inherit property "family" with the proper type 
+PASS FontFace interface: fontFace must inherit property "style" with the proper type 
+PASS FontFace interface: fontFace must inherit property "weight" with the proper type 
+PASS FontFace interface: fontFace must inherit property "stretch" with the proper type 
+PASS FontFace interface: fontFace must inherit property "unicodeRange" with the proper type 
+FAIL FontFace interface: fontFace must inherit property "variant" with the proper type assert_inherits: property "variant" not found in prototype chain
+PASS FontFace interface: fontFace must inherit property "featureSettings" with the proper type 
+FAIL FontFace interface: fontFace must inherit property "variationSettings" with the proper type assert_inherits: property "variationSettings" not found in prototype chain
+PASS FontFace interface: fontFace must inherit property "display" with the proper type 
+PASS FontFace interface: fontFace must inherit property "status" with the proper type 
+PASS FontFace interface: fontFace must inherit property "load()" with the proper type 
+PASS FontFace interface: fontFace must inherit property "loaded" with the proper type 
 FAIL FontFaceSetLoadEvent interface: existence and properties of interface object assert_own_property: self does not have own property "FontFaceSetLoadEvent" expected property "FontFaceSetLoadEvent" missing
 FAIL FontFaceSetLoadEvent interface object length assert_own_property: self does not have own property "FontFaceSetLoadEvent" expected property "FontFaceSetLoadEvent" missing
 FAIL FontFaceSetLoadEvent interface object name assert_own_property: self does not have own property "FontFaceSetLoadEvent" expected property "FontFaceSetLoadEvent" missing
index 4aa31c2..f4e45e7 100644 (file)
@@ -1,3 +1,40 @@
+2020-02-14  Nikos Mouchtaris  <nmouchtaris@apple.com>
+
+        new FontFace() should not throw when failing to parse arguments
+        https://bugs.webkit.org/show_bug.cgi?id=205770
+
+        Reviewed by Myles Maxfield.
+
+        Change FontFace constructor to conform to API specification:
+        https://drafts.csswg.org/css-font-loading/#dom-fontface-fontface.
+        No longer throws. For parsing failure, now rejects promise, sets 
+        status to error, and sets FontFace members to default string.
+
+        Test: http/tests/css/font-face-constructor.html
+
+        * css/CSSFontFace.cpp:
+        (WebCore::CSSFontFace::setErrorState):
+        * css/CSSFontFace.h:
+        * css/CSSFontFaceSet.cpp:
+        (WebCore::CSSFontFaceSet::addToFacesLookupTable):
+        (WebCore::CSSFontFaceSet::remove):
+        (WebCore::CSSFontFaceSet::fontFace):
+        * css/CSSSegmentedFontFace.cpp:
+        (WebCore::CSSSegmentedFontFace::fontRanges):
+        * css/FontFace.cpp:
+        (WebCore::FontFace::setErrorState):
+        (WebCore::FontFace::create):
+        (WebCore::FontFace::family const):
+        (WebCore::FontFace::style const):
+        (WebCore::FontFace::weight const):
+        (WebCore::FontFace::stretch const):
+        (WebCore::FontFace::unicodeRange const):
+        (WebCore::FontFace::featureSettings const):
+        (WebCore::FontFace::display const):
+        (WebCore::FontFace::fontStateChanged):
+        * css/FontFace.h:
+        * css/FontFace.idl:
+
 2020-02-14  Youenn Fablet  <youenn@apple.com>
 
         Introduce MediaStreamPrivate::forEachTrack
index 0891db4..824b4eb 100644 (file)
@@ -712,4 +712,22 @@ bool CSSFontFace::hasSVGFontFaceSource() const
 }
 #endif
 
+void CSSFontFace::setErrorState()
+{
+    switch (m_status) {
+    case Status::Pending:
+        setStatus(Status::Loading);
+        break;
+    case Status::Success:
+        ASSERT_NOT_REACHED();
+        break;
+    case Status::Failure:
+        return;
+    default:
+        break;
+    }
+    
+    setStatus(Status::Failure);
+}
+
 }
index 909bb2e..c2c3650 100644 (file)
@@ -74,16 +74,28 @@ public:
     void setFeatureSettings(CSSValue&);
     void setLoadingBehavior(CSSValue&);
 
-    enum class Status : uint8_t;
+    // Pending => Loading  => TimedOut
+    //              ||  \\    //  ||
+    //              ||   \\  //   ||
+    //              ||    \\//    ||
+    //              ||     //     ||
+    //              ||    //\\    ||
+    //              ||   //  \\   ||
+    //              \/  \/    \/  \/
+    //             Success    Failure
+    enum class Status : uint8_t { Pending, Loading, TimedOut, Success, Failure };
+    
     struct UnicodeRange;
-    const CSSValueList* families() const { return m_families.get(); }
-    FontSelectionRange weight() const { return m_fontSelectionCapabilities.computeWeight(); }
-    FontSelectionRange stretch() const { return m_fontSelectionCapabilities.computeWidth(); }
-    FontSelectionRange italic() const { return m_fontSelectionCapabilities.computeSlope(); }
-    FontSelectionCapabilities fontSelectionCapabilities() const { return m_fontSelectionCapabilities.computeFontSelectionCapabilities(); }
-    const Vector<UnicodeRange>& ranges() const { return m_ranges; }
-    const FontFeatureSettings& featureSettings() const { return m_featureSettings; }
-    FontLoadingBehavior loadingBehavior() const { return m_loadingBehavior; }
+    
+    // Optional return values to represent default string for members of FontFace.h
+    const Optional<CSSValueList*> families() const { return m_status == Status::Failure ? WTF::nullopt : static_cast<Optional<CSSValueList*>>(m_families.get()); }
+    Optional<FontSelectionRange> weight() const { return m_status == Status::Failure ? WTF::nullopt : static_cast<Optional<FontSelectionRange>>(m_fontSelectionCapabilities.computeWeight()); }
+    Optional<FontSelectionRange> stretch() const { return m_status == Status::Failure ? WTF::nullopt : static_cast<Optional<FontSelectionRange>>(m_fontSelectionCapabilities.computeWidth()); }
+    Optional<FontSelectionRange> italic() const { return m_status == Status::Failure ? WTF::nullopt : static_cast<Optional<FontSelectionRange>>(m_fontSelectionCapabilities.computeSlope()); }
+    Optional<FontSelectionCapabilities> fontSelectionCapabilities() const { return m_status == Status::Failure ? WTF::nullopt : static_cast<Optional<FontSelectionCapabilities>>(m_fontSelectionCapabilities.computeFontSelectionCapabilities()); }
+    const Optional<Vector<UnicodeRange>> ranges() const { return m_status == Status::Failure ? WTF::nullopt : static_cast<Optional<Vector<UnicodeRange>>>(m_ranges); }
+    const Optional<FontFeatureSettings> featureSettings() const { return m_status == Status::Failure ? WTF::nullopt : static_cast<Optional<FontFeatureSettings>>(m_featureSettings); }
+    Optional<FontLoadingBehavior> loadingBehavior() const { return m_status == Status::Failure ? WTF::nullopt :  static_cast<Optional<FontLoadingBehavior>>(m_loadingBehavior); }
     void setWeight(FontSelectionRange weight) { m_fontSelectionCapabilities.weight = weight; }
     void setStretch(FontSelectionRange stretch) { m_fontSelectionCapabilities.width = stretch; }
     void setStyle(FontSelectionRange italic) { m_fontSelectionCapabilities.slope = italic; }
@@ -121,17 +133,6 @@ public:
         virtual void deref() = 0;
     };
 
-    // Pending => Loading  => TimedOut
-    //              ||  \\    //  ||
-    //              ||   \\  //   ||
-    //              ||    \\//    ||
-    //              ||     //     ||
-    //              ||    //\\    ||
-    //              ||   //  \\   ||
-    //              \/  \/    \/  \/
-    //             Success    Failure
-    enum class Status : uint8_t { Pending, Loading, TimedOut, Success, Failure };
-
     struct UnicodeRange {
         UChar32 from;
         UChar32 to;
@@ -162,6 +163,7 @@ public:
 #if ENABLE(SVG_FONTS)
     bool hasSVGFontFaceSource() const;
 #endif
+    void setErrorState();
 
 private:
     CSSFontFace(CSSFontSelector*, StyleRuleFontFace*, FontFace*, bool isLocalFallback);
index d7990a4..b5bcd20 100644 (file)
@@ -157,10 +157,11 @@ String CSSFontFaceSet::familyNameFromPrimitive(const CSSPrimitiveValue& value)
 
 void CSSFontFaceSet::addToFacesLookupTable(CSSFontFace& face)
 {
-    if (!face.families())
+    if (!face.families() || !face.families().hasValue())
         return;
+    auto families = face.families().value();
 
-    for (auto& item : *face.families()) {
+    for (auto& item : *families) {
         String familyName = CSSFontFaceSet::familyNameFromPrimitive(downcast<CSSPrimitiveValue>(item.get()));
         if (familyName.isEmpty())
             continue;
@@ -236,9 +237,9 @@ void CSSFontFaceSet::remove(const CSSFontFace& face)
 
     for (auto* client : m_clients)
         client->fontModified();
-
-    if (face.families())
-        removeFromFacesLookupTable(face, *face.families());
+    
+    if (face.families() && face.families().hasValue())
+        removeFromFacesLookupTable(face, *face.families().value());
 
     if (face.cssConnection()) {
         ASSERT(m_constituentCSSConnections.get(face.cssConnection()) == &face);
@@ -426,7 +427,10 @@ CSSSegmentedFontFace* CSSFontFaceSet::fontFace(FontSelectionRequest request, con
     Vector<std::reference_wrapper<CSSFontFace>, 32> candidateFontFaces;
     for (int i = familyFontFaces.size() - 1; i >= 0; --i) {
         CSSFontFace& candidate = familyFontFaces[i];
-        auto capabilities = candidate.fontSelectionCapabilities();
+        auto capabilitiesWrapped = candidate.fontSelectionCapabilities();
+        if (!capabilitiesWrapped.hasValue())
+            continue;
+        auto capabilities = capabilitiesWrapped.value();
         if (!isItalic(request.slope) && isItalic(capabilities.slope.minimum))
             continue;
         candidateFontFaces.append(candidate);
@@ -435,7 +439,10 @@ CSSSegmentedFontFace* CSSFontFaceSet::fontFace(FontSelectionRequest request, con
     auto localIterator = m_locallyInstalledFacesLookupTable.find(family);
     if (localIterator != m_locallyInstalledFacesLookupTable.end()) {
         for (auto& candidate : localIterator->value) {
-            auto capabilities = candidate->fontSelectionCapabilities();
+            auto capabilitiesWrapped = candidate->fontSelectionCapabilities();
+            if (!capabilitiesWrapped.hasValue())
+                continue;
+            auto capabilities = capabilitiesWrapped.value();
             if (!isItalic(request.slope) && isItalic(capabilities.slope.minimum))
                 continue;
             candidateFontFaces.append(candidate);
@@ -445,13 +452,20 @@ CSSSegmentedFontFace* CSSFontFaceSet::fontFace(FontSelectionRequest request, con
     if (!candidateFontFaces.isEmpty()) {
         Vector<FontSelectionCapabilities> capabilities;
         capabilities.reserveInitialCapacity(candidateFontFaces.size());
-        for (auto& face : candidateFontFaces)
-            capabilities.uncheckedAppend(face.get().fontSelectionCapabilities());
+        for (auto& face : candidateFontFaces) {
+            auto fontSelectionCapabilitiesWrapped = face.get().fontSelectionCapabilities();
+            ASSERT(fontSelectionCapabilitiesWrapped.hasValue());
+            auto fontSelectionCapabilities = fontSelectionCapabilitiesWrapped.value();
+            capabilities.uncheckedAppend(fontSelectionCapabilities);
+        }
         FontSelectionAlgorithm fontSelectionAlgorithm(request, capabilities);
         std::stable_sort(candidateFontFaces.begin(), candidateFontFaces.end(), [&fontSelectionAlgorithm](const CSSFontFace& first, const CSSFontFace& second) {
-            auto firstCapabilities = first.fontSelectionCapabilities();
-            auto secondCapabilities = second.fontSelectionCapabilities();
-
+            auto firstCapabilitiesWrapped = first.fontSelectionCapabilities();
+            auto secondCapabilitiesWrapped = second.fontSelectionCapabilities();
+            ASSERT(firstCapabilitiesWrapped.hasValue() && secondCapabilitiesWrapped.hasValue());
+            
+            auto firstCapabilities = firstCapabilitiesWrapped.value();
+            auto secondCapabilities = secondCapabilitiesWrapped.value();
             auto stretchDistanceFirst = fontSelectionAlgorithm.stretchDistance(firstCapabilities).distance;
             auto stretchDistanceSecond = fontSelectionAlgorithm.stretchDistance(secondCapabilities).distance;
             if (stretchDistanceFirst < stretchDistanceSecond)
index ae1ce5b..8bf44b0 100644 (file)
@@ -118,7 +118,10 @@ FontRanges CSSSegmentedFontFace::fontRanges(const FontDescription& fontDescripti
             if (face->computeFailureState())
                 continue;
 
-            auto selectionCapabilities = face->fontSelectionCapabilities();
+            auto selectionCapabilitiesWrapped = face->fontSelectionCapabilities();
+            ASSERT(selectionCapabilitiesWrapped.hasValue());
+            auto selectionCapabilities = selectionCapabilitiesWrapped.value();
+
             bool syntheticBold = (fontDescription.fontSynthesis() & FontSynthesisWeight) && !isFontWeightBold(selectionCapabilities.weight.maximum) && isFontWeightBold(desiredRequest.weight);
             bool syntheticItalic = (fontDescription.fontSynthesis() & FontSynthesisStyle) && !isItalic(selectionCapabilities.slope.maximum) && isItalic(desiredRequest.slope);
 
@@ -126,7 +129,11 @@ FontRanges CSSSegmentedFontFace::fontRanges(const FontDescription& fontDescripti
             auto fontAccessor = CSSFontAccessor::create(face, fontDescription, syntheticBold, syntheticItalic);
             if (result.isNull() && !fontAccessor->font(ExternalResourceDownloadPolicy::Forbid))
                 continue;
-            appendFont(result, WTFMove(fontAccessor), face->ranges());
+            
+            auto faceRangesWrapped = face->ranges();
+            ASSERT(faceRangesWrapped.hasValue());
+            auto faceRanges = faceRangesWrapped.value();
+            appendFont(result, WTFMove(fontAccessor), faceRanges);
         }
     }
     return result;
index 495c0cd..e18d6f5 100644 (file)
@@ -54,15 +54,23 @@ static bool populateFontFaceWithArrayBuffer(CSSFontFace& fontFace, Ref<JSC::Arra
     return false;
 }
 
-ExceptionOr<Ref<FontFace>> FontFace::create(Document& document, const String& family, Source&& source, const Descriptors& descriptors)
+void FontFace::setErrorState()
+{
+    m_loadedPromise->reject(Exception { SyntaxError });
+    m_backing->setErrorState();
+}
+
+Ref<FontFace> FontFace::create(Document& document, const String& family, Source&& source, const Descriptors& descriptors)
 {
     auto result = adoptRef(*new FontFace(document.fontSelector()));
 
     bool dataRequiresAsynchronousLoading = true;
 
     auto setFamilyResult = result->setFamily(document, family);
-    if (setFamilyResult.hasException())
-        return setFamilyResult.releaseException();
+    if (setFamilyResult.hasException()) {
+        result->setErrorState();
+        return result;
+    }
 
     auto sourceConversionResult = WTF::switchOn(source,
         [&] (String& string) -> ExceptionOr<void> {
@@ -84,28 +92,42 @@ ExceptionOr<Ref<FontFace>> FontFace::create(Document& document, const String& fa
         }
     );
 
-    if (sourceConversionResult.hasException())
-        return sourceConversionResult.releaseException();
+    if (sourceConversionResult.hasException()) {
+        result->setErrorState();
+        return result;
+    }
 
     // These ternaries match the default strings inside the FontFaceDescriptors dictionary inside FontFace.idl.
     auto setStyleResult = result->setStyle(descriptors.style.isEmpty() ? "normal"_s : descriptors.style);
-    if (setStyleResult.hasException())
-        return setStyleResult.releaseException();
+    if (setStyleResult.hasException()) {
+        result->setErrorState();
+        return result;
+    }
     auto setWeightResult = result->setWeight(descriptors.weight.isEmpty() ? "normal"_s : descriptors.weight);
-    if (setWeightResult.hasException())
-        return setWeightResult.releaseException();
+    if (setWeightResult.hasException()) {
+        result->setErrorState();
+        return result;
+    }
     auto setStretchResult = result->setStretch(descriptors.stretch.isEmpty() ? "normal"_s : descriptors.stretch);
-    if (setStretchResult.hasException())
-        return setStretchResult.releaseException();
+    if (setStretchResult.hasException()) {
+        result->setErrorState();
+        return result;
+    }
     auto setUnicodeRangeResult = result->setUnicodeRange(descriptors.unicodeRange.isEmpty() ? "U+0-10FFFF"_s : descriptors.unicodeRange);
-    if (setUnicodeRangeResult.hasException())
-        return setUnicodeRangeResult.releaseException();
+    if (setUnicodeRangeResult.hasException()) {
+        result->setErrorState();
+        return result;
+    }
     auto setFeatureSettingsResult = result->setFeatureSettings(descriptors.featureSettings.isEmpty() ? "normal"_s : descriptors.featureSettings);
-    if (setFeatureSettingsResult.hasException())
-        return setFeatureSettingsResult.releaseException();
+    if (setFeatureSettingsResult.hasException()) {
+        result->setErrorState();
+        return result;
+    }
     auto setDisplayResult = result->setDisplay(descriptors.display.isEmpty() ? "auto"_s : descriptors.display);
-    if (setDisplayResult.hasException())
-        return setDisplayResult.releaseException();
+    if (setDisplayResult.hasException()) {
+        result->setErrorState();
+        return result;
+    }
 
     if (!dataRequiresAsynchronousLoading) {
         result->backing().load();
@@ -243,11 +265,15 @@ String FontFace::family() const
 {
     m_backing->updateStyleIfNeeded();
 
+    const auto& families = m_backing->families();
+    if (!families.hasValue())
+        return "normal"_s;
+    auto familiesUnrwapped = families.value();
     // FIXME: https://bugs.webkit.org/show_bug.cgi?id=196381 This is only here because CSSFontFace erroneously uses a list of values instead of a single value.
     // See consumeFontFamilyDescriptor() in CSSPropertyParser.cpp.
-    if (m_backing->families()->length() == 1) {
-        if (m_backing->families()->item(0)) {
-            auto& item = *m_backing->families()->item(0);
+    if (familiesUnrwapped->length() == 1) {
+        if (familiesUnrwapped->item(0)) {
+            auto& item = *familiesUnrwapped->item(0);
             if (item.isPrimitiveValue()) {
                 auto& primitiveValue = downcast<CSSPrimitiveValue>(item);
                 if (primitiveValue.isFontFamily()) {
@@ -257,14 +283,17 @@ String FontFace::family() const
             }
         }
     }
-    return m_backing->families()->cssText();
+    return familiesUnrwapped->cssText();
 }
 
 String FontFace::style() const
 {
     m_backing->updateStyleIfNeeded();
-    auto style = m_backing->italic();
-
+    const auto& styleWrapped = m_backing->italic();
+    
+    if (!styleWrapped.hasValue())
+        return "normal"_s;
+    auto style = styleWrapped.value();
     auto minimum = ComputedStyleExtractor::fontStyleFromStyleValue(style.minimum, FontStyleAxis::ital);
     auto maximum = ComputedStyleExtractor::fontStyleFromStyleValue(style.maximum, FontStyleAxis::ital);
 
@@ -288,13 +317,16 @@ String FontFace::style() const
         builder.append(maximumNonKeyword->obliqueValue->cssText());
     }
     return builder.toString();
+    
 }
 
 String FontFace::weight() const
 {
     m_backing->updateStyleIfNeeded();
-    auto weight = m_backing->weight();
-
+    const auto& weightWrapped = m_backing->weight();
+    if (!weightWrapped.hasValue())
+        return "normal"_s;
+    auto weight = weightWrapped.value();
     auto minimum = ComputedStyleExtractor::fontWeightFromStyleValue(weight.minimum);
     auto maximum = ComputedStyleExtractor::fontWeightFromStyleValue(weight.maximum);
 
@@ -314,8 +346,10 @@ String FontFace::weight() const
 String FontFace::stretch() const
 {
     m_backing->updateStyleIfNeeded();
-    auto stretch = m_backing->stretch();
-
+    const auto& stretchWrapped = m_backing->stretch();
+    if (!stretchWrapped.hasValue())
+        return "normal"_s;
+    auto stretch = stretchWrapped.value();
     auto minimum = ComputedStyleExtractor::fontStretchFromStyleValue(stretch.minimum);
     auto maximum = ComputedStyleExtractor::fontStretchFromStyleValue(stretch.maximum);
 
@@ -335,10 +369,14 @@ String FontFace::stretch() const
 String FontFace::unicodeRange() const
 {
     m_backing->updateStyleIfNeeded();
-    if (!m_backing->ranges().size())
+    const auto& rangesWrapped = m_backing->ranges();
+    if (!rangesWrapped.hasValue())
+        return "U+0-10FFFF";
+    auto ranges = rangesWrapped.value();
+    if (!ranges.size())
         return "U+0-10FFFF"_s;
     auto values = CSSValueList::createCommaSeparated();
-    for (auto& range : m_backing->ranges())
+    for (auto& range : ranges)
         values->append(CSSUnicodeRangeValue::create(range.from, range.to));
     return values->cssText();
 }
@@ -346,10 +384,14 @@ String FontFace::unicodeRange() const
 String FontFace::featureSettings() const
 {
     m_backing->updateStyleIfNeeded();
-    if (!m_backing->featureSettings().size())
+    const auto& featureSettingsWrapped = m_backing->featureSettings();
+    if (!featureSettingsWrapped.hasValue())
+        return "normal"_s;
+    auto featureSettings = featureSettingsWrapped.value();
+    if (!featureSettings.size())
         return "normal"_s;
     auto list = CSSValueList::createCommaSeparated();
-    for (auto& feature : m_backing->featureSettings())
+    for (auto& feature : featureSettings)
         list->append(CSSFontFeatureValue::create(FontTag(feature.tag()), feature.value()));
     return list->cssText();
 }
@@ -357,7 +399,10 @@ String FontFace::featureSettings() const
 String FontFace::display() const
 {
     m_backing->updateStyleIfNeeded();
-    return CSSValuePool::singleton().createValue(m_backing->loadingBehavior())->cssText();
+    const auto& loadingBehaviorWrapped = m_backing->loadingBehavior();
+    if (!loadingBehaviorWrapped.hasValue())
+        return "auto"_s;
+    return CSSValuePool::singleton().createValue(loadingBehaviorWrapped.value())->cssText();
 }
 
 auto FontFace::status() const -> LoadStatus
@@ -398,14 +443,14 @@ void FontFace::fontStateChanged(CSSFontFace& face, CSSFontFace::Status, CSSFontF
         break;
     case CSSFontFace::Status::Success:
         // FIXME: This check should not be needed, but because FontFace's are sometimes adopted after they have already
-        // gone through a load cycle, we can sometimes come back through here and try to resolve the promise again.  
+        // gone through a load cycle, we can sometimes come back through here and try to resolve the promise again.
         if (!m_loadedPromise->isFulfilled())
             m_loadedPromise->resolve(*this);
         deref();
         return;
     case CSSFontFace::Status::Failure:
         // FIXME: This check should not be needed, but because FontFace's are sometimes adopted after they have already
-        // gone through a load cycle, we can sometimes come back through here and try to resolve the promise again.  
+        // gone through a load cycle, we can sometimes come back through here and try to resolve the promise again.
         if (!m_loadedPromise->isFulfilled())
             m_loadedPromise->reject(Exception { NetworkError });
         deref();
index cbeda5c..79d0880 100644 (file)
@@ -53,7 +53,7 @@ public:
     };
     
     using Source = Variant<String, RefPtr<JSC::ArrayBuffer>, RefPtr<JSC::ArrayBufferView>>;
-    static ExceptionOr<Ref<FontFace>> create(Document&, const String& family, Source&&, const Descriptors&);
+    static Ref<FontFace> create(Document&, const String& family, Source&&, const Descriptors&);
     static Ref<FontFace> create(CSSFontFace&);
     virtual ~FontFace();
 
@@ -94,10 +94,9 @@ public:
 private:
     explicit FontFace(CSSFontSelector&);
     explicit FontFace(CSSFontFace&);
-
     // Callback for LoadedPromise.
     FontFace& loadedPromiseResolve();
-
+    void setErrorState();
     Ref<CSSFontFace> m_backing;
     UniqueRef<LoadedPromise> m_loadedPromise;
 };
index 2cbc07e..aaeec86 100644 (file)
@@ -43,7 +43,6 @@ dictionary FontFaceDescriptors {
 
 [
     ConstructorCallWith=Document,
-    ConstructorMayThrowException,
     Constructor(DOMString family, (DOMString or BinaryData) source, optional FontFaceDescriptors descriptors)
 ] interface FontFace {
     [SetterCallWith=Document] attribute DOMString family;